4 * Copyright (c) 2003 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 #include "qemu/osdep.h"
21 #include "qemu/host-utils.h"
23 #include "disas/disas.h"
24 #include "exec/exec-all.h"
26 #include "exec/cpu_ldst.h"
27 #include "exec/translator.h"
29 #include "exec/helper-proto.h"
30 #include "exec/helper-gen.h"
32 #include "trace-tcg.h"
35 #define PREFIX_REPZ 0x01
36 #define PREFIX_REPNZ 0x02
37 #define PREFIX_LOCK 0x04
38 #define PREFIX_DATA 0x08
39 #define PREFIX_ADR 0x10
40 #define PREFIX_VEX 0x20
43 #define CODE64(s) ((s)->code64)
44 #define REX_X(s) ((s)->rex_x)
45 #define REX_B(s) ((s)->rex_b)
60 /* For a switch indexed by MODRM, match all memory operands for a given OP. */
61 #define CASE_MODRM_MEM_OP(OP) \
62 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
63 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
64 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7
66 #define CASE_MODRM_OP(OP) \
67 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
68 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
69 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7: \
70 case (3 << 6) | (OP << 3) | 0 ... (3 << 6) | (OP << 3) | 7
72 //#define MACRO_TEST 1
74 /* global register indexes */
75 static TCGv_env cpu_env;
77 static TCGv cpu_cc_dst, cpu_cc_src, cpu_cc_src2, cpu_cc_srcT;
78 static TCGv_i32 cpu_cc_op;
79 static TCGv cpu_regs[CPU_NB_REGS];
80 static TCGv cpu_seg_base[6];
81 static TCGv_i64 cpu_bndl[4];
82 static TCGv_i64 cpu_bndu[4];
84 static TCGv cpu_T0, cpu_T1;
85 /* local register indexes (only used inside old micro ops) */
86 static TCGv cpu_tmp0, cpu_tmp4;
87 static TCGv_ptr cpu_ptr0, cpu_ptr1;
88 static TCGv_i32 cpu_tmp2_i32, cpu_tmp3_i32;
89 static TCGv_i64 cpu_tmp1_i64;
91 #include "exec/gen-icount.h"
94 static int x86_64_hregs;
97 typedef struct DisasContext {
98 DisasContextBase base;
100 /* current insn context */
101 int override; /* -1 if no override */
105 target_ulong pc_start;
106 target_ulong pc; /* pc = eip + cs_base */
107 /* current block context */
108 target_ulong cs_base; /* base of CS segment */
109 int pe; /* protected mode */
110 int code32; /* 32 bit code segment */
112 int lma; /* long mode active */
113 int code64; /* 64 bit code segment */
116 int vex_l; /* vex vector length */
117 int vex_v; /* vex vvvv register, without 1's compliment. */
118 int ss32; /* 32 bit stack segment */
119 CCOp cc_op; /* current CC operation */
121 int addseg; /* non zero if either DS/ES/SS have a non zero base */
122 int f_st; /* currently unused */
123 int vm86; /* vm86 mode */
126 int tf; /* TF cpu flag */
127 int jmp_opt; /* use direct block chaining for direct jumps */
128 int repz_opt; /* optimize jumps within repz instructions */
129 int mem_index; /* select memory access functions */
130 uint64_t flags; /* all execution flags */
131 int popl_esp_hack; /* for correct popl with esp base handling */
132 int rip_offset; /* only used in x86_64, but left for simplicity */
134 int cpuid_ext_features;
135 int cpuid_ext2_features;
136 int cpuid_ext3_features;
137 int cpuid_7_0_ebx_features;
138 int cpuid_xsave_features;
142 static void gen_eob(DisasContext *s);
143 static void gen_jr(DisasContext *s, TCGv dest);
144 static void gen_jmp(DisasContext *s, target_ulong eip);
145 static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num);
146 static void gen_op(DisasContext *s1, int op, TCGMemOp ot, int d);
148 /* i386 arith/logic operations */
168 OP_SHL1, /* undocumented */
184 /* I386 int registers */
185 OR_EAX, /* MUST be even numbered */
194 OR_TMP0 = 16, /* temporary operand register */
196 OR_A0, /* temporary register used when doing address evaluation */
206 /* Bit set if the global variable is live after setting CC_OP to X. */
207 static const uint8_t cc_op_live[CC_OP_NB] = {
208 [CC_OP_DYNAMIC] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
209 [CC_OP_EFLAGS] = USES_CC_SRC,
210 [CC_OP_MULB ... CC_OP_MULQ] = USES_CC_DST | USES_CC_SRC,
211 [CC_OP_ADDB ... CC_OP_ADDQ] = USES_CC_DST | USES_CC_SRC,
212 [CC_OP_ADCB ... CC_OP_ADCQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
213 [CC_OP_SUBB ... CC_OP_SUBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRCT,
214 [CC_OP_SBBB ... CC_OP_SBBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
215 [CC_OP_LOGICB ... CC_OP_LOGICQ] = USES_CC_DST,
216 [CC_OP_INCB ... CC_OP_INCQ] = USES_CC_DST | USES_CC_SRC,
217 [CC_OP_DECB ... CC_OP_DECQ] = USES_CC_DST | USES_CC_SRC,
218 [CC_OP_SHLB ... CC_OP_SHLQ] = USES_CC_DST | USES_CC_SRC,
219 [CC_OP_SARB ... CC_OP_SARQ] = USES_CC_DST | USES_CC_SRC,
220 [CC_OP_BMILGB ... CC_OP_BMILGQ] = USES_CC_DST | USES_CC_SRC,
221 [CC_OP_ADCX] = USES_CC_DST | USES_CC_SRC,
222 [CC_OP_ADOX] = USES_CC_SRC | USES_CC_SRC2,
223 [CC_OP_ADCOX] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
225 [CC_OP_POPCNT] = USES_CC_SRC,
228 static void set_cc_op(DisasContext *s, CCOp op)
232 if (s->cc_op == op) {
236 /* Discard CC computation that will no longer be used. */
237 dead = cc_op_live[s->cc_op] & ~cc_op_live[op];
238 if (dead & USES_CC_DST) {
239 tcg_gen_discard_tl(cpu_cc_dst);
241 if (dead & USES_CC_SRC) {
242 tcg_gen_discard_tl(cpu_cc_src);
244 if (dead & USES_CC_SRC2) {
245 tcg_gen_discard_tl(cpu_cc_src2);
247 if (dead & USES_CC_SRCT) {
248 tcg_gen_discard_tl(cpu_cc_srcT);
251 if (op == CC_OP_DYNAMIC) {
252 /* The DYNAMIC setting is translator only, and should never be
253 stored. Thus we always consider it clean. */
254 s->cc_op_dirty = false;
256 /* Discard any computed CC_OP value (see shifts). */
257 if (s->cc_op == CC_OP_DYNAMIC) {
258 tcg_gen_discard_i32(cpu_cc_op);
260 s->cc_op_dirty = true;
265 static void gen_update_cc_op(DisasContext *s)
267 if (s->cc_op_dirty) {
268 tcg_gen_movi_i32(cpu_cc_op, s->cc_op);
269 s->cc_op_dirty = false;
275 #define NB_OP_SIZES 4
277 #else /* !TARGET_X86_64 */
279 #define NB_OP_SIZES 3
281 #endif /* !TARGET_X86_64 */
283 #if defined(HOST_WORDS_BIGENDIAN)
284 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
285 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
286 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
287 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
288 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
290 #define REG_B_OFFSET 0
291 #define REG_H_OFFSET 1
292 #define REG_W_OFFSET 0
293 #define REG_L_OFFSET 0
294 #define REG_LH_OFFSET 4
297 /* In instruction encodings for byte register accesses the
298 * register number usually indicates "low 8 bits of register N";
299 * however there are some special cases where N 4..7 indicates
300 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
301 * true for this special case, false otherwise.
303 static inline bool byte_reg_is_xH(int reg)
309 if (reg >= 8 || x86_64_hregs) {
316 /* Select the size of a push/pop operation. */
317 static inline TCGMemOp mo_pushpop(DisasContext *s, TCGMemOp ot)
320 return ot == MO_16 ? MO_16 : MO_64;
326 /* Select the size of the stack pointer. */
327 static inline TCGMemOp mo_stacksize(DisasContext *s)
329 return CODE64(s) ? MO_64 : s->ss32 ? MO_32 : MO_16;
332 /* Select only size 64 else 32. Used for SSE operand sizes. */
333 static inline TCGMemOp mo_64_32(TCGMemOp ot)
336 return ot == MO_64 ? MO_64 : MO_32;
342 /* Select size 8 if lsb of B is clear, else OT. Used for decoding
343 byte vs word opcodes. */
344 static inline TCGMemOp mo_b_d(int b, TCGMemOp ot)
346 return b & 1 ? ot : MO_8;
349 /* Select size 8 if lsb of B is clear, else OT capped at 32.
350 Used for decoding operand size of port opcodes. */
351 static inline TCGMemOp mo_b_d32(int b, TCGMemOp ot)
353 return b & 1 ? (ot == MO_16 ? MO_16 : MO_32) : MO_8;
356 static void gen_op_mov_reg_v(TCGMemOp ot, int reg, TCGv t0)
360 if (!byte_reg_is_xH(reg)) {
361 tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 8);
363 tcg_gen_deposit_tl(cpu_regs[reg - 4], cpu_regs[reg - 4], t0, 8, 8);
367 tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 16);
370 /* For x86_64, this sets the higher half of register to zero.
371 For i386, this is equivalent to a mov. */
372 tcg_gen_ext32u_tl(cpu_regs[reg], t0);
376 tcg_gen_mov_tl(cpu_regs[reg], t0);
384 static inline void gen_op_mov_v_reg(TCGMemOp ot, TCGv t0, int reg)
386 if (ot == MO_8 && byte_reg_is_xH(reg)) {
387 tcg_gen_extract_tl(t0, cpu_regs[reg - 4], 8, 8);
389 tcg_gen_mov_tl(t0, cpu_regs[reg]);
393 static void gen_add_A0_im(DisasContext *s, int val)
395 tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
397 tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
401 static inline void gen_op_jmp_v(TCGv dest)
403 tcg_gen_st_tl(dest, cpu_env, offsetof(CPUX86State, eip));
406 static inline void gen_op_add_reg_im(TCGMemOp size, int reg, int32_t val)
408 tcg_gen_addi_tl(cpu_tmp0, cpu_regs[reg], val);
409 gen_op_mov_reg_v(size, reg, cpu_tmp0);
412 static inline void gen_op_add_reg_T0(TCGMemOp size, int reg)
414 tcg_gen_add_tl(cpu_tmp0, cpu_regs[reg], cpu_T0);
415 gen_op_mov_reg_v(size, reg, cpu_tmp0);
418 static inline void gen_op_ld_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
420 tcg_gen_qemu_ld_tl(t0, a0, s->mem_index, idx | MO_LE);
423 static inline void gen_op_st_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
425 tcg_gen_qemu_st_tl(t0, a0, s->mem_index, idx | MO_LE);
428 static inline void gen_op_st_rm_T0_A0(DisasContext *s, int idx, int d)
431 gen_op_st_v(s, idx, cpu_T0, cpu_A0);
433 gen_op_mov_reg_v(idx, d, cpu_T0);
437 static inline void gen_jmp_im(target_ulong pc)
439 tcg_gen_movi_tl(cpu_tmp0, pc);
440 gen_op_jmp_v(cpu_tmp0);
443 /* Compute SEG:REG into A0. SEG is selected from the override segment
444 (OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to
445 indicate no override. */
446 static void gen_lea_v_seg(DisasContext *s, TCGMemOp aflag, TCGv a0,
447 int def_seg, int ovr_seg)
453 tcg_gen_mov_tl(cpu_A0, a0);
460 if (ovr_seg < 0 && s->addseg) {
464 tcg_gen_ext32u_tl(cpu_A0, a0);
470 tcg_gen_ext16u_tl(cpu_A0, a0);
485 TCGv seg = cpu_seg_base[ovr_seg];
487 if (aflag == MO_64) {
488 tcg_gen_add_tl(cpu_A0, a0, seg);
489 } else if (CODE64(s)) {
490 tcg_gen_ext32u_tl(cpu_A0, a0);
491 tcg_gen_add_tl(cpu_A0, cpu_A0, seg);
493 tcg_gen_add_tl(cpu_A0, a0, seg);
494 tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
499 static inline void gen_string_movl_A0_ESI(DisasContext *s)
501 gen_lea_v_seg(s, s->aflag, cpu_regs[R_ESI], R_DS, s->override);
504 static inline void gen_string_movl_A0_EDI(DisasContext *s)
506 gen_lea_v_seg(s, s->aflag, cpu_regs[R_EDI], R_ES, -1);
509 static inline void gen_op_movl_T0_Dshift(TCGMemOp ot)
511 tcg_gen_ld32s_tl(cpu_T0, cpu_env, offsetof(CPUX86State, df));
512 tcg_gen_shli_tl(cpu_T0, cpu_T0, ot);
515 static TCGv gen_ext_tl(TCGv dst, TCGv src, TCGMemOp size, bool sign)
520 tcg_gen_ext8s_tl(dst, src);
522 tcg_gen_ext8u_tl(dst, src);
527 tcg_gen_ext16s_tl(dst, src);
529 tcg_gen_ext16u_tl(dst, src);
535 tcg_gen_ext32s_tl(dst, src);
537 tcg_gen_ext32u_tl(dst, src);
546 static void gen_extu(TCGMemOp ot, TCGv reg)
548 gen_ext_tl(reg, reg, ot, false);
551 static void gen_exts(TCGMemOp ot, TCGv reg)
553 gen_ext_tl(reg, reg, ot, true);
556 static inline void gen_op_jnz_ecx(TCGMemOp size, TCGLabel *label1)
558 tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
559 gen_extu(size, cpu_tmp0);
560 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_tmp0, 0, label1);
563 static inline void gen_op_jz_ecx(TCGMemOp size, TCGLabel *label1)
565 tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
566 gen_extu(size, cpu_tmp0);
567 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
570 static void gen_helper_in_func(TCGMemOp ot, TCGv v, TCGv_i32 n)
574 gen_helper_inb(v, cpu_env, n);
577 gen_helper_inw(v, cpu_env, n);
580 gen_helper_inl(v, cpu_env, n);
587 static void gen_helper_out_func(TCGMemOp ot, TCGv_i32 v, TCGv_i32 n)
591 gen_helper_outb(cpu_env, v, n);
594 gen_helper_outw(cpu_env, v, n);
597 gen_helper_outl(cpu_env, v, n);
604 static void gen_check_io(DisasContext *s, TCGMemOp ot, target_ulong cur_eip,
607 target_ulong next_eip;
609 if (s->pe && (s->cpl > s->iopl || s->vm86)) {
610 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
613 gen_helper_check_iob(cpu_env, cpu_tmp2_i32);
616 gen_helper_check_iow(cpu_env, cpu_tmp2_i32);
619 gen_helper_check_iol(cpu_env, cpu_tmp2_i32);
625 if(s->flags & HF_SVMI_MASK) {
628 svm_flags |= (1 << (4 + ot));
629 next_eip = s->pc - s->cs_base;
630 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
631 gen_helper_svm_check_io(cpu_env, cpu_tmp2_i32,
632 tcg_const_i32(svm_flags),
633 tcg_const_i32(next_eip - cur_eip));
637 static inline void gen_movs(DisasContext *s, TCGMemOp ot)
639 gen_string_movl_A0_ESI(s);
640 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
641 gen_string_movl_A0_EDI(s);
642 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
643 gen_op_movl_T0_Dshift(ot);
644 gen_op_add_reg_T0(s->aflag, R_ESI);
645 gen_op_add_reg_T0(s->aflag, R_EDI);
648 static void gen_op_update1_cc(void)
650 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
653 static void gen_op_update2_cc(void)
655 tcg_gen_mov_tl(cpu_cc_src, cpu_T1);
656 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
659 static void gen_op_update3_cc(TCGv reg)
661 tcg_gen_mov_tl(cpu_cc_src2, reg);
662 tcg_gen_mov_tl(cpu_cc_src, cpu_T1);
663 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
666 static inline void gen_op_testl_T0_T1_cc(void)
668 tcg_gen_and_tl(cpu_cc_dst, cpu_T0, cpu_T1);
671 static void gen_op_update_neg_cc(void)
673 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
674 tcg_gen_neg_tl(cpu_cc_src, cpu_T0);
675 tcg_gen_movi_tl(cpu_cc_srcT, 0);
678 /* compute all eflags to cc_src */
679 static void gen_compute_eflags(DisasContext *s)
681 TCGv zero, dst, src1, src2;
684 if (s->cc_op == CC_OP_EFLAGS) {
687 if (s->cc_op == CC_OP_CLR) {
688 tcg_gen_movi_tl(cpu_cc_src, CC_Z | CC_P);
689 set_cc_op(s, CC_OP_EFLAGS);
698 /* Take care to not read values that are not live. */
699 live = cc_op_live[s->cc_op] & ~USES_CC_SRCT;
700 dead = live ^ (USES_CC_DST | USES_CC_SRC | USES_CC_SRC2);
702 zero = tcg_const_tl(0);
703 if (dead & USES_CC_DST) {
706 if (dead & USES_CC_SRC) {
709 if (dead & USES_CC_SRC2) {
715 gen_helper_cc_compute_all(cpu_cc_src, dst, src1, src2, cpu_cc_op);
716 set_cc_op(s, CC_OP_EFLAGS);
723 typedef struct CCPrepare {
733 /* compute eflags.C to reg */
734 static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg)
740 case CC_OP_SUBB ... CC_OP_SUBQ:
741 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
742 size = s->cc_op - CC_OP_SUBB;
743 t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
744 /* If no temporary was used, be careful not to alias t1 and t0. */
745 t0 = TCGV_EQUAL(t1, cpu_cc_src) ? cpu_tmp0 : reg;
746 tcg_gen_mov_tl(t0, cpu_cc_srcT);
750 case CC_OP_ADDB ... CC_OP_ADDQ:
751 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
752 size = s->cc_op - CC_OP_ADDB;
753 t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
754 t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
756 return (CCPrepare) { .cond = TCG_COND_LTU, .reg = t0,
757 .reg2 = t1, .mask = -1, .use_reg2 = true };
759 case CC_OP_LOGICB ... CC_OP_LOGICQ:
762 return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
764 case CC_OP_INCB ... CC_OP_INCQ:
765 case CC_OP_DECB ... CC_OP_DECQ:
766 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
767 .mask = -1, .no_setcond = true };
769 case CC_OP_SHLB ... CC_OP_SHLQ:
770 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
771 size = s->cc_op - CC_OP_SHLB;
772 shift = (8 << size) - 1;
773 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
774 .mask = (target_ulong)1 << shift };
776 case CC_OP_MULB ... CC_OP_MULQ:
777 return (CCPrepare) { .cond = TCG_COND_NE,
778 .reg = cpu_cc_src, .mask = -1 };
780 case CC_OP_BMILGB ... CC_OP_BMILGQ:
781 size = s->cc_op - CC_OP_BMILGB;
782 t0 = gen_ext_tl(reg, cpu_cc_src, size, false);
783 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 };
787 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_dst,
788 .mask = -1, .no_setcond = true };
791 case CC_OP_SARB ... CC_OP_SARQ:
793 return (CCPrepare) { .cond = TCG_COND_NE,
794 .reg = cpu_cc_src, .mask = CC_C };
797 /* The need to compute only C from CC_OP_DYNAMIC is important
798 in efficiently implementing e.g. INC at the start of a TB. */
800 gen_helper_cc_compute_c(reg, cpu_cc_dst, cpu_cc_src,
801 cpu_cc_src2, cpu_cc_op);
802 return (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
803 .mask = -1, .no_setcond = true };
807 /* compute eflags.P to reg */
808 static CCPrepare gen_prepare_eflags_p(DisasContext *s, TCGv reg)
810 gen_compute_eflags(s);
811 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
815 /* compute eflags.S to reg */
816 static CCPrepare gen_prepare_eflags_s(DisasContext *s, TCGv reg)
820 gen_compute_eflags(s);
826 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
830 return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
833 TCGMemOp size = (s->cc_op - CC_OP_ADDB) & 3;
834 TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, true);
835 return (CCPrepare) { .cond = TCG_COND_LT, .reg = t0, .mask = -1 };
840 /* compute eflags.O to reg */
841 static CCPrepare gen_prepare_eflags_o(DisasContext *s, TCGv reg)
846 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src2,
847 .mask = -1, .no_setcond = true };
850 return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
852 gen_compute_eflags(s);
853 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
858 /* compute eflags.Z to reg */
859 static CCPrepare gen_prepare_eflags_z(DisasContext *s, TCGv reg)
863 gen_compute_eflags(s);
869 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
872 return (CCPrepare) { .cond = TCG_COND_ALWAYS, .mask = -1 };
874 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = cpu_cc_src,
878 TCGMemOp size = (s->cc_op - CC_OP_ADDB) & 3;
879 TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
880 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 };
885 /* perform a conditional store into register 'reg' according to jump opcode
886 value 'b'. In the fast case, T0 is guaranted not to be used. */
887 static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg)
889 int inv, jcc_op, cond;
895 jcc_op = (b >> 1) & 7;
898 case CC_OP_SUBB ... CC_OP_SUBQ:
899 /* We optimize relational operators for the cmp/jcc case. */
900 size = s->cc_op - CC_OP_SUBB;
903 tcg_gen_mov_tl(cpu_tmp4, cpu_cc_srcT);
904 gen_extu(size, cpu_tmp4);
905 t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
906 cc = (CCPrepare) { .cond = TCG_COND_LEU, .reg = cpu_tmp4,
907 .reg2 = t0, .mask = -1, .use_reg2 = true };
916 tcg_gen_mov_tl(cpu_tmp4, cpu_cc_srcT);
917 gen_exts(size, cpu_tmp4);
918 t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, true);
919 cc = (CCPrepare) { .cond = cond, .reg = cpu_tmp4,
920 .reg2 = t0, .mask = -1, .use_reg2 = true };
930 /* This actually generates good code for JC, JZ and JS. */
933 cc = gen_prepare_eflags_o(s, reg);
936 cc = gen_prepare_eflags_c(s, reg);
939 cc = gen_prepare_eflags_z(s, reg);
942 gen_compute_eflags(s);
943 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
944 .mask = CC_Z | CC_C };
947 cc = gen_prepare_eflags_s(s, reg);
950 cc = gen_prepare_eflags_p(s, reg);
953 gen_compute_eflags(s);
954 if (TCGV_EQUAL(reg, cpu_cc_src)) {
957 tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */
958 tcg_gen_xor_tl(reg, reg, cpu_cc_src);
959 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
964 gen_compute_eflags(s);
965 if (TCGV_EQUAL(reg, cpu_cc_src)) {
968 tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */
969 tcg_gen_xor_tl(reg, reg, cpu_cc_src);
970 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
971 .mask = CC_S | CC_Z };
978 cc.cond = tcg_invert_cond(cc.cond);
983 static void gen_setcc1(DisasContext *s, int b, TCGv reg)
985 CCPrepare cc = gen_prepare_cc(s, b, reg);
988 if (cc.cond == TCG_COND_EQ) {
989 tcg_gen_xori_tl(reg, cc.reg, 1);
991 tcg_gen_mov_tl(reg, cc.reg);
996 if (cc.cond == TCG_COND_NE && !cc.use_reg2 && cc.imm == 0 &&
997 cc.mask != 0 && (cc.mask & (cc.mask - 1)) == 0) {
998 tcg_gen_shri_tl(reg, cc.reg, ctztl(cc.mask));
999 tcg_gen_andi_tl(reg, reg, 1);
1002 if (cc.mask != -1) {
1003 tcg_gen_andi_tl(reg, cc.reg, cc.mask);
1007 tcg_gen_setcond_tl(cc.cond, reg, cc.reg, cc.reg2);
1009 tcg_gen_setcondi_tl(cc.cond, reg, cc.reg, cc.imm);
1013 static inline void gen_compute_eflags_c(DisasContext *s, TCGv reg)
1015 gen_setcc1(s, JCC_B << 1, reg);
1018 /* generate a conditional jump to label 'l1' according to jump opcode
1019 value 'b'. In the fast case, T0 is guaranted not to be used. */
1020 static inline void gen_jcc1_noeob(DisasContext *s, int b, TCGLabel *l1)
1022 CCPrepare cc = gen_prepare_cc(s, b, cpu_T0);
1024 if (cc.mask != -1) {
1025 tcg_gen_andi_tl(cpu_T0, cc.reg, cc.mask);
1029 tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1031 tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1035 /* Generate a conditional jump to label 'l1' according to jump opcode
1036 value 'b'. In the fast case, T0 is guaranted not to be used.
1037 A translation block must end soon. */
1038 static inline void gen_jcc1(DisasContext *s, int b, TCGLabel *l1)
1040 CCPrepare cc = gen_prepare_cc(s, b, cpu_T0);
1042 gen_update_cc_op(s);
1043 if (cc.mask != -1) {
1044 tcg_gen_andi_tl(cpu_T0, cc.reg, cc.mask);
1047 set_cc_op(s, CC_OP_DYNAMIC);
1049 tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1051 tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1055 /* XXX: does not work with gdbstub "ice" single step - not a
1057 static TCGLabel *gen_jz_ecx_string(DisasContext *s, target_ulong next_eip)
1059 TCGLabel *l1 = gen_new_label();
1060 TCGLabel *l2 = gen_new_label();
1061 gen_op_jnz_ecx(s->aflag, l1);
1063 gen_jmp_tb(s, next_eip, 1);
1068 static inline void gen_stos(DisasContext *s, TCGMemOp ot)
1070 gen_op_mov_v_reg(MO_32, cpu_T0, R_EAX);
1071 gen_string_movl_A0_EDI(s);
1072 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
1073 gen_op_movl_T0_Dshift(ot);
1074 gen_op_add_reg_T0(s->aflag, R_EDI);
1077 static inline void gen_lods(DisasContext *s, TCGMemOp ot)
1079 gen_string_movl_A0_ESI(s);
1080 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1081 gen_op_mov_reg_v(ot, R_EAX, cpu_T0);
1082 gen_op_movl_T0_Dshift(ot);
1083 gen_op_add_reg_T0(s->aflag, R_ESI);
1086 static inline void gen_scas(DisasContext *s, TCGMemOp ot)
1088 gen_string_movl_A0_EDI(s);
1089 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
1090 gen_op(s, OP_CMPL, ot, R_EAX);
1091 gen_op_movl_T0_Dshift(ot);
1092 gen_op_add_reg_T0(s->aflag, R_EDI);
1095 static inline void gen_cmps(DisasContext *s, TCGMemOp ot)
1097 gen_string_movl_A0_EDI(s);
1098 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
1099 gen_string_movl_A0_ESI(s);
1100 gen_op(s, OP_CMPL, ot, OR_TMP0);
1101 gen_op_movl_T0_Dshift(ot);
1102 gen_op_add_reg_T0(s->aflag, R_ESI);
1103 gen_op_add_reg_T0(s->aflag, R_EDI);
1106 static void gen_bpt_io(DisasContext *s, TCGv_i32 t_port, int ot)
1108 if (s->flags & HF_IOBPT_MASK) {
1109 TCGv_i32 t_size = tcg_const_i32(1 << ot);
1110 TCGv t_next = tcg_const_tl(s->pc - s->cs_base);
1112 gen_helper_bpt_io(cpu_env, t_port, t_size, t_next);
1113 tcg_temp_free_i32(t_size);
1114 tcg_temp_free(t_next);
1119 static inline void gen_ins(DisasContext *s, TCGMemOp ot)
1121 if (s->base.tb->cflags & CF_USE_ICOUNT) {
1124 gen_string_movl_A0_EDI(s);
1125 /* Note: we must do this dummy write first to be restartable in
1126 case of page fault. */
1127 tcg_gen_movi_tl(cpu_T0, 0);
1128 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
1129 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_EDX]);
1130 tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1131 gen_helper_in_func(ot, cpu_T0, cpu_tmp2_i32);
1132 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
1133 gen_op_movl_T0_Dshift(ot);
1134 gen_op_add_reg_T0(s->aflag, R_EDI);
1135 gen_bpt_io(s, cpu_tmp2_i32, ot);
1136 if (s->base.tb->cflags & CF_USE_ICOUNT) {
1141 static inline void gen_outs(DisasContext *s, TCGMemOp ot)
1143 if (s->base.tb->cflags & CF_USE_ICOUNT) {
1146 gen_string_movl_A0_ESI(s);
1147 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1149 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_EDX]);
1150 tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1151 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T0);
1152 gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
1153 gen_op_movl_T0_Dshift(ot);
1154 gen_op_add_reg_T0(s->aflag, R_ESI);
1155 gen_bpt_io(s, cpu_tmp2_i32, ot);
1156 if (s->base.tb->cflags & CF_USE_ICOUNT) {
1161 /* same method as Valgrind : we generate jumps to current or next
1163 #define GEN_REPZ(op) \
1164 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1165 target_ulong cur_eip, target_ulong next_eip) \
1168 gen_update_cc_op(s); \
1169 l2 = gen_jz_ecx_string(s, next_eip); \
1170 gen_ ## op(s, ot); \
1171 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1172 /* a loop would cause two single step exceptions if ECX = 1 \
1173 before rep string_insn */ \
1175 gen_op_jz_ecx(s->aflag, l2); \
1176 gen_jmp(s, cur_eip); \
1179 #define GEN_REPZ2(op) \
1180 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1181 target_ulong cur_eip, \
1182 target_ulong next_eip, \
1186 gen_update_cc_op(s); \
1187 l2 = gen_jz_ecx_string(s, next_eip); \
1188 gen_ ## op(s, ot); \
1189 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1190 gen_update_cc_op(s); \
1191 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
1193 gen_op_jz_ecx(s->aflag, l2); \
1194 gen_jmp(s, cur_eip); \
1205 static void gen_helper_fp_arith_ST0_FT0(int op)
1209 gen_helper_fadd_ST0_FT0(cpu_env);
1212 gen_helper_fmul_ST0_FT0(cpu_env);
1215 gen_helper_fcom_ST0_FT0(cpu_env);
1218 gen_helper_fcom_ST0_FT0(cpu_env);
1221 gen_helper_fsub_ST0_FT0(cpu_env);
1224 gen_helper_fsubr_ST0_FT0(cpu_env);
1227 gen_helper_fdiv_ST0_FT0(cpu_env);
1230 gen_helper_fdivr_ST0_FT0(cpu_env);
1235 /* NOTE the exception in "r" op ordering */
1236 static void gen_helper_fp_arith_STN_ST0(int op, int opreg)
1238 TCGv_i32 tmp = tcg_const_i32(opreg);
1241 gen_helper_fadd_STN_ST0(cpu_env, tmp);
1244 gen_helper_fmul_STN_ST0(cpu_env, tmp);
1247 gen_helper_fsubr_STN_ST0(cpu_env, tmp);
1250 gen_helper_fsub_STN_ST0(cpu_env, tmp);
1253 gen_helper_fdivr_STN_ST0(cpu_env, tmp);
1256 gen_helper_fdiv_STN_ST0(cpu_env, tmp);
1261 /* if d == OR_TMP0, it means memory operand (address in A0) */
1262 static void gen_op(DisasContext *s1, int op, TCGMemOp ot, int d)
1265 gen_op_mov_v_reg(ot, cpu_T0, d);
1266 } else if (!(s1->prefix & PREFIX_LOCK)) {
1267 gen_op_ld_v(s1, ot, cpu_T0, cpu_A0);
1271 gen_compute_eflags_c(s1, cpu_tmp4);
1272 if (s1->prefix & PREFIX_LOCK) {
1273 tcg_gen_add_tl(cpu_T0, cpu_tmp4, cpu_T1);
1274 tcg_gen_atomic_add_fetch_tl(cpu_T0, cpu_A0, cpu_T0,
1275 s1->mem_index, ot | MO_LE);
1277 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
1278 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_tmp4);
1279 gen_op_st_rm_T0_A0(s1, ot, d);
1281 gen_op_update3_cc(cpu_tmp4);
1282 set_cc_op(s1, CC_OP_ADCB + ot);
1285 gen_compute_eflags_c(s1, cpu_tmp4);
1286 if (s1->prefix & PREFIX_LOCK) {
1287 tcg_gen_add_tl(cpu_T0, cpu_T1, cpu_tmp4);
1288 tcg_gen_neg_tl(cpu_T0, cpu_T0);
1289 tcg_gen_atomic_add_fetch_tl(cpu_T0, cpu_A0, cpu_T0,
1290 s1->mem_index, ot | MO_LE);
1292 tcg_gen_sub_tl(cpu_T0, cpu_T0, cpu_T1);
1293 tcg_gen_sub_tl(cpu_T0, cpu_T0, cpu_tmp4);
1294 gen_op_st_rm_T0_A0(s1, ot, d);
1296 gen_op_update3_cc(cpu_tmp4);
1297 set_cc_op(s1, CC_OP_SBBB + ot);
1300 if (s1->prefix & PREFIX_LOCK) {
1301 tcg_gen_atomic_add_fetch_tl(cpu_T0, cpu_A0, cpu_T1,
1302 s1->mem_index, ot | MO_LE);
1304 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
1305 gen_op_st_rm_T0_A0(s1, ot, d);
1307 gen_op_update2_cc();
1308 set_cc_op(s1, CC_OP_ADDB + ot);
1311 if (s1->prefix & PREFIX_LOCK) {
1312 tcg_gen_neg_tl(cpu_T0, cpu_T1);
1313 tcg_gen_atomic_fetch_add_tl(cpu_cc_srcT, cpu_A0, cpu_T0,
1314 s1->mem_index, ot | MO_LE);
1315 tcg_gen_sub_tl(cpu_T0, cpu_cc_srcT, cpu_T1);
1317 tcg_gen_mov_tl(cpu_cc_srcT, cpu_T0);
1318 tcg_gen_sub_tl(cpu_T0, cpu_T0, cpu_T1);
1319 gen_op_st_rm_T0_A0(s1, ot, d);
1321 gen_op_update2_cc();
1322 set_cc_op(s1, CC_OP_SUBB + ot);
1326 if (s1->prefix & PREFIX_LOCK) {
1327 tcg_gen_atomic_and_fetch_tl(cpu_T0, cpu_A0, cpu_T1,
1328 s1->mem_index, ot | MO_LE);
1330 tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1);
1331 gen_op_st_rm_T0_A0(s1, ot, d);
1333 gen_op_update1_cc();
1334 set_cc_op(s1, CC_OP_LOGICB + ot);
1337 if (s1->prefix & PREFIX_LOCK) {
1338 tcg_gen_atomic_or_fetch_tl(cpu_T0, cpu_A0, cpu_T1,
1339 s1->mem_index, ot | MO_LE);
1341 tcg_gen_or_tl(cpu_T0, cpu_T0, cpu_T1);
1342 gen_op_st_rm_T0_A0(s1, ot, d);
1344 gen_op_update1_cc();
1345 set_cc_op(s1, CC_OP_LOGICB + ot);
1348 if (s1->prefix & PREFIX_LOCK) {
1349 tcg_gen_atomic_xor_fetch_tl(cpu_T0, cpu_A0, cpu_T1,
1350 s1->mem_index, ot | MO_LE);
1352 tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_T1);
1353 gen_op_st_rm_T0_A0(s1, ot, d);
1355 gen_op_update1_cc();
1356 set_cc_op(s1, CC_OP_LOGICB + ot);
1359 tcg_gen_mov_tl(cpu_cc_src, cpu_T1);
1360 tcg_gen_mov_tl(cpu_cc_srcT, cpu_T0);
1361 tcg_gen_sub_tl(cpu_cc_dst, cpu_T0, cpu_T1);
1362 set_cc_op(s1, CC_OP_SUBB + ot);
1367 /* if d == OR_TMP0, it means memory operand (address in A0) */
1368 static void gen_inc(DisasContext *s1, TCGMemOp ot, int d, int c)
1370 if (s1->prefix & PREFIX_LOCK) {
1371 tcg_gen_movi_tl(cpu_T0, c > 0 ? 1 : -1);
1372 tcg_gen_atomic_add_fetch_tl(cpu_T0, cpu_A0, cpu_T0,
1373 s1->mem_index, ot | MO_LE);
1376 gen_op_mov_v_reg(ot, cpu_T0, d);
1378 gen_op_ld_v(s1, ot, cpu_T0, cpu_A0);
1380 tcg_gen_addi_tl(cpu_T0, cpu_T0, (c > 0 ? 1 : -1));
1381 gen_op_st_rm_T0_A0(s1, ot, d);
1384 gen_compute_eflags_c(s1, cpu_cc_src);
1385 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
1386 set_cc_op(s1, (c > 0 ? CC_OP_INCB : CC_OP_DECB) + ot);
1389 static void gen_shift_flags(DisasContext *s, TCGMemOp ot, TCGv result,
1390 TCGv shm1, TCGv count, bool is_right)
1392 TCGv_i32 z32, s32, oldop;
1395 /* Store the results into the CC variables. If we know that the
1396 variable must be dead, store unconditionally. Otherwise we'll
1397 need to not disrupt the current contents. */
1398 z_tl = tcg_const_tl(0);
1399 if (cc_op_live[s->cc_op] & USES_CC_DST) {
1400 tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_dst, count, z_tl,
1401 result, cpu_cc_dst);
1403 tcg_gen_mov_tl(cpu_cc_dst, result);
1405 if (cc_op_live[s->cc_op] & USES_CC_SRC) {
1406 tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_src, count, z_tl,
1409 tcg_gen_mov_tl(cpu_cc_src, shm1);
1411 tcg_temp_free(z_tl);
1413 /* Get the two potential CC_OP values into temporaries. */
1414 tcg_gen_movi_i32(cpu_tmp2_i32, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot);
1415 if (s->cc_op == CC_OP_DYNAMIC) {
1418 tcg_gen_movi_i32(cpu_tmp3_i32, s->cc_op);
1419 oldop = cpu_tmp3_i32;
1422 /* Conditionally store the CC_OP value. */
1423 z32 = tcg_const_i32(0);
1424 s32 = tcg_temp_new_i32();
1425 tcg_gen_trunc_tl_i32(s32, count);
1426 tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, s32, z32, cpu_tmp2_i32, oldop);
1427 tcg_temp_free_i32(z32);
1428 tcg_temp_free_i32(s32);
1430 /* The CC_OP value is no longer predictable. */
1431 set_cc_op(s, CC_OP_DYNAMIC);
1434 static void gen_shift_rm_T1(DisasContext *s, TCGMemOp ot, int op1,
1435 int is_right, int is_arith)
1437 target_ulong mask = (ot == MO_64 ? 0x3f : 0x1f);
1440 if (op1 == OR_TMP0) {
1441 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1443 gen_op_mov_v_reg(ot, cpu_T0, op1);
1446 tcg_gen_andi_tl(cpu_T1, cpu_T1, mask);
1447 tcg_gen_subi_tl(cpu_tmp0, cpu_T1, 1);
1451 gen_exts(ot, cpu_T0);
1452 tcg_gen_sar_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1453 tcg_gen_sar_tl(cpu_T0, cpu_T0, cpu_T1);
1455 gen_extu(ot, cpu_T0);
1456 tcg_gen_shr_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1457 tcg_gen_shr_tl(cpu_T0, cpu_T0, cpu_T1);
1460 tcg_gen_shl_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1461 tcg_gen_shl_tl(cpu_T0, cpu_T0, cpu_T1);
1465 gen_op_st_rm_T0_A0(s, ot, op1);
1467 gen_shift_flags(s, ot, cpu_T0, cpu_tmp0, cpu_T1, is_right);
1470 static void gen_shift_rm_im(DisasContext *s, TCGMemOp ot, int op1, int op2,
1471 int is_right, int is_arith)
1473 int mask = (ot == MO_64 ? 0x3f : 0x1f);
1477 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1479 gen_op_mov_v_reg(ot, cpu_T0, op1);
1485 gen_exts(ot, cpu_T0);
1486 tcg_gen_sari_tl(cpu_tmp4, cpu_T0, op2 - 1);
1487 tcg_gen_sari_tl(cpu_T0, cpu_T0, op2);
1489 gen_extu(ot, cpu_T0);
1490 tcg_gen_shri_tl(cpu_tmp4, cpu_T0, op2 - 1);
1491 tcg_gen_shri_tl(cpu_T0, cpu_T0, op2);
1494 tcg_gen_shli_tl(cpu_tmp4, cpu_T0, op2 - 1);
1495 tcg_gen_shli_tl(cpu_T0, cpu_T0, op2);
1500 gen_op_st_rm_T0_A0(s, ot, op1);
1502 /* update eflags if non zero shift */
1504 tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
1505 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
1506 set_cc_op(s, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot);
1510 static void gen_rot_rm_T1(DisasContext *s, TCGMemOp ot, int op1, int is_right)
1512 target_ulong mask = (ot == MO_64 ? 0x3f : 0x1f);
1516 if (op1 == OR_TMP0) {
1517 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1519 gen_op_mov_v_reg(ot, cpu_T0, op1);
1522 tcg_gen_andi_tl(cpu_T1, cpu_T1, mask);
1526 /* Replicate the 8-bit input so that a 32-bit rotate works. */
1527 tcg_gen_ext8u_tl(cpu_T0, cpu_T0);
1528 tcg_gen_muli_tl(cpu_T0, cpu_T0, 0x01010101);
1531 /* Replicate the 16-bit input so that a 32-bit rotate works. */
1532 tcg_gen_deposit_tl(cpu_T0, cpu_T0, cpu_T0, 16, 16);
1535 #ifdef TARGET_X86_64
1537 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
1538 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T1);
1540 tcg_gen_rotr_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
1542 tcg_gen_rotl_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
1544 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
1549 tcg_gen_rotr_tl(cpu_T0, cpu_T0, cpu_T1);
1551 tcg_gen_rotl_tl(cpu_T0, cpu_T0, cpu_T1);
1557 gen_op_st_rm_T0_A0(s, ot, op1);
1559 /* We'll need the flags computed into CC_SRC. */
1560 gen_compute_eflags(s);
1562 /* The value that was "rotated out" is now present at the other end
1563 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1564 since we've computed the flags into CC_SRC, these variables are
1567 tcg_gen_shri_tl(cpu_cc_src2, cpu_T0, mask - 1);
1568 tcg_gen_shri_tl(cpu_cc_dst, cpu_T0, mask);
1569 tcg_gen_andi_tl(cpu_cc_dst, cpu_cc_dst, 1);
1571 tcg_gen_shri_tl(cpu_cc_src2, cpu_T0, mask);
1572 tcg_gen_andi_tl(cpu_cc_dst, cpu_T0, 1);
1574 tcg_gen_andi_tl(cpu_cc_src2, cpu_cc_src2, 1);
1575 tcg_gen_xor_tl(cpu_cc_src2, cpu_cc_src2, cpu_cc_dst);
1577 /* Now conditionally store the new CC_OP value. If the shift count
1578 is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1579 Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1580 exactly as we computed above. */
1581 t0 = tcg_const_i32(0);
1582 t1 = tcg_temp_new_i32();
1583 tcg_gen_trunc_tl_i32(t1, cpu_T1);
1584 tcg_gen_movi_i32(cpu_tmp2_i32, CC_OP_ADCOX);
1585 tcg_gen_movi_i32(cpu_tmp3_i32, CC_OP_EFLAGS);
1586 tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, t1, t0,
1587 cpu_tmp2_i32, cpu_tmp3_i32);
1588 tcg_temp_free_i32(t0);
1589 tcg_temp_free_i32(t1);
1591 /* The CC_OP value is no longer predictable. */
1592 set_cc_op(s, CC_OP_DYNAMIC);
1595 static void gen_rot_rm_im(DisasContext *s, TCGMemOp ot, int op1, int op2,
1598 int mask = (ot == MO_64 ? 0x3f : 0x1f);
1602 if (op1 == OR_TMP0) {
1603 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1605 gen_op_mov_v_reg(ot, cpu_T0, op1);
1611 #ifdef TARGET_X86_64
1613 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
1615 tcg_gen_rotri_i32(cpu_tmp2_i32, cpu_tmp2_i32, op2);
1617 tcg_gen_rotli_i32(cpu_tmp2_i32, cpu_tmp2_i32, op2);
1619 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
1624 tcg_gen_rotri_tl(cpu_T0, cpu_T0, op2);
1626 tcg_gen_rotli_tl(cpu_T0, cpu_T0, op2);
1637 shift = mask + 1 - shift;
1639 gen_extu(ot, cpu_T0);
1640 tcg_gen_shli_tl(cpu_tmp0, cpu_T0, shift);
1641 tcg_gen_shri_tl(cpu_T0, cpu_T0, mask + 1 - shift);
1642 tcg_gen_or_tl(cpu_T0, cpu_T0, cpu_tmp0);
1648 gen_op_st_rm_T0_A0(s, ot, op1);
1651 /* Compute the flags into CC_SRC. */
1652 gen_compute_eflags(s);
1654 /* The value that was "rotated out" is now present at the other end
1655 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1656 since we've computed the flags into CC_SRC, these variables are
1659 tcg_gen_shri_tl(cpu_cc_src2, cpu_T0, mask - 1);
1660 tcg_gen_shri_tl(cpu_cc_dst, cpu_T0, mask);
1661 tcg_gen_andi_tl(cpu_cc_dst, cpu_cc_dst, 1);
1663 tcg_gen_shri_tl(cpu_cc_src2, cpu_T0, mask);
1664 tcg_gen_andi_tl(cpu_cc_dst, cpu_T0, 1);
1666 tcg_gen_andi_tl(cpu_cc_src2, cpu_cc_src2, 1);
1667 tcg_gen_xor_tl(cpu_cc_src2, cpu_cc_src2, cpu_cc_dst);
1668 set_cc_op(s, CC_OP_ADCOX);
1672 /* XXX: add faster immediate = 1 case */
1673 static void gen_rotc_rm_T1(DisasContext *s, TCGMemOp ot, int op1,
1676 gen_compute_eflags(s);
1677 assert(s->cc_op == CC_OP_EFLAGS);
1681 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1683 gen_op_mov_v_reg(ot, cpu_T0, op1);
1688 gen_helper_rcrb(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1691 gen_helper_rcrw(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1694 gen_helper_rcrl(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1696 #ifdef TARGET_X86_64
1698 gen_helper_rcrq(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1707 gen_helper_rclb(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1710 gen_helper_rclw(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1713 gen_helper_rcll(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1715 #ifdef TARGET_X86_64
1717 gen_helper_rclq(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1725 gen_op_st_rm_T0_A0(s, ot, op1);
1728 /* XXX: add faster immediate case */
1729 static void gen_shiftd_rm_T1(DisasContext *s, TCGMemOp ot, int op1,
1730 bool is_right, TCGv count_in)
1732 target_ulong mask = (ot == MO_64 ? 63 : 31);
1736 if (op1 == OR_TMP0) {
1737 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1739 gen_op_mov_v_reg(ot, cpu_T0, op1);
1742 count = tcg_temp_new();
1743 tcg_gen_andi_tl(count, count_in, mask);
1747 /* Note: we implement the Intel behaviour for shift count > 16.
1748 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A
1749 portion by constructing it as a 32-bit value. */
1751 tcg_gen_deposit_tl(cpu_tmp0, cpu_T0, cpu_T1, 16, 16);
1752 tcg_gen_mov_tl(cpu_T1, cpu_T0);
1753 tcg_gen_mov_tl(cpu_T0, cpu_tmp0);
1755 tcg_gen_deposit_tl(cpu_T1, cpu_T0, cpu_T1, 16, 16);
1758 #ifdef TARGET_X86_64
1760 /* Concatenate the two 32-bit values and use a 64-bit shift. */
1761 tcg_gen_subi_tl(cpu_tmp0, count, 1);
1763 tcg_gen_concat_tl_i64(cpu_T0, cpu_T0, cpu_T1);
1764 tcg_gen_shr_i64(cpu_tmp0, cpu_T0, cpu_tmp0);
1765 tcg_gen_shr_i64(cpu_T0, cpu_T0, count);
1767 tcg_gen_concat_tl_i64(cpu_T0, cpu_T1, cpu_T0);
1768 tcg_gen_shl_i64(cpu_tmp0, cpu_T0, cpu_tmp0);
1769 tcg_gen_shl_i64(cpu_T0, cpu_T0, count);
1770 tcg_gen_shri_i64(cpu_tmp0, cpu_tmp0, 32);
1771 tcg_gen_shri_i64(cpu_T0, cpu_T0, 32);
1776 tcg_gen_subi_tl(cpu_tmp0, count, 1);
1778 tcg_gen_shr_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1780 tcg_gen_subfi_tl(cpu_tmp4, mask + 1, count);
1781 tcg_gen_shr_tl(cpu_T0, cpu_T0, count);
1782 tcg_gen_shl_tl(cpu_T1, cpu_T1, cpu_tmp4);
1784 tcg_gen_shl_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1786 /* Only needed if count > 16, for Intel behaviour. */
1787 tcg_gen_subfi_tl(cpu_tmp4, 33, count);
1788 tcg_gen_shr_tl(cpu_tmp4, cpu_T1, cpu_tmp4);
1789 tcg_gen_or_tl(cpu_tmp0, cpu_tmp0, cpu_tmp4);
1792 tcg_gen_subfi_tl(cpu_tmp4, mask + 1, count);
1793 tcg_gen_shl_tl(cpu_T0, cpu_T0, count);
1794 tcg_gen_shr_tl(cpu_T1, cpu_T1, cpu_tmp4);
1796 tcg_gen_movi_tl(cpu_tmp4, 0);
1797 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_T1, count, cpu_tmp4,
1799 tcg_gen_or_tl(cpu_T0, cpu_T0, cpu_T1);
1804 gen_op_st_rm_T0_A0(s, ot, op1);
1806 gen_shift_flags(s, ot, cpu_T0, cpu_tmp0, count, is_right);
1807 tcg_temp_free(count);
1810 static void gen_shift(DisasContext *s1, int op, TCGMemOp ot, int d, int s)
1813 gen_op_mov_v_reg(ot, cpu_T1, s);
1816 gen_rot_rm_T1(s1, ot, d, 0);
1819 gen_rot_rm_T1(s1, ot, d, 1);
1823 gen_shift_rm_T1(s1, ot, d, 0, 0);
1826 gen_shift_rm_T1(s1, ot, d, 1, 0);
1829 gen_shift_rm_T1(s1, ot, d, 1, 1);
1832 gen_rotc_rm_T1(s1, ot, d, 0);
1835 gen_rotc_rm_T1(s1, ot, d, 1);
1840 static void gen_shifti(DisasContext *s1, int op, TCGMemOp ot, int d, int c)
1844 gen_rot_rm_im(s1, ot, d, c, 0);
1847 gen_rot_rm_im(s1, ot, d, c, 1);
1851 gen_shift_rm_im(s1, ot, d, c, 0, 0);
1854 gen_shift_rm_im(s1, ot, d, c, 1, 0);
1857 gen_shift_rm_im(s1, ot, d, c, 1, 1);
1860 /* currently not optimized */
1861 tcg_gen_movi_tl(cpu_T1, c);
1862 gen_shift(s1, op, ot, d, OR_TMP1);
1867 #define X86_MAX_INSN_LENGTH 15
1869 static uint64_t advance_pc(CPUX86State *env, DisasContext *s, int num_bytes)
1871 uint64_t pc = s->pc;
1874 if (unlikely(s->pc - s->pc_start > X86_MAX_INSN_LENGTH)) {
1875 /* If the instruction's 16th byte is on a different page than the 1st, a
1876 * page fault on the second page wins over the general protection fault
1877 * caused by the instruction being too long.
1878 * This can happen even if the operand is only one byte long!
1880 if (((s->pc - 1) ^ (pc - 1)) & TARGET_PAGE_MASK) {
1881 volatile uint8_t unused =
1882 cpu_ldub_code(env, (s->pc - 1) & TARGET_PAGE_MASK);
1885 siglongjmp(s->jmpbuf, 1);
1891 static inline uint8_t x86_ldub_code(CPUX86State *env, DisasContext *s)
1893 return cpu_ldub_code(env, advance_pc(env, s, 1));
1896 static inline int16_t x86_ldsw_code(CPUX86State *env, DisasContext *s)
1898 return cpu_ldsw_code(env, advance_pc(env, s, 2));
1901 static inline uint16_t x86_lduw_code(CPUX86State *env, DisasContext *s)
1903 return cpu_lduw_code(env, advance_pc(env, s, 2));
1906 static inline uint32_t x86_ldl_code(CPUX86State *env, DisasContext *s)
1908 return cpu_ldl_code(env, advance_pc(env, s, 4));
1911 #ifdef TARGET_X86_64
1912 static inline uint64_t x86_ldq_code(CPUX86State *env, DisasContext *s)
1914 return cpu_ldq_code(env, advance_pc(env, s, 8));
1918 /* Decompose an address. */
1920 typedef struct AddressParts {
1928 static AddressParts gen_lea_modrm_0(CPUX86State *env, DisasContext *s,
1931 int def_seg, base, index, scale, mod, rm;
1940 mod = (modrm >> 6) & 3;
1942 base = rm | REX_B(s);
1945 /* Normally filtered out earlier, but including this path
1946 simplifies multi-byte nop, as well as bndcl, bndcu, bndcn. */
1955 int code = x86_ldub_code(env, s);
1956 scale = (code >> 6) & 3;
1957 index = ((code >> 3) & 7) | REX_X(s);
1959 index = -1; /* no index */
1961 base = (code & 7) | REX_B(s);
1967 if ((base & 7) == 5) {
1969 disp = (int32_t)x86_ldl_code(env, s);
1970 if (CODE64(s) && !havesib) {
1972 disp += s->pc + s->rip_offset;
1977 disp = (int8_t)x86_ldub_code(env, s);
1981 disp = (int32_t)x86_ldl_code(env, s);
1985 /* For correct popl handling with esp. */
1986 if (base == R_ESP && s->popl_esp_hack) {
1987 disp += s->popl_esp_hack;
1989 if (base == R_EBP || base == R_ESP) {
1998 disp = x86_lduw_code(env, s);
2001 } else if (mod == 1) {
2002 disp = (int8_t)x86_ldub_code(env, s);
2004 disp = (int16_t)x86_lduw_code(env, s);
2048 return (AddressParts){ def_seg, base, index, scale, disp };
2051 /* Compute the address, with a minimum number of TCG ops. */
2052 static TCGv gen_lea_modrm_1(AddressParts a)
2059 ea = cpu_regs[a.index];
2061 tcg_gen_shli_tl(cpu_A0, cpu_regs[a.index], a.scale);
2065 tcg_gen_add_tl(cpu_A0, ea, cpu_regs[a.base]);
2068 } else if (a.base >= 0) {
2069 ea = cpu_regs[a.base];
2071 if (TCGV_IS_UNUSED(ea)) {
2072 tcg_gen_movi_tl(cpu_A0, a.disp);
2074 } else if (a.disp != 0) {
2075 tcg_gen_addi_tl(cpu_A0, ea, a.disp);
2082 static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm)
2084 AddressParts a = gen_lea_modrm_0(env, s, modrm);
2085 TCGv ea = gen_lea_modrm_1(a);
2086 gen_lea_v_seg(s, s->aflag, ea, a.def_seg, s->override);
2089 static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm)
2091 (void)gen_lea_modrm_0(env, s, modrm);
2094 /* Used for BNDCL, BNDCU, BNDCN. */
2095 static void gen_bndck(CPUX86State *env, DisasContext *s, int modrm,
2096 TCGCond cond, TCGv_i64 bndv)
2098 TCGv ea = gen_lea_modrm_1(gen_lea_modrm_0(env, s, modrm));
2100 tcg_gen_extu_tl_i64(cpu_tmp1_i64, ea);
2102 tcg_gen_ext32u_i64(cpu_tmp1_i64, cpu_tmp1_i64);
2104 tcg_gen_setcond_i64(cond, cpu_tmp1_i64, cpu_tmp1_i64, bndv);
2105 tcg_gen_extrl_i64_i32(cpu_tmp2_i32, cpu_tmp1_i64);
2106 gen_helper_bndck(cpu_env, cpu_tmp2_i32);
2109 /* used for LEA and MOV AX, mem */
2110 static void gen_add_A0_ds_seg(DisasContext *s)
2112 gen_lea_v_seg(s, s->aflag, cpu_A0, R_DS, s->override);
2115 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2117 static void gen_ldst_modrm(CPUX86State *env, DisasContext *s, int modrm,
2118 TCGMemOp ot, int reg, int is_store)
2122 mod = (modrm >> 6) & 3;
2123 rm = (modrm & 7) | REX_B(s);
2127 gen_op_mov_v_reg(ot, cpu_T0, reg);
2128 gen_op_mov_reg_v(ot, rm, cpu_T0);
2130 gen_op_mov_v_reg(ot, cpu_T0, rm);
2132 gen_op_mov_reg_v(ot, reg, cpu_T0);
2135 gen_lea_modrm(env, s, modrm);
2138 gen_op_mov_v_reg(ot, cpu_T0, reg);
2139 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
2141 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
2143 gen_op_mov_reg_v(ot, reg, cpu_T0);
2148 static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, TCGMemOp ot)
2154 ret = x86_ldub_code(env, s);
2157 ret = x86_lduw_code(env, s);
2160 #ifdef TARGET_X86_64
2163 ret = x86_ldl_code(env, s);
2171 static inline int insn_const_size(TCGMemOp ot)
2180 static inline bool use_goto_tb(DisasContext *s, target_ulong pc)
2182 #ifndef CONFIG_USER_ONLY
2183 return (pc & TARGET_PAGE_MASK) == (s->base.tb->pc & TARGET_PAGE_MASK) ||
2184 (pc & TARGET_PAGE_MASK) == (s->pc_start & TARGET_PAGE_MASK);
2190 static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
2192 target_ulong pc = s->cs_base + eip;
2194 if (use_goto_tb(s, pc)) {
2195 /* jump to same page: we can use a direct jump */
2196 tcg_gen_goto_tb(tb_num);
2198 tcg_gen_exit_tb((uintptr_t)s->base.tb + tb_num);
2199 s->base.is_jmp = DISAS_NORETURN;
2201 /* jump to another page */
2203 gen_jr(s, cpu_tmp0);
2207 static inline void gen_jcc(DisasContext *s, int b,
2208 target_ulong val, target_ulong next_eip)
2213 l1 = gen_new_label();
2216 gen_goto_tb(s, 0, next_eip);
2219 gen_goto_tb(s, 1, val);
2221 l1 = gen_new_label();
2222 l2 = gen_new_label();
2225 gen_jmp_im(next_eip);
2235 static void gen_cmovcc1(CPUX86State *env, DisasContext *s, TCGMemOp ot, int b,
2240 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
2242 cc = gen_prepare_cc(s, b, cpu_T1);
2243 if (cc.mask != -1) {
2244 TCGv t0 = tcg_temp_new();
2245 tcg_gen_andi_tl(t0, cc.reg, cc.mask);
2249 cc.reg2 = tcg_const_tl(cc.imm);
2252 tcg_gen_movcond_tl(cc.cond, cpu_T0, cc.reg, cc.reg2,
2253 cpu_T0, cpu_regs[reg]);
2254 gen_op_mov_reg_v(ot, reg, cpu_T0);
2256 if (cc.mask != -1) {
2257 tcg_temp_free(cc.reg);
2260 tcg_temp_free(cc.reg2);
2264 static inline void gen_op_movl_T0_seg(int seg_reg)
2266 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
2267 offsetof(CPUX86State,segs[seg_reg].selector));
2270 static inline void gen_op_movl_seg_T0_vm(int seg_reg)
2272 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
2273 tcg_gen_st32_tl(cpu_T0, cpu_env,
2274 offsetof(CPUX86State,segs[seg_reg].selector));
2275 tcg_gen_shli_tl(cpu_seg_base[seg_reg], cpu_T0, 4);
2278 /* move T0 to seg_reg and compute if the CPU state may change. Never
2279 call this function with seg_reg == R_CS */
2280 static void gen_movl_seg_T0(DisasContext *s, int seg_reg)
2282 if (s->pe && !s->vm86) {
2283 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
2284 gen_helper_load_seg(cpu_env, tcg_const_i32(seg_reg), cpu_tmp2_i32);
2285 /* abort translation because the addseg value may change or
2286 because ss32 may change. For R_SS, translation must always
2287 stop as a special handling must be done to disable hardware
2288 interrupts for the next instruction */
2289 if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS)) {
2290 s->base.is_jmp = DISAS_TOO_MANY;
2293 gen_op_movl_seg_T0_vm(seg_reg);
2294 if (seg_reg == R_SS) {
2295 s->base.is_jmp = DISAS_TOO_MANY;
2300 static inline int svm_is_rep(int prefixes)
2302 return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0);
2306 gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
2307 uint32_t type, uint64_t param)
2309 /* no SVM activated; fast case */
2310 if (likely(!(s->flags & HF_SVMI_MASK)))
2312 gen_update_cc_op(s);
2313 gen_jmp_im(pc_start - s->cs_base);
2314 gen_helper_svm_check_intercept_param(cpu_env, tcg_const_i32(type),
2315 tcg_const_i64(param));
2319 gen_svm_check_intercept(DisasContext *s, target_ulong pc_start, uint64_t type)
2321 gen_svm_check_intercept_param(s, pc_start, type, 0);
2324 static inline void gen_stack_update(DisasContext *s, int addend)
2326 gen_op_add_reg_im(mo_stacksize(s), R_ESP, addend);
2329 /* Generate a push. It depends on ss32, addseg and dflag. */
2330 static void gen_push_v(DisasContext *s, TCGv val)
2332 TCGMemOp d_ot = mo_pushpop(s, s->dflag);
2333 TCGMemOp a_ot = mo_stacksize(s);
2334 int size = 1 << d_ot;
2335 TCGv new_esp = cpu_A0;
2337 tcg_gen_subi_tl(cpu_A0, cpu_regs[R_ESP], size);
2342 tcg_gen_mov_tl(new_esp, cpu_A0);
2344 gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1);
2347 gen_op_st_v(s, d_ot, val, cpu_A0);
2348 gen_op_mov_reg_v(a_ot, R_ESP, new_esp);
2351 /* two step pop is necessary for precise exceptions */
2352 static TCGMemOp gen_pop_T0(DisasContext *s)
2354 TCGMemOp d_ot = mo_pushpop(s, s->dflag);
2356 gen_lea_v_seg(s, mo_stacksize(s), cpu_regs[R_ESP], R_SS, -1);
2357 gen_op_ld_v(s, d_ot, cpu_T0, cpu_A0);
2362 static inline void gen_pop_update(DisasContext *s, TCGMemOp ot)
2364 gen_stack_update(s, 1 << ot);
2367 static inline void gen_stack_A0(DisasContext *s)
2369 gen_lea_v_seg(s, s->ss32 ? MO_32 : MO_16, cpu_regs[R_ESP], R_SS, -1);
2372 static void gen_pusha(DisasContext *s)
2374 TCGMemOp s_ot = s->ss32 ? MO_32 : MO_16;
2375 TCGMemOp d_ot = s->dflag;
2376 int size = 1 << d_ot;
2379 for (i = 0; i < 8; i++) {
2380 tcg_gen_addi_tl(cpu_A0, cpu_regs[R_ESP], (i - 8) * size);
2381 gen_lea_v_seg(s, s_ot, cpu_A0, R_SS, -1);
2382 gen_op_st_v(s, d_ot, cpu_regs[7 - i], cpu_A0);
2385 gen_stack_update(s, -8 * size);
2388 static void gen_popa(DisasContext *s)
2390 TCGMemOp s_ot = s->ss32 ? MO_32 : MO_16;
2391 TCGMemOp d_ot = s->dflag;
2392 int size = 1 << d_ot;
2395 for (i = 0; i < 8; i++) {
2396 /* ESP is not reloaded */
2397 if (7 - i == R_ESP) {
2400 tcg_gen_addi_tl(cpu_A0, cpu_regs[R_ESP], i * size);
2401 gen_lea_v_seg(s, s_ot, cpu_A0, R_SS, -1);
2402 gen_op_ld_v(s, d_ot, cpu_T0, cpu_A0);
2403 gen_op_mov_reg_v(d_ot, 7 - i, cpu_T0);
2406 gen_stack_update(s, 8 * size);
2409 static void gen_enter(DisasContext *s, int esp_addend, int level)
2411 TCGMemOp d_ot = mo_pushpop(s, s->dflag);
2412 TCGMemOp a_ot = CODE64(s) ? MO_64 : s->ss32 ? MO_32 : MO_16;
2413 int size = 1 << d_ot;
2415 /* Push BP; compute FrameTemp into T1. */
2416 tcg_gen_subi_tl(cpu_T1, cpu_regs[R_ESP], size);
2417 gen_lea_v_seg(s, a_ot, cpu_T1, R_SS, -1);
2418 gen_op_st_v(s, d_ot, cpu_regs[R_EBP], cpu_A0);
2424 /* Copy level-1 pointers from the previous frame. */
2425 for (i = 1; i < level; ++i) {
2426 tcg_gen_subi_tl(cpu_A0, cpu_regs[R_EBP], size * i);
2427 gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1);
2428 gen_op_ld_v(s, d_ot, cpu_tmp0, cpu_A0);
2430 tcg_gen_subi_tl(cpu_A0, cpu_T1, size * i);
2431 gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1);
2432 gen_op_st_v(s, d_ot, cpu_tmp0, cpu_A0);
2435 /* Push the current FrameTemp as the last level. */
2436 tcg_gen_subi_tl(cpu_A0, cpu_T1, size * level);
2437 gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1);
2438 gen_op_st_v(s, d_ot, cpu_T1, cpu_A0);
2441 /* Copy the FrameTemp value to EBP. */
2442 gen_op_mov_reg_v(a_ot, R_EBP, cpu_T1);
2444 /* Compute the final value of ESP. */
2445 tcg_gen_subi_tl(cpu_T1, cpu_T1, esp_addend + size * level);
2446 gen_op_mov_reg_v(a_ot, R_ESP, cpu_T1);
2449 static void gen_leave(DisasContext *s)
2451 TCGMemOp d_ot = mo_pushpop(s, s->dflag);
2452 TCGMemOp a_ot = mo_stacksize(s);
2454 gen_lea_v_seg(s, a_ot, cpu_regs[R_EBP], R_SS, -1);
2455 gen_op_ld_v(s, d_ot, cpu_T0, cpu_A0);
2457 tcg_gen_addi_tl(cpu_T1, cpu_regs[R_EBP], 1 << d_ot);
2459 gen_op_mov_reg_v(d_ot, R_EBP, cpu_T0);
2460 gen_op_mov_reg_v(a_ot, R_ESP, cpu_T1);
2463 static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
2465 gen_update_cc_op(s);
2466 gen_jmp_im(cur_eip);
2467 gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno));
2468 s->base.is_jmp = DISAS_NORETURN;
2471 /* Generate #UD for the current instruction. The assumption here is that
2472 the instruction is known, but it isn't allowed in the current cpu mode. */
2473 static void gen_illegal_opcode(DisasContext *s)
2475 gen_exception(s, EXCP06_ILLOP, s->pc_start - s->cs_base);
2478 /* Similarly, except that the assumption here is that we don't decode
2479 the instruction at all -- either a missing opcode, an unimplemented
2480 feature, or just a bogus instruction stream. */
2481 static void gen_unknown_opcode(CPUX86State *env, DisasContext *s)
2483 gen_illegal_opcode(s);
2485 if (qemu_loglevel_mask(LOG_UNIMP)) {
2486 target_ulong pc = s->pc_start, end = s->pc;
2488 qemu_log("ILLOPC: " TARGET_FMT_lx ":", pc);
2489 for (; pc < end; ++pc) {
2490 qemu_log(" %02x", cpu_ldub_code(env, pc));
2497 /* an interrupt is different from an exception because of the
2499 static void gen_interrupt(DisasContext *s, int intno,
2500 target_ulong cur_eip, target_ulong next_eip)
2502 gen_update_cc_op(s);
2503 gen_jmp_im(cur_eip);
2504 gen_helper_raise_interrupt(cpu_env, tcg_const_i32(intno),
2505 tcg_const_i32(next_eip - cur_eip));
2506 s->base.is_jmp = DISAS_NORETURN;
2509 static void gen_debug(DisasContext *s, target_ulong cur_eip)
2511 gen_update_cc_op(s);
2512 gen_jmp_im(cur_eip);
2513 gen_helper_debug(cpu_env);
2514 s->base.is_jmp = DISAS_NORETURN;
2517 static void gen_set_hflag(DisasContext *s, uint32_t mask)
2519 if ((s->flags & mask) == 0) {
2520 TCGv_i32 t = tcg_temp_new_i32();
2521 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2522 tcg_gen_ori_i32(t, t, mask);
2523 tcg_gen_st_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2524 tcg_temp_free_i32(t);
2529 static void gen_reset_hflag(DisasContext *s, uint32_t mask)
2531 if (s->flags & mask) {
2532 TCGv_i32 t = tcg_temp_new_i32();
2533 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2534 tcg_gen_andi_i32(t, t, ~mask);
2535 tcg_gen_st_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2536 tcg_temp_free_i32(t);
2541 /* Clear BND registers during legacy branches. */
2542 static void gen_bnd_jmp(DisasContext *s)
2544 /* Clear the registers only if BND prefix is missing, MPX is enabled,
2545 and if the BNDREGs are known to be in use (non-zero) already.
2546 The helper itself will check BNDPRESERVE at runtime. */
2547 if ((s->prefix & PREFIX_REPNZ) == 0
2548 && (s->flags & HF_MPX_EN_MASK) != 0
2549 && (s->flags & HF_MPX_IU_MASK) != 0) {
2550 gen_helper_bnd_jmp(cpu_env);
2554 /* Generate an end of block. Trace exception is also generated if needed.
2555 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set.
2556 If RECHECK_TF, emit a rechecking helper for #DB, ignoring the state of
2557 S->TF. This is used by the syscall/sysret insns. */
2559 do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, bool jr)
2561 gen_update_cc_op(s);
2563 /* If several instructions disable interrupts, only the first does it. */
2564 if (inhibit && !(s->flags & HF_INHIBIT_IRQ_MASK)) {
2565 gen_set_hflag(s, HF_INHIBIT_IRQ_MASK);
2567 gen_reset_hflag(s, HF_INHIBIT_IRQ_MASK);
2570 if (s->base.tb->flags & HF_RF_MASK) {
2571 gen_helper_reset_rf(cpu_env);
2573 if (s->base.singlestep_enabled) {
2574 gen_helper_debug(cpu_env);
2575 } else if (recheck_tf) {
2576 gen_helper_rechecking_single_step(cpu_env);
2579 gen_helper_single_step(cpu_env);
2581 tcg_gen_lookup_and_goto_ptr();
2585 s->base.is_jmp = DISAS_NORETURN;
2589 gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf)
2591 do_gen_eob_worker(s, inhibit, recheck_tf, false);
2595 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set. */
2596 static void gen_eob_inhibit_irq(DisasContext *s, bool inhibit)
2598 gen_eob_worker(s, inhibit, false);
2601 /* End of block, resetting the inhibit irq flag. */
2602 static void gen_eob(DisasContext *s)
2604 gen_eob_worker(s, false, false);
2607 /* Jump to register */
2608 static void gen_jr(DisasContext *s, TCGv dest)
2610 do_gen_eob_worker(s, false, false, true);
2613 /* generate a jump to eip. No segment change must happen before as a
2614 direct call to the next block may occur */
2615 static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
2617 gen_update_cc_op(s);
2618 set_cc_op(s, CC_OP_DYNAMIC);
2620 gen_goto_tb(s, tb_num, eip);
2627 static void gen_jmp(DisasContext *s, target_ulong eip)
2629 gen_jmp_tb(s, eip, 0);
2632 static inline void gen_ldq_env_A0(DisasContext *s, int offset)
2634 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
2635 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset);
2638 static inline void gen_stq_env_A0(DisasContext *s, int offset)
2640 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset);
2641 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
2644 static inline void gen_ldo_env_A0(DisasContext *s, int offset)
2646 int mem_index = s->mem_index;
2647 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, mem_index, MO_LEQ);
2648 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(0)));
2649 tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2650 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_tmp0, mem_index, MO_LEQ);
2651 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(1)));
2654 static inline void gen_sto_env_A0(DisasContext *s, int offset)
2656 int mem_index = s->mem_index;
2657 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(0)));
2658 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, mem_index, MO_LEQ);
2659 tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2660 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(1)));
2661 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_tmp0, mem_index, MO_LEQ);
2664 static inline void gen_op_movo(int d_offset, int s_offset)
2666 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + offsetof(ZMMReg, ZMM_Q(0)));
2667 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + offsetof(ZMMReg, ZMM_Q(0)));
2668 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + offsetof(ZMMReg, ZMM_Q(1)));
2669 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + offsetof(ZMMReg, ZMM_Q(1)));
2672 static inline void gen_op_movq(int d_offset, int s_offset)
2674 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
2675 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2678 static inline void gen_op_movl(int d_offset, int s_offset)
2680 tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env, s_offset);
2681 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, d_offset);
2684 static inline void gen_op_movq_env_0(int d_offset)
2686 tcg_gen_movi_i64(cpu_tmp1_i64, 0);
2687 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2690 typedef void (*SSEFunc_i_ep)(TCGv_i32 val, TCGv_ptr env, TCGv_ptr reg);
2691 typedef void (*SSEFunc_l_ep)(TCGv_i64 val, TCGv_ptr env, TCGv_ptr reg);
2692 typedef void (*SSEFunc_0_epi)(TCGv_ptr env, TCGv_ptr reg, TCGv_i32 val);
2693 typedef void (*SSEFunc_0_epl)(TCGv_ptr env, TCGv_ptr reg, TCGv_i64 val);
2694 typedef void (*SSEFunc_0_epp)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b);
2695 typedef void (*SSEFunc_0_eppi)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2697 typedef void (*SSEFunc_0_ppi)(TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv_i32 val);
2698 typedef void (*SSEFunc_0_eppt)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2701 #define SSE_SPECIAL ((void *)1)
2702 #define SSE_DUMMY ((void *)2)
2704 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2705 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2706 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2708 static const SSEFunc_0_epp sse_op_table1[256][4] = {
2709 /* 3DNow! extensions */
2710 [0x0e] = { SSE_DUMMY }, /* femms */
2711 [0x0f] = { SSE_DUMMY }, /* pf... */
2712 /* pure SSE operations */
2713 [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2714 [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2715 [0x12] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd, movsldup, movddup */
2716 [0x13] = { SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd */
2717 [0x14] = { gen_helper_punpckldq_xmm, gen_helper_punpcklqdq_xmm },
2718 [0x15] = { gen_helper_punpckhdq_xmm, gen_helper_punpckhqdq_xmm },
2719 [0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movhps, movhpd, movshdup */
2720 [0x17] = { SSE_SPECIAL, SSE_SPECIAL }, /* movhps, movhpd */
2722 [0x28] = { SSE_SPECIAL, SSE_SPECIAL }, /* movaps, movapd */
2723 [0x29] = { SSE_SPECIAL, SSE_SPECIAL }, /* movaps, movapd */
2724 [0x2a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2725 [0x2b] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movntps, movntpd, movntss, movntsd */
2726 [0x2c] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2727 [0x2d] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2728 [0x2e] = { gen_helper_ucomiss, gen_helper_ucomisd },
2729 [0x2f] = { gen_helper_comiss, gen_helper_comisd },
2730 [0x50] = { SSE_SPECIAL, SSE_SPECIAL }, /* movmskps, movmskpd */
2731 [0x51] = SSE_FOP(sqrt),
2732 [0x52] = { gen_helper_rsqrtps, NULL, gen_helper_rsqrtss, NULL },
2733 [0x53] = { gen_helper_rcpps, NULL, gen_helper_rcpss, NULL },
2734 [0x54] = { gen_helper_pand_xmm, gen_helper_pand_xmm }, /* andps, andpd */
2735 [0x55] = { gen_helper_pandn_xmm, gen_helper_pandn_xmm }, /* andnps, andnpd */
2736 [0x56] = { gen_helper_por_xmm, gen_helper_por_xmm }, /* orps, orpd */
2737 [0x57] = { gen_helper_pxor_xmm, gen_helper_pxor_xmm }, /* xorps, xorpd */
2738 [0x58] = SSE_FOP(add),
2739 [0x59] = SSE_FOP(mul),
2740 [0x5a] = { gen_helper_cvtps2pd, gen_helper_cvtpd2ps,
2741 gen_helper_cvtss2sd, gen_helper_cvtsd2ss },
2742 [0x5b] = { gen_helper_cvtdq2ps, gen_helper_cvtps2dq, gen_helper_cvttps2dq },
2743 [0x5c] = SSE_FOP(sub),
2744 [0x5d] = SSE_FOP(min),
2745 [0x5e] = SSE_FOP(div),
2746 [0x5f] = SSE_FOP(max),
2748 [0xc2] = SSE_FOP(cmpeq),
2749 [0xc6] = { (SSEFunc_0_epp)gen_helper_shufps,
2750 (SSEFunc_0_epp)gen_helper_shufpd }, /* XXX: casts */
2752 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */
2753 [0x38] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2754 [0x3a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2756 /* MMX ops and their SSE extensions */
2757 [0x60] = MMX_OP2(punpcklbw),
2758 [0x61] = MMX_OP2(punpcklwd),
2759 [0x62] = MMX_OP2(punpckldq),
2760 [0x63] = MMX_OP2(packsswb),
2761 [0x64] = MMX_OP2(pcmpgtb),
2762 [0x65] = MMX_OP2(pcmpgtw),
2763 [0x66] = MMX_OP2(pcmpgtl),
2764 [0x67] = MMX_OP2(packuswb),
2765 [0x68] = MMX_OP2(punpckhbw),
2766 [0x69] = MMX_OP2(punpckhwd),
2767 [0x6a] = MMX_OP2(punpckhdq),
2768 [0x6b] = MMX_OP2(packssdw),
2769 [0x6c] = { NULL, gen_helper_punpcklqdq_xmm },
2770 [0x6d] = { NULL, gen_helper_punpckhqdq_xmm },
2771 [0x6e] = { SSE_SPECIAL, SSE_SPECIAL }, /* movd mm, ea */
2772 [0x6f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, , movqdu */
2773 [0x70] = { (SSEFunc_0_epp)gen_helper_pshufw_mmx,
2774 (SSEFunc_0_epp)gen_helper_pshufd_xmm,
2775 (SSEFunc_0_epp)gen_helper_pshufhw_xmm,
2776 (SSEFunc_0_epp)gen_helper_pshuflw_xmm }, /* XXX: casts */
2777 [0x71] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftw */
2778 [0x72] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftd */
2779 [0x73] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftq */
2780 [0x74] = MMX_OP2(pcmpeqb),
2781 [0x75] = MMX_OP2(pcmpeqw),
2782 [0x76] = MMX_OP2(pcmpeql),
2783 [0x77] = { SSE_DUMMY }, /* emms */
2784 [0x78] = { NULL, SSE_SPECIAL, NULL, SSE_SPECIAL }, /* extrq_i, insertq_i */
2785 [0x79] = { NULL, gen_helper_extrq_r, NULL, gen_helper_insertq_r },
2786 [0x7c] = { NULL, gen_helper_haddpd, NULL, gen_helper_haddps },
2787 [0x7d] = { NULL, gen_helper_hsubpd, NULL, gen_helper_hsubps },
2788 [0x7e] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movd, movd, , movq */
2789 [0x7f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, movdqu */
2790 [0xc4] = { SSE_SPECIAL, SSE_SPECIAL }, /* pinsrw */
2791 [0xc5] = { SSE_SPECIAL, SSE_SPECIAL }, /* pextrw */
2792 [0xd0] = { NULL, gen_helper_addsubpd, NULL, gen_helper_addsubps },
2793 [0xd1] = MMX_OP2(psrlw),
2794 [0xd2] = MMX_OP2(psrld),
2795 [0xd3] = MMX_OP2(psrlq),
2796 [0xd4] = MMX_OP2(paddq),
2797 [0xd5] = MMX_OP2(pmullw),
2798 [0xd6] = { NULL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2799 [0xd7] = { SSE_SPECIAL, SSE_SPECIAL }, /* pmovmskb */
2800 [0xd8] = MMX_OP2(psubusb),
2801 [0xd9] = MMX_OP2(psubusw),
2802 [0xda] = MMX_OP2(pminub),
2803 [0xdb] = MMX_OP2(pand),
2804 [0xdc] = MMX_OP2(paddusb),
2805 [0xdd] = MMX_OP2(paddusw),
2806 [0xde] = MMX_OP2(pmaxub),
2807 [0xdf] = MMX_OP2(pandn),
2808 [0xe0] = MMX_OP2(pavgb),
2809 [0xe1] = MMX_OP2(psraw),
2810 [0xe2] = MMX_OP2(psrad),
2811 [0xe3] = MMX_OP2(pavgw),
2812 [0xe4] = MMX_OP2(pmulhuw),
2813 [0xe5] = MMX_OP2(pmulhw),
2814 [0xe6] = { NULL, gen_helper_cvttpd2dq, gen_helper_cvtdq2pd, gen_helper_cvtpd2dq },
2815 [0xe7] = { SSE_SPECIAL , SSE_SPECIAL }, /* movntq, movntq */
2816 [0xe8] = MMX_OP2(psubsb),
2817 [0xe9] = MMX_OP2(psubsw),
2818 [0xea] = MMX_OP2(pminsw),
2819 [0xeb] = MMX_OP2(por),
2820 [0xec] = MMX_OP2(paddsb),
2821 [0xed] = MMX_OP2(paddsw),
2822 [0xee] = MMX_OP2(pmaxsw),
2823 [0xef] = MMX_OP2(pxor),
2824 [0xf0] = { NULL, NULL, NULL, SSE_SPECIAL }, /* lddqu */
2825 [0xf1] = MMX_OP2(psllw),
2826 [0xf2] = MMX_OP2(pslld),
2827 [0xf3] = MMX_OP2(psllq),
2828 [0xf4] = MMX_OP2(pmuludq),
2829 [0xf5] = MMX_OP2(pmaddwd),
2830 [0xf6] = MMX_OP2(psadbw),
2831 [0xf7] = { (SSEFunc_0_epp)gen_helper_maskmov_mmx,
2832 (SSEFunc_0_epp)gen_helper_maskmov_xmm }, /* XXX: casts */
2833 [0xf8] = MMX_OP2(psubb),
2834 [0xf9] = MMX_OP2(psubw),
2835 [0xfa] = MMX_OP2(psubl),
2836 [0xfb] = MMX_OP2(psubq),
2837 [0xfc] = MMX_OP2(paddb),
2838 [0xfd] = MMX_OP2(paddw),
2839 [0xfe] = MMX_OP2(paddl),
2842 static const SSEFunc_0_epp sse_op_table2[3 * 8][2] = {
2843 [0 + 2] = MMX_OP2(psrlw),
2844 [0 + 4] = MMX_OP2(psraw),
2845 [0 + 6] = MMX_OP2(psllw),
2846 [8 + 2] = MMX_OP2(psrld),
2847 [8 + 4] = MMX_OP2(psrad),
2848 [8 + 6] = MMX_OP2(pslld),
2849 [16 + 2] = MMX_OP2(psrlq),
2850 [16 + 3] = { NULL, gen_helper_psrldq_xmm },
2851 [16 + 6] = MMX_OP2(psllq),
2852 [16 + 7] = { NULL, gen_helper_pslldq_xmm },
2855 static const SSEFunc_0_epi sse_op_table3ai[] = {
2856 gen_helper_cvtsi2ss,
2860 #ifdef TARGET_X86_64
2861 static const SSEFunc_0_epl sse_op_table3aq[] = {
2862 gen_helper_cvtsq2ss,
2867 static const SSEFunc_i_ep sse_op_table3bi[] = {
2868 gen_helper_cvttss2si,
2869 gen_helper_cvtss2si,
2870 gen_helper_cvttsd2si,
2874 #ifdef TARGET_X86_64
2875 static const SSEFunc_l_ep sse_op_table3bq[] = {
2876 gen_helper_cvttss2sq,
2877 gen_helper_cvtss2sq,
2878 gen_helper_cvttsd2sq,
2883 static const SSEFunc_0_epp sse_op_table4[8][4] = {
2894 static const SSEFunc_0_epp sse_op_table5[256] = {
2895 [0x0c] = gen_helper_pi2fw,
2896 [0x0d] = gen_helper_pi2fd,
2897 [0x1c] = gen_helper_pf2iw,
2898 [0x1d] = gen_helper_pf2id,
2899 [0x8a] = gen_helper_pfnacc,
2900 [0x8e] = gen_helper_pfpnacc,
2901 [0x90] = gen_helper_pfcmpge,
2902 [0x94] = gen_helper_pfmin,
2903 [0x96] = gen_helper_pfrcp,
2904 [0x97] = gen_helper_pfrsqrt,
2905 [0x9a] = gen_helper_pfsub,
2906 [0x9e] = gen_helper_pfadd,
2907 [0xa0] = gen_helper_pfcmpgt,
2908 [0xa4] = gen_helper_pfmax,
2909 [0xa6] = gen_helper_movq, /* pfrcpit1; no need to actually increase precision */
2910 [0xa7] = gen_helper_movq, /* pfrsqit1 */
2911 [0xaa] = gen_helper_pfsubr,
2912 [0xae] = gen_helper_pfacc,
2913 [0xb0] = gen_helper_pfcmpeq,
2914 [0xb4] = gen_helper_pfmul,
2915 [0xb6] = gen_helper_movq, /* pfrcpit2 */
2916 [0xb7] = gen_helper_pmulhrw_mmx,
2917 [0xbb] = gen_helper_pswapd,
2918 [0xbf] = gen_helper_pavgb_mmx /* pavgusb */
2921 struct SSEOpHelper_epp {
2922 SSEFunc_0_epp op[2];
2926 struct SSEOpHelper_eppi {
2927 SSEFunc_0_eppi op[2];
2931 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
2932 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
2933 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
2934 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
2935 #define PCLMULQDQ_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, \
2936 CPUID_EXT_PCLMULQDQ }
2937 #define AESNI_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_AES }
2939 static const struct SSEOpHelper_epp sse_op_table6[256] = {
2940 [0x00] = SSSE3_OP(pshufb),
2941 [0x01] = SSSE3_OP(phaddw),
2942 [0x02] = SSSE3_OP(phaddd),
2943 [0x03] = SSSE3_OP(phaddsw),
2944 [0x04] = SSSE3_OP(pmaddubsw),
2945 [0x05] = SSSE3_OP(phsubw),
2946 [0x06] = SSSE3_OP(phsubd),
2947 [0x07] = SSSE3_OP(phsubsw),
2948 [0x08] = SSSE3_OP(psignb),
2949 [0x09] = SSSE3_OP(psignw),
2950 [0x0a] = SSSE3_OP(psignd),
2951 [0x0b] = SSSE3_OP(pmulhrsw),
2952 [0x10] = SSE41_OP(pblendvb),
2953 [0x14] = SSE41_OP(blendvps),
2954 [0x15] = SSE41_OP(blendvpd),
2955 [0x17] = SSE41_OP(ptest),
2956 [0x1c] = SSSE3_OP(pabsb),
2957 [0x1d] = SSSE3_OP(pabsw),
2958 [0x1e] = SSSE3_OP(pabsd),
2959 [0x20] = SSE41_OP(pmovsxbw),
2960 [0x21] = SSE41_OP(pmovsxbd),
2961 [0x22] = SSE41_OP(pmovsxbq),
2962 [0x23] = SSE41_OP(pmovsxwd),
2963 [0x24] = SSE41_OP(pmovsxwq),
2964 [0x25] = SSE41_OP(pmovsxdq),
2965 [0x28] = SSE41_OP(pmuldq),
2966 [0x29] = SSE41_OP(pcmpeqq),
2967 [0x2a] = SSE41_SPECIAL, /* movntqda */
2968 [0x2b] = SSE41_OP(packusdw),
2969 [0x30] = SSE41_OP(pmovzxbw),
2970 [0x31] = SSE41_OP(pmovzxbd),
2971 [0x32] = SSE41_OP(pmovzxbq),
2972 [0x33] = SSE41_OP(pmovzxwd),
2973 [0x34] = SSE41_OP(pmovzxwq),
2974 [0x35] = SSE41_OP(pmovzxdq),
2975 [0x37] = SSE42_OP(pcmpgtq),
2976 [0x38] = SSE41_OP(pminsb),
2977 [0x39] = SSE41_OP(pminsd),
2978 [0x3a] = SSE41_OP(pminuw),
2979 [0x3b] = SSE41_OP(pminud),
2980 [0x3c] = SSE41_OP(pmaxsb),
2981 [0x3d] = SSE41_OP(pmaxsd),
2982 [0x3e] = SSE41_OP(pmaxuw),
2983 [0x3f] = SSE41_OP(pmaxud),
2984 [0x40] = SSE41_OP(pmulld),
2985 [0x41] = SSE41_OP(phminposuw),
2986 [0xdb] = AESNI_OP(aesimc),
2987 [0xdc] = AESNI_OP(aesenc),
2988 [0xdd] = AESNI_OP(aesenclast),
2989 [0xde] = AESNI_OP(aesdec),
2990 [0xdf] = AESNI_OP(aesdeclast),
2993 static const struct SSEOpHelper_eppi sse_op_table7[256] = {
2994 [0x08] = SSE41_OP(roundps),
2995 [0x09] = SSE41_OP(roundpd),
2996 [0x0a] = SSE41_OP(roundss),
2997 [0x0b] = SSE41_OP(roundsd),
2998 [0x0c] = SSE41_OP(blendps),
2999 [0x0d] = SSE41_OP(blendpd),
3000 [0x0e] = SSE41_OP(pblendw),
3001 [0x0f] = SSSE3_OP(palignr),
3002 [0x14] = SSE41_SPECIAL, /* pextrb */
3003 [0x15] = SSE41_SPECIAL, /* pextrw */
3004 [0x16] = SSE41_SPECIAL, /* pextrd/pextrq */
3005 [0x17] = SSE41_SPECIAL, /* extractps */
3006 [0x20] = SSE41_SPECIAL, /* pinsrb */
3007 [0x21] = SSE41_SPECIAL, /* insertps */
3008 [0x22] = SSE41_SPECIAL, /* pinsrd/pinsrq */
3009 [0x40] = SSE41_OP(dpps),
3010 [0x41] = SSE41_OP(dppd),
3011 [0x42] = SSE41_OP(mpsadbw),
3012 [0x44] = PCLMULQDQ_OP(pclmulqdq),
3013 [0x60] = SSE42_OP(pcmpestrm),
3014 [0x61] = SSE42_OP(pcmpestri),
3015 [0x62] = SSE42_OP(pcmpistrm),
3016 [0x63] = SSE42_OP(pcmpistri),
3017 [0xdf] = AESNI_OP(aeskeygenassist),
3020 static void gen_sse(CPUX86State *env, DisasContext *s, int b,
3021 target_ulong pc_start, int rex_r)
3023 int b1, op1_offset, op2_offset, is_xmm, val;
3024 int modrm, mod, rm, reg;
3025 SSEFunc_0_epp sse_fn_epp;
3026 SSEFunc_0_eppi sse_fn_eppi;
3027 SSEFunc_0_ppi sse_fn_ppi;
3028 SSEFunc_0_eppt sse_fn_eppt;
3032 if (s->prefix & PREFIX_DATA)
3034 else if (s->prefix & PREFIX_REPZ)
3036 else if (s->prefix & PREFIX_REPNZ)
3040 sse_fn_epp = sse_op_table1[b][b1];
3044 if ((b <= 0x5f && b >= 0x10) || b == 0xc6 || b == 0xc2) {
3054 /* simple MMX/SSE operation */
3055 if (s->flags & HF_TS_MASK) {
3056 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
3059 if (s->flags & HF_EM_MASK) {
3061 gen_illegal_opcode(s);
3065 && !(s->flags & HF_OSFXSR_MASK)
3066 && ((b != 0x38 && b != 0x3a) || (s->prefix & PREFIX_DATA))) {
3070 if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) {
3071 /* If we were fully decoding this we might use illegal_op. */
3075 gen_helper_emms(cpu_env);
3080 gen_helper_emms(cpu_env);
3083 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3084 the static cpu state) */
3086 gen_helper_enter_mmx(cpu_env);
3089 modrm = x86_ldub_code(env, s);
3090 reg = ((modrm >> 3) & 7);
3093 mod = (modrm >> 6) & 3;
3094 if (sse_fn_epp == SSE_SPECIAL) {
3097 case 0x0e7: /* movntq */
3101 gen_lea_modrm(env, s, modrm);
3102 gen_stq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
3104 case 0x1e7: /* movntdq */
3105 case 0x02b: /* movntps */
3106 case 0x12b: /* movntps */
3109 gen_lea_modrm(env, s, modrm);
3110 gen_sto_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3112 case 0x3f0: /* lddqu */
3115 gen_lea_modrm(env, s, modrm);
3116 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3118 case 0x22b: /* movntss */
3119 case 0x32b: /* movntsd */
3122 gen_lea_modrm(env, s, modrm);
3124 gen_stq_env_A0(s, offsetof(CPUX86State,
3125 xmm_regs[reg].ZMM_Q(0)));
3127 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
3128 xmm_regs[reg].ZMM_L(0)));
3129 gen_op_st_v(s, MO_32, cpu_T0, cpu_A0);
3132 case 0x6e: /* movd mm, ea */
3133 #ifdef TARGET_X86_64
3134 if (s->dflag == MO_64) {
3135 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 0);
3136 tcg_gen_st_tl(cpu_T0, cpu_env, offsetof(CPUX86State,fpregs[reg].mmx));
3140 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 0);
3141 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3142 offsetof(CPUX86State,fpregs[reg].mmx));
3143 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
3144 gen_helper_movl_mm_T0_mmx(cpu_ptr0, cpu_tmp2_i32);
3147 case 0x16e: /* movd xmm, ea */
3148 #ifdef TARGET_X86_64
3149 if (s->dflag == MO_64) {
3150 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 0);
3151 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3152 offsetof(CPUX86State,xmm_regs[reg]));
3153 gen_helper_movq_mm_T0_xmm(cpu_ptr0, cpu_T0);
3157 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 0);
3158 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3159 offsetof(CPUX86State,xmm_regs[reg]));
3160 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
3161 gen_helper_movl_mm_T0_xmm(cpu_ptr0, cpu_tmp2_i32);
3164 case 0x6f: /* movq mm, ea */
3166 gen_lea_modrm(env, s, modrm);
3167 gen_ldq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
3170 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
3171 offsetof(CPUX86State,fpregs[rm].mmx));
3172 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
3173 offsetof(CPUX86State,fpregs[reg].mmx));
3176 case 0x010: /* movups */
3177 case 0x110: /* movupd */
3178 case 0x028: /* movaps */
3179 case 0x128: /* movapd */
3180 case 0x16f: /* movdqa xmm, ea */
3181 case 0x26f: /* movdqu xmm, ea */
3183 gen_lea_modrm(env, s, modrm);
3184 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3186 rm = (modrm & 7) | REX_B(s);
3187 gen_op_movo(offsetof(CPUX86State,xmm_regs[reg]),
3188 offsetof(CPUX86State,xmm_regs[rm]));
3191 case 0x210: /* movss xmm, ea */
3193 gen_lea_modrm(env, s, modrm);
3194 gen_op_ld_v(s, MO_32, cpu_T0, cpu_A0);
3195 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3196 tcg_gen_movi_tl(cpu_T0, 0);
3197 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)));
3198 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)));
3199 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)));
3201 rm = (modrm & 7) | REX_B(s);
3202 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)),
3203 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0)));
3206 case 0x310: /* movsd xmm, ea */
3208 gen_lea_modrm(env, s, modrm);
3209 gen_ldq_env_A0(s, offsetof(CPUX86State,
3210 xmm_regs[reg].ZMM_Q(0)));
3211 tcg_gen_movi_tl(cpu_T0, 0);
3212 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)));
3213 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)));
3215 rm = (modrm & 7) | REX_B(s);
3216 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3217 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3220 case 0x012: /* movlps */
3221 case 0x112: /* movlpd */
3223 gen_lea_modrm(env, s, modrm);
3224 gen_ldq_env_A0(s, offsetof(CPUX86State,
3225 xmm_regs[reg].ZMM_Q(0)));
3228 rm = (modrm & 7) | REX_B(s);
3229 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3230 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(1)));
3233 case 0x212: /* movsldup */
3235 gen_lea_modrm(env, s, modrm);
3236 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3238 rm = (modrm & 7) | REX_B(s);
3239 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)),
3240 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0)));
3241 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)),
3242 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(2)));
3244 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)),
3245 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3246 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)),
3247 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)));
3249 case 0x312: /* movddup */
3251 gen_lea_modrm(env, s, modrm);
3252 gen_ldq_env_A0(s, offsetof(CPUX86State,
3253 xmm_regs[reg].ZMM_Q(0)));
3255 rm = (modrm & 7) | REX_B(s);
3256 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3257 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3259 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)),
3260 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3262 case 0x016: /* movhps */
3263 case 0x116: /* movhpd */
3265 gen_lea_modrm(env, s, modrm);
3266 gen_ldq_env_A0(s, offsetof(CPUX86State,
3267 xmm_regs[reg].ZMM_Q(1)));
3270 rm = (modrm & 7) | REX_B(s);
3271 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)),
3272 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3275 case 0x216: /* movshdup */
3277 gen_lea_modrm(env, s, modrm);
3278 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3280 rm = (modrm & 7) | REX_B(s);
3281 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)),
3282 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(1)));
3283 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)),
3284 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(3)));
3286 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)),
3287 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)));
3288 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)),
3289 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)));
3294 int bit_index, field_length;
3296 if (b1 == 1 && reg != 0)
3298 field_length = x86_ldub_code(env, s) & 0x3F;
3299 bit_index = x86_ldub_code(env, s) & 0x3F;
3300 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3301 offsetof(CPUX86State,xmm_regs[reg]));
3303 gen_helper_extrq_i(cpu_env, cpu_ptr0,
3304 tcg_const_i32(bit_index),
3305 tcg_const_i32(field_length));
3307 gen_helper_insertq_i(cpu_env, cpu_ptr0,
3308 tcg_const_i32(bit_index),
3309 tcg_const_i32(field_length));
3312 case 0x7e: /* movd ea, mm */
3313 #ifdef TARGET_X86_64
3314 if (s->dflag == MO_64) {
3315 tcg_gen_ld_i64(cpu_T0, cpu_env,
3316 offsetof(CPUX86State,fpregs[reg].mmx));
3317 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 1);
3321 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
3322 offsetof(CPUX86State,fpregs[reg].mmx.MMX_L(0)));
3323 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 1);
3326 case 0x17e: /* movd ea, xmm */
3327 #ifdef TARGET_X86_64
3328 if (s->dflag == MO_64) {
3329 tcg_gen_ld_i64(cpu_T0, cpu_env,
3330 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3331 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 1);
3335 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
3336 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3337 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 1);
3340 case 0x27e: /* movq xmm, ea */
3342 gen_lea_modrm(env, s, modrm);
3343 gen_ldq_env_A0(s, offsetof(CPUX86State,
3344 xmm_regs[reg].ZMM_Q(0)));
3346 rm = (modrm & 7) | REX_B(s);
3347 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3348 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3350 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)));
3352 case 0x7f: /* movq ea, mm */
3354 gen_lea_modrm(env, s, modrm);
3355 gen_stq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
3358 gen_op_movq(offsetof(CPUX86State,fpregs[rm].mmx),
3359 offsetof(CPUX86State,fpregs[reg].mmx));
3362 case 0x011: /* movups */
3363 case 0x111: /* movupd */
3364 case 0x029: /* movaps */
3365 case 0x129: /* movapd */
3366 case 0x17f: /* movdqa ea, xmm */
3367 case 0x27f: /* movdqu ea, xmm */
3369 gen_lea_modrm(env, s, modrm);
3370 gen_sto_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3372 rm = (modrm & 7) | REX_B(s);
3373 gen_op_movo(offsetof(CPUX86State,xmm_regs[rm]),
3374 offsetof(CPUX86State,xmm_regs[reg]));
3377 case 0x211: /* movss ea, xmm */
3379 gen_lea_modrm(env, s, modrm);
3380 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3381 gen_op_st_v(s, MO_32, cpu_T0, cpu_A0);
3383 rm = (modrm & 7) | REX_B(s);
3384 gen_op_movl(offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0)),
3385 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3388 case 0x311: /* movsd ea, xmm */
3390 gen_lea_modrm(env, s, modrm);
3391 gen_stq_env_A0(s, offsetof(CPUX86State,
3392 xmm_regs[reg].ZMM_Q(0)));
3394 rm = (modrm & 7) | REX_B(s);
3395 gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)),
3396 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3399 case 0x013: /* movlps */
3400 case 0x113: /* movlpd */
3402 gen_lea_modrm(env, s, modrm);
3403 gen_stq_env_A0(s, offsetof(CPUX86State,
3404 xmm_regs[reg].ZMM_Q(0)));
3409 case 0x017: /* movhps */
3410 case 0x117: /* movhpd */
3412 gen_lea_modrm(env, s, modrm);
3413 gen_stq_env_A0(s, offsetof(CPUX86State,
3414 xmm_regs[reg].ZMM_Q(1)));
3419 case 0x71: /* shift mm, im */
3422 case 0x171: /* shift xmm, im */
3428 val = x86_ldub_code(env, s);
3430 tcg_gen_movi_tl(cpu_T0, val);
3431 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(0)));
3432 tcg_gen_movi_tl(cpu_T0, 0);
3433 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(1)));
3434 op1_offset = offsetof(CPUX86State,xmm_t0);
3436 tcg_gen_movi_tl(cpu_T0, val);
3437 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(0)));
3438 tcg_gen_movi_tl(cpu_T0, 0);
3439 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(1)));
3440 op1_offset = offsetof(CPUX86State,mmx_t0);
3442 sse_fn_epp = sse_op_table2[((b - 1) & 3) * 8 +
3443 (((modrm >> 3)) & 7)][b1];
3448 rm = (modrm & 7) | REX_B(s);
3449 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3452 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3454 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
3455 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op1_offset);
3456 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
3458 case 0x050: /* movmskps */
3459 rm = (modrm & 7) | REX_B(s);
3460 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3461 offsetof(CPUX86State,xmm_regs[rm]));
3462 gen_helper_movmskps(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3463 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
3465 case 0x150: /* movmskpd */
3466 rm = (modrm & 7) | REX_B(s);
3467 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3468 offsetof(CPUX86State,xmm_regs[rm]));
3469 gen_helper_movmskpd(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3470 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
3472 case 0x02a: /* cvtpi2ps */
3473 case 0x12a: /* cvtpi2pd */
3474 gen_helper_enter_mmx(cpu_env);
3476 gen_lea_modrm(env, s, modrm);
3477 op2_offset = offsetof(CPUX86State,mmx_t0);
3478 gen_ldq_env_A0(s, op2_offset);
3481 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3483 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3484 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3485 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3488 gen_helper_cvtpi2ps(cpu_env, cpu_ptr0, cpu_ptr1);
3492 gen_helper_cvtpi2pd(cpu_env, cpu_ptr0, cpu_ptr1);
3496 case 0x22a: /* cvtsi2ss */
3497 case 0x32a: /* cvtsi2sd */
3498 ot = mo_64_32(s->dflag);
3499 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3500 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3501 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3503 SSEFunc_0_epi sse_fn_epi = sse_op_table3ai[(b >> 8) & 1];
3504 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
3505 sse_fn_epi(cpu_env, cpu_ptr0, cpu_tmp2_i32);
3507 #ifdef TARGET_X86_64
3508 SSEFunc_0_epl sse_fn_epl = sse_op_table3aq[(b >> 8) & 1];
3509 sse_fn_epl(cpu_env, cpu_ptr0, cpu_T0);
3515 case 0x02c: /* cvttps2pi */
3516 case 0x12c: /* cvttpd2pi */
3517 case 0x02d: /* cvtps2pi */
3518 case 0x12d: /* cvtpd2pi */
3519 gen_helper_enter_mmx(cpu_env);
3521 gen_lea_modrm(env, s, modrm);
3522 op2_offset = offsetof(CPUX86State,xmm_t0);
3523 gen_ldo_env_A0(s, op2_offset);
3525 rm = (modrm & 7) | REX_B(s);
3526 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3528 op1_offset = offsetof(CPUX86State,fpregs[reg & 7].mmx);
3529 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3530 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3533 gen_helper_cvttps2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3536 gen_helper_cvttpd2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3539 gen_helper_cvtps2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3542 gen_helper_cvtpd2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3546 case 0x22c: /* cvttss2si */
3547 case 0x32c: /* cvttsd2si */
3548 case 0x22d: /* cvtss2si */
3549 case 0x32d: /* cvtsd2si */
3550 ot = mo_64_32(s->dflag);
3552 gen_lea_modrm(env, s, modrm);
3554 gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_Q(0)));
3556 gen_op_ld_v(s, MO_32, cpu_T0, cpu_A0);
3557 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(0)));
3559 op2_offset = offsetof(CPUX86State,xmm_t0);
3561 rm = (modrm & 7) | REX_B(s);
3562 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3564 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
3566 SSEFunc_i_ep sse_fn_i_ep =
3567 sse_op_table3bi[((b >> 7) & 2) | (b & 1)];
3568 sse_fn_i_ep(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3569 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
3571 #ifdef TARGET_X86_64
3572 SSEFunc_l_ep sse_fn_l_ep =
3573 sse_op_table3bq[((b >> 7) & 2) | (b & 1)];
3574 sse_fn_l_ep(cpu_T0, cpu_env, cpu_ptr0);
3579 gen_op_mov_reg_v(ot, reg, cpu_T0);
3581 case 0xc4: /* pinsrw */
3584 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
3585 val = x86_ldub_code(env, s);
3588 tcg_gen_st16_tl(cpu_T0, cpu_env,
3589 offsetof(CPUX86State,xmm_regs[reg].ZMM_W(val)));
3592 tcg_gen_st16_tl(cpu_T0, cpu_env,
3593 offsetof(CPUX86State,fpregs[reg].mmx.MMX_W(val)));
3596 case 0xc5: /* pextrw */
3600 ot = mo_64_32(s->dflag);
3601 val = x86_ldub_code(env, s);
3604 rm = (modrm & 7) | REX_B(s);
3605 tcg_gen_ld16u_tl(cpu_T0, cpu_env,
3606 offsetof(CPUX86State,xmm_regs[rm].ZMM_W(val)));
3610 tcg_gen_ld16u_tl(cpu_T0, cpu_env,
3611 offsetof(CPUX86State,fpregs[rm].mmx.MMX_W(val)));
3613 reg = ((modrm >> 3) & 7) | rex_r;
3614 gen_op_mov_reg_v(ot, reg, cpu_T0);
3616 case 0x1d6: /* movq ea, xmm */
3618 gen_lea_modrm(env, s, modrm);
3619 gen_stq_env_A0(s, offsetof(CPUX86State,
3620 xmm_regs[reg].ZMM_Q(0)));
3622 rm = (modrm & 7) | REX_B(s);
3623 gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)),
3624 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3625 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(1)));
3628 case 0x2d6: /* movq2dq */
3629 gen_helper_enter_mmx(cpu_env);
3631 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3632 offsetof(CPUX86State,fpregs[rm].mmx));
3633 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)));
3635 case 0x3d6: /* movdq2q */
3636 gen_helper_enter_mmx(cpu_env);
3637 rm = (modrm & 7) | REX_B(s);
3638 gen_op_movq(offsetof(CPUX86State,fpregs[reg & 7].mmx),
3639 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3641 case 0xd7: /* pmovmskb */
3646 rm = (modrm & 7) | REX_B(s);
3647 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[rm]));
3648 gen_helper_pmovmskb_xmm(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3651 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,fpregs[rm].mmx));
3652 gen_helper_pmovmskb_mmx(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3654 reg = ((modrm >> 3) & 7) | rex_r;
3655 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
3661 if ((b & 0xf0) == 0xf0) {
3664 modrm = x86_ldub_code(env, s);
3666 reg = ((modrm >> 3) & 7) | rex_r;
3667 mod = (modrm >> 6) & 3;
3672 sse_fn_epp = sse_op_table6[b].op[b1];
3676 if (!(s->cpuid_ext_features & sse_op_table6[b].ext_mask))
3680 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3682 op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
3684 op2_offset = offsetof(CPUX86State,xmm_t0);
3685 gen_lea_modrm(env, s, modrm);
3687 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3688 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3689 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3690 gen_ldq_env_A0(s, op2_offset +
3691 offsetof(ZMMReg, ZMM_Q(0)));
3693 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3694 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3695 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
3696 s->mem_index, MO_LEUL);
3697 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, op2_offset +
3698 offsetof(ZMMReg, ZMM_L(0)));
3700 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3701 tcg_gen_qemu_ld_tl(cpu_tmp0, cpu_A0,
3702 s->mem_index, MO_LEUW);
3703 tcg_gen_st16_tl(cpu_tmp0, cpu_env, op2_offset +
3704 offsetof(ZMMReg, ZMM_W(0)));
3706 case 0x2a: /* movntqda */
3707 gen_ldo_env_A0(s, op1_offset);
3710 gen_ldo_env_A0(s, op2_offset);
3714 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
3716 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3718 op2_offset = offsetof(CPUX86State,mmx_t0);
3719 gen_lea_modrm(env, s, modrm);
3720 gen_ldq_env_A0(s, op2_offset);
3723 if (sse_fn_epp == SSE_SPECIAL) {
3727 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3728 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3729 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
3732 set_cc_op(s, CC_OP_EFLAGS);
3739 /* Various integer extensions at 0f 38 f[0-f]. */
3740 b = modrm | (b1 << 8);
3741 modrm = x86_ldub_code(env, s);
3742 reg = ((modrm >> 3) & 7) | rex_r;
3745 case 0x3f0: /* crc32 Gd,Eb */
3746 case 0x3f1: /* crc32 Gd,Ey */
3748 if (!(s->cpuid_ext_features & CPUID_EXT_SSE42)) {
3751 if ((b & 0xff) == 0xf0) {
3753 } else if (s->dflag != MO_64) {
3754 ot = (s->prefix & PREFIX_DATA ? MO_16 : MO_32);
3759 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[reg]);
3760 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3761 gen_helper_crc32(cpu_T0, cpu_tmp2_i32,
3762 cpu_T0, tcg_const_i32(8 << ot));
3764 ot = mo_64_32(s->dflag);
3765 gen_op_mov_reg_v(ot, reg, cpu_T0);
3768 case 0x1f0: /* crc32 or movbe */
3770 /* For these insns, the f3 prefix is supposed to have priority
3771 over the 66 prefix, but that's not what we implement above
3773 if (s->prefix & PREFIX_REPNZ) {
3777 case 0x0f0: /* movbe Gy,My */
3778 case 0x0f1: /* movbe My,Gy */
3779 if (!(s->cpuid_ext_features & CPUID_EXT_MOVBE)) {
3782 if (s->dflag != MO_64) {
3783 ot = (s->prefix & PREFIX_DATA ? MO_16 : MO_32);
3788 gen_lea_modrm(env, s, modrm);
3790 tcg_gen_qemu_ld_tl(cpu_T0, cpu_A0,
3791 s->mem_index, ot | MO_BE);
3792 gen_op_mov_reg_v(ot, reg, cpu_T0);
3794 tcg_gen_qemu_st_tl(cpu_regs[reg], cpu_A0,
3795 s->mem_index, ot | MO_BE);
3799 case 0x0f2: /* andn Gy, By, Ey */
3800 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
3801 || !(s->prefix & PREFIX_VEX)
3805 ot = mo_64_32(s->dflag);
3806 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3807 tcg_gen_andc_tl(cpu_T0, cpu_regs[s->vex_v], cpu_T0);
3808 gen_op_mov_reg_v(ot, reg, cpu_T0);
3809 gen_op_update1_cc();
3810 set_cc_op(s, CC_OP_LOGICB + ot);
3813 case 0x0f7: /* bextr Gy, Ey, By */
3814 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
3815 || !(s->prefix & PREFIX_VEX)
3819 ot = mo_64_32(s->dflag);
3823 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3824 /* Extract START, and shift the operand.
3825 Shifts larger than operand size get zeros. */
3826 tcg_gen_ext8u_tl(cpu_A0, cpu_regs[s->vex_v]);
3827 tcg_gen_shr_tl(cpu_T0, cpu_T0, cpu_A0);
3829 bound = tcg_const_tl(ot == MO_64 ? 63 : 31);
3830 zero = tcg_const_tl(0);
3831 tcg_gen_movcond_tl(TCG_COND_LEU, cpu_T0, cpu_A0, bound,
3833 tcg_temp_free(zero);
3835 /* Extract the LEN into a mask. Lengths larger than
3836 operand size get all ones. */
3837 tcg_gen_extract_tl(cpu_A0, cpu_regs[s->vex_v], 8, 8);
3838 tcg_gen_movcond_tl(TCG_COND_LEU, cpu_A0, cpu_A0, bound,
3840 tcg_temp_free(bound);
3841 tcg_gen_movi_tl(cpu_T1, 1);
3842 tcg_gen_shl_tl(cpu_T1, cpu_T1, cpu_A0);
3843 tcg_gen_subi_tl(cpu_T1, cpu_T1, 1);
3844 tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1);
3846 gen_op_mov_reg_v(ot, reg, cpu_T0);
3847 gen_op_update1_cc();
3848 set_cc_op(s, CC_OP_LOGICB + ot);
3852 case 0x0f5: /* bzhi Gy, Ey, By */
3853 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3854 || !(s->prefix & PREFIX_VEX)
3858 ot = mo_64_32(s->dflag);
3859 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3860 tcg_gen_ext8u_tl(cpu_T1, cpu_regs[s->vex_v]);
3862 TCGv bound = tcg_const_tl(ot == MO_64 ? 63 : 31);
3863 /* Note that since we're using BMILG (in order to get O
3864 cleared) we need to store the inverse into C. */
3865 tcg_gen_setcond_tl(TCG_COND_LT, cpu_cc_src,
3867 tcg_gen_movcond_tl(TCG_COND_GT, cpu_T1, cpu_T1,
3868 bound, bound, cpu_T1);
3869 tcg_temp_free(bound);
3871 tcg_gen_movi_tl(cpu_A0, -1);
3872 tcg_gen_shl_tl(cpu_A0, cpu_A0, cpu_T1);
3873 tcg_gen_andc_tl(cpu_T0, cpu_T0, cpu_A0);
3874 gen_op_mov_reg_v(ot, reg, cpu_T0);
3875 gen_op_update1_cc();
3876 set_cc_op(s, CC_OP_BMILGB + ot);
3879 case 0x3f6: /* mulx By, Gy, rdx, Ey */
3880 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3881 || !(s->prefix & PREFIX_VEX)
3885 ot = mo_64_32(s->dflag);
3886 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3889 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
3890 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_regs[R_EDX]);
3891 tcg_gen_mulu2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
3892 cpu_tmp2_i32, cpu_tmp3_i32);
3893 tcg_gen_extu_i32_tl(cpu_regs[s->vex_v], cpu_tmp2_i32);
3894 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp3_i32);
3896 #ifdef TARGET_X86_64
3898 tcg_gen_mulu2_i64(cpu_T0, cpu_T1,
3899 cpu_T0, cpu_regs[R_EDX]);
3900 tcg_gen_mov_i64(cpu_regs[s->vex_v], cpu_T0);
3901 tcg_gen_mov_i64(cpu_regs[reg], cpu_T1);
3907 case 0x3f5: /* pdep Gy, By, Ey */
3908 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3909 || !(s->prefix & PREFIX_VEX)
3913 ot = mo_64_32(s->dflag);
3914 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3915 /* Note that by zero-extending the mask operand, we
3916 automatically handle zero-extending the result. */
3918 tcg_gen_mov_tl(cpu_T1, cpu_regs[s->vex_v]);
3920 tcg_gen_ext32u_tl(cpu_T1, cpu_regs[s->vex_v]);
3922 gen_helper_pdep(cpu_regs[reg], cpu_T0, cpu_T1);
3925 case 0x2f5: /* pext Gy, By, Ey */
3926 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3927 || !(s->prefix & PREFIX_VEX)
3931 ot = mo_64_32(s->dflag);
3932 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3933 /* Note that by zero-extending the mask operand, we
3934 automatically handle zero-extending the result. */
3936 tcg_gen_mov_tl(cpu_T1, cpu_regs[s->vex_v]);
3938 tcg_gen_ext32u_tl(cpu_T1, cpu_regs[s->vex_v]);
3940 gen_helper_pext(cpu_regs[reg], cpu_T0, cpu_T1);
3943 case 0x1f6: /* adcx Gy, Ey */
3944 case 0x2f6: /* adox Gy, Ey */
3945 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_ADX)) {
3948 TCGv carry_in, carry_out, zero;
3951 ot = mo_64_32(s->dflag);
3952 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3954 /* Re-use the carry-out from a previous round. */
3955 TCGV_UNUSED(carry_in);
3956 carry_out = (b == 0x1f6 ? cpu_cc_dst : cpu_cc_src2);
3960 carry_in = cpu_cc_dst;
3961 end_op = CC_OP_ADCX;
3963 end_op = CC_OP_ADCOX;
3968 end_op = CC_OP_ADCOX;
3970 carry_in = cpu_cc_src2;
3971 end_op = CC_OP_ADOX;
3975 end_op = CC_OP_ADCOX;
3976 carry_in = carry_out;
3979 end_op = (b == 0x1f6 ? CC_OP_ADCX : CC_OP_ADOX);
3982 /* If we can't reuse carry-out, get it out of EFLAGS. */
3983 if (TCGV_IS_UNUSED(carry_in)) {
3984 if (s->cc_op != CC_OP_ADCX && s->cc_op != CC_OP_ADOX) {
3985 gen_compute_eflags(s);
3987 carry_in = cpu_tmp0;
3988 tcg_gen_extract_tl(carry_in, cpu_cc_src,
3989 ctz32(b == 0x1f6 ? CC_C : CC_O), 1);
3993 #ifdef TARGET_X86_64
3995 /* If we know TL is 64-bit, and we want a 32-bit
3996 result, just do everything in 64-bit arithmetic. */
3997 tcg_gen_ext32u_i64(cpu_regs[reg], cpu_regs[reg]);
3998 tcg_gen_ext32u_i64(cpu_T0, cpu_T0);
3999 tcg_gen_add_i64(cpu_T0, cpu_T0, cpu_regs[reg]);
4000 tcg_gen_add_i64(cpu_T0, cpu_T0, carry_in);
4001 tcg_gen_ext32u_i64(cpu_regs[reg], cpu_T0);
4002 tcg_gen_shri_i64(carry_out, cpu_T0, 32);
4006 /* Otherwise compute the carry-out in two steps. */
4007 zero = tcg_const_tl(0);
4008 tcg_gen_add2_tl(cpu_T0, carry_out,
4011 tcg_gen_add2_tl(cpu_regs[reg], carry_out,
4012 cpu_regs[reg], carry_out,
4014 tcg_temp_free(zero);
4017 set_cc_op(s, end_op);
4021 case 0x1f7: /* shlx Gy, Ey, By */
4022 case 0x2f7: /* sarx Gy, Ey, By */
4023 case 0x3f7: /* shrx Gy, Ey, By */
4024 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
4025 || !(s->prefix & PREFIX_VEX)
4029 ot = mo_64_32(s->dflag);
4030 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4032 tcg_gen_andi_tl(cpu_T1, cpu_regs[s->vex_v], 63);
4034 tcg_gen_andi_tl(cpu_T1, cpu_regs[s->vex_v], 31);
4037 tcg_gen_shl_tl(cpu_T0, cpu_T0, cpu_T1);
4038 } else if (b == 0x2f7) {
4040 tcg_gen_ext32s_tl(cpu_T0, cpu_T0);
4042 tcg_gen_sar_tl(cpu_T0, cpu_T0, cpu_T1);
4045 tcg_gen_ext32u_tl(cpu_T0, cpu_T0);
4047 tcg_gen_shr_tl(cpu_T0, cpu_T0, cpu_T1);
4049 gen_op_mov_reg_v(ot, reg, cpu_T0);
4055 case 0x3f3: /* Group 17 */
4056 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
4057 || !(s->prefix & PREFIX_VEX)
4061 ot = mo_64_32(s->dflag);
4062 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4065 case 1: /* blsr By,Ey */
4066 tcg_gen_neg_tl(cpu_T1, cpu_T0);
4067 tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1);
4068 gen_op_mov_reg_v(ot, s->vex_v, cpu_T0);
4069 gen_op_update2_cc();
4070 set_cc_op(s, CC_OP_BMILGB + ot);
4073 case 2: /* blsmsk By,Ey */
4074 tcg_gen_mov_tl(cpu_cc_src, cpu_T0);
4075 tcg_gen_subi_tl(cpu_T0, cpu_T0, 1);
4076 tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_cc_src);
4077 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4078 set_cc_op(s, CC_OP_BMILGB + ot);
4081 case 3: /* blsi By, Ey */
4082 tcg_gen_mov_tl(cpu_cc_src, cpu_T0);
4083 tcg_gen_subi_tl(cpu_T0, cpu_T0, 1);
4084 tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_cc_src);
4085 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4086 set_cc_op(s, CC_OP_BMILGB + ot);
4102 modrm = x86_ldub_code(env, s);
4104 reg = ((modrm >> 3) & 7) | rex_r;
4105 mod = (modrm >> 6) & 3;
4110 sse_fn_eppi = sse_op_table7[b].op[b1];
4114 if (!(s->cpuid_ext_features & sse_op_table7[b].ext_mask))
4119 if (sse_fn_eppi == SSE_SPECIAL) {
4120 ot = mo_64_32(s->dflag);
4121 rm = (modrm & 7) | REX_B(s);
4123 gen_lea_modrm(env, s, modrm);
4124 reg = ((modrm >> 3) & 7) | rex_r;
4125 val = x86_ldub_code(env, s);
4127 case 0x14: /* pextrb */
4128 tcg_gen_ld8u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
4129 xmm_regs[reg].ZMM_B(val & 15)));
4131 gen_op_mov_reg_v(ot, rm, cpu_T0);
4133 tcg_gen_qemu_st_tl(cpu_T0, cpu_A0,
4134 s->mem_index, MO_UB);
4137 case 0x15: /* pextrw */
4138 tcg_gen_ld16u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
4139 xmm_regs[reg].ZMM_W(val & 7)));
4141 gen_op_mov_reg_v(ot, rm, cpu_T0);
4143 tcg_gen_qemu_st_tl(cpu_T0, cpu_A0,
4144 s->mem_index, MO_LEUW);
4148 if (ot == MO_32) { /* pextrd */
4149 tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
4150 offsetof(CPUX86State,
4151 xmm_regs[reg].ZMM_L(val & 3)));
4153 tcg_gen_extu_i32_tl(cpu_regs[rm], cpu_tmp2_i32);
4155 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
4156 s->mem_index, MO_LEUL);
4158 } else { /* pextrq */
4159 #ifdef TARGET_X86_64
4160 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
4161 offsetof(CPUX86State,
4162 xmm_regs[reg].ZMM_Q(val & 1)));
4164 tcg_gen_mov_i64(cpu_regs[rm], cpu_tmp1_i64);
4166 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0,
4167 s->mem_index, MO_LEQ);
4174 case 0x17: /* extractps */
4175 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
4176 xmm_regs[reg].ZMM_L(val & 3)));
4178 gen_op_mov_reg_v(ot, rm, cpu_T0);
4180 tcg_gen_qemu_st_tl(cpu_T0, cpu_A0,
4181 s->mem_index, MO_LEUL);
4184 case 0x20: /* pinsrb */
4186 gen_op_mov_v_reg(MO_32, cpu_T0, rm);
4188 tcg_gen_qemu_ld_tl(cpu_T0, cpu_A0,
4189 s->mem_index, MO_UB);
4191 tcg_gen_st8_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
4192 xmm_regs[reg].ZMM_B(val & 15)));
4194 case 0x21: /* insertps */
4196 tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
4197 offsetof(CPUX86State,xmm_regs[rm]
4198 .ZMM_L((val >> 6) & 3)));
4200 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
4201 s->mem_index, MO_LEUL);
4203 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
4204 offsetof(CPUX86State,xmm_regs[reg]
4205 .ZMM_L((val >> 4) & 3)));
4207 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4208 cpu_env, offsetof(CPUX86State,
4209 xmm_regs[reg].ZMM_L(0)));
4211 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4212 cpu_env, offsetof(CPUX86State,
4213 xmm_regs[reg].ZMM_L(1)));
4215 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4216 cpu_env, offsetof(CPUX86State,
4217 xmm_regs[reg].ZMM_L(2)));
4219 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4220 cpu_env, offsetof(CPUX86State,
4221 xmm_regs[reg].ZMM_L(3)));
4224 if (ot == MO_32) { /* pinsrd */
4226 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[rm]);
4228 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
4229 s->mem_index, MO_LEUL);
4231 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
4232 offsetof(CPUX86State,
4233 xmm_regs[reg].ZMM_L(val & 3)));
4234 } else { /* pinsrq */
4235 #ifdef TARGET_X86_64
4237 gen_op_mov_v_reg(ot, cpu_tmp1_i64, rm);
4239 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0,
4240 s->mem_index, MO_LEQ);
4242 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
4243 offsetof(CPUX86State,
4244 xmm_regs[reg].ZMM_Q(val & 1)));
4255 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
4257 op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
4259 op2_offset = offsetof(CPUX86State,xmm_t0);
4260 gen_lea_modrm(env, s, modrm);
4261 gen_ldo_env_A0(s, op2_offset);
4264 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
4266 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
4268 op2_offset = offsetof(CPUX86State,mmx_t0);
4269 gen_lea_modrm(env, s, modrm);
4270 gen_ldq_env_A0(s, op2_offset);
4273 val = x86_ldub_code(env, s);
4275 if ((b & 0xfc) == 0x60) { /* pcmpXstrX */
4276 set_cc_op(s, CC_OP_EFLAGS);
4278 if (s->dflag == MO_64) {
4279 /* The helper must use entire 64-bit gp registers */
4284 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4285 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4286 sse_fn_eppi(cpu_env, cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
4290 /* Various integer extensions at 0f 3a f[0-f]. */
4291 b = modrm | (b1 << 8);
4292 modrm = x86_ldub_code(env, s);
4293 reg = ((modrm >> 3) & 7) | rex_r;
4296 case 0x3f0: /* rorx Gy,Ey, Ib */
4297 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
4298 || !(s->prefix & PREFIX_VEX)
4302 ot = mo_64_32(s->dflag);
4303 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4304 b = x86_ldub_code(env, s);
4306 tcg_gen_rotri_tl(cpu_T0, cpu_T0, b & 63);
4308 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
4309 tcg_gen_rotri_i32(cpu_tmp2_i32, cpu_tmp2_i32, b & 31);
4310 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
4312 gen_op_mov_reg_v(ot, reg, cpu_T0);
4322 gen_unknown_opcode(env, s);
4326 /* generic MMX or SSE operation */
4328 case 0x70: /* pshufx insn */
4329 case 0xc6: /* pshufx insn */
4330 case 0xc2: /* compare insns */
4337 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
4341 gen_lea_modrm(env, s, modrm);
4342 op2_offset = offsetof(CPUX86State,xmm_t0);
4348 /* Most sse scalar operations. */
4351 } else if (b1 == 3) {
4356 case 0x2e: /* ucomis[sd] */
4357 case 0x2f: /* comis[sd] */
4369 gen_op_ld_v(s, MO_32, cpu_T0, cpu_A0);
4370 tcg_gen_st32_tl(cpu_T0, cpu_env,
4371 offsetof(CPUX86State,xmm_t0.ZMM_L(0)));
4375 gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_D(0)));
4378 /* 128 bit access */
4379 gen_ldo_env_A0(s, op2_offset);
4383 rm = (modrm & 7) | REX_B(s);
4384 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
4387 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
4389 gen_lea_modrm(env, s, modrm);
4390 op2_offset = offsetof(CPUX86State,mmx_t0);
4391 gen_ldq_env_A0(s, op2_offset);
4394 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
4398 case 0x0f: /* 3DNow! data insns */
4399 val = x86_ldub_code(env, s);
4400 sse_fn_epp = sse_op_table5[val];
4404 if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) {
4407 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4408 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4409 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4411 case 0x70: /* pshufx insn */
4412 case 0xc6: /* pshufx insn */
4413 val = x86_ldub_code(env, s);
4414 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4415 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4416 /* XXX: introduce a new table? */
4417 sse_fn_ppi = (SSEFunc_0_ppi)sse_fn_epp;
4418 sse_fn_ppi(cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
4422 val = x86_ldub_code(env, s);
4425 sse_fn_epp = sse_op_table4[val][b1];
4427 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4428 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4429 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4432 /* maskmov : we must prepare A0 */
4435 tcg_gen_mov_tl(cpu_A0, cpu_regs[R_EDI]);
4436 gen_extu(s->aflag, cpu_A0);
4437 gen_add_A0_ds_seg(s);
4439 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4440 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4441 /* XXX: introduce a new table? */
4442 sse_fn_eppt = (SSEFunc_0_eppt)sse_fn_epp;
4443 sse_fn_eppt(cpu_env, cpu_ptr0, cpu_ptr1, cpu_A0);
4446 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4447 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4448 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4451 if (b == 0x2e || b == 0x2f) {
4452 set_cc_op(s, CC_OP_EFLAGS);
4457 /* convert one instruction. s->base.is_jmp is set if the translation must
4458 be stopped. Return the next pc value */
4459 static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
4461 CPUX86State *env = cpu->env_ptr;
4464 TCGMemOp ot, aflag, dflag;
4465 int modrm, reg, rm, mod, op, opreg, val;
4466 target_ulong next_eip, tval;
4468 target_ulong pc_start = s->base.pc_next;
4470 s->pc_start = s->pc = pc_start;
4475 #ifdef TARGET_X86_64
4480 s->rip_offset = 0; /* for relative ip address */
4483 if (sigsetjmp(s->jmpbuf, 0) != 0) {
4484 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
4489 b = x86_ldub_code(env, s);
4490 /* Collect prefixes. */
4493 prefixes |= PREFIX_REPZ;
4496 prefixes |= PREFIX_REPNZ;
4499 prefixes |= PREFIX_LOCK;
4520 prefixes |= PREFIX_DATA;
4523 prefixes |= PREFIX_ADR;
4525 #ifdef TARGET_X86_64
4529 rex_w = (b >> 3) & 1;
4530 rex_r = (b & 0x4) << 1;
4531 s->rex_x = (b & 0x2) << 2;
4532 REX_B(s) = (b & 0x1) << 3;
4533 x86_64_hregs = 1; /* select uniform byte register addressing */
4538 case 0xc5: /* 2-byte VEX */
4539 case 0xc4: /* 3-byte VEX */
4540 /* VEX prefixes cannot be used except in 32-bit mode.
4541 Otherwise the instruction is LES or LDS. */
4542 if (s->code32 && !s->vm86) {
4543 static const int pp_prefix[4] = {
4544 0, PREFIX_DATA, PREFIX_REPZ, PREFIX_REPNZ
4546 int vex3, vex2 = x86_ldub_code(env, s);
4548 if (!CODE64(s) && (vex2 & 0xc0) != 0xc0) {
4549 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4550 otherwise the instruction is LES or LDS. */
4555 /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
4556 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ
4557 | PREFIX_LOCK | PREFIX_DATA)) {
4560 #ifdef TARGET_X86_64
4565 rex_r = (~vex2 >> 4) & 8;
4568 b = x86_ldub_code(env, s);
4570 #ifdef TARGET_X86_64
4571 s->rex_x = (~vex2 >> 3) & 8;
4572 s->rex_b = (~vex2 >> 2) & 8;
4574 vex3 = x86_ldub_code(env, s);
4575 rex_w = (vex3 >> 7) & 1;
4576 switch (vex2 & 0x1f) {
4577 case 0x01: /* Implied 0f leading opcode bytes. */
4578 b = x86_ldub_code(env, s) | 0x100;
4580 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4583 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4586 default: /* Reserved for future use. */
4590 s->vex_v = (~vex3 >> 3) & 0xf;
4591 s->vex_l = (vex3 >> 2) & 1;
4592 prefixes |= pp_prefix[vex3 & 3] | PREFIX_VEX;
4597 /* Post-process prefixes. */
4599 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit
4600 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4601 over 0x66 if both are present. */
4602 dflag = (rex_w > 0 ? MO_64 : prefixes & PREFIX_DATA ? MO_16 : MO_32);
4603 /* In 64-bit mode, 0x67 selects 32-bit addressing. */
4604 aflag = (prefixes & PREFIX_ADR ? MO_32 : MO_64);
4606 /* In 16/32-bit mode, 0x66 selects the opposite data size. */
4607 if (s->code32 ^ ((prefixes & PREFIX_DATA) != 0)) {
4612 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */
4613 if (s->code32 ^ ((prefixes & PREFIX_ADR) != 0)) {
4620 s->prefix = prefixes;
4624 /* now check op code */
4628 /**************************/
4629 /* extended op code */
4630 b = x86_ldub_code(env, s) | 0x100;
4633 /**************************/
4648 ot = mo_b_d(b, dflag);
4651 case 0: /* OP Ev, Gv */
4652 modrm = x86_ldub_code(env, s);
4653 reg = ((modrm >> 3) & 7) | rex_r;
4654 mod = (modrm >> 6) & 3;
4655 rm = (modrm & 7) | REX_B(s);
4657 gen_lea_modrm(env, s, modrm);
4659 } else if (op == OP_XORL && rm == reg) {
4661 /* xor reg, reg optimisation */
4662 set_cc_op(s, CC_OP_CLR);
4663 tcg_gen_movi_tl(cpu_T0, 0);
4664 gen_op_mov_reg_v(ot, reg, cpu_T0);
4669 gen_op_mov_v_reg(ot, cpu_T1, reg);
4670 gen_op(s, op, ot, opreg);
4672 case 1: /* OP Gv, Ev */
4673 modrm = x86_ldub_code(env, s);
4674 mod = (modrm >> 6) & 3;
4675 reg = ((modrm >> 3) & 7) | rex_r;
4676 rm = (modrm & 7) | REX_B(s);
4678 gen_lea_modrm(env, s, modrm);
4679 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
4680 } else if (op == OP_XORL && rm == reg) {
4683 gen_op_mov_v_reg(ot, cpu_T1, rm);
4685 gen_op(s, op, ot, reg);
4687 case 2: /* OP A, Iv */
4688 val = insn_get(env, s, ot);
4689 tcg_gen_movi_tl(cpu_T1, val);
4690 gen_op(s, op, ot, OR_EAX);
4699 case 0x80: /* GRP1 */
4705 ot = mo_b_d(b, dflag);
4707 modrm = x86_ldub_code(env, s);
4708 mod = (modrm >> 6) & 3;
4709 rm = (modrm & 7) | REX_B(s);
4710 op = (modrm >> 3) & 7;
4716 s->rip_offset = insn_const_size(ot);
4717 gen_lea_modrm(env, s, modrm);
4728 val = insn_get(env, s, ot);
4731 val = (int8_t)insn_get(env, s, MO_8);
4734 tcg_gen_movi_tl(cpu_T1, val);
4735 gen_op(s, op, ot, opreg);
4739 /**************************/
4740 /* inc, dec, and other misc arith */
4741 case 0x40 ... 0x47: /* inc Gv */
4743 gen_inc(s, ot, OR_EAX + (b & 7), 1);
4745 case 0x48 ... 0x4f: /* dec Gv */
4747 gen_inc(s, ot, OR_EAX + (b & 7), -1);
4749 case 0xf6: /* GRP3 */
4751 ot = mo_b_d(b, dflag);
4753 modrm = x86_ldub_code(env, s);
4754 mod = (modrm >> 6) & 3;
4755 rm = (modrm & 7) | REX_B(s);
4756 op = (modrm >> 3) & 7;
4759 s->rip_offset = insn_const_size(ot);
4761 gen_lea_modrm(env, s, modrm);
4762 /* For those below that handle locked memory, don't load here. */
4763 if (!(s->prefix & PREFIX_LOCK)
4765 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
4768 gen_op_mov_v_reg(ot, cpu_T0, rm);
4773 val = insn_get(env, s, ot);
4774 tcg_gen_movi_tl(cpu_T1, val);
4775 gen_op_testl_T0_T1_cc();
4776 set_cc_op(s, CC_OP_LOGICB + ot);
4779 if (s->prefix & PREFIX_LOCK) {
4783 tcg_gen_movi_tl(cpu_T0, ~0);
4784 tcg_gen_atomic_xor_fetch_tl(cpu_T0, cpu_A0, cpu_T0,
4785 s->mem_index, ot | MO_LE);
4787 tcg_gen_not_tl(cpu_T0, cpu_T0);
4789 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
4791 gen_op_mov_reg_v(ot, rm, cpu_T0);
4796 if (s->prefix & PREFIX_LOCK) {
4798 TCGv a0, t0, t1, t2;
4803 a0 = tcg_temp_local_new();
4804 t0 = tcg_temp_local_new();
4805 label1 = gen_new_label();
4807 tcg_gen_mov_tl(a0, cpu_A0);
4808 tcg_gen_mov_tl(t0, cpu_T0);
4810 gen_set_label(label1);
4811 t1 = tcg_temp_new();
4812 t2 = tcg_temp_new();
4813 tcg_gen_mov_tl(t2, t0);
4814 tcg_gen_neg_tl(t1, t0);
4815 tcg_gen_atomic_cmpxchg_tl(t0, a0, t0, t1,
4816 s->mem_index, ot | MO_LE);
4818 tcg_gen_brcond_tl(TCG_COND_NE, t0, t2, label1);
4822 tcg_gen_mov_tl(cpu_T0, t0);
4825 tcg_gen_neg_tl(cpu_T0, cpu_T0);
4827 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
4829 gen_op_mov_reg_v(ot, rm, cpu_T0);
4832 gen_op_update_neg_cc();
4833 set_cc_op(s, CC_OP_SUBB + ot);
4838 gen_op_mov_v_reg(MO_8, cpu_T1, R_EAX);
4839 tcg_gen_ext8u_tl(cpu_T0, cpu_T0);
4840 tcg_gen_ext8u_tl(cpu_T1, cpu_T1);
4841 /* XXX: use 32 bit mul which could be faster */
4842 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
4843 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
4844 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4845 tcg_gen_andi_tl(cpu_cc_src, cpu_T0, 0xff00);
4846 set_cc_op(s, CC_OP_MULB);
4849 gen_op_mov_v_reg(MO_16, cpu_T1, R_EAX);
4850 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
4851 tcg_gen_ext16u_tl(cpu_T1, cpu_T1);
4852 /* XXX: use 32 bit mul which could be faster */
4853 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
4854 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
4855 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4856 tcg_gen_shri_tl(cpu_T0, cpu_T0, 16);
4857 gen_op_mov_reg_v(MO_16, R_EDX, cpu_T0);
4858 tcg_gen_mov_tl(cpu_cc_src, cpu_T0);
4859 set_cc_op(s, CC_OP_MULW);
4863 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
4864 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_regs[R_EAX]);
4865 tcg_gen_mulu2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
4866 cpu_tmp2_i32, cpu_tmp3_i32);
4867 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], cpu_tmp2_i32);
4868 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], cpu_tmp3_i32);
4869 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4870 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]);
4871 set_cc_op(s, CC_OP_MULL);
4873 #ifdef TARGET_X86_64
4875 tcg_gen_mulu2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX],
4876 cpu_T0, cpu_regs[R_EAX]);
4877 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4878 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]);
4879 set_cc_op(s, CC_OP_MULQ);
4887 gen_op_mov_v_reg(MO_8, cpu_T1, R_EAX);
4888 tcg_gen_ext8s_tl(cpu_T0, cpu_T0);
4889 tcg_gen_ext8s_tl(cpu_T1, cpu_T1);
4890 /* XXX: use 32 bit mul which could be faster */
4891 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
4892 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
4893 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4894 tcg_gen_ext8s_tl(cpu_tmp0, cpu_T0);
4895 tcg_gen_sub_tl(cpu_cc_src, cpu_T0, cpu_tmp0);
4896 set_cc_op(s, CC_OP_MULB);
4899 gen_op_mov_v_reg(MO_16, cpu_T1, R_EAX);
4900 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
4901 tcg_gen_ext16s_tl(cpu_T1, cpu_T1);
4902 /* XXX: use 32 bit mul which could be faster */
4903 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
4904 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
4905 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4906 tcg_gen_ext16s_tl(cpu_tmp0, cpu_T0);
4907 tcg_gen_sub_tl(cpu_cc_src, cpu_T0, cpu_tmp0);
4908 tcg_gen_shri_tl(cpu_T0, cpu_T0, 16);
4909 gen_op_mov_reg_v(MO_16, R_EDX, cpu_T0);
4910 set_cc_op(s, CC_OP_MULW);
4914 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
4915 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_regs[R_EAX]);
4916 tcg_gen_muls2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
4917 cpu_tmp2_i32, cpu_tmp3_i32);
4918 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], cpu_tmp2_i32);
4919 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], cpu_tmp3_i32);
4920 tcg_gen_sari_i32(cpu_tmp2_i32, cpu_tmp2_i32, 31);
4921 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4922 tcg_gen_sub_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
4923 tcg_gen_extu_i32_tl(cpu_cc_src, cpu_tmp2_i32);
4924 set_cc_op(s, CC_OP_MULL);
4926 #ifdef TARGET_X86_64
4928 tcg_gen_muls2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX],
4929 cpu_T0, cpu_regs[R_EAX]);
4930 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4931 tcg_gen_sari_tl(cpu_cc_src, cpu_regs[R_EAX], 63);
4932 tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, cpu_regs[R_EDX]);
4933 set_cc_op(s, CC_OP_MULQ);
4941 gen_helper_divb_AL(cpu_env, cpu_T0);
4944 gen_helper_divw_AX(cpu_env, cpu_T0);
4948 gen_helper_divl_EAX(cpu_env, cpu_T0);
4950 #ifdef TARGET_X86_64
4952 gen_helper_divq_EAX(cpu_env, cpu_T0);
4960 gen_helper_idivb_AL(cpu_env, cpu_T0);
4963 gen_helper_idivw_AX(cpu_env, cpu_T0);
4967 gen_helper_idivl_EAX(cpu_env, cpu_T0);
4969 #ifdef TARGET_X86_64
4971 gen_helper_idivq_EAX(cpu_env, cpu_T0);
4981 case 0xfe: /* GRP4 */
4982 case 0xff: /* GRP5 */
4983 ot = mo_b_d(b, dflag);
4985 modrm = x86_ldub_code(env, s);
4986 mod = (modrm >> 6) & 3;
4987 rm = (modrm & 7) | REX_B(s);
4988 op = (modrm >> 3) & 7;
4989 if (op >= 2 && b == 0xfe) {
4993 if (op == 2 || op == 4) {
4994 /* operand size for jumps is 64 bit */
4996 } else if (op == 3 || op == 5) {
4997 ot = dflag != MO_16 ? MO_32 + (rex_w == 1) : MO_16;
4998 } else if (op == 6) {
4999 /* default push size is 64 bit */
5000 ot = mo_pushpop(s, dflag);
5004 gen_lea_modrm(env, s, modrm);
5005 if (op >= 2 && op != 3 && op != 5)
5006 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
5008 gen_op_mov_v_reg(ot, cpu_T0, rm);
5012 case 0: /* inc Ev */
5017 gen_inc(s, ot, opreg, 1);
5019 case 1: /* dec Ev */
5024 gen_inc(s, ot, opreg, -1);
5026 case 2: /* call Ev */
5027 /* XXX: optimize if memory (no 'and' is necessary) */
5028 if (dflag == MO_16) {
5029 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
5031 next_eip = s->pc - s->cs_base;
5032 tcg_gen_movi_tl(cpu_T1, next_eip);
5033 gen_push_v(s, cpu_T1);
5034 gen_op_jmp_v(cpu_T0);
5038 case 3: /* lcall Ev */
5039 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
5040 gen_add_A0_im(s, 1 << ot);
5041 gen_op_ld_v(s, MO_16, cpu_T0, cpu_A0);
5043 if (s->pe && !s->vm86) {
5044 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
5045 gen_helper_lcall_protected(cpu_env, cpu_tmp2_i32, cpu_T1,
5046 tcg_const_i32(dflag - 1),
5047 tcg_const_tl(s->pc - s->cs_base));
5049 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
5050 gen_helper_lcall_real(cpu_env, cpu_tmp2_i32, cpu_T1,
5051 tcg_const_i32(dflag - 1),
5052 tcg_const_i32(s->pc - s->cs_base));
5054 tcg_gen_ld_tl(cpu_tmp4, cpu_env, offsetof(CPUX86State, eip));
5055 gen_jr(s, cpu_tmp4);
5057 case 4: /* jmp Ev */
5058 if (dflag == MO_16) {
5059 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
5061 gen_op_jmp_v(cpu_T0);
5065 case 5: /* ljmp Ev */
5066 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
5067 gen_add_A0_im(s, 1 << ot);
5068 gen_op_ld_v(s, MO_16, cpu_T0, cpu_A0);
5070 if (s->pe && !s->vm86) {
5071 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
5072 gen_helper_ljmp_protected(cpu_env, cpu_tmp2_i32, cpu_T1,
5073 tcg_const_tl(s->pc - s->cs_base));
5075 gen_op_movl_seg_T0_vm(R_CS);
5076 gen_op_jmp_v(cpu_T1);
5078 tcg_gen_ld_tl(cpu_tmp4, cpu_env, offsetof(CPUX86State, eip));
5079 gen_jr(s, cpu_tmp4);
5081 case 6: /* push Ev */
5082 gen_push_v(s, cpu_T0);
5089 case 0x84: /* test Ev, Gv */
5091 ot = mo_b_d(b, dflag);
5093 modrm = x86_ldub_code(env, s);
5094 reg = ((modrm >> 3) & 7) | rex_r;
5096 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5097 gen_op_mov_v_reg(ot, cpu_T1, reg);
5098 gen_op_testl_T0_T1_cc();
5099 set_cc_op(s, CC_OP_LOGICB + ot);
5102 case 0xa8: /* test eAX, Iv */
5104 ot = mo_b_d(b, dflag);
5105 val = insn_get(env, s, ot);
5107 gen_op_mov_v_reg(ot, cpu_T0, OR_EAX);
5108 tcg_gen_movi_tl(cpu_T1, val);
5109 gen_op_testl_T0_T1_cc();
5110 set_cc_op(s, CC_OP_LOGICB + ot);
5113 case 0x98: /* CWDE/CBW */
5115 #ifdef TARGET_X86_64
5117 gen_op_mov_v_reg(MO_32, cpu_T0, R_EAX);
5118 tcg_gen_ext32s_tl(cpu_T0, cpu_T0);
5119 gen_op_mov_reg_v(MO_64, R_EAX, cpu_T0);
5123 gen_op_mov_v_reg(MO_16, cpu_T0, R_EAX);
5124 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
5125 gen_op_mov_reg_v(MO_32, R_EAX, cpu_T0);
5128 gen_op_mov_v_reg(MO_8, cpu_T0, R_EAX);
5129 tcg_gen_ext8s_tl(cpu_T0, cpu_T0);
5130 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
5136 case 0x99: /* CDQ/CWD */
5138 #ifdef TARGET_X86_64
5140 gen_op_mov_v_reg(MO_64, cpu_T0, R_EAX);
5141 tcg_gen_sari_tl(cpu_T0, cpu_T0, 63);
5142 gen_op_mov_reg_v(MO_64, R_EDX, cpu_T0);
5146 gen_op_mov_v_reg(MO_32, cpu_T0, R_EAX);
5147 tcg_gen_ext32s_tl(cpu_T0, cpu_T0);
5148 tcg_gen_sari_tl(cpu_T0, cpu_T0, 31);
5149 gen_op_mov_reg_v(MO_32, R_EDX, cpu_T0);
5152 gen_op_mov_v_reg(MO_16, cpu_T0, R_EAX);
5153 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
5154 tcg_gen_sari_tl(cpu_T0, cpu_T0, 15);
5155 gen_op_mov_reg_v(MO_16, R_EDX, cpu_T0);
5161 case 0x1af: /* imul Gv, Ev */
5162 case 0x69: /* imul Gv, Ev, I */
5165 modrm = x86_ldub_code(env, s);
5166 reg = ((modrm >> 3) & 7) | rex_r;
5168 s->rip_offset = insn_const_size(ot);
5171 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5173 val = insn_get(env, s, ot);
5174 tcg_gen_movi_tl(cpu_T1, val);
5175 } else if (b == 0x6b) {
5176 val = (int8_t)insn_get(env, s, MO_8);
5177 tcg_gen_movi_tl(cpu_T1, val);
5179 gen_op_mov_v_reg(ot, cpu_T1, reg);
5182 #ifdef TARGET_X86_64
5184 tcg_gen_muls2_i64(cpu_regs[reg], cpu_T1, cpu_T0, cpu_T1);
5185 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]);
5186 tcg_gen_sari_tl(cpu_cc_src, cpu_cc_dst, 63);
5187 tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, cpu_T1);
5191 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
5192 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T1);
5193 tcg_gen_muls2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
5194 cpu_tmp2_i32, cpu_tmp3_i32);
5195 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
5196 tcg_gen_sari_i32(cpu_tmp2_i32, cpu_tmp2_i32, 31);
5197 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]);
5198 tcg_gen_sub_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
5199 tcg_gen_extu_i32_tl(cpu_cc_src, cpu_tmp2_i32);
5202 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
5203 tcg_gen_ext16s_tl(cpu_T1, cpu_T1);
5204 /* XXX: use 32 bit mul which could be faster */
5205 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
5206 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
5207 tcg_gen_ext16s_tl(cpu_tmp0, cpu_T0);
5208 tcg_gen_sub_tl(cpu_cc_src, cpu_T0, cpu_tmp0);
5209 gen_op_mov_reg_v(ot, reg, cpu_T0);
5212 set_cc_op(s, CC_OP_MULB + ot);
5215 case 0x1c1: /* xadd Ev, Gv */
5216 ot = mo_b_d(b, dflag);
5217 modrm = x86_ldub_code(env, s);
5218 reg = ((modrm >> 3) & 7) | rex_r;
5219 mod = (modrm >> 6) & 3;
5220 gen_op_mov_v_reg(ot, cpu_T0, reg);
5222 rm = (modrm & 7) | REX_B(s);
5223 gen_op_mov_v_reg(ot, cpu_T1, rm);
5224 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
5225 gen_op_mov_reg_v(ot, reg, cpu_T1);
5226 gen_op_mov_reg_v(ot, rm, cpu_T0);
5228 gen_lea_modrm(env, s, modrm);
5229 if (s->prefix & PREFIX_LOCK) {
5230 tcg_gen_atomic_fetch_add_tl(cpu_T1, cpu_A0, cpu_T0,
5231 s->mem_index, ot | MO_LE);
5232 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
5234 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
5235 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
5236 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
5238 gen_op_mov_reg_v(ot, reg, cpu_T1);
5240 gen_op_update2_cc();
5241 set_cc_op(s, CC_OP_ADDB + ot);
5244 case 0x1b1: /* cmpxchg Ev, Gv */
5246 TCGv oldv, newv, cmpv;
5248 ot = mo_b_d(b, dflag);
5249 modrm = x86_ldub_code(env, s);
5250 reg = ((modrm >> 3) & 7) | rex_r;
5251 mod = (modrm >> 6) & 3;
5252 oldv = tcg_temp_new();
5253 newv = tcg_temp_new();
5254 cmpv = tcg_temp_new();
5255 gen_op_mov_v_reg(ot, newv, reg);
5256 tcg_gen_mov_tl(cmpv, cpu_regs[R_EAX]);
5258 if (s->prefix & PREFIX_LOCK) {
5262 gen_lea_modrm(env, s, modrm);
5263 tcg_gen_atomic_cmpxchg_tl(oldv, cpu_A0, cmpv, newv,
5264 s->mem_index, ot | MO_LE);
5265 gen_op_mov_reg_v(ot, R_EAX, oldv);
5268 rm = (modrm & 7) | REX_B(s);
5269 gen_op_mov_v_reg(ot, oldv, rm);
5271 gen_lea_modrm(env, s, modrm);
5272 gen_op_ld_v(s, ot, oldv, cpu_A0);
5273 rm = 0; /* avoid warning */
5277 /* store value = (old == cmp ? new : old); */
5278 tcg_gen_movcond_tl(TCG_COND_EQ, newv, oldv, cmpv, newv, oldv);
5280 gen_op_mov_reg_v(ot, R_EAX, oldv);
5281 gen_op_mov_reg_v(ot, rm, newv);
5283 /* Perform an unconditional store cycle like physical cpu;
5284 must be before changing accumulator to ensure
5285 idempotency if the store faults and the instruction
5287 gen_op_st_v(s, ot, newv, cpu_A0);
5288 gen_op_mov_reg_v(ot, R_EAX, oldv);
5291 tcg_gen_mov_tl(cpu_cc_src, oldv);
5292 tcg_gen_mov_tl(cpu_cc_srcT, cmpv);
5293 tcg_gen_sub_tl(cpu_cc_dst, cmpv, oldv);
5294 set_cc_op(s, CC_OP_SUBB + ot);
5295 tcg_temp_free(oldv);
5296 tcg_temp_free(newv);
5297 tcg_temp_free(cmpv);
5300 case 0x1c7: /* cmpxchg8b */
5301 modrm = x86_ldub_code(env, s);
5302 mod = (modrm >> 6) & 3;
5303 if ((mod == 3) || ((modrm & 0x38) != 0x8))
5305 #ifdef TARGET_X86_64
5306 if (dflag == MO_64) {
5307 if (!(s->cpuid_ext_features & CPUID_EXT_CX16))
5309 gen_lea_modrm(env, s, modrm);
5310 if ((s->prefix & PREFIX_LOCK) && parallel_cpus) {
5311 gen_helper_cmpxchg16b(cpu_env, cpu_A0);
5313 gen_helper_cmpxchg16b_unlocked(cpu_env, cpu_A0);
5318 if (!(s->cpuid_features & CPUID_CX8))
5320 gen_lea_modrm(env, s, modrm);
5321 if ((s->prefix & PREFIX_LOCK) && parallel_cpus) {
5322 gen_helper_cmpxchg8b(cpu_env, cpu_A0);
5324 gen_helper_cmpxchg8b_unlocked(cpu_env, cpu_A0);
5327 set_cc_op(s, CC_OP_EFLAGS);
5330 /**************************/
5332 case 0x50 ... 0x57: /* push */
5333 gen_op_mov_v_reg(MO_32, cpu_T0, (b & 7) | REX_B(s));
5334 gen_push_v(s, cpu_T0);
5336 case 0x58 ... 0x5f: /* pop */
5338 /* NOTE: order is important for pop %sp */
5339 gen_pop_update(s, ot);
5340 gen_op_mov_reg_v(ot, (b & 7) | REX_B(s), cpu_T0);
5342 case 0x60: /* pusha */
5347 case 0x61: /* popa */
5352 case 0x68: /* push Iv */
5354 ot = mo_pushpop(s, dflag);
5356 val = insn_get(env, s, ot);
5358 val = (int8_t)insn_get(env, s, MO_8);
5359 tcg_gen_movi_tl(cpu_T0, val);
5360 gen_push_v(s, cpu_T0);
5362 case 0x8f: /* pop Ev */
5363 modrm = x86_ldub_code(env, s);
5364 mod = (modrm >> 6) & 3;
5367 /* NOTE: order is important for pop %sp */
5368 gen_pop_update(s, ot);
5369 rm = (modrm & 7) | REX_B(s);
5370 gen_op_mov_reg_v(ot, rm, cpu_T0);
5372 /* NOTE: order is important too for MMU exceptions */
5373 s->popl_esp_hack = 1 << ot;
5374 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5375 s->popl_esp_hack = 0;
5376 gen_pop_update(s, ot);
5379 case 0xc8: /* enter */
5382 val = x86_lduw_code(env, s);
5383 level = x86_ldub_code(env, s);
5384 gen_enter(s, val, level);
5387 case 0xc9: /* leave */
5390 case 0x06: /* push es */
5391 case 0x0e: /* push cs */
5392 case 0x16: /* push ss */
5393 case 0x1e: /* push ds */
5396 gen_op_movl_T0_seg(b >> 3);
5397 gen_push_v(s, cpu_T0);
5399 case 0x1a0: /* push fs */
5400 case 0x1a8: /* push gs */
5401 gen_op_movl_T0_seg((b >> 3) & 7);
5402 gen_push_v(s, cpu_T0);
5404 case 0x07: /* pop es */
5405 case 0x17: /* pop ss */
5406 case 0x1f: /* pop ds */
5411 gen_movl_seg_T0(s, reg);
5412 gen_pop_update(s, ot);
5413 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5414 if (s->base.is_jmp) {
5415 gen_jmp_im(s->pc - s->cs_base);
5418 gen_eob_inhibit_irq(s, true);
5424 case 0x1a1: /* pop fs */
5425 case 0x1a9: /* pop gs */
5427 gen_movl_seg_T0(s, (b >> 3) & 7);
5428 gen_pop_update(s, ot);
5429 if (s->base.is_jmp) {
5430 gen_jmp_im(s->pc - s->cs_base);
5435 /**************************/
5438 case 0x89: /* mov Gv, Ev */
5439 ot = mo_b_d(b, dflag);
5440 modrm = x86_ldub_code(env, s);
5441 reg = ((modrm >> 3) & 7) | rex_r;
5443 /* generate a generic store */
5444 gen_ldst_modrm(env, s, modrm, ot, reg, 1);
5447 case 0xc7: /* mov Ev, Iv */
5448 ot = mo_b_d(b, dflag);
5449 modrm = x86_ldub_code(env, s);
5450 mod = (modrm >> 6) & 3;
5452 s->rip_offset = insn_const_size(ot);
5453 gen_lea_modrm(env, s, modrm);
5455 val = insn_get(env, s, ot);
5456 tcg_gen_movi_tl(cpu_T0, val);
5458 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
5460 gen_op_mov_reg_v(ot, (modrm & 7) | REX_B(s), cpu_T0);
5464 case 0x8b: /* mov Ev, Gv */
5465 ot = mo_b_d(b, dflag);
5466 modrm = x86_ldub_code(env, s);
5467 reg = ((modrm >> 3) & 7) | rex_r;
5469 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5470 gen_op_mov_reg_v(ot, reg, cpu_T0);
5472 case 0x8e: /* mov seg, Gv */
5473 modrm = x86_ldub_code(env, s);
5474 reg = (modrm >> 3) & 7;
5475 if (reg >= 6 || reg == R_CS)
5477 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
5478 gen_movl_seg_T0(s, reg);
5479 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5480 if (s->base.is_jmp) {
5481 gen_jmp_im(s->pc - s->cs_base);
5484 gen_eob_inhibit_irq(s, true);
5490 case 0x8c: /* mov Gv, seg */
5491 modrm = x86_ldub_code(env, s);
5492 reg = (modrm >> 3) & 7;
5493 mod = (modrm >> 6) & 3;
5496 gen_op_movl_T0_seg(reg);
5497 ot = mod == 3 ? dflag : MO_16;
5498 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5501 case 0x1b6: /* movzbS Gv, Eb */
5502 case 0x1b7: /* movzwS Gv, Eb */
5503 case 0x1be: /* movsbS Gv, Eb */
5504 case 0x1bf: /* movswS Gv, Eb */
5509 /* d_ot is the size of destination */
5511 /* ot is the size of source */
5512 ot = (b & 1) + MO_8;
5513 /* s_ot is the sign+size of source */
5514 s_ot = b & 8 ? MO_SIGN | ot : ot;
5516 modrm = x86_ldub_code(env, s);
5517 reg = ((modrm >> 3) & 7) | rex_r;
5518 mod = (modrm >> 6) & 3;
5519 rm = (modrm & 7) | REX_B(s);
5522 if (s_ot == MO_SB && byte_reg_is_xH(rm)) {
5523 tcg_gen_sextract_tl(cpu_T0, cpu_regs[rm - 4], 8, 8);
5525 gen_op_mov_v_reg(ot, cpu_T0, rm);
5528 tcg_gen_ext8u_tl(cpu_T0, cpu_T0);
5531 tcg_gen_ext8s_tl(cpu_T0, cpu_T0);
5534 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
5538 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
5542 gen_op_mov_reg_v(d_ot, reg, cpu_T0);
5544 gen_lea_modrm(env, s, modrm);
5545 gen_op_ld_v(s, s_ot, cpu_T0, cpu_A0);
5546 gen_op_mov_reg_v(d_ot, reg, cpu_T0);
5551 case 0x8d: /* lea */
5552 modrm = x86_ldub_code(env, s);
5553 mod = (modrm >> 6) & 3;
5556 reg = ((modrm >> 3) & 7) | rex_r;
5558 AddressParts a = gen_lea_modrm_0(env, s, modrm);
5559 TCGv ea = gen_lea_modrm_1(a);
5560 gen_lea_v_seg(s, s->aflag, ea, -1, -1);
5561 gen_op_mov_reg_v(dflag, reg, cpu_A0);
5565 case 0xa0: /* mov EAX, Ov */
5567 case 0xa2: /* mov Ov, EAX */
5570 target_ulong offset_addr;
5572 ot = mo_b_d(b, dflag);
5574 #ifdef TARGET_X86_64
5576 offset_addr = x86_ldq_code(env, s);
5580 offset_addr = insn_get(env, s, s->aflag);
5583 tcg_gen_movi_tl(cpu_A0, offset_addr);
5584 gen_add_A0_ds_seg(s);
5586 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
5587 gen_op_mov_reg_v(ot, R_EAX, cpu_T0);
5589 gen_op_mov_v_reg(ot, cpu_T0, R_EAX);
5590 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
5594 case 0xd7: /* xlat */
5595 tcg_gen_mov_tl(cpu_A0, cpu_regs[R_EBX]);
5596 tcg_gen_ext8u_tl(cpu_T0, cpu_regs[R_EAX]);
5597 tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T0);
5598 gen_extu(s->aflag, cpu_A0);
5599 gen_add_A0_ds_seg(s);
5600 gen_op_ld_v(s, MO_8, cpu_T0, cpu_A0);
5601 gen_op_mov_reg_v(MO_8, R_EAX, cpu_T0);
5603 case 0xb0 ... 0xb7: /* mov R, Ib */
5604 val = insn_get(env, s, MO_8);
5605 tcg_gen_movi_tl(cpu_T0, val);
5606 gen_op_mov_reg_v(MO_8, (b & 7) | REX_B(s), cpu_T0);
5608 case 0xb8 ... 0xbf: /* mov R, Iv */
5609 #ifdef TARGET_X86_64
5610 if (dflag == MO_64) {
5613 tmp = x86_ldq_code(env, s);
5614 reg = (b & 7) | REX_B(s);
5615 tcg_gen_movi_tl(cpu_T0, tmp);
5616 gen_op_mov_reg_v(MO_64, reg, cpu_T0);
5621 val = insn_get(env, s, ot);
5622 reg = (b & 7) | REX_B(s);
5623 tcg_gen_movi_tl(cpu_T0, val);
5624 gen_op_mov_reg_v(ot, reg, cpu_T0);
5628 case 0x91 ... 0x97: /* xchg R, EAX */
5631 reg = (b & 7) | REX_B(s);
5635 case 0x87: /* xchg Ev, Gv */
5636 ot = mo_b_d(b, dflag);
5637 modrm = x86_ldub_code(env, s);
5638 reg = ((modrm >> 3) & 7) | rex_r;
5639 mod = (modrm >> 6) & 3;
5641 rm = (modrm & 7) | REX_B(s);
5643 gen_op_mov_v_reg(ot, cpu_T0, reg);
5644 gen_op_mov_v_reg(ot, cpu_T1, rm);
5645 gen_op_mov_reg_v(ot, rm, cpu_T0);
5646 gen_op_mov_reg_v(ot, reg, cpu_T1);
5648 gen_lea_modrm(env, s, modrm);
5649 gen_op_mov_v_reg(ot, cpu_T0, reg);
5650 /* for xchg, lock is implicit */
5651 tcg_gen_atomic_xchg_tl(cpu_T1, cpu_A0, cpu_T0,
5652 s->mem_index, ot | MO_LE);
5653 gen_op_mov_reg_v(ot, reg, cpu_T1);
5656 case 0xc4: /* les Gv */
5657 /* In CODE64 this is VEX3; see above. */
5660 case 0xc5: /* lds Gv */
5661 /* In CODE64 this is VEX2; see above. */
5664 case 0x1b2: /* lss Gv */
5667 case 0x1b4: /* lfs Gv */
5670 case 0x1b5: /* lgs Gv */
5673 ot = dflag != MO_16 ? MO_32 : MO_16;
5674 modrm = x86_ldub_code(env, s);
5675 reg = ((modrm >> 3) & 7) | rex_r;
5676 mod = (modrm >> 6) & 3;
5679 gen_lea_modrm(env, s, modrm);
5680 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
5681 gen_add_A0_im(s, 1 << ot);
5682 /* load the segment first to handle exceptions properly */
5683 gen_op_ld_v(s, MO_16, cpu_T0, cpu_A0);
5684 gen_movl_seg_T0(s, op);
5685 /* then put the data */
5686 gen_op_mov_reg_v(ot, reg, cpu_T1);
5687 if (s->base.is_jmp) {
5688 gen_jmp_im(s->pc - s->cs_base);
5693 /************************/
5701 ot = mo_b_d(b, dflag);
5702 modrm = x86_ldub_code(env, s);
5703 mod = (modrm >> 6) & 3;
5704 op = (modrm >> 3) & 7;
5710 gen_lea_modrm(env, s, modrm);
5713 opreg = (modrm & 7) | REX_B(s);
5718 gen_shift(s, op, ot, opreg, OR_ECX);
5721 shift = x86_ldub_code(env, s);
5723 gen_shifti(s, op, ot, opreg, shift);
5738 case 0x1a4: /* shld imm */
5742 case 0x1a5: /* shld cl */
5746 case 0x1ac: /* shrd imm */
5750 case 0x1ad: /* shrd cl */
5755 modrm = x86_ldub_code(env, s);
5756 mod = (modrm >> 6) & 3;
5757 rm = (modrm & 7) | REX_B(s);
5758 reg = ((modrm >> 3) & 7) | rex_r;
5760 gen_lea_modrm(env, s, modrm);
5765 gen_op_mov_v_reg(ot, cpu_T1, reg);
5768 TCGv imm = tcg_const_tl(x86_ldub_code(env, s));
5769 gen_shiftd_rm_T1(s, ot, opreg, op, imm);
5772 gen_shiftd_rm_T1(s, ot, opreg, op, cpu_regs[R_ECX]);
5776 /************************/
5779 if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
5780 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5781 /* XXX: what to do if illegal op ? */
5782 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
5785 modrm = x86_ldub_code(env, s);
5786 mod = (modrm >> 6) & 3;
5788 op = ((b & 7) << 3) | ((modrm >> 3) & 7);
5791 gen_lea_modrm(env, s, modrm);
5793 case 0x00 ... 0x07: /* fxxxs */
5794 case 0x10 ... 0x17: /* fixxxl */
5795 case 0x20 ... 0x27: /* fxxxl */
5796 case 0x30 ... 0x37: /* fixxx */
5803 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5804 s->mem_index, MO_LEUL);
5805 gen_helper_flds_FT0(cpu_env, cpu_tmp2_i32);
5808 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5809 s->mem_index, MO_LEUL);
5810 gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32);
5813 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0,
5814 s->mem_index, MO_LEQ);
5815 gen_helper_fldl_FT0(cpu_env, cpu_tmp1_i64);
5819 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5820 s->mem_index, MO_LESW);
5821 gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32);
5825 gen_helper_fp_arith_ST0_FT0(op1);
5827 /* fcomp needs pop */
5828 gen_helper_fpop(cpu_env);
5832 case 0x08: /* flds */
5833 case 0x0a: /* fsts */
5834 case 0x0b: /* fstps */
5835 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5836 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5837 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5842 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5843 s->mem_index, MO_LEUL);
5844 gen_helper_flds_ST0(cpu_env, cpu_tmp2_i32);
5847 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5848 s->mem_index, MO_LEUL);
5849 gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32);
5852 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0,
5853 s->mem_index, MO_LEQ);
5854 gen_helper_fldl_ST0(cpu_env, cpu_tmp1_i64);
5858 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5859 s->mem_index, MO_LESW);
5860 gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32);
5865 /* XXX: the corresponding CPUID bit must be tested ! */
5868 gen_helper_fisttl_ST0(cpu_tmp2_i32, cpu_env);
5869 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5870 s->mem_index, MO_LEUL);
5873 gen_helper_fisttll_ST0(cpu_tmp1_i64, cpu_env);
5874 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0,
5875 s->mem_index, MO_LEQ);
5879 gen_helper_fistt_ST0(cpu_tmp2_i32, cpu_env);
5880 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5881 s->mem_index, MO_LEUW);
5884 gen_helper_fpop(cpu_env);
5889 gen_helper_fsts_ST0(cpu_tmp2_i32, cpu_env);
5890 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5891 s->mem_index, MO_LEUL);
5894 gen_helper_fistl_ST0(cpu_tmp2_i32, cpu_env);
5895 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5896 s->mem_index, MO_LEUL);
5899 gen_helper_fstl_ST0(cpu_tmp1_i64, cpu_env);
5900 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0,
5901 s->mem_index, MO_LEQ);
5905 gen_helper_fist_ST0(cpu_tmp2_i32, cpu_env);
5906 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5907 s->mem_index, MO_LEUW);
5911 gen_helper_fpop(cpu_env);
5915 case 0x0c: /* fldenv mem */
5916 gen_helper_fldenv(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5918 case 0x0d: /* fldcw mem */
5919 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5920 s->mem_index, MO_LEUW);
5921 gen_helper_fldcw(cpu_env, cpu_tmp2_i32);
5923 case 0x0e: /* fnstenv mem */
5924 gen_helper_fstenv(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5926 case 0x0f: /* fnstcw mem */
5927 gen_helper_fnstcw(cpu_tmp2_i32, cpu_env);
5928 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5929 s->mem_index, MO_LEUW);
5931 case 0x1d: /* fldt mem */
5932 gen_helper_fldt_ST0(cpu_env, cpu_A0);
5934 case 0x1f: /* fstpt mem */
5935 gen_helper_fstt_ST0(cpu_env, cpu_A0);
5936 gen_helper_fpop(cpu_env);
5938 case 0x2c: /* frstor mem */
5939 gen_helper_frstor(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5941 case 0x2e: /* fnsave mem */
5942 gen_helper_fsave(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5944 case 0x2f: /* fnstsw mem */
5945 gen_helper_fnstsw(cpu_tmp2_i32, cpu_env);
5946 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5947 s->mem_index, MO_LEUW);
5949 case 0x3c: /* fbld */
5950 gen_helper_fbld_ST0(cpu_env, cpu_A0);
5952 case 0x3e: /* fbstp */
5953 gen_helper_fbst_ST0(cpu_env, cpu_A0);
5954 gen_helper_fpop(cpu_env);
5956 case 0x3d: /* fildll */
5957 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
5958 gen_helper_fildll_ST0(cpu_env, cpu_tmp1_i64);
5960 case 0x3f: /* fistpll */
5961 gen_helper_fistll_ST0(cpu_tmp1_i64, cpu_env);
5962 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
5963 gen_helper_fpop(cpu_env);
5969 /* register float ops */
5973 case 0x08: /* fld sti */
5974 gen_helper_fpush(cpu_env);
5975 gen_helper_fmov_ST0_STN(cpu_env,
5976 tcg_const_i32((opreg + 1) & 7));
5978 case 0x09: /* fxchg sti */
5979 case 0x29: /* fxchg4 sti, undocumented op */
5980 case 0x39: /* fxchg7 sti, undocumented op */
5981 gen_helper_fxchg_ST0_STN(cpu_env, tcg_const_i32(opreg));
5983 case 0x0a: /* grp d9/2 */
5986 /* check exceptions (FreeBSD FPU probe) */
5987 gen_helper_fwait(cpu_env);
5993 case 0x0c: /* grp d9/4 */
5996 gen_helper_fchs_ST0(cpu_env);
5999 gen_helper_fabs_ST0(cpu_env);
6002 gen_helper_fldz_FT0(cpu_env);
6003 gen_helper_fcom_ST0_FT0(cpu_env);
6006 gen_helper_fxam_ST0(cpu_env);
6012 case 0x0d: /* grp d9/5 */
6016 gen_helper_fpush(cpu_env);
6017 gen_helper_fld1_ST0(cpu_env);
6020 gen_helper_fpush(cpu_env);
6021 gen_helper_fldl2t_ST0(cpu_env);
6024 gen_helper_fpush(cpu_env);
6025 gen_helper_fldl2e_ST0(cpu_env);
6028 gen_helper_fpush(cpu_env);
6029 gen_helper_fldpi_ST0(cpu_env);
6032 gen_helper_fpush(cpu_env);
6033 gen_helper_fldlg2_ST0(cpu_env);
6036 gen_helper_fpush(cpu_env);
6037 gen_helper_fldln2_ST0(cpu_env);
6040 gen_helper_fpush(cpu_env);
6041 gen_helper_fldz_ST0(cpu_env);
6048 case 0x0e: /* grp d9/6 */
6051 gen_helper_f2xm1(cpu_env);
6054 gen_helper_fyl2x(cpu_env);
6057 gen_helper_fptan(cpu_env);
6059 case 3: /* fpatan */
6060 gen_helper_fpatan(cpu_env);
6062 case 4: /* fxtract */
6063 gen_helper_fxtract(cpu_env);
6065 case 5: /* fprem1 */
6066 gen_helper_fprem1(cpu_env);
6068 case 6: /* fdecstp */
6069 gen_helper_fdecstp(cpu_env);
6072 case 7: /* fincstp */
6073 gen_helper_fincstp(cpu_env);
6077 case 0x0f: /* grp d9/7 */
6080 gen_helper_fprem(cpu_env);
6082 case 1: /* fyl2xp1 */
6083 gen_helper_fyl2xp1(cpu_env);
6086 gen_helper_fsqrt(cpu_env);
6088 case 3: /* fsincos */
6089 gen_helper_fsincos(cpu_env);
6091 case 5: /* fscale */
6092 gen_helper_fscale(cpu_env);
6094 case 4: /* frndint */
6095 gen_helper_frndint(cpu_env);
6098 gen_helper_fsin(cpu_env);
6102 gen_helper_fcos(cpu_env);
6106 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6107 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6108 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6114 gen_helper_fp_arith_STN_ST0(op1, opreg);
6116 gen_helper_fpop(cpu_env);
6118 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6119 gen_helper_fp_arith_ST0_FT0(op1);
6123 case 0x02: /* fcom */
6124 case 0x22: /* fcom2, undocumented op */
6125 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6126 gen_helper_fcom_ST0_FT0(cpu_env);
6128 case 0x03: /* fcomp */
6129 case 0x23: /* fcomp3, undocumented op */
6130 case 0x32: /* fcomp5, undocumented op */
6131 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6132 gen_helper_fcom_ST0_FT0(cpu_env);
6133 gen_helper_fpop(cpu_env);
6135 case 0x15: /* da/5 */
6137 case 1: /* fucompp */
6138 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
6139 gen_helper_fucom_ST0_FT0(cpu_env);
6140 gen_helper_fpop(cpu_env);
6141 gen_helper_fpop(cpu_env);
6149 case 0: /* feni (287 only, just do nop here) */
6151 case 1: /* fdisi (287 only, just do nop here) */
6154 gen_helper_fclex(cpu_env);
6156 case 3: /* fninit */
6157 gen_helper_fninit(cpu_env);
6159 case 4: /* fsetpm (287 only, just do nop here) */
6165 case 0x1d: /* fucomi */
6166 if (!(s->cpuid_features & CPUID_CMOV)) {
6169 gen_update_cc_op(s);
6170 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6171 gen_helper_fucomi_ST0_FT0(cpu_env);
6172 set_cc_op(s, CC_OP_EFLAGS);
6174 case 0x1e: /* fcomi */
6175 if (!(s->cpuid_features & CPUID_CMOV)) {
6178 gen_update_cc_op(s);
6179 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6180 gen_helper_fcomi_ST0_FT0(cpu_env);
6181 set_cc_op(s, CC_OP_EFLAGS);
6183 case 0x28: /* ffree sti */
6184 gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
6186 case 0x2a: /* fst sti */
6187 gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
6189 case 0x2b: /* fstp sti */
6190 case 0x0b: /* fstp1 sti, undocumented op */
6191 case 0x3a: /* fstp8 sti, undocumented op */
6192 case 0x3b: /* fstp9 sti, undocumented op */
6193 gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
6194 gen_helper_fpop(cpu_env);
6196 case 0x2c: /* fucom st(i) */
6197 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6198 gen_helper_fucom_ST0_FT0(cpu_env);
6200 case 0x2d: /* fucomp st(i) */
6201 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6202 gen_helper_fucom_ST0_FT0(cpu_env);
6203 gen_helper_fpop(cpu_env);
6205 case 0x33: /* de/3 */
6207 case 1: /* fcompp */
6208 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
6209 gen_helper_fcom_ST0_FT0(cpu_env);
6210 gen_helper_fpop(cpu_env);
6211 gen_helper_fpop(cpu_env);
6217 case 0x38: /* ffreep sti, undocumented op */
6218 gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
6219 gen_helper_fpop(cpu_env);
6221 case 0x3c: /* df/4 */
6224 gen_helper_fnstsw(cpu_tmp2_i32, cpu_env);
6225 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
6226 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
6232 case 0x3d: /* fucomip */
6233 if (!(s->cpuid_features & CPUID_CMOV)) {
6236 gen_update_cc_op(s);
6237 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6238 gen_helper_fucomi_ST0_FT0(cpu_env);
6239 gen_helper_fpop(cpu_env);
6240 set_cc_op(s, CC_OP_EFLAGS);
6242 case 0x3e: /* fcomip */
6243 if (!(s->cpuid_features & CPUID_CMOV)) {
6246 gen_update_cc_op(s);
6247 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6248 gen_helper_fcomi_ST0_FT0(cpu_env);
6249 gen_helper_fpop(cpu_env);
6250 set_cc_op(s, CC_OP_EFLAGS);
6252 case 0x10 ... 0x13: /* fcmovxx */
6257 static const uint8_t fcmov_cc[8] = {
6264 if (!(s->cpuid_features & CPUID_CMOV)) {
6267 op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1);
6268 l1 = gen_new_label();
6269 gen_jcc1_noeob(s, op1, l1);
6270 gen_helper_fmov_ST0_STN(cpu_env, tcg_const_i32(opreg));
6279 /************************/
6282 case 0xa4: /* movsS */
6284 ot = mo_b_d(b, dflag);
6285 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6286 gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6292 case 0xaa: /* stosS */
6294 ot = mo_b_d(b, dflag);
6295 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6296 gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6301 case 0xac: /* lodsS */
6303 ot = mo_b_d(b, dflag);
6304 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6305 gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6310 case 0xae: /* scasS */
6312 ot = mo_b_d(b, dflag);
6313 if (prefixes & PREFIX_REPNZ) {
6314 gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
6315 } else if (prefixes & PREFIX_REPZ) {
6316 gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
6322 case 0xa6: /* cmpsS */
6324 ot = mo_b_d(b, dflag);
6325 if (prefixes & PREFIX_REPNZ) {
6326 gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
6327 } else if (prefixes & PREFIX_REPZ) {
6328 gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
6333 case 0x6c: /* insS */
6335 ot = mo_b_d32(b, dflag);
6336 tcg_gen_ext16u_tl(cpu_T0, cpu_regs[R_EDX]);
6337 gen_check_io(s, ot, pc_start - s->cs_base,
6338 SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) | 4);
6339 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6340 gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6343 if (s->base.tb->cflags & CF_USE_ICOUNT) {
6344 gen_jmp(s, s->pc - s->cs_base);
6348 case 0x6e: /* outsS */
6350 ot = mo_b_d32(b, dflag);
6351 tcg_gen_ext16u_tl(cpu_T0, cpu_regs[R_EDX]);
6352 gen_check_io(s, ot, pc_start - s->cs_base,
6353 svm_is_rep(prefixes) | 4);
6354 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6355 gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6358 if (s->base.tb->cflags & CF_USE_ICOUNT) {
6359 gen_jmp(s, s->pc - s->cs_base);
6364 /************************/
6369 ot = mo_b_d32(b, dflag);
6370 val = x86_ldub_code(env, s);
6371 tcg_gen_movi_tl(cpu_T0, val);
6372 gen_check_io(s, ot, pc_start - s->cs_base,
6373 SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6374 if (s->base.tb->cflags & CF_USE_ICOUNT) {
6377 tcg_gen_movi_i32(cpu_tmp2_i32, val);
6378 gen_helper_in_func(ot, cpu_T1, cpu_tmp2_i32);
6379 gen_op_mov_reg_v(ot, R_EAX, cpu_T1);
6380 gen_bpt_io(s, cpu_tmp2_i32, ot);
6381 if (s->base.tb->cflags & CF_USE_ICOUNT) {
6383 gen_jmp(s, s->pc - s->cs_base);
6388 ot = mo_b_d32(b, dflag);
6389 val = x86_ldub_code(env, s);
6390 tcg_gen_movi_tl(cpu_T0, val);
6391 gen_check_io(s, ot, pc_start - s->cs_base,
6392 svm_is_rep(prefixes));
6393 gen_op_mov_v_reg(ot, cpu_T1, R_EAX);
6395 if (s->base.tb->cflags & CF_USE_ICOUNT) {
6398 tcg_gen_movi_i32(cpu_tmp2_i32, val);
6399 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T1);
6400 gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6401 gen_bpt_io(s, cpu_tmp2_i32, ot);
6402 if (s->base.tb->cflags & CF_USE_ICOUNT) {
6404 gen_jmp(s, s->pc - s->cs_base);
6409 ot = mo_b_d32(b, dflag);
6410 tcg_gen_ext16u_tl(cpu_T0, cpu_regs[R_EDX]);
6411 gen_check_io(s, ot, pc_start - s->cs_base,
6412 SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6413 if (s->base.tb->cflags & CF_USE_ICOUNT) {
6416 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
6417 gen_helper_in_func(ot, cpu_T1, cpu_tmp2_i32);
6418 gen_op_mov_reg_v(ot, R_EAX, cpu_T1);
6419 gen_bpt_io(s, cpu_tmp2_i32, ot);
6420 if (s->base.tb->cflags & CF_USE_ICOUNT) {
6422 gen_jmp(s, s->pc - s->cs_base);
6427 ot = mo_b_d32(b, dflag);
6428 tcg_gen_ext16u_tl(cpu_T0, cpu_regs[R_EDX]);
6429 gen_check_io(s, ot, pc_start - s->cs_base,
6430 svm_is_rep(prefixes));
6431 gen_op_mov_v_reg(ot, cpu_T1, R_EAX);
6433 if (s->base.tb->cflags & CF_USE_ICOUNT) {
6436 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
6437 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T1);
6438 gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6439 gen_bpt_io(s, cpu_tmp2_i32, ot);
6440 if (s->base.tb->cflags & CF_USE_ICOUNT) {
6442 gen_jmp(s, s->pc - s->cs_base);
6446 /************************/
6448 case 0xc2: /* ret im */
6449 val = x86_ldsw_code(env, s);
6451 gen_stack_update(s, val + (1 << ot));
6452 /* Note that gen_pop_T0 uses a zero-extending load. */
6453 gen_op_jmp_v(cpu_T0);
6457 case 0xc3: /* ret */
6459 gen_pop_update(s, ot);
6460 /* Note that gen_pop_T0 uses a zero-extending load. */
6461 gen_op_jmp_v(cpu_T0);
6465 case 0xca: /* lret im */
6466 val = x86_ldsw_code(env, s);
6468 if (s->pe && !s->vm86) {
6469 gen_update_cc_op(s);
6470 gen_jmp_im(pc_start - s->cs_base);
6471 gen_helper_lret_protected(cpu_env, tcg_const_i32(dflag - 1),
6472 tcg_const_i32(val));
6476 gen_op_ld_v(s, dflag, cpu_T0, cpu_A0);
6477 /* NOTE: keeping EIP updated is not a problem in case of
6479 gen_op_jmp_v(cpu_T0);
6481 gen_add_A0_im(s, 1 << dflag);
6482 gen_op_ld_v(s, dflag, cpu_T0, cpu_A0);
6483 gen_op_movl_seg_T0_vm(R_CS);
6484 /* add stack offset */
6485 gen_stack_update(s, val + (2 << dflag));
6489 case 0xcb: /* lret */
6492 case 0xcf: /* iret */
6493 gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET);
6496 gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
6497 set_cc_op(s, CC_OP_EFLAGS);
6498 } else if (s->vm86) {
6500 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6502 gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
6503 set_cc_op(s, CC_OP_EFLAGS);
6506 gen_helper_iret_protected(cpu_env, tcg_const_i32(dflag - 1),
6507 tcg_const_i32(s->pc - s->cs_base));
6508 set_cc_op(s, CC_OP_EFLAGS);
6512 case 0xe8: /* call im */
6514 if (dflag != MO_16) {
6515 tval = (int32_t)insn_get(env, s, MO_32);
6517 tval = (int16_t)insn_get(env, s, MO_16);
6519 next_eip = s->pc - s->cs_base;
6521 if (dflag == MO_16) {
6523 } else if (!CODE64(s)) {
6526 tcg_gen_movi_tl(cpu_T0, next_eip);
6527 gen_push_v(s, cpu_T0);
6532 case 0x9a: /* lcall im */
6534 unsigned int selector, offset;
6539 offset = insn_get(env, s, ot);
6540 selector = insn_get(env, s, MO_16);
6542 tcg_gen_movi_tl(cpu_T0, selector);
6543 tcg_gen_movi_tl(cpu_T1, offset);
6546 case 0xe9: /* jmp im */
6547 if (dflag != MO_16) {
6548 tval = (int32_t)insn_get(env, s, MO_32);
6550 tval = (int16_t)insn_get(env, s, MO_16);
6552 tval += s->pc - s->cs_base;
6553 if (dflag == MO_16) {
6555 } else if (!CODE64(s)) {
6561 case 0xea: /* ljmp im */
6563 unsigned int selector, offset;
6568 offset = insn_get(env, s, ot);
6569 selector = insn_get(env, s, MO_16);
6571 tcg_gen_movi_tl(cpu_T0, selector);
6572 tcg_gen_movi_tl(cpu_T1, offset);
6575 case 0xeb: /* jmp Jb */
6576 tval = (int8_t)insn_get(env, s, MO_8);
6577 tval += s->pc - s->cs_base;
6578 if (dflag == MO_16) {
6583 case 0x70 ... 0x7f: /* jcc Jb */
6584 tval = (int8_t)insn_get(env, s, MO_8);
6586 case 0x180 ... 0x18f: /* jcc Jv */
6587 if (dflag != MO_16) {
6588 tval = (int32_t)insn_get(env, s, MO_32);
6590 tval = (int16_t)insn_get(env, s, MO_16);
6593 next_eip = s->pc - s->cs_base;
6595 if (dflag == MO_16) {
6599 gen_jcc(s, b, tval, next_eip);
6602 case 0x190 ... 0x19f: /* setcc Gv */
6603 modrm = x86_ldub_code(env, s);
6604 gen_setcc1(s, b, cpu_T0);
6605 gen_ldst_modrm(env, s, modrm, MO_8, OR_TMP0, 1);
6607 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6608 if (!(s->cpuid_features & CPUID_CMOV)) {
6612 modrm = x86_ldub_code(env, s);
6613 reg = ((modrm >> 3) & 7) | rex_r;
6614 gen_cmovcc1(env, s, ot, b, modrm, reg);
6617 /************************/
6619 case 0x9c: /* pushf */
6620 gen_svm_check_intercept(s, pc_start, SVM_EXIT_PUSHF);
6621 if (s->vm86 && s->iopl != 3) {
6622 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6624 gen_update_cc_op(s);
6625 gen_helper_read_eflags(cpu_T0, cpu_env);
6626 gen_push_v(s, cpu_T0);
6629 case 0x9d: /* popf */
6630 gen_svm_check_intercept(s, pc_start, SVM_EXIT_POPF);
6631 if (s->vm86 && s->iopl != 3) {
6632 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6636 if (dflag != MO_16) {
6637 gen_helper_write_eflags(cpu_env, cpu_T0,
6638 tcg_const_i32((TF_MASK | AC_MASK |
6643 gen_helper_write_eflags(cpu_env, cpu_T0,
6644 tcg_const_i32((TF_MASK | AC_MASK |
6646 IF_MASK | IOPL_MASK)
6650 if (s->cpl <= s->iopl) {
6651 if (dflag != MO_16) {
6652 gen_helper_write_eflags(cpu_env, cpu_T0,
6653 tcg_const_i32((TF_MASK |
6659 gen_helper_write_eflags(cpu_env, cpu_T0,
6660 tcg_const_i32((TF_MASK |
6668 if (dflag != MO_16) {
6669 gen_helper_write_eflags(cpu_env, cpu_T0,
6670 tcg_const_i32((TF_MASK | AC_MASK |
6671 ID_MASK | NT_MASK)));
6673 gen_helper_write_eflags(cpu_env, cpu_T0,
6674 tcg_const_i32((TF_MASK | AC_MASK |
6680 gen_pop_update(s, ot);
6681 set_cc_op(s, CC_OP_EFLAGS);
6682 /* abort translation because TF/AC flag may change */
6683 gen_jmp_im(s->pc - s->cs_base);
6687 case 0x9e: /* sahf */
6688 if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6690 gen_op_mov_v_reg(MO_8, cpu_T0, R_AH);
6691 gen_compute_eflags(s);
6692 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O);
6693 tcg_gen_andi_tl(cpu_T0, cpu_T0, CC_S | CC_Z | CC_A | CC_P | CC_C);
6694 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_T0);
6696 case 0x9f: /* lahf */
6697 if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6699 gen_compute_eflags(s);
6700 /* Note: gen_compute_eflags() only gives the condition codes */
6701 tcg_gen_ori_tl(cpu_T0, cpu_cc_src, 0x02);
6702 gen_op_mov_reg_v(MO_8, R_AH, cpu_T0);
6704 case 0xf5: /* cmc */
6705 gen_compute_eflags(s);
6706 tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6708 case 0xf8: /* clc */
6709 gen_compute_eflags(s);
6710 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C);
6712 case 0xf9: /* stc */
6713 gen_compute_eflags(s);
6714 tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6716 case 0xfc: /* cld */
6717 tcg_gen_movi_i32(cpu_tmp2_i32, 1);
6718 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, df));
6720 case 0xfd: /* std */
6721 tcg_gen_movi_i32(cpu_tmp2_i32, -1);
6722 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, df));
6725 /************************/
6726 /* bit operations */
6727 case 0x1ba: /* bt/bts/btr/btc Gv, im */
6729 modrm = x86_ldub_code(env, s);
6730 op = (modrm >> 3) & 7;
6731 mod = (modrm >> 6) & 3;
6732 rm = (modrm & 7) | REX_B(s);
6735 gen_lea_modrm(env, s, modrm);
6736 if (!(s->prefix & PREFIX_LOCK)) {
6737 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
6740 gen_op_mov_v_reg(ot, cpu_T0, rm);
6743 val = x86_ldub_code(env, s);
6744 tcg_gen_movi_tl(cpu_T1, val);
6749 case 0x1a3: /* bt Gv, Ev */
6752 case 0x1ab: /* bts */
6755 case 0x1b3: /* btr */
6758 case 0x1bb: /* btc */
6762 modrm = x86_ldub_code(env, s);
6763 reg = ((modrm >> 3) & 7) | rex_r;
6764 mod = (modrm >> 6) & 3;
6765 rm = (modrm & 7) | REX_B(s);
6766 gen_op_mov_v_reg(MO_32, cpu_T1, reg);
6768 AddressParts a = gen_lea_modrm_0(env, s, modrm);
6769 /* specific case: we need to add a displacement */
6770 gen_exts(ot, cpu_T1);
6771 tcg_gen_sari_tl(cpu_tmp0, cpu_T1, 3 + ot);
6772 tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, ot);
6773 tcg_gen_add_tl(cpu_A0, gen_lea_modrm_1(a), cpu_tmp0);
6774 gen_lea_v_seg(s, s->aflag, cpu_A0, a.def_seg, s->override);
6775 if (!(s->prefix & PREFIX_LOCK)) {
6776 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
6779 gen_op_mov_v_reg(ot, cpu_T0, rm);
6782 tcg_gen_andi_tl(cpu_T1, cpu_T1, (1 << (3 + ot)) - 1);
6783 tcg_gen_movi_tl(cpu_tmp0, 1);
6784 tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T1);
6785 if (s->prefix & PREFIX_LOCK) {
6788 /* Needs no atomic ops; we surpressed the normal
6789 memory load for LOCK above so do it now. */
6790 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
6793 tcg_gen_atomic_fetch_or_tl(cpu_T0, cpu_A0, cpu_tmp0,
6794 s->mem_index, ot | MO_LE);
6797 tcg_gen_not_tl(cpu_tmp0, cpu_tmp0);
6798 tcg_gen_atomic_fetch_and_tl(cpu_T0, cpu_A0, cpu_tmp0,
6799 s->mem_index, ot | MO_LE);
6803 tcg_gen_atomic_fetch_xor_tl(cpu_T0, cpu_A0, cpu_tmp0,
6804 s->mem_index, ot | MO_LE);
6807 tcg_gen_shr_tl(cpu_tmp4, cpu_T0, cpu_T1);
6809 tcg_gen_shr_tl(cpu_tmp4, cpu_T0, cpu_T1);
6812 /* Data already loaded; nothing to do. */
6815 tcg_gen_or_tl(cpu_T0, cpu_T0, cpu_tmp0);
6818 tcg_gen_andc_tl(cpu_T0, cpu_T0, cpu_tmp0);
6822 tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_tmp0);
6827 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
6829 gen_op_mov_reg_v(ot, rm, cpu_T0);
6834 /* Delay all CC updates until after the store above. Note that
6835 C is the result of the test, Z is unchanged, and the others
6836 are all undefined. */
6838 case CC_OP_MULB ... CC_OP_MULQ:
6839 case CC_OP_ADDB ... CC_OP_ADDQ:
6840 case CC_OP_ADCB ... CC_OP_ADCQ:
6841 case CC_OP_SUBB ... CC_OP_SUBQ:
6842 case CC_OP_SBBB ... CC_OP_SBBQ:
6843 case CC_OP_LOGICB ... CC_OP_LOGICQ:
6844 case CC_OP_INCB ... CC_OP_INCQ:
6845 case CC_OP_DECB ... CC_OP_DECQ:
6846 case CC_OP_SHLB ... CC_OP_SHLQ:
6847 case CC_OP_SARB ... CC_OP_SARQ:
6848 case CC_OP_BMILGB ... CC_OP_BMILGQ:
6849 /* Z was going to be computed from the non-zero status of CC_DST.
6850 We can get that same Z value (and the new C value) by leaving
6851 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
6853 tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
6854 set_cc_op(s, ((s->cc_op - CC_OP_MULB) & 3) + CC_OP_SARB);
6857 /* Otherwise, generate EFLAGS and replace the C bit. */
6858 gen_compute_eflags(s);
6859 tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, cpu_tmp4,
6864 case 0x1bc: /* bsf / tzcnt */
6865 case 0x1bd: /* bsr / lzcnt */
6867 modrm = x86_ldub_code(env, s);
6868 reg = ((modrm >> 3) & 7) | rex_r;
6869 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
6870 gen_extu(ot, cpu_T0);
6872 /* Note that lzcnt and tzcnt are in different extensions. */
6873 if ((prefixes & PREFIX_REPZ)
6875 ? s->cpuid_ext3_features & CPUID_EXT3_ABM
6876 : s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)) {
6878 /* For lzcnt/tzcnt, C bit is defined related to the input. */
6879 tcg_gen_mov_tl(cpu_cc_src, cpu_T0);
6881 /* For lzcnt, reduce the target_ulong result by the
6882 number of zeros that we expect to find at the top. */
6883 tcg_gen_clzi_tl(cpu_T0, cpu_T0, TARGET_LONG_BITS);
6884 tcg_gen_subi_tl(cpu_T0, cpu_T0, TARGET_LONG_BITS - size);
6886 /* For tzcnt, a zero input must return the operand size. */
6887 tcg_gen_ctzi_tl(cpu_T0, cpu_T0, size);
6889 /* For lzcnt/tzcnt, Z bit is defined related to the result. */
6890 gen_op_update1_cc();
6891 set_cc_op(s, CC_OP_BMILGB + ot);
6893 /* For bsr/bsf, only the Z bit is defined and it is related
6894 to the input and not the result. */
6895 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
6896 set_cc_op(s, CC_OP_LOGICB + ot);
6898 /* ??? The manual says that the output is undefined when the
6899 input is zero, but real hardware leaves it unchanged, and
6900 real programs appear to depend on that. Accomplish this
6901 by passing the output as the value to return upon zero. */
6903 /* For bsr, return the bit index of the first 1 bit,
6904 not the count of leading zeros. */
6905 tcg_gen_xori_tl(cpu_T1, cpu_regs[reg], TARGET_LONG_BITS - 1);
6906 tcg_gen_clz_tl(cpu_T0, cpu_T0, cpu_T1);
6907 tcg_gen_xori_tl(cpu_T0, cpu_T0, TARGET_LONG_BITS - 1);
6909 tcg_gen_ctz_tl(cpu_T0, cpu_T0, cpu_regs[reg]);
6912 gen_op_mov_reg_v(ot, reg, cpu_T0);
6914 /************************/
6916 case 0x27: /* daa */
6919 gen_update_cc_op(s);
6920 gen_helper_daa(cpu_env);
6921 set_cc_op(s, CC_OP_EFLAGS);
6923 case 0x2f: /* das */
6926 gen_update_cc_op(s);
6927 gen_helper_das(cpu_env);
6928 set_cc_op(s, CC_OP_EFLAGS);
6930 case 0x37: /* aaa */
6933 gen_update_cc_op(s);
6934 gen_helper_aaa(cpu_env);
6935 set_cc_op(s, CC_OP_EFLAGS);
6937 case 0x3f: /* aas */
6940 gen_update_cc_op(s);
6941 gen_helper_aas(cpu_env);
6942 set_cc_op(s, CC_OP_EFLAGS);
6944 case 0xd4: /* aam */
6947 val = x86_ldub_code(env, s);
6949 gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base);
6951 gen_helper_aam(cpu_env, tcg_const_i32(val));
6952 set_cc_op(s, CC_OP_LOGICB);
6955 case 0xd5: /* aad */
6958 val = x86_ldub_code(env, s);
6959 gen_helper_aad(cpu_env, tcg_const_i32(val));
6960 set_cc_op(s, CC_OP_LOGICB);
6962 /************************/
6964 case 0x90: /* nop */
6965 /* XXX: correct lock test for all insn */
6966 if (prefixes & PREFIX_LOCK) {
6969 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
6971 goto do_xchg_reg_eax;
6973 if (prefixes & PREFIX_REPZ) {
6974 gen_update_cc_op(s);
6975 gen_jmp_im(pc_start - s->cs_base);
6976 gen_helper_pause(cpu_env, tcg_const_i32(s->pc - pc_start));
6977 s->base.is_jmp = DISAS_NORETURN;
6980 case 0x9b: /* fwait */
6981 if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
6982 (HF_MP_MASK | HF_TS_MASK)) {
6983 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
6985 gen_helper_fwait(cpu_env);
6988 case 0xcc: /* int3 */
6989 gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
6991 case 0xcd: /* int N */
6992 val = x86_ldub_code(env, s);
6993 if (s->vm86 && s->iopl != 3) {
6994 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6996 gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
6999 case 0xce: /* into */
7002 gen_update_cc_op(s);
7003 gen_jmp_im(pc_start - s->cs_base);
7004 gen_helper_into(cpu_env, tcg_const_i32(s->pc - pc_start));
7007 case 0xf1: /* icebp (undocumented, exits to external debugger) */
7008 gen_svm_check_intercept(s, pc_start, SVM_EXIT_ICEBP);
7010 gen_debug(s, pc_start - s->cs_base);
7013 tb_flush(CPU(x86_env_get_cpu(env)));
7014 qemu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM);
7018 case 0xfa: /* cli */
7020 if (s->cpl <= s->iopl) {
7021 gen_helper_cli(cpu_env);
7023 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7027 gen_helper_cli(cpu_env);
7029 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7033 case 0xfb: /* sti */
7034 if (s->vm86 ? s->iopl == 3 : s->cpl <= s->iopl) {
7035 gen_helper_sti(cpu_env);
7036 /* interruptions are enabled only the first insn after sti */
7037 gen_jmp_im(s->pc - s->cs_base);
7038 gen_eob_inhibit_irq(s, true);
7040 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7043 case 0x62: /* bound */
7047 modrm = x86_ldub_code(env, s);
7048 reg = (modrm >> 3) & 7;
7049 mod = (modrm >> 6) & 3;
7052 gen_op_mov_v_reg(ot, cpu_T0, reg);
7053 gen_lea_modrm(env, s, modrm);
7054 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
7056 gen_helper_boundw(cpu_env, cpu_A0, cpu_tmp2_i32);
7058 gen_helper_boundl(cpu_env, cpu_A0, cpu_tmp2_i32);
7061 case 0x1c8 ... 0x1cf: /* bswap reg */
7062 reg = (b & 7) | REX_B(s);
7063 #ifdef TARGET_X86_64
7064 if (dflag == MO_64) {
7065 gen_op_mov_v_reg(MO_64, cpu_T0, reg);
7066 tcg_gen_bswap64_i64(cpu_T0, cpu_T0);
7067 gen_op_mov_reg_v(MO_64, reg, cpu_T0);
7071 gen_op_mov_v_reg(MO_32, cpu_T0, reg);
7072 tcg_gen_ext32u_tl(cpu_T0, cpu_T0);
7073 tcg_gen_bswap32_tl(cpu_T0, cpu_T0);
7074 gen_op_mov_reg_v(MO_32, reg, cpu_T0);
7077 case 0xd6: /* salc */
7080 gen_compute_eflags_c(s, cpu_T0);
7081 tcg_gen_neg_tl(cpu_T0, cpu_T0);
7082 gen_op_mov_reg_v(MO_8, R_EAX, cpu_T0);
7084 case 0xe0: /* loopnz */
7085 case 0xe1: /* loopz */
7086 case 0xe2: /* loop */
7087 case 0xe3: /* jecxz */
7089 TCGLabel *l1, *l2, *l3;
7091 tval = (int8_t)insn_get(env, s, MO_8);
7092 next_eip = s->pc - s->cs_base;
7094 if (dflag == MO_16) {
7098 l1 = gen_new_label();
7099 l2 = gen_new_label();
7100 l3 = gen_new_label();
7103 case 0: /* loopnz */
7105 gen_op_add_reg_im(s->aflag, R_ECX, -1);
7106 gen_op_jz_ecx(s->aflag, l3);
7107 gen_jcc1(s, (JCC_Z << 1) | (b ^ 1), l1);
7110 gen_op_add_reg_im(s->aflag, R_ECX, -1);
7111 gen_op_jnz_ecx(s->aflag, l1);
7115 gen_op_jz_ecx(s->aflag, l1);
7120 gen_jmp_im(next_eip);
7129 case 0x130: /* wrmsr */
7130 case 0x132: /* rdmsr */
7132 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7134 gen_update_cc_op(s);
7135 gen_jmp_im(pc_start - s->cs_base);
7137 gen_helper_rdmsr(cpu_env);
7139 gen_helper_wrmsr(cpu_env);
7143 case 0x131: /* rdtsc */
7144 gen_update_cc_op(s);
7145 gen_jmp_im(pc_start - s->cs_base);
7146 if (s->base.tb->cflags & CF_USE_ICOUNT) {
7149 gen_helper_rdtsc(cpu_env);
7150 if (s->base.tb->cflags & CF_USE_ICOUNT) {
7152 gen_jmp(s, s->pc - s->cs_base);
7155 case 0x133: /* rdpmc */
7156 gen_update_cc_op(s);
7157 gen_jmp_im(pc_start - s->cs_base);
7158 gen_helper_rdpmc(cpu_env);
7160 case 0x134: /* sysenter */
7161 /* For Intel SYSENTER is valid on 64-bit */
7162 if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
7165 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7167 gen_helper_sysenter(cpu_env);
7171 case 0x135: /* sysexit */
7172 /* For Intel SYSEXIT is valid on 64-bit */
7173 if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
7176 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7178 gen_helper_sysexit(cpu_env, tcg_const_i32(dflag - 1));
7182 #ifdef TARGET_X86_64
7183 case 0x105: /* syscall */
7184 /* XXX: is it usable in real mode ? */
7185 gen_update_cc_op(s);
7186 gen_jmp_im(pc_start - s->cs_base);
7187 gen_helper_syscall(cpu_env, tcg_const_i32(s->pc - pc_start));
7188 /* TF handling for the syscall insn is different. The TF bit is checked
7189 after the syscall insn completes. This allows #DB to not be
7190 generated after one has entered CPL0 if TF is set in FMASK. */
7191 gen_eob_worker(s, false, true);
7193 case 0x107: /* sysret */
7195 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7197 gen_helper_sysret(cpu_env, tcg_const_i32(dflag - 1));
7198 /* condition codes are modified only in long mode */
7200 set_cc_op(s, CC_OP_EFLAGS);
7202 /* TF handling for the sysret insn is different. The TF bit is
7203 checked after the sysret insn completes. This allows #DB to be
7204 generated "as if" the syscall insn in userspace has just
7206 gen_eob_worker(s, false, true);
7210 case 0x1a2: /* cpuid */
7211 gen_update_cc_op(s);
7212 gen_jmp_im(pc_start - s->cs_base);
7213 gen_helper_cpuid(cpu_env);
7215 case 0xf4: /* hlt */
7217 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7219 gen_update_cc_op(s);
7220 gen_jmp_im(pc_start - s->cs_base);
7221 gen_helper_hlt(cpu_env, tcg_const_i32(s->pc - pc_start));
7222 s->base.is_jmp = DISAS_NORETURN;
7226 modrm = x86_ldub_code(env, s);
7227 mod = (modrm >> 6) & 3;
7228 op = (modrm >> 3) & 7;
7231 if (!s->pe || s->vm86)
7233 gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_READ);
7234 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
7235 offsetof(CPUX86State, ldt.selector));
7236 ot = mod == 3 ? dflag : MO_16;
7237 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7240 if (!s->pe || s->vm86)
7243 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7245 gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_WRITE);
7246 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7247 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
7248 gen_helper_lldt(cpu_env, cpu_tmp2_i32);
7252 if (!s->pe || s->vm86)
7254 gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_READ);
7255 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
7256 offsetof(CPUX86State, tr.selector));
7257 ot = mod == 3 ? dflag : MO_16;
7258 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7261 if (!s->pe || s->vm86)
7264 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7266 gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_WRITE);
7267 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7268 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
7269 gen_helper_ltr(cpu_env, cpu_tmp2_i32);
7274 if (!s->pe || s->vm86)
7276 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7277 gen_update_cc_op(s);
7279 gen_helper_verr(cpu_env, cpu_T0);
7281 gen_helper_verw(cpu_env, cpu_T0);
7283 set_cc_op(s, CC_OP_EFLAGS);
7291 modrm = x86_ldub_code(env, s);
7293 CASE_MODRM_MEM_OP(0): /* sgdt */
7294 gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_READ);
7295 gen_lea_modrm(env, s, modrm);
7296 tcg_gen_ld32u_tl(cpu_T0,
7297 cpu_env, offsetof(CPUX86State, gdt.limit));
7298 gen_op_st_v(s, MO_16, cpu_T0, cpu_A0);
7299 gen_add_A0_im(s, 2);
7300 tcg_gen_ld_tl(cpu_T0, cpu_env, offsetof(CPUX86State, gdt.base));
7301 if (dflag == MO_16) {
7302 tcg_gen_andi_tl(cpu_T0, cpu_T0, 0xffffff);
7304 gen_op_st_v(s, CODE64(s) + MO_32, cpu_T0, cpu_A0);
7307 case 0xc8: /* monitor */
7308 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || s->cpl != 0) {
7311 gen_update_cc_op(s);
7312 gen_jmp_im(pc_start - s->cs_base);
7313 tcg_gen_mov_tl(cpu_A0, cpu_regs[R_EAX]);
7314 gen_extu(s->aflag, cpu_A0);
7315 gen_add_A0_ds_seg(s);
7316 gen_helper_monitor(cpu_env, cpu_A0);
7319 case 0xc9: /* mwait */
7320 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || s->cpl != 0) {
7323 gen_update_cc_op(s);
7324 gen_jmp_im(pc_start - s->cs_base);
7325 gen_helper_mwait(cpu_env, tcg_const_i32(s->pc - pc_start));
7329 case 0xca: /* clac */
7330 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)
7334 gen_helper_clac(cpu_env);
7335 gen_jmp_im(s->pc - s->cs_base);
7339 case 0xcb: /* stac */
7340 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)
7344 gen_helper_stac(cpu_env);
7345 gen_jmp_im(s->pc - s->cs_base);
7349 CASE_MODRM_MEM_OP(1): /* sidt */
7350 gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_READ);
7351 gen_lea_modrm(env, s, modrm);
7352 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State, idt.limit));
7353 gen_op_st_v(s, MO_16, cpu_T0, cpu_A0);
7354 gen_add_A0_im(s, 2);
7355 tcg_gen_ld_tl(cpu_T0, cpu_env, offsetof(CPUX86State, idt.base));
7356 if (dflag == MO_16) {
7357 tcg_gen_andi_tl(cpu_T0, cpu_T0, 0xffffff);
7359 gen_op_st_v(s, CODE64(s) + MO_32, cpu_T0, cpu_A0);
7362 case 0xd0: /* xgetbv */
7363 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
7364 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA
7365 | PREFIX_REPZ | PREFIX_REPNZ))) {
7368 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_ECX]);
7369 gen_helper_xgetbv(cpu_tmp1_i64, cpu_env, cpu_tmp2_i32);
7370 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], cpu_tmp1_i64);
7373 case 0xd1: /* xsetbv */
7374 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
7375 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA
7376 | PREFIX_REPZ | PREFIX_REPNZ))) {
7380 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7383 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
7385 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_ECX]);
7386 gen_helper_xsetbv(cpu_env, cpu_tmp2_i32, cpu_tmp1_i64);
7387 /* End TB because translation flags may change. */
7388 gen_jmp_im(s->pc - s->cs_base);
7392 case 0xd8: /* VMRUN */
7393 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7397 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7400 gen_update_cc_op(s);
7401 gen_jmp_im(pc_start - s->cs_base);
7402 gen_helper_vmrun(cpu_env, tcg_const_i32(s->aflag - 1),
7403 tcg_const_i32(s->pc - pc_start));
7405 s->base.is_jmp = DISAS_NORETURN;
7408 case 0xd9: /* VMMCALL */
7409 if (!(s->flags & HF_SVME_MASK)) {
7412 gen_update_cc_op(s);
7413 gen_jmp_im(pc_start - s->cs_base);
7414 gen_helper_vmmcall(cpu_env);
7417 case 0xda: /* VMLOAD */
7418 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7422 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7425 gen_update_cc_op(s);
7426 gen_jmp_im(pc_start - s->cs_base);
7427 gen_helper_vmload(cpu_env, tcg_const_i32(s->aflag - 1));
7430 case 0xdb: /* VMSAVE */
7431 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7435 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7438 gen_update_cc_op(s);
7439 gen_jmp_im(pc_start - s->cs_base);
7440 gen_helper_vmsave(cpu_env, tcg_const_i32(s->aflag - 1));
7443 case 0xdc: /* STGI */
7444 if ((!(s->flags & HF_SVME_MASK)
7445 && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
7450 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7453 gen_update_cc_op(s);
7454 gen_jmp_im(pc_start - s->cs_base);
7455 gen_helper_stgi(cpu_env);
7458 case 0xdd: /* CLGI */
7459 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7463 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7466 gen_update_cc_op(s);
7467 gen_jmp_im(pc_start - s->cs_base);
7468 gen_helper_clgi(cpu_env);
7471 case 0xde: /* SKINIT */
7472 if ((!(s->flags & HF_SVME_MASK)
7473 && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
7477 gen_update_cc_op(s);
7478 gen_jmp_im(pc_start - s->cs_base);
7479 gen_helper_skinit(cpu_env);
7482 case 0xdf: /* INVLPGA */
7483 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7487 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7490 gen_update_cc_op(s);
7491 gen_jmp_im(pc_start - s->cs_base);
7492 gen_helper_invlpga(cpu_env, tcg_const_i32(s->aflag - 1));
7495 CASE_MODRM_MEM_OP(2): /* lgdt */
7497 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7500 gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_WRITE);
7501 gen_lea_modrm(env, s, modrm);
7502 gen_op_ld_v(s, MO_16, cpu_T1, cpu_A0);
7503 gen_add_A0_im(s, 2);
7504 gen_op_ld_v(s, CODE64(s) + MO_32, cpu_T0, cpu_A0);
7505 if (dflag == MO_16) {
7506 tcg_gen_andi_tl(cpu_T0, cpu_T0, 0xffffff);
7508 tcg_gen_st_tl(cpu_T0, cpu_env, offsetof(CPUX86State, gdt.base));
7509 tcg_gen_st32_tl(cpu_T1, cpu_env, offsetof(CPUX86State, gdt.limit));
7512 CASE_MODRM_MEM_OP(3): /* lidt */
7514 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7517 gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_WRITE);
7518 gen_lea_modrm(env, s, modrm);
7519 gen_op_ld_v(s, MO_16, cpu_T1, cpu_A0);
7520 gen_add_A0_im(s, 2);
7521 gen_op_ld_v(s, CODE64(s) + MO_32, cpu_T0, cpu_A0);
7522 if (dflag == MO_16) {
7523 tcg_gen_andi_tl(cpu_T0, cpu_T0, 0xffffff);
7525 tcg_gen_st_tl(cpu_T0, cpu_env, offsetof(CPUX86State, idt.base));
7526 tcg_gen_st32_tl(cpu_T1, cpu_env, offsetof(CPUX86State, idt.limit));
7529 CASE_MODRM_OP(4): /* smsw */
7530 gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0);
7531 tcg_gen_ld_tl(cpu_T0, cpu_env, offsetof(CPUX86State, cr[0]));
7533 mod = (modrm >> 6) & 3;
7534 ot = (mod != 3 ? MO_16 : s->dflag);
7538 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7540 case 0xee: /* rdpkru */
7541 if (prefixes & PREFIX_LOCK) {
7544 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_ECX]);
7545 gen_helper_rdpkru(cpu_tmp1_i64, cpu_env, cpu_tmp2_i32);
7546 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], cpu_tmp1_i64);
7548 case 0xef: /* wrpkru */
7549 if (prefixes & PREFIX_LOCK) {
7552 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
7554 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_ECX]);
7555 gen_helper_wrpkru(cpu_env, cpu_tmp2_i32, cpu_tmp1_i64);
7557 CASE_MODRM_OP(6): /* lmsw */
7559 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7562 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
7563 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7564 gen_helper_lmsw(cpu_env, cpu_T0);
7565 gen_jmp_im(s->pc - s->cs_base);
7569 CASE_MODRM_MEM_OP(7): /* invlpg */
7571 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7574 gen_update_cc_op(s);
7575 gen_jmp_im(pc_start - s->cs_base);
7576 gen_lea_modrm(env, s, modrm);
7577 gen_helper_invlpg(cpu_env, cpu_A0);
7578 gen_jmp_im(s->pc - s->cs_base);
7582 case 0xf8: /* swapgs */
7583 #ifdef TARGET_X86_64
7586 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7588 tcg_gen_mov_tl(cpu_T0, cpu_seg_base[R_GS]);
7589 tcg_gen_ld_tl(cpu_seg_base[R_GS], cpu_env,
7590 offsetof(CPUX86State, kernelgsbase));
7591 tcg_gen_st_tl(cpu_T0, cpu_env,
7592 offsetof(CPUX86State, kernelgsbase));
7599 case 0xf9: /* rdtscp */
7600 if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP)) {
7603 gen_update_cc_op(s);
7604 gen_jmp_im(pc_start - s->cs_base);
7605 if (s->base.tb->cflags & CF_USE_ICOUNT) {
7608 gen_helper_rdtscp(cpu_env);
7609 if (s->base.tb->cflags & CF_USE_ICOUNT) {
7611 gen_jmp(s, s->pc - s->cs_base);
7620 case 0x108: /* invd */
7621 case 0x109: /* wbinvd */
7623 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7625 gen_svm_check_intercept(s, pc_start, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD);
7629 case 0x63: /* arpl or movslS (x86_64) */
7630 #ifdef TARGET_X86_64
7633 /* d_ot is the size of destination */
7636 modrm = x86_ldub_code(env, s);
7637 reg = ((modrm >> 3) & 7) | rex_r;
7638 mod = (modrm >> 6) & 3;
7639 rm = (modrm & 7) | REX_B(s);
7642 gen_op_mov_v_reg(MO_32, cpu_T0, rm);
7644 if (d_ot == MO_64) {
7645 tcg_gen_ext32s_tl(cpu_T0, cpu_T0);
7647 gen_op_mov_reg_v(d_ot, reg, cpu_T0);
7649 gen_lea_modrm(env, s, modrm);
7650 gen_op_ld_v(s, MO_32 | MO_SIGN, cpu_T0, cpu_A0);
7651 gen_op_mov_reg_v(d_ot, reg, cpu_T0);
7657 TCGv t0, t1, t2, a0;
7659 if (!s->pe || s->vm86)
7661 t0 = tcg_temp_local_new();
7662 t1 = tcg_temp_local_new();
7663 t2 = tcg_temp_local_new();
7665 modrm = x86_ldub_code(env, s);
7666 reg = (modrm >> 3) & 7;
7667 mod = (modrm >> 6) & 3;
7670 gen_lea_modrm(env, s, modrm);
7671 gen_op_ld_v(s, ot, t0, cpu_A0);
7672 a0 = tcg_temp_local_new();
7673 tcg_gen_mov_tl(a0, cpu_A0);
7675 gen_op_mov_v_reg(ot, t0, rm);
7678 gen_op_mov_v_reg(ot, t1, reg);
7679 tcg_gen_andi_tl(cpu_tmp0, t0, 3);
7680 tcg_gen_andi_tl(t1, t1, 3);
7681 tcg_gen_movi_tl(t2, 0);
7682 label1 = gen_new_label();
7683 tcg_gen_brcond_tl(TCG_COND_GE, cpu_tmp0, t1, label1);
7684 tcg_gen_andi_tl(t0, t0, ~3);
7685 tcg_gen_or_tl(t0, t0, t1);
7686 tcg_gen_movi_tl(t2, CC_Z);
7687 gen_set_label(label1);
7689 gen_op_st_v(s, ot, t0, a0);
7692 gen_op_mov_reg_v(ot, rm, t0);
7694 gen_compute_eflags(s);
7695 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z);
7696 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t2);
7702 case 0x102: /* lar */
7703 case 0x103: /* lsl */
7707 if (!s->pe || s->vm86)
7709 ot = dflag != MO_16 ? MO_32 : MO_16;
7710 modrm = x86_ldub_code(env, s);
7711 reg = ((modrm >> 3) & 7) | rex_r;
7712 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7713 t0 = tcg_temp_local_new();
7714 gen_update_cc_op(s);
7716 gen_helper_lar(t0, cpu_env, cpu_T0);
7718 gen_helper_lsl(t0, cpu_env, cpu_T0);
7720 tcg_gen_andi_tl(cpu_tmp0, cpu_cc_src, CC_Z);
7721 label1 = gen_new_label();
7722 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
7723 gen_op_mov_reg_v(ot, reg, t0);
7724 gen_set_label(label1);
7725 set_cc_op(s, CC_OP_EFLAGS);
7730 modrm = x86_ldub_code(env, s);
7731 mod = (modrm >> 6) & 3;
7732 op = (modrm >> 3) & 7;
7734 case 0: /* prefetchnta */
7735 case 1: /* prefetchnt0 */
7736 case 2: /* prefetchnt0 */
7737 case 3: /* prefetchnt0 */
7740 gen_nop_modrm(env, s, modrm);
7741 /* nothing more to do */
7743 default: /* nop (multi byte) */
7744 gen_nop_modrm(env, s, modrm);
7749 modrm = x86_ldub_code(env, s);
7750 if (s->flags & HF_MPX_EN_MASK) {
7751 mod = (modrm >> 6) & 3;
7752 reg = ((modrm >> 3) & 7) | rex_r;
7753 if (prefixes & PREFIX_REPZ) {
7756 || (prefixes & PREFIX_LOCK)
7757 || s->aflag == MO_16) {
7760 gen_bndck(env, s, modrm, TCG_COND_LTU, cpu_bndl[reg]);
7761 } else if (prefixes & PREFIX_REPNZ) {
7764 || (prefixes & PREFIX_LOCK)
7765 || s->aflag == MO_16) {
7768 TCGv_i64 notu = tcg_temp_new_i64();
7769 tcg_gen_not_i64(notu, cpu_bndu[reg]);
7770 gen_bndck(env, s, modrm, TCG_COND_GTU, notu);
7771 tcg_temp_free_i64(notu);
7772 } else if (prefixes & PREFIX_DATA) {
7773 /* bndmov -- from reg/mem */
7774 if (reg >= 4 || s->aflag == MO_16) {
7778 int reg2 = (modrm & 7) | REX_B(s);
7779 if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) {
7782 if (s->flags & HF_MPX_IU_MASK) {
7783 tcg_gen_mov_i64(cpu_bndl[reg], cpu_bndl[reg2]);
7784 tcg_gen_mov_i64(cpu_bndu[reg], cpu_bndu[reg2]);
7787 gen_lea_modrm(env, s, modrm);
7789 tcg_gen_qemu_ld_i64(cpu_bndl[reg], cpu_A0,
7790 s->mem_index, MO_LEQ);
7791 tcg_gen_addi_tl(cpu_A0, cpu_A0, 8);
7792 tcg_gen_qemu_ld_i64(cpu_bndu[reg], cpu_A0,
7793 s->mem_index, MO_LEQ);
7795 tcg_gen_qemu_ld_i64(cpu_bndl[reg], cpu_A0,
7796 s->mem_index, MO_LEUL);
7797 tcg_gen_addi_tl(cpu_A0, cpu_A0, 4);
7798 tcg_gen_qemu_ld_i64(cpu_bndu[reg], cpu_A0,
7799 s->mem_index, MO_LEUL);
7801 /* bnd registers are now in-use */
7802 gen_set_hflag(s, HF_MPX_IU_MASK);
7804 } else if (mod != 3) {
7806 AddressParts a = gen_lea_modrm_0(env, s, modrm);
7808 || (prefixes & PREFIX_LOCK)
7809 || s->aflag == MO_16
7814 tcg_gen_addi_tl(cpu_A0, cpu_regs[a.base], a.disp);
7816 tcg_gen_movi_tl(cpu_A0, 0);
7818 gen_lea_v_seg(s, s->aflag, cpu_A0, a.def_seg, s->override);
7820 tcg_gen_mov_tl(cpu_T0, cpu_regs[a.index]);
7822 tcg_gen_movi_tl(cpu_T0, 0);
7825 gen_helper_bndldx64(cpu_bndl[reg], cpu_env, cpu_A0, cpu_T0);
7826 tcg_gen_ld_i64(cpu_bndu[reg], cpu_env,
7827 offsetof(CPUX86State, mmx_t0.MMX_Q(0)));
7829 gen_helper_bndldx32(cpu_bndu[reg], cpu_env, cpu_A0, cpu_T0);
7830 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndu[reg]);
7831 tcg_gen_shri_i64(cpu_bndu[reg], cpu_bndu[reg], 32);
7833 gen_set_hflag(s, HF_MPX_IU_MASK);
7836 gen_nop_modrm(env, s, modrm);
7839 modrm = x86_ldub_code(env, s);
7840 if (s->flags & HF_MPX_EN_MASK) {
7841 mod = (modrm >> 6) & 3;
7842 reg = ((modrm >> 3) & 7) | rex_r;
7843 if (mod != 3 && (prefixes & PREFIX_REPZ)) {
7846 || (prefixes & PREFIX_LOCK)
7847 || s->aflag == MO_16) {
7850 AddressParts a = gen_lea_modrm_0(env, s, modrm);
7852 tcg_gen_extu_tl_i64(cpu_bndl[reg], cpu_regs[a.base]);
7854 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndl[reg]);
7856 } else if (a.base == -1) {
7857 /* no base register has lower bound of 0 */
7858 tcg_gen_movi_i64(cpu_bndl[reg], 0);
7860 /* rip-relative generates #ud */
7863 tcg_gen_not_tl(cpu_A0, gen_lea_modrm_1(a));
7865 tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
7867 tcg_gen_extu_tl_i64(cpu_bndu[reg], cpu_A0);
7868 /* bnd registers are now in-use */
7869 gen_set_hflag(s, HF_MPX_IU_MASK);
7871 } else if (prefixes & PREFIX_REPNZ) {
7874 || (prefixes & PREFIX_LOCK)
7875 || s->aflag == MO_16) {
7878 gen_bndck(env, s, modrm, TCG_COND_GTU, cpu_bndu[reg]);
7879 } else if (prefixes & PREFIX_DATA) {
7880 /* bndmov -- to reg/mem */
7881 if (reg >= 4 || s->aflag == MO_16) {
7885 int reg2 = (modrm & 7) | REX_B(s);
7886 if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) {
7889 if (s->flags & HF_MPX_IU_MASK) {
7890 tcg_gen_mov_i64(cpu_bndl[reg2], cpu_bndl[reg]);
7891 tcg_gen_mov_i64(cpu_bndu[reg2], cpu_bndu[reg]);
7894 gen_lea_modrm(env, s, modrm);
7896 tcg_gen_qemu_st_i64(cpu_bndl[reg], cpu_A0,
7897 s->mem_index, MO_LEQ);
7898 tcg_gen_addi_tl(cpu_A0, cpu_A0, 8);
7899 tcg_gen_qemu_st_i64(cpu_bndu[reg], cpu_A0,
7900 s->mem_index, MO_LEQ);
7902 tcg_gen_qemu_st_i64(cpu_bndl[reg], cpu_A0,
7903 s->mem_index, MO_LEUL);
7904 tcg_gen_addi_tl(cpu_A0, cpu_A0, 4);
7905 tcg_gen_qemu_st_i64(cpu_bndu[reg], cpu_A0,
7906 s->mem_index, MO_LEUL);
7909 } else if (mod != 3) {
7911 AddressParts a = gen_lea_modrm_0(env, s, modrm);
7913 || (prefixes & PREFIX_LOCK)
7914 || s->aflag == MO_16
7919 tcg_gen_addi_tl(cpu_A0, cpu_regs[a.base], a.disp);
7921 tcg_gen_movi_tl(cpu_A0, 0);
7923 gen_lea_v_seg(s, s->aflag, cpu_A0, a.def_seg, s->override);
7925 tcg_gen_mov_tl(cpu_T0, cpu_regs[a.index]);
7927 tcg_gen_movi_tl(cpu_T0, 0);
7930 gen_helper_bndstx64(cpu_env, cpu_A0, cpu_T0,
7931 cpu_bndl[reg], cpu_bndu[reg]);
7933 gen_helper_bndstx32(cpu_env, cpu_A0, cpu_T0,
7934 cpu_bndl[reg], cpu_bndu[reg]);
7938 gen_nop_modrm(env, s, modrm);
7940 case 0x119: case 0x11c ... 0x11f: /* nop (multi byte) */
7941 modrm = x86_ldub_code(env, s);
7942 gen_nop_modrm(env, s, modrm);
7944 case 0x120: /* mov reg, crN */
7945 case 0x122: /* mov crN, reg */
7947 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7949 modrm = x86_ldub_code(env, s);
7950 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7951 * AMD documentation (24594.pdf) and testing of
7952 * intel 386 and 486 processors all show that the mod bits
7953 * are assumed to be 1's, regardless of actual values.
7955 rm = (modrm & 7) | REX_B(s);
7956 reg = ((modrm >> 3) & 7) | rex_r;
7961 if ((prefixes & PREFIX_LOCK) && (reg == 0) &&
7962 (s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) {
7971 gen_update_cc_op(s);
7972 gen_jmp_im(pc_start - s->cs_base);
7974 if (s->base.tb->cflags & CF_USE_ICOUNT) {
7977 gen_op_mov_v_reg(ot, cpu_T0, rm);
7978 gen_helper_write_crN(cpu_env, tcg_const_i32(reg),
7980 if (s->base.tb->cflags & CF_USE_ICOUNT) {
7983 gen_jmp_im(s->pc - s->cs_base);
7986 if (s->base.tb->cflags & CF_USE_ICOUNT) {
7989 gen_helper_read_crN(cpu_T0, cpu_env, tcg_const_i32(reg));
7990 gen_op_mov_reg_v(ot, rm, cpu_T0);
7991 if (s->base.tb->cflags & CF_USE_ICOUNT) {
8001 case 0x121: /* mov reg, drN */
8002 case 0x123: /* mov drN, reg */
8004 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
8006 modrm = x86_ldub_code(env, s);
8007 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
8008 * AMD documentation (24594.pdf) and testing of
8009 * intel 386 and 486 processors all show that the mod bits
8010 * are assumed to be 1's, regardless of actual values.
8012 rm = (modrm & 7) | REX_B(s);
8013 reg = ((modrm >> 3) & 7) | rex_r;
8022 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
8023 gen_op_mov_v_reg(ot, cpu_T0, rm);
8024 tcg_gen_movi_i32(cpu_tmp2_i32, reg);
8025 gen_helper_set_dr(cpu_env, cpu_tmp2_i32, cpu_T0);
8026 gen_jmp_im(s->pc - s->cs_base);
8029 gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_DR0 + reg);
8030 tcg_gen_movi_i32(cpu_tmp2_i32, reg);
8031 gen_helper_get_dr(cpu_T0, cpu_env, cpu_tmp2_i32);
8032 gen_op_mov_reg_v(ot, rm, cpu_T0);
8036 case 0x106: /* clts */
8038 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
8040 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
8041 gen_helper_clts(cpu_env);
8042 /* abort block because static cpu state changed */
8043 gen_jmp_im(s->pc - s->cs_base);
8047 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
8048 case 0x1c3: /* MOVNTI reg, mem */
8049 if (!(s->cpuid_features & CPUID_SSE2))
8051 ot = mo_64_32(dflag);
8052 modrm = x86_ldub_code(env, s);
8053 mod = (modrm >> 6) & 3;
8056 reg = ((modrm >> 3) & 7) | rex_r;
8057 /* generate a generic store */
8058 gen_ldst_modrm(env, s, modrm, ot, reg, 1);
8061 modrm = x86_ldub_code(env, s);
8063 CASE_MODRM_MEM_OP(0): /* fxsave */
8064 if (!(s->cpuid_features & CPUID_FXSR)
8065 || (prefixes & PREFIX_LOCK)) {
8068 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
8069 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
8072 gen_lea_modrm(env, s, modrm);
8073 gen_helper_fxsave(cpu_env, cpu_A0);
8076 CASE_MODRM_MEM_OP(1): /* fxrstor */
8077 if (!(s->cpuid_features & CPUID_FXSR)
8078 || (prefixes & PREFIX_LOCK)) {
8081 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
8082 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
8085 gen_lea_modrm(env, s, modrm);
8086 gen_helper_fxrstor(cpu_env, cpu_A0);
8089 CASE_MODRM_MEM_OP(2): /* ldmxcsr */
8090 if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) {
8093 if (s->flags & HF_TS_MASK) {
8094 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
8097 gen_lea_modrm(env, s, modrm);
8098 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0, s->mem_index, MO_LEUL);
8099 gen_helper_ldmxcsr(cpu_env, cpu_tmp2_i32);
8102 CASE_MODRM_MEM_OP(3): /* stmxcsr */
8103 if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) {
8106 if (s->flags & HF_TS_MASK) {
8107 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
8110 gen_lea_modrm(env, s, modrm);
8111 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State, mxcsr));
8112 gen_op_st_v(s, MO_32, cpu_T0, cpu_A0);
8115 CASE_MODRM_MEM_OP(4): /* xsave */
8116 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
8117 || (prefixes & (PREFIX_LOCK | PREFIX_DATA
8118 | PREFIX_REPZ | PREFIX_REPNZ))) {
8121 gen_lea_modrm(env, s, modrm);
8122 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
8124 gen_helper_xsave(cpu_env, cpu_A0, cpu_tmp1_i64);
8127 CASE_MODRM_MEM_OP(5): /* xrstor */
8128 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
8129 || (prefixes & (PREFIX_LOCK | PREFIX_DATA
8130 | PREFIX_REPZ | PREFIX_REPNZ))) {
8133 gen_lea_modrm(env, s, modrm);
8134 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
8136 gen_helper_xrstor(cpu_env, cpu_A0, cpu_tmp1_i64);
8137 /* XRSTOR is how MPX is enabled, which changes how
8138 we translate. Thus we need to end the TB. */
8139 gen_update_cc_op(s);
8140 gen_jmp_im(s->pc - s->cs_base);
8144 CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */
8145 if (prefixes & PREFIX_LOCK) {
8148 if (prefixes & PREFIX_DATA) {
8150 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLWB)) {
8153 gen_nop_modrm(env, s, modrm);
8156 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
8157 || (s->cpuid_xsave_features & CPUID_XSAVE_XSAVEOPT) == 0
8158 || (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))) {
8161 gen_lea_modrm(env, s, modrm);
8162 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
8164 gen_helper_xsaveopt(cpu_env, cpu_A0, cpu_tmp1_i64);
8168 CASE_MODRM_MEM_OP(7): /* clflush / clflushopt */
8169 if (prefixes & PREFIX_LOCK) {
8172 if (prefixes & PREFIX_DATA) {
8174 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLFLUSHOPT)) {
8179 if ((s->prefix & (PREFIX_REPZ | PREFIX_REPNZ))
8180 || !(s->cpuid_features & CPUID_CLFLUSH)) {
8184 gen_nop_modrm(env, s, modrm);
8187 case 0xc0 ... 0xc7: /* rdfsbase (f3 0f ae /0) */
8188 case 0xc8 ... 0xcf: /* rdgsbase (f3 0f ae /1) */
8189 case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */
8190 case 0xd8 ... 0xdf: /* wrgsbase (f3 0f ae /3) */
8192 && (prefixes & PREFIX_REPZ)
8193 && !(prefixes & PREFIX_LOCK)
8194 && (s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_FSGSBASE)) {
8195 TCGv base, treg, src, dst;
8197 /* Preserve hflags bits by testing CR4 at runtime. */
8198 tcg_gen_movi_i32(cpu_tmp2_i32, CR4_FSGSBASE_MASK);
8199 gen_helper_cr4_testbit(cpu_env, cpu_tmp2_i32);
8201 base = cpu_seg_base[modrm & 8 ? R_GS : R_FS];
8202 treg = cpu_regs[(modrm & 7) | REX_B(s)];
8206 dst = base, src = treg;
8209 dst = treg, src = base;
8212 if (s->dflag == MO_32) {
8213 tcg_gen_ext32u_tl(dst, src);
8215 tcg_gen_mov_tl(dst, src);
8221 case 0xf8: /* sfence / pcommit */
8222 if (prefixes & PREFIX_DATA) {
8224 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_PCOMMIT)
8225 || (prefixes & PREFIX_LOCK)) {
8231 case 0xf9 ... 0xff: /* sfence */
8232 if (!(s->cpuid_features & CPUID_SSE)
8233 || (prefixes & PREFIX_LOCK)) {
8236 tcg_gen_mb(TCG_MO_ST_ST | TCG_BAR_SC);
8238 case 0xe8 ... 0xef: /* lfence */
8239 if (!(s->cpuid_features & CPUID_SSE)
8240 || (prefixes & PREFIX_LOCK)) {
8243 tcg_gen_mb(TCG_MO_LD_LD | TCG_BAR_SC);
8245 case 0xf0 ... 0xf7: /* mfence */
8246 if (!(s->cpuid_features & CPUID_SSE2)
8247 || (prefixes & PREFIX_LOCK)) {
8250 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8258 case 0x10d: /* 3DNow! prefetch(w) */
8259 modrm = x86_ldub_code(env, s);
8260 mod = (modrm >> 6) & 3;
8263 gen_nop_modrm(env, s, modrm);
8265 case 0x1aa: /* rsm */
8266 gen_svm_check_intercept(s, pc_start, SVM_EXIT_RSM);
8267 if (!(s->flags & HF_SMM_MASK))
8269 gen_update_cc_op(s);
8270 gen_jmp_im(s->pc - s->cs_base);
8271 gen_helper_rsm(cpu_env);
8274 case 0x1b8: /* SSE4.2 popcnt */
8275 if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) !=
8278 if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT))
8281 modrm = x86_ldub_code(env, s);
8282 reg = ((modrm >> 3) & 7) | rex_r;
8284 if (s->prefix & PREFIX_DATA) {
8287 ot = mo_64_32(dflag);
8290 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
8291 gen_extu(ot, cpu_T0);
8292 tcg_gen_mov_tl(cpu_cc_src, cpu_T0);
8293 tcg_gen_ctpop_tl(cpu_T0, cpu_T0);
8294 gen_op_mov_reg_v(ot, reg, cpu_T0);
8296 set_cc_op(s, CC_OP_POPCNT);
8298 case 0x10e ... 0x10f:
8299 /* 3DNow! instructions, ignore prefixes */
8300 s->prefix &= ~(PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA);
8301 case 0x110 ... 0x117:
8302 case 0x128 ... 0x12f:
8303 case 0x138 ... 0x13a:
8304 case 0x150 ... 0x179:
8305 case 0x17c ... 0x17f:
8307 case 0x1c4 ... 0x1c6:
8308 case 0x1d0 ... 0x1fe:
8309 gen_sse(env, s, b, pc_start, rex_r);
8316 gen_illegal_opcode(s);
8319 gen_unknown_opcode(env, s);
8323 void tcg_x86_init(void)
8325 static const char reg_names[CPU_NB_REGS][4] = {
8326 #ifdef TARGET_X86_64
8354 static const char seg_base_names[6][8] = {
8362 static const char bnd_regl_names[4][8] = {
8363 "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb"
8365 static const char bnd_regu_names[4][8] = {
8366 "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub"
8369 static bool initialized;
8376 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
8377 tcg_ctx.tcg_env = cpu_env;
8378 cpu_cc_op = tcg_global_mem_new_i32(cpu_env,
8379 offsetof(CPUX86State, cc_op), "cc_op");
8380 cpu_cc_dst = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_dst),
8382 cpu_cc_src = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src),
8384 cpu_cc_src2 = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src2),
8387 for (i = 0; i < CPU_NB_REGS; ++i) {
8388 cpu_regs[i] = tcg_global_mem_new(cpu_env,
8389 offsetof(CPUX86State, regs[i]),
8393 for (i = 0; i < 6; ++i) {
8395 = tcg_global_mem_new(cpu_env,
8396 offsetof(CPUX86State, segs[i].base),
8400 for (i = 0; i < 4; ++i) {
8402 = tcg_global_mem_new_i64(cpu_env,
8403 offsetof(CPUX86State, bnd_regs[i].lb),
8406 = tcg_global_mem_new_i64(cpu_env,
8407 offsetof(CPUX86State, bnd_regs[i].ub),
8412 static int i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu,
8415 DisasContext *dc = container_of(dcbase, DisasContext, base);
8416 CPUX86State *env = cpu->env_ptr;
8417 uint32_t flags = dc->base.tb->flags;
8418 target_ulong cs_base = dc->base.tb->cs_base;
8420 dc->pe = (flags >> HF_PE_SHIFT) & 1;
8421 dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
8422 dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
8423 dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
8425 dc->vm86 = (flags >> VM_SHIFT) & 1;
8426 dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
8427 dc->iopl = (flags >> IOPL_SHIFT) & 3;
8428 dc->tf = (flags >> TF_SHIFT) & 1;
8429 dc->cc_op = CC_OP_DYNAMIC;
8430 dc->cc_op_dirty = false;
8431 dc->cs_base = cs_base;
8432 dc->popl_esp_hack = 0;
8433 /* select memory access functions */
8435 #ifdef CONFIG_SOFTMMU
8436 dc->mem_index = cpu_mmu_index(env, false);
8438 dc->cpuid_features = env->features[FEAT_1_EDX];
8439 dc->cpuid_ext_features = env->features[FEAT_1_ECX];
8440 dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX];
8441 dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX];
8442 dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX];
8443 dc->cpuid_xsave_features = env->features[FEAT_XSAVE];
8444 #ifdef TARGET_X86_64
8445 dc->lma = (flags >> HF_LMA_SHIFT) & 1;
8446 dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
8449 dc->jmp_opt = !(dc->tf || dc->base.singlestep_enabled ||
8450 (flags & HF_INHIBIT_IRQ_MASK));
8451 /* Do not optimize repz jumps at all in icount mode, because
8452 rep movsS instructions are execured with different paths
8453 in !repz_opt and repz_opt modes. The first one was used
8454 always except single step mode. And this setting
8455 disables jumps optimization and control paths become
8456 equivalent in run and single step modes.
8457 Now there will be no jump optimization for repz in
8458 record/replay modes and there will always be an
8459 additional step for ecx=0 when icount is enabled.
8461 dc->repz_opt = !dc->jmp_opt && !(dc->base.tb->cflags & CF_USE_ICOUNT);
8463 /* check addseg logic */
8464 if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
8465 printf("ERROR addseg\n");
8468 cpu_T0 = tcg_temp_new();
8469 cpu_T1 = tcg_temp_new();
8470 cpu_A0 = tcg_temp_new();
8472 cpu_tmp0 = tcg_temp_new();
8473 cpu_tmp1_i64 = tcg_temp_new_i64();
8474 cpu_tmp2_i32 = tcg_temp_new_i32();
8475 cpu_tmp3_i32 = tcg_temp_new_i32();
8476 cpu_tmp4 = tcg_temp_new();
8477 cpu_ptr0 = tcg_temp_new_ptr();
8478 cpu_ptr1 = tcg_temp_new_ptr();
8479 cpu_cc_srcT = tcg_temp_local_new();
8484 static void i386_tr_tb_start(DisasContextBase *db, CPUState *cpu)
8488 static void i386_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
8490 DisasContext *dc = container_of(dcbase, DisasContext, base);
8492 tcg_gen_insn_start(dc->base.pc_next, dc->cc_op);
8495 static bool i386_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
8496 const CPUBreakpoint *bp)
8498 DisasContext *dc = container_of(dcbase, DisasContext, base);
8499 /* If RF is set, suppress an internally generated breakpoint. */
8500 int flags = dc->base.tb->flags & HF_RF_MASK ? BP_GDB : BP_ANY;
8501 if (bp->flags & flags) {
8502 gen_debug(dc, dc->base.pc_next - dc->cs_base);
8503 dc->base.is_jmp = DISAS_NORETURN;
8504 /* The address covered by the breakpoint must be included in
8505 [tb->pc, tb->pc + tb->size) in order to for it to be
8506 properly cleared -- thus we increment the PC here so that
8507 the generic logic setting tb->size later does the right thing. */
8508 dc->base.pc_next += 1;
8515 static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
8517 DisasContext *dc = container_of(dcbase, DisasContext, base);
8518 target_ulong pc_next = disas_insn(dc, cpu);
8520 if (dc->tf || (dc->base.tb->flags & HF_INHIBIT_IRQ_MASK)) {
8521 /* if single step mode, we generate only one instruction and
8522 generate an exception */
8523 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
8524 the flag and abort the translation to give the irqs a
8526 dc->base.is_jmp = DISAS_TOO_MANY;
8527 } else if ((dc->base.tb->cflags & CF_USE_ICOUNT)
8528 && ((dc->base.pc_next & TARGET_PAGE_MASK)
8529 != ((dc->base.pc_next + TARGET_MAX_INSN_SIZE - 1)
8531 || (dc->base.pc_next & ~TARGET_PAGE_MASK) == 0)) {
8532 /* Do not cross the boundary of the pages in icount mode,
8533 it can cause an exception. Do it only when boundary is
8534 crossed by the first instruction in the block.
8535 If current instruction already crossed the bound - it's ok,
8536 because an exception hasn't stopped this code.
8538 dc->base.is_jmp = DISAS_TOO_MANY;
8539 } else if ((pc_next - dc->base.pc_first) >= (TARGET_PAGE_SIZE - 32)) {
8540 dc->base.is_jmp = DISAS_TOO_MANY;
8543 dc->base.pc_next = pc_next;
8546 static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
8548 DisasContext *dc = container_of(dcbase, DisasContext, base);
8550 if (dc->base.is_jmp == DISAS_TOO_MANY) {
8551 gen_jmp_im(dc->base.pc_next - dc->cs_base);
8556 static void i386_tr_disas_log(const DisasContextBase *dcbase,
8559 DisasContext *dc = container_of(dcbase, DisasContext, base);
8561 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
8562 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size, 0);
8565 static const TranslatorOps i386_tr_ops = {
8566 .init_disas_context = i386_tr_init_disas_context,
8567 .tb_start = i386_tr_tb_start,
8568 .insn_start = i386_tr_insn_start,
8569 .breakpoint_check = i386_tr_breakpoint_check,
8570 .translate_insn = i386_tr_translate_insn,
8571 .tb_stop = i386_tr_tb_stop,
8572 .disas_log = i386_tr_disas_log,
8575 /* generate intermediate code for basic block 'tb'. */
8576 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
8580 translator_loop(&i386_tr_ops, &dc.base, cpu, tb);
8583 void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb,
8586 int cc_op = data[1];
8587 env->eip = data[0] - tb->cs_base;
8588 if (cc_op != CC_OP_DYNAMIC) {