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;
141 static void gen_eob(DisasContext *s);
142 static void gen_jr(DisasContext *s, TCGv dest);
143 static void gen_jmp(DisasContext *s, target_ulong eip);
144 static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num);
145 static void gen_op(DisasContext *s1, int op, TCGMemOp ot, int d);
147 /* i386 arith/logic operations */
167 OP_SHL1, /* undocumented */
183 /* I386 int registers */
184 OR_EAX, /* MUST be even numbered */
193 OR_TMP0 = 16, /* temporary operand register */
195 OR_A0, /* temporary register used when doing address evaluation */
205 /* Bit set if the global variable is live after setting CC_OP to X. */
206 static const uint8_t cc_op_live[CC_OP_NB] = {
207 [CC_OP_DYNAMIC] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
208 [CC_OP_EFLAGS] = USES_CC_SRC,
209 [CC_OP_MULB ... CC_OP_MULQ] = USES_CC_DST | USES_CC_SRC,
210 [CC_OP_ADDB ... CC_OP_ADDQ] = USES_CC_DST | USES_CC_SRC,
211 [CC_OP_ADCB ... CC_OP_ADCQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
212 [CC_OP_SUBB ... CC_OP_SUBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRCT,
213 [CC_OP_SBBB ... CC_OP_SBBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
214 [CC_OP_LOGICB ... CC_OP_LOGICQ] = USES_CC_DST,
215 [CC_OP_INCB ... CC_OP_INCQ] = USES_CC_DST | USES_CC_SRC,
216 [CC_OP_DECB ... CC_OP_DECQ] = USES_CC_DST | USES_CC_SRC,
217 [CC_OP_SHLB ... CC_OP_SHLQ] = USES_CC_DST | USES_CC_SRC,
218 [CC_OP_SARB ... CC_OP_SARQ] = USES_CC_DST | USES_CC_SRC,
219 [CC_OP_BMILGB ... CC_OP_BMILGQ] = USES_CC_DST | USES_CC_SRC,
220 [CC_OP_ADCX] = USES_CC_DST | USES_CC_SRC,
221 [CC_OP_ADOX] = USES_CC_SRC | USES_CC_SRC2,
222 [CC_OP_ADCOX] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
224 [CC_OP_POPCNT] = USES_CC_SRC,
227 static void set_cc_op(DisasContext *s, CCOp op)
231 if (s->cc_op == op) {
235 /* Discard CC computation that will no longer be used. */
236 dead = cc_op_live[s->cc_op] & ~cc_op_live[op];
237 if (dead & USES_CC_DST) {
238 tcg_gen_discard_tl(cpu_cc_dst);
240 if (dead & USES_CC_SRC) {
241 tcg_gen_discard_tl(cpu_cc_src);
243 if (dead & USES_CC_SRC2) {
244 tcg_gen_discard_tl(cpu_cc_src2);
246 if (dead & USES_CC_SRCT) {
247 tcg_gen_discard_tl(cpu_cc_srcT);
250 if (op == CC_OP_DYNAMIC) {
251 /* The DYNAMIC setting is translator only, and should never be
252 stored. Thus we always consider it clean. */
253 s->cc_op_dirty = false;
255 /* Discard any computed CC_OP value (see shifts). */
256 if (s->cc_op == CC_OP_DYNAMIC) {
257 tcg_gen_discard_i32(cpu_cc_op);
259 s->cc_op_dirty = true;
264 static void gen_update_cc_op(DisasContext *s)
266 if (s->cc_op_dirty) {
267 tcg_gen_movi_i32(cpu_cc_op, s->cc_op);
268 s->cc_op_dirty = false;
274 #define NB_OP_SIZES 4
276 #else /* !TARGET_X86_64 */
278 #define NB_OP_SIZES 3
280 #endif /* !TARGET_X86_64 */
282 #if defined(HOST_WORDS_BIGENDIAN)
283 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
284 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
285 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
286 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
287 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
289 #define REG_B_OFFSET 0
290 #define REG_H_OFFSET 1
291 #define REG_W_OFFSET 0
292 #define REG_L_OFFSET 0
293 #define REG_LH_OFFSET 4
296 /* In instruction encodings for byte register accesses the
297 * register number usually indicates "low 8 bits of register N";
298 * however there are some special cases where N 4..7 indicates
299 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
300 * true for this special case, false otherwise.
302 static inline bool byte_reg_is_xH(int reg)
308 if (reg >= 8 || x86_64_hregs) {
315 /* Select the size of a push/pop operation. */
316 static inline TCGMemOp mo_pushpop(DisasContext *s, TCGMemOp ot)
319 return ot == MO_16 ? MO_16 : MO_64;
325 /* Select the size of the stack pointer. */
326 static inline TCGMemOp mo_stacksize(DisasContext *s)
328 return CODE64(s) ? MO_64 : s->ss32 ? MO_32 : MO_16;
331 /* Select only size 64 else 32. Used for SSE operand sizes. */
332 static inline TCGMemOp mo_64_32(TCGMemOp ot)
335 return ot == MO_64 ? MO_64 : MO_32;
341 /* Select size 8 if lsb of B is clear, else OT. Used for decoding
342 byte vs word opcodes. */
343 static inline TCGMemOp mo_b_d(int b, TCGMemOp ot)
345 return b & 1 ? ot : MO_8;
348 /* Select size 8 if lsb of B is clear, else OT capped at 32.
349 Used for decoding operand size of port opcodes. */
350 static inline TCGMemOp mo_b_d32(int b, TCGMemOp ot)
352 return b & 1 ? (ot == MO_16 ? MO_16 : MO_32) : MO_8;
355 static void gen_op_mov_reg_v(TCGMemOp ot, int reg, TCGv t0)
359 if (!byte_reg_is_xH(reg)) {
360 tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 8);
362 tcg_gen_deposit_tl(cpu_regs[reg - 4], cpu_regs[reg - 4], t0, 8, 8);
366 tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 16);
369 /* For x86_64, this sets the higher half of register to zero.
370 For i386, this is equivalent to a mov. */
371 tcg_gen_ext32u_tl(cpu_regs[reg], t0);
375 tcg_gen_mov_tl(cpu_regs[reg], t0);
383 static inline void gen_op_mov_v_reg(TCGMemOp ot, TCGv t0, int reg)
385 if (ot == MO_8 && byte_reg_is_xH(reg)) {
386 tcg_gen_extract_tl(t0, cpu_regs[reg - 4], 8, 8);
388 tcg_gen_mov_tl(t0, cpu_regs[reg]);
392 static void gen_add_A0_im(DisasContext *s, int val)
394 tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
396 tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
400 static inline void gen_op_jmp_v(TCGv dest)
402 tcg_gen_st_tl(dest, cpu_env, offsetof(CPUX86State, eip));
405 static inline void gen_op_add_reg_im(TCGMemOp size, int reg, int32_t val)
407 tcg_gen_addi_tl(cpu_tmp0, cpu_regs[reg], val);
408 gen_op_mov_reg_v(size, reg, cpu_tmp0);
411 static inline void gen_op_add_reg_T0(TCGMemOp size, int reg)
413 tcg_gen_add_tl(cpu_tmp0, cpu_regs[reg], cpu_T0);
414 gen_op_mov_reg_v(size, reg, cpu_tmp0);
417 static inline void gen_op_ld_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
419 tcg_gen_qemu_ld_tl(t0, a0, s->mem_index, idx | MO_LE);
422 static inline void gen_op_st_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
424 tcg_gen_qemu_st_tl(t0, a0, s->mem_index, idx | MO_LE);
427 static inline void gen_op_st_rm_T0_A0(DisasContext *s, int idx, int d)
430 gen_op_st_v(s, idx, cpu_T0, cpu_A0);
432 gen_op_mov_reg_v(idx, d, cpu_T0);
436 static inline void gen_jmp_im(target_ulong pc)
438 tcg_gen_movi_tl(cpu_tmp0, pc);
439 gen_op_jmp_v(cpu_tmp0);
442 /* Compute SEG:REG into A0. SEG is selected from the override segment
443 (OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to
444 indicate no override. */
445 static void gen_lea_v_seg(DisasContext *s, TCGMemOp aflag, TCGv a0,
446 int def_seg, int ovr_seg)
452 tcg_gen_mov_tl(cpu_A0, a0);
459 if (ovr_seg < 0 && s->addseg) {
463 tcg_gen_ext32u_tl(cpu_A0, a0);
469 tcg_gen_ext16u_tl(cpu_A0, a0);
484 TCGv seg = cpu_seg_base[ovr_seg];
486 if (aflag == MO_64) {
487 tcg_gen_add_tl(cpu_A0, a0, seg);
488 } else if (CODE64(s)) {
489 tcg_gen_ext32u_tl(cpu_A0, a0);
490 tcg_gen_add_tl(cpu_A0, cpu_A0, seg);
492 tcg_gen_add_tl(cpu_A0, a0, seg);
493 tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
498 static inline void gen_string_movl_A0_ESI(DisasContext *s)
500 gen_lea_v_seg(s, s->aflag, cpu_regs[R_ESI], R_DS, s->override);
503 static inline void gen_string_movl_A0_EDI(DisasContext *s)
505 gen_lea_v_seg(s, s->aflag, cpu_regs[R_EDI], R_ES, -1);
508 static inline void gen_op_movl_T0_Dshift(TCGMemOp ot)
510 tcg_gen_ld32s_tl(cpu_T0, cpu_env, offsetof(CPUX86State, df));
511 tcg_gen_shli_tl(cpu_T0, cpu_T0, ot);
514 static TCGv gen_ext_tl(TCGv dst, TCGv src, TCGMemOp size, bool sign)
519 tcg_gen_ext8s_tl(dst, src);
521 tcg_gen_ext8u_tl(dst, src);
526 tcg_gen_ext16s_tl(dst, src);
528 tcg_gen_ext16u_tl(dst, src);
534 tcg_gen_ext32s_tl(dst, src);
536 tcg_gen_ext32u_tl(dst, src);
545 static void gen_extu(TCGMemOp ot, TCGv reg)
547 gen_ext_tl(reg, reg, ot, false);
550 static void gen_exts(TCGMemOp ot, TCGv reg)
552 gen_ext_tl(reg, reg, ot, true);
555 static inline void gen_op_jnz_ecx(TCGMemOp size, TCGLabel *label1)
557 tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
558 gen_extu(size, cpu_tmp0);
559 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_tmp0, 0, label1);
562 static inline void gen_op_jz_ecx(TCGMemOp size, TCGLabel *label1)
564 tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
565 gen_extu(size, cpu_tmp0);
566 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
569 static void gen_helper_in_func(TCGMemOp ot, TCGv v, TCGv_i32 n)
573 gen_helper_inb(v, cpu_env, n);
576 gen_helper_inw(v, cpu_env, n);
579 gen_helper_inl(v, cpu_env, n);
586 static void gen_helper_out_func(TCGMemOp ot, TCGv_i32 v, TCGv_i32 n)
590 gen_helper_outb(cpu_env, v, n);
593 gen_helper_outw(cpu_env, v, n);
596 gen_helper_outl(cpu_env, v, n);
603 static void gen_check_io(DisasContext *s, TCGMemOp ot, target_ulong cur_eip,
606 target_ulong next_eip;
608 if (s->pe && (s->cpl > s->iopl || s->vm86)) {
609 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
612 gen_helper_check_iob(cpu_env, cpu_tmp2_i32);
615 gen_helper_check_iow(cpu_env, cpu_tmp2_i32);
618 gen_helper_check_iol(cpu_env, cpu_tmp2_i32);
624 if(s->flags & HF_SVMI_MASK) {
627 svm_flags |= (1 << (4 + ot));
628 next_eip = s->pc - s->cs_base;
629 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
630 gen_helper_svm_check_io(cpu_env, cpu_tmp2_i32,
631 tcg_const_i32(svm_flags),
632 tcg_const_i32(next_eip - cur_eip));
636 static inline void gen_movs(DisasContext *s, TCGMemOp ot)
638 gen_string_movl_A0_ESI(s);
639 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
640 gen_string_movl_A0_EDI(s);
641 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
642 gen_op_movl_T0_Dshift(ot);
643 gen_op_add_reg_T0(s->aflag, R_ESI);
644 gen_op_add_reg_T0(s->aflag, R_EDI);
647 static void gen_op_update1_cc(void)
649 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
652 static void gen_op_update2_cc(void)
654 tcg_gen_mov_tl(cpu_cc_src, cpu_T1);
655 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
658 static void gen_op_update3_cc(TCGv reg)
660 tcg_gen_mov_tl(cpu_cc_src2, reg);
661 tcg_gen_mov_tl(cpu_cc_src, cpu_T1);
662 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
665 static inline void gen_op_testl_T0_T1_cc(void)
667 tcg_gen_and_tl(cpu_cc_dst, cpu_T0, cpu_T1);
670 static void gen_op_update_neg_cc(void)
672 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
673 tcg_gen_neg_tl(cpu_cc_src, cpu_T0);
674 tcg_gen_movi_tl(cpu_cc_srcT, 0);
677 /* compute all eflags to cc_src */
678 static void gen_compute_eflags(DisasContext *s)
680 TCGv zero, dst, src1, src2;
683 if (s->cc_op == CC_OP_EFLAGS) {
686 if (s->cc_op == CC_OP_CLR) {
687 tcg_gen_movi_tl(cpu_cc_src, CC_Z | CC_P);
688 set_cc_op(s, CC_OP_EFLAGS);
697 /* Take care to not read values that are not live. */
698 live = cc_op_live[s->cc_op] & ~USES_CC_SRCT;
699 dead = live ^ (USES_CC_DST | USES_CC_SRC | USES_CC_SRC2);
701 zero = tcg_const_tl(0);
702 if (dead & USES_CC_DST) {
705 if (dead & USES_CC_SRC) {
708 if (dead & USES_CC_SRC2) {
714 gen_helper_cc_compute_all(cpu_cc_src, dst, src1, src2, cpu_cc_op);
715 set_cc_op(s, CC_OP_EFLAGS);
722 typedef struct CCPrepare {
732 /* compute eflags.C to reg */
733 static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg)
739 case CC_OP_SUBB ... CC_OP_SUBQ:
740 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
741 size = s->cc_op - CC_OP_SUBB;
742 t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
743 /* If no temporary was used, be careful not to alias t1 and t0. */
744 t0 = TCGV_EQUAL(t1, cpu_cc_src) ? cpu_tmp0 : reg;
745 tcg_gen_mov_tl(t0, cpu_cc_srcT);
749 case CC_OP_ADDB ... CC_OP_ADDQ:
750 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
751 size = s->cc_op - CC_OP_ADDB;
752 t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
753 t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
755 return (CCPrepare) { .cond = TCG_COND_LTU, .reg = t0,
756 .reg2 = t1, .mask = -1, .use_reg2 = true };
758 case CC_OP_LOGICB ... CC_OP_LOGICQ:
761 return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
763 case CC_OP_INCB ... CC_OP_INCQ:
764 case CC_OP_DECB ... CC_OP_DECQ:
765 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
766 .mask = -1, .no_setcond = true };
768 case CC_OP_SHLB ... CC_OP_SHLQ:
769 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
770 size = s->cc_op - CC_OP_SHLB;
771 shift = (8 << size) - 1;
772 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
773 .mask = (target_ulong)1 << shift };
775 case CC_OP_MULB ... CC_OP_MULQ:
776 return (CCPrepare) { .cond = TCG_COND_NE,
777 .reg = cpu_cc_src, .mask = -1 };
779 case CC_OP_BMILGB ... CC_OP_BMILGQ:
780 size = s->cc_op - CC_OP_BMILGB;
781 t0 = gen_ext_tl(reg, cpu_cc_src, size, false);
782 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 };
786 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_dst,
787 .mask = -1, .no_setcond = true };
790 case CC_OP_SARB ... CC_OP_SARQ:
792 return (CCPrepare) { .cond = TCG_COND_NE,
793 .reg = cpu_cc_src, .mask = CC_C };
796 /* The need to compute only C from CC_OP_DYNAMIC is important
797 in efficiently implementing e.g. INC at the start of a TB. */
799 gen_helper_cc_compute_c(reg, cpu_cc_dst, cpu_cc_src,
800 cpu_cc_src2, cpu_cc_op);
801 return (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
802 .mask = -1, .no_setcond = true };
806 /* compute eflags.P to reg */
807 static CCPrepare gen_prepare_eflags_p(DisasContext *s, TCGv reg)
809 gen_compute_eflags(s);
810 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
814 /* compute eflags.S to reg */
815 static CCPrepare gen_prepare_eflags_s(DisasContext *s, TCGv reg)
819 gen_compute_eflags(s);
825 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
829 return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
832 TCGMemOp size = (s->cc_op - CC_OP_ADDB) & 3;
833 TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, true);
834 return (CCPrepare) { .cond = TCG_COND_LT, .reg = t0, .mask = -1 };
839 /* compute eflags.O to reg */
840 static CCPrepare gen_prepare_eflags_o(DisasContext *s, TCGv reg)
845 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src2,
846 .mask = -1, .no_setcond = true };
849 return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
851 gen_compute_eflags(s);
852 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
857 /* compute eflags.Z to reg */
858 static CCPrepare gen_prepare_eflags_z(DisasContext *s, TCGv reg)
862 gen_compute_eflags(s);
868 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
871 return (CCPrepare) { .cond = TCG_COND_ALWAYS, .mask = -1 };
873 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = cpu_cc_src,
877 TCGMemOp size = (s->cc_op - CC_OP_ADDB) & 3;
878 TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
879 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 };
884 /* perform a conditional store into register 'reg' according to jump opcode
885 value 'b'. In the fast case, T0 is guaranted not to be used. */
886 static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg)
888 int inv, jcc_op, cond;
894 jcc_op = (b >> 1) & 7;
897 case CC_OP_SUBB ... CC_OP_SUBQ:
898 /* We optimize relational operators for the cmp/jcc case. */
899 size = s->cc_op - CC_OP_SUBB;
902 tcg_gen_mov_tl(cpu_tmp4, cpu_cc_srcT);
903 gen_extu(size, cpu_tmp4);
904 t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
905 cc = (CCPrepare) { .cond = TCG_COND_LEU, .reg = cpu_tmp4,
906 .reg2 = t0, .mask = -1, .use_reg2 = true };
915 tcg_gen_mov_tl(cpu_tmp4, cpu_cc_srcT);
916 gen_exts(size, cpu_tmp4);
917 t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, true);
918 cc = (CCPrepare) { .cond = cond, .reg = cpu_tmp4,
919 .reg2 = t0, .mask = -1, .use_reg2 = true };
929 /* This actually generates good code for JC, JZ and JS. */
932 cc = gen_prepare_eflags_o(s, reg);
935 cc = gen_prepare_eflags_c(s, reg);
938 cc = gen_prepare_eflags_z(s, reg);
941 gen_compute_eflags(s);
942 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
943 .mask = CC_Z | CC_C };
946 cc = gen_prepare_eflags_s(s, reg);
949 cc = gen_prepare_eflags_p(s, reg);
952 gen_compute_eflags(s);
953 if (TCGV_EQUAL(reg, cpu_cc_src)) {
956 tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */
957 tcg_gen_xor_tl(reg, reg, cpu_cc_src);
958 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
963 gen_compute_eflags(s);
964 if (TCGV_EQUAL(reg, cpu_cc_src)) {
967 tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */
968 tcg_gen_xor_tl(reg, reg, cpu_cc_src);
969 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
970 .mask = CC_S | CC_Z };
977 cc.cond = tcg_invert_cond(cc.cond);
982 static void gen_setcc1(DisasContext *s, int b, TCGv reg)
984 CCPrepare cc = gen_prepare_cc(s, b, reg);
987 if (cc.cond == TCG_COND_EQ) {
988 tcg_gen_xori_tl(reg, cc.reg, 1);
990 tcg_gen_mov_tl(reg, cc.reg);
995 if (cc.cond == TCG_COND_NE && !cc.use_reg2 && cc.imm == 0 &&
996 cc.mask != 0 && (cc.mask & (cc.mask - 1)) == 0) {
997 tcg_gen_shri_tl(reg, cc.reg, ctztl(cc.mask));
998 tcg_gen_andi_tl(reg, reg, 1);
1001 if (cc.mask != -1) {
1002 tcg_gen_andi_tl(reg, cc.reg, cc.mask);
1006 tcg_gen_setcond_tl(cc.cond, reg, cc.reg, cc.reg2);
1008 tcg_gen_setcondi_tl(cc.cond, reg, cc.reg, cc.imm);
1012 static inline void gen_compute_eflags_c(DisasContext *s, TCGv reg)
1014 gen_setcc1(s, JCC_B << 1, reg);
1017 /* generate a conditional jump to label 'l1' according to jump opcode
1018 value 'b'. In the fast case, T0 is guaranted not to be used. */
1019 static inline void gen_jcc1_noeob(DisasContext *s, int b, TCGLabel *l1)
1021 CCPrepare cc = gen_prepare_cc(s, b, cpu_T0);
1023 if (cc.mask != -1) {
1024 tcg_gen_andi_tl(cpu_T0, cc.reg, cc.mask);
1028 tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1030 tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1034 /* Generate a conditional jump to label 'l1' according to jump opcode
1035 value 'b'. In the fast case, T0 is guaranted not to be used.
1036 A translation block must end soon. */
1037 static inline void gen_jcc1(DisasContext *s, int b, TCGLabel *l1)
1039 CCPrepare cc = gen_prepare_cc(s, b, cpu_T0);
1041 gen_update_cc_op(s);
1042 if (cc.mask != -1) {
1043 tcg_gen_andi_tl(cpu_T0, cc.reg, cc.mask);
1046 set_cc_op(s, CC_OP_DYNAMIC);
1048 tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1050 tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1054 /* XXX: does not work with gdbstub "ice" single step - not a
1056 static TCGLabel *gen_jz_ecx_string(DisasContext *s, target_ulong next_eip)
1058 TCGLabel *l1 = gen_new_label();
1059 TCGLabel *l2 = gen_new_label();
1060 gen_op_jnz_ecx(s->aflag, l1);
1062 gen_jmp_tb(s, next_eip, 1);
1067 static inline void gen_stos(DisasContext *s, TCGMemOp ot)
1069 gen_op_mov_v_reg(MO_32, cpu_T0, R_EAX);
1070 gen_string_movl_A0_EDI(s);
1071 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
1072 gen_op_movl_T0_Dshift(ot);
1073 gen_op_add_reg_T0(s->aflag, R_EDI);
1076 static inline void gen_lods(DisasContext *s, TCGMemOp ot)
1078 gen_string_movl_A0_ESI(s);
1079 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1080 gen_op_mov_reg_v(ot, R_EAX, cpu_T0);
1081 gen_op_movl_T0_Dshift(ot);
1082 gen_op_add_reg_T0(s->aflag, R_ESI);
1085 static inline void gen_scas(DisasContext *s, TCGMemOp ot)
1087 gen_string_movl_A0_EDI(s);
1088 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
1089 gen_op(s, OP_CMPL, ot, R_EAX);
1090 gen_op_movl_T0_Dshift(ot);
1091 gen_op_add_reg_T0(s->aflag, R_EDI);
1094 static inline void gen_cmps(DisasContext *s, TCGMemOp ot)
1096 gen_string_movl_A0_EDI(s);
1097 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
1098 gen_string_movl_A0_ESI(s);
1099 gen_op(s, OP_CMPL, ot, OR_TMP0);
1100 gen_op_movl_T0_Dshift(ot);
1101 gen_op_add_reg_T0(s->aflag, R_ESI);
1102 gen_op_add_reg_T0(s->aflag, R_EDI);
1105 static void gen_bpt_io(DisasContext *s, TCGv_i32 t_port, int ot)
1107 if (s->flags & HF_IOBPT_MASK) {
1108 TCGv_i32 t_size = tcg_const_i32(1 << ot);
1109 TCGv t_next = tcg_const_tl(s->pc - s->cs_base);
1111 gen_helper_bpt_io(cpu_env, t_port, t_size, t_next);
1112 tcg_temp_free_i32(t_size);
1113 tcg_temp_free(t_next);
1118 static inline void gen_ins(DisasContext *s, TCGMemOp ot)
1120 if (s->base.tb->cflags & CF_USE_ICOUNT) {
1123 gen_string_movl_A0_EDI(s);
1124 /* Note: we must do this dummy write first to be restartable in
1125 case of page fault. */
1126 tcg_gen_movi_tl(cpu_T0, 0);
1127 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
1128 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_EDX]);
1129 tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1130 gen_helper_in_func(ot, cpu_T0, cpu_tmp2_i32);
1131 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
1132 gen_op_movl_T0_Dshift(ot);
1133 gen_op_add_reg_T0(s->aflag, R_EDI);
1134 gen_bpt_io(s, cpu_tmp2_i32, ot);
1135 if (s->base.tb->cflags & CF_USE_ICOUNT) {
1140 static inline void gen_outs(DisasContext *s, TCGMemOp ot)
1142 if (s->base.tb->cflags & CF_USE_ICOUNT) {
1145 gen_string_movl_A0_ESI(s);
1146 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1148 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_EDX]);
1149 tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1150 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T0);
1151 gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
1152 gen_op_movl_T0_Dshift(ot);
1153 gen_op_add_reg_T0(s->aflag, R_ESI);
1154 gen_bpt_io(s, cpu_tmp2_i32, ot);
1155 if (s->base.tb->cflags & CF_USE_ICOUNT) {
1160 /* same method as Valgrind : we generate jumps to current or next
1162 #define GEN_REPZ(op) \
1163 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1164 target_ulong cur_eip, target_ulong next_eip) \
1167 gen_update_cc_op(s); \
1168 l2 = gen_jz_ecx_string(s, next_eip); \
1169 gen_ ## op(s, ot); \
1170 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1171 /* a loop would cause two single step exceptions if ECX = 1 \
1172 before rep string_insn */ \
1174 gen_op_jz_ecx(s->aflag, l2); \
1175 gen_jmp(s, cur_eip); \
1178 #define GEN_REPZ2(op) \
1179 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1180 target_ulong cur_eip, \
1181 target_ulong next_eip, \
1185 gen_update_cc_op(s); \
1186 l2 = gen_jz_ecx_string(s, next_eip); \
1187 gen_ ## op(s, ot); \
1188 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1189 gen_update_cc_op(s); \
1190 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
1192 gen_op_jz_ecx(s->aflag, l2); \
1193 gen_jmp(s, cur_eip); \
1204 static void gen_helper_fp_arith_ST0_FT0(int op)
1208 gen_helper_fadd_ST0_FT0(cpu_env);
1211 gen_helper_fmul_ST0_FT0(cpu_env);
1214 gen_helper_fcom_ST0_FT0(cpu_env);
1217 gen_helper_fcom_ST0_FT0(cpu_env);
1220 gen_helper_fsub_ST0_FT0(cpu_env);
1223 gen_helper_fsubr_ST0_FT0(cpu_env);
1226 gen_helper_fdiv_ST0_FT0(cpu_env);
1229 gen_helper_fdivr_ST0_FT0(cpu_env);
1234 /* NOTE the exception in "r" op ordering */
1235 static void gen_helper_fp_arith_STN_ST0(int op, int opreg)
1237 TCGv_i32 tmp = tcg_const_i32(opreg);
1240 gen_helper_fadd_STN_ST0(cpu_env, tmp);
1243 gen_helper_fmul_STN_ST0(cpu_env, tmp);
1246 gen_helper_fsubr_STN_ST0(cpu_env, tmp);
1249 gen_helper_fsub_STN_ST0(cpu_env, tmp);
1252 gen_helper_fdivr_STN_ST0(cpu_env, tmp);
1255 gen_helper_fdiv_STN_ST0(cpu_env, tmp);
1260 /* if d == OR_TMP0, it means memory operand (address in A0) */
1261 static void gen_op(DisasContext *s1, int op, TCGMemOp ot, int d)
1264 gen_op_mov_v_reg(ot, cpu_T0, d);
1265 } else if (!(s1->prefix & PREFIX_LOCK)) {
1266 gen_op_ld_v(s1, ot, cpu_T0, cpu_A0);
1270 gen_compute_eflags_c(s1, cpu_tmp4);
1271 if (s1->prefix & PREFIX_LOCK) {
1272 tcg_gen_add_tl(cpu_T0, cpu_tmp4, cpu_T1);
1273 tcg_gen_atomic_add_fetch_tl(cpu_T0, cpu_A0, cpu_T0,
1274 s1->mem_index, ot | MO_LE);
1276 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
1277 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_tmp4);
1278 gen_op_st_rm_T0_A0(s1, ot, d);
1280 gen_op_update3_cc(cpu_tmp4);
1281 set_cc_op(s1, CC_OP_ADCB + ot);
1284 gen_compute_eflags_c(s1, cpu_tmp4);
1285 if (s1->prefix & PREFIX_LOCK) {
1286 tcg_gen_add_tl(cpu_T0, cpu_T1, cpu_tmp4);
1287 tcg_gen_neg_tl(cpu_T0, cpu_T0);
1288 tcg_gen_atomic_add_fetch_tl(cpu_T0, cpu_A0, cpu_T0,
1289 s1->mem_index, ot | MO_LE);
1291 tcg_gen_sub_tl(cpu_T0, cpu_T0, cpu_T1);
1292 tcg_gen_sub_tl(cpu_T0, cpu_T0, cpu_tmp4);
1293 gen_op_st_rm_T0_A0(s1, ot, d);
1295 gen_op_update3_cc(cpu_tmp4);
1296 set_cc_op(s1, CC_OP_SBBB + ot);
1299 if (s1->prefix & PREFIX_LOCK) {
1300 tcg_gen_atomic_add_fetch_tl(cpu_T0, cpu_A0, cpu_T1,
1301 s1->mem_index, ot | MO_LE);
1303 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
1304 gen_op_st_rm_T0_A0(s1, ot, d);
1306 gen_op_update2_cc();
1307 set_cc_op(s1, CC_OP_ADDB + ot);
1310 if (s1->prefix & PREFIX_LOCK) {
1311 tcg_gen_neg_tl(cpu_T0, cpu_T1);
1312 tcg_gen_atomic_fetch_add_tl(cpu_cc_srcT, cpu_A0, cpu_T0,
1313 s1->mem_index, ot | MO_LE);
1314 tcg_gen_sub_tl(cpu_T0, cpu_cc_srcT, cpu_T1);
1316 tcg_gen_mov_tl(cpu_cc_srcT, cpu_T0);
1317 tcg_gen_sub_tl(cpu_T0, cpu_T0, cpu_T1);
1318 gen_op_st_rm_T0_A0(s1, ot, d);
1320 gen_op_update2_cc();
1321 set_cc_op(s1, CC_OP_SUBB + ot);
1325 if (s1->prefix & PREFIX_LOCK) {
1326 tcg_gen_atomic_and_fetch_tl(cpu_T0, cpu_A0, cpu_T1,
1327 s1->mem_index, ot | MO_LE);
1329 tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1);
1330 gen_op_st_rm_T0_A0(s1, ot, d);
1332 gen_op_update1_cc();
1333 set_cc_op(s1, CC_OP_LOGICB + ot);
1336 if (s1->prefix & PREFIX_LOCK) {
1337 tcg_gen_atomic_or_fetch_tl(cpu_T0, cpu_A0, cpu_T1,
1338 s1->mem_index, ot | MO_LE);
1340 tcg_gen_or_tl(cpu_T0, cpu_T0, cpu_T1);
1341 gen_op_st_rm_T0_A0(s1, ot, d);
1343 gen_op_update1_cc();
1344 set_cc_op(s1, CC_OP_LOGICB + ot);
1347 if (s1->prefix & PREFIX_LOCK) {
1348 tcg_gen_atomic_xor_fetch_tl(cpu_T0, cpu_A0, cpu_T1,
1349 s1->mem_index, ot | MO_LE);
1351 tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_T1);
1352 gen_op_st_rm_T0_A0(s1, ot, d);
1354 gen_op_update1_cc();
1355 set_cc_op(s1, CC_OP_LOGICB + ot);
1358 tcg_gen_mov_tl(cpu_cc_src, cpu_T1);
1359 tcg_gen_mov_tl(cpu_cc_srcT, cpu_T0);
1360 tcg_gen_sub_tl(cpu_cc_dst, cpu_T0, cpu_T1);
1361 set_cc_op(s1, CC_OP_SUBB + ot);
1366 /* if d == OR_TMP0, it means memory operand (address in A0) */
1367 static void gen_inc(DisasContext *s1, TCGMemOp ot, int d, int c)
1369 if (s1->prefix & PREFIX_LOCK) {
1370 tcg_gen_movi_tl(cpu_T0, c > 0 ? 1 : -1);
1371 tcg_gen_atomic_add_fetch_tl(cpu_T0, cpu_A0, cpu_T0,
1372 s1->mem_index, ot | MO_LE);
1375 gen_op_mov_v_reg(ot, cpu_T0, d);
1377 gen_op_ld_v(s1, ot, cpu_T0, cpu_A0);
1379 tcg_gen_addi_tl(cpu_T0, cpu_T0, (c > 0 ? 1 : -1));
1380 gen_op_st_rm_T0_A0(s1, ot, d);
1383 gen_compute_eflags_c(s1, cpu_cc_src);
1384 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
1385 set_cc_op(s1, (c > 0 ? CC_OP_INCB : CC_OP_DECB) + ot);
1388 static void gen_shift_flags(DisasContext *s, TCGMemOp ot, TCGv result,
1389 TCGv shm1, TCGv count, bool is_right)
1391 TCGv_i32 z32, s32, oldop;
1394 /* Store the results into the CC variables. If we know that the
1395 variable must be dead, store unconditionally. Otherwise we'll
1396 need to not disrupt the current contents. */
1397 z_tl = tcg_const_tl(0);
1398 if (cc_op_live[s->cc_op] & USES_CC_DST) {
1399 tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_dst, count, z_tl,
1400 result, cpu_cc_dst);
1402 tcg_gen_mov_tl(cpu_cc_dst, result);
1404 if (cc_op_live[s->cc_op] & USES_CC_SRC) {
1405 tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_src, count, z_tl,
1408 tcg_gen_mov_tl(cpu_cc_src, shm1);
1410 tcg_temp_free(z_tl);
1412 /* Get the two potential CC_OP values into temporaries. */
1413 tcg_gen_movi_i32(cpu_tmp2_i32, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot);
1414 if (s->cc_op == CC_OP_DYNAMIC) {
1417 tcg_gen_movi_i32(cpu_tmp3_i32, s->cc_op);
1418 oldop = cpu_tmp3_i32;
1421 /* Conditionally store the CC_OP value. */
1422 z32 = tcg_const_i32(0);
1423 s32 = tcg_temp_new_i32();
1424 tcg_gen_trunc_tl_i32(s32, count);
1425 tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, s32, z32, cpu_tmp2_i32, oldop);
1426 tcg_temp_free_i32(z32);
1427 tcg_temp_free_i32(s32);
1429 /* The CC_OP value is no longer predictable. */
1430 set_cc_op(s, CC_OP_DYNAMIC);
1433 static void gen_shift_rm_T1(DisasContext *s, TCGMemOp ot, int op1,
1434 int is_right, int is_arith)
1436 target_ulong mask = (ot == MO_64 ? 0x3f : 0x1f);
1439 if (op1 == OR_TMP0) {
1440 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1442 gen_op_mov_v_reg(ot, cpu_T0, op1);
1445 tcg_gen_andi_tl(cpu_T1, cpu_T1, mask);
1446 tcg_gen_subi_tl(cpu_tmp0, cpu_T1, 1);
1450 gen_exts(ot, cpu_T0);
1451 tcg_gen_sar_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1452 tcg_gen_sar_tl(cpu_T0, cpu_T0, cpu_T1);
1454 gen_extu(ot, cpu_T0);
1455 tcg_gen_shr_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1456 tcg_gen_shr_tl(cpu_T0, cpu_T0, cpu_T1);
1459 tcg_gen_shl_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1460 tcg_gen_shl_tl(cpu_T0, cpu_T0, cpu_T1);
1464 gen_op_st_rm_T0_A0(s, ot, op1);
1466 gen_shift_flags(s, ot, cpu_T0, cpu_tmp0, cpu_T1, is_right);
1469 static void gen_shift_rm_im(DisasContext *s, TCGMemOp ot, int op1, int op2,
1470 int is_right, int is_arith)
1472 int mask = (ot == MO_64 ? 0x3f : 0x1f);
1476 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1478 gen_op_mov_v_reg(ot, cpu_T0, op1);
1484 gen_exts(ot, cpu_T0);
1485 tcg_gen_sari_tl(cpu_tmp4, cpu_T0, op2 - 1);
1486 tcg_gen_sari_tl(cpu_T0, cpu_T0, op2);
1488 gen_extu(ot, cpu_T0);
1489 tcg_gen_shri_tl(cpu_tmp4, cpu_T0, op2 - 1);
1490 tcg_gen_shri_tl(cpu_T0, cpu_T0, op2);
1493 tcg_gen_shli_tl(cpu_tmp4, cpu_T0, op2 - 1);
1494 tcg_gen_shli_tl(cpu_T0, cpu_T0, op2);
1499 gen_op_st_rm_T0_A0(s, ot, op1);
1501 /* update eflags if non zero shift */
1503 tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
1504 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
1505 set_cc_op(s, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot);
1509 static void gen_rot_rm_T1(DisasContext *s, TCGMemOp ot, int op1, int is_right)
1511 target_ulong mask = (ot == MO_64 ? 0x3f : 0x1f);
1515 if (op1 == OR_TMP0) {
1516 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1518 gen_op_mov_v_reg(ot, cpu_T0, op1);
1521 tcg_gen_andi_tl(cpu_T1, cpu_T1, mask);
1525 /* Replicate the 8-bit input so that a 32-bit rotate works. */
1526 tcg_gen_ext8u_tl(cpu_T0, cpu_T0);
1527 tcg_gen_muli_tl(cpu_T0, cpu_T0, 0x01010101);
1530 /* Replicate the 16-bit input so that a 32-bit rotate works. */
1531 tcg_gen_deposit_tl(cpu_T0, cpu_T0, cpu_T0, 16, 16);
1534 #ifdef TARGET_X86_64
1536 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
1537 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T1);
1539 tcg_gen_rotr_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
1541 tcg_gen_rotl_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
1543 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
1548 tcg_gen_rotr_tl(cpu_T0, cpu_T0, cpu_T1);
1550 tcg_gen_rotl_tl(cpu_T0, cpu_T0, cpu_T1);
1556 gen_op_st_rm_T0_A0(s, ot, op1);
1558 /* We'll need the flags computed into CC_SRC. */
1559 gen_compute_eflags(s);
1561 /* The value that was "rotated out" is now present at the other end
1562 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1563 since we've computed the flags into CC_SRC, these variables are
1566 tcg_gen_shri_tl(cpu_cc_src2, cpu_T0, mask - 1);
1567 tcg_gen_shri_tl(cpu_cc_dst, cpu_T0, mask);
1568 tcg_gen_andi_tl(cpu_cc_dst, cpu_cc_dst, 1);
1570 tcg_gen_shri_tl(cpu_cc_src2, cpu_T0, mask);
1571 tcg_gen_andi_tl(cpu_cc_dst, cpu_T0, 1);
1573 tcg_gen_andi_tl(cpu_cc_src2, cpu_cc_src2, 1);
1574 tcg_gen_xor_tl(cpu_cc_src2, cpu_cc_src2, cpu_cc_dst);
1576 /* Now conditionally store the new CC_OP value. If the shift count
1577 is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1578 Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1579 exactly as we computed above. */
1580 t0 = tcg_const_i32(0);
1581 t1 = tcg_temp_new_i32();
1582 tcg_gen_trunc_tl_i32(t1, cpu_T1);
1583 tcg_gen_movi_i32(cpu_tmp2_i32, CC_OP_ADCOX);
1584 tcg_gen_movi_i32(cpu_tmp3_i32, CC_OP_EFLAGS);
1585 tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, t1, t0,
1586 cpu_tmp2_i32, cpu_tmp3_i32);
1587 tcg_temp_free_i32(t0);
1588 tcg_temp_free_i32(t1);
1590 /* The CC_OP value is no longer predictable. */
1591 set_cc_op(s, CC_OP_DYNAMIC);
1594 static void gen_rot_rm_im(DisasContext *s, TCGMemOp ot, int op1, int op2,
1597 int mask = (ot == MO_64 ? 0x3f : 0x1f);
1601 if (op1 == OR_TMP0) {
1602 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1604 gen_op_mov_v_reg(ot, cpu_T0, op1);
1610 #ifdef TARGET_X86_64
1612 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
1614 tcg_gen_rotri_i32(cpu_tmp2_i32, cpu_tmp2_i32, op2);
1616 tcg_gen_rotli_i32(cpu_tmp2_i32, cpu_tmp2_i32, op2);
1618 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
1623 tcg_gen_rotri_tl(cpu_T0, cpu_T0, op2);
1625 tcg_gen_rotli_tl(cpu_T0, cpu_T0, op2);
1636 shift = mask + 1 - shift;
1638 gen_extu(ot, cpu_T0);
1639 tcg_gen_shli_tl(cpu_tmp0, cpu_T0, shift);
1640 tcg_gen_shri_tl(cpu_T0, cpu_T0, mask + 1 - shift);
1641 tcg_gen_or_tl(cpu_T0, cpu_T0, cpu_tmp0);
1647 gen_op_st_rm_T0_A0(s, ot, op1);
1650 /* Compute the flags into CC_SRC. */
1651 gen_compute_eflags(s);
1653 /* The value that was "rotated out" is now present at the other end
1654 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1655 since we've computed the flags into CC_SRC, these variables are
1658 tcg_gen_shri_tl(cpu_cc_src2, cpu_T0, mask - 1);
1659 tcg_gen_shri_tl(cpu_cc_dst, cpu_T0, mask);
1660 tcg_gen_andi_tl(cpu_cc_dst, cpu_cc_dst, 1);
1662 tcg_gen_shri_tl(cpu_cc_src2, cpu_T0, mask);
1663 tcg_gen_andi_tl(cpu_cc_dst, cpu_T0, 1);
1665 tcg_gen_andi_tl(cpu_cc_src2, cpu_cc_src2, 1);
1666 tcg_gen_xor_tl(cpu_cc_src2, cpu_cc_src2, cpu_cc_dst);
1667 set_cc_op(s, CC_OP_ADCOX);
1671 /* XXX: add faster immediate = 1 case */
1672 static void gen_rotc_rm_T1(DisasContext *s, TCGMemOp ot, int op1,
1675 gen_compute_eflags(s);
1676 assert(s->cc_op == CC_OP_EFLAGS);
1680 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1682 gen_op_mov_v_reg(ot, cpu_T0, op1);
1687 gen_helper_rcrb(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1690 gen_helper_rcrw(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1693 gen_helper_rcrl(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1695 #ifdef TARGET_X86_64
1697 gen_helper_rcrq(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1706 gen_helper_rclb(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1709 gen_helper_rclw(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1712 gen_helper_rcll(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1714 #ifdef TARGET_X86_64
1716 gen_helper_rclq(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1724 gen_op_st_rm_T0_A0(s, ot, op1);
1727 /* XXX: add faster immediate case */
1728 static void gen_shiftd_rm_T1(DisasContext *s, TCGMemOp ot, int op1,
1729 bool is_right, TCGv count_in)
1731 target_ulong mask = (ot == MO_64 ? 63 : 31);
1735 if (op1 == OR_TMP0) {
1736 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1738 gen_op_mov_v_reg(ot, cpu_T0, op1);
1741 count = tcg_temp_new();
1742 tcg_gen_andi_tl(count, count_in, mask);
1746 /* Note: we implement the Intel behaviour for shift count > 16.
1747 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A
1748 portion by constructing it as a 32-bit value. */
1750 tcg_gen_deposit_tl(cpu_tmp0, cpu_T0, cpu_T1, 16, 16);
1751 tcg_gen_mov_tl(cpu_T1, cpu_T0);
1752 tcg_gen_mov_tl(cpu_T0, cpu_tmp0);
1754 tcg_gen_deposit_tl(cpu_T1, cpu_T0, cpu_T1, 16, 16);
1757 #ifdef TARGET_X86_64
1759 /* Concatenate the two 32-bit values and use a 64-bit shift. */
1760 tcg_gen_subi_tl(cpu_tmp0, count, 1);
1762 tcg_gen_concat_tl_i64(cpu_T0, cpu_T0, cpu_T1);
1763 tcg_gen_shr_i64(cpu_tmp0, cpu_T0, cpu_tmp0);
1764 tcg_gen_shr_i64(cpu_T0, cpu_T0, count);
1766 tcg_gen_concat_tl_i64(cpu_T0, cpu_T1, cpu_T0);
1767 tcg_gen_shl_i64(cpu_tmp0, cpu_T0, cpu_tmp0);
1768 tcg_gen_shl_i64(cpu_T0, cpu_T0, count);
1769 tcg_gen_shri_i64(cpu_tmp0, cpu_tmp0, 32);
1770 tcg_gen_shri_i64(cpu_T0, cpu_T0, 32);
1775 tcg_gen_subi_tl(cpu_tmp0, count, 1);
1777 tcg_gen_shr_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1779 tcg_gen_subfi_tl(cpu_tmp4, mask + 1, count);
1780 tcg_gen_shr_tl(cpu_T0, cpu_T0, count);
1781 tcg_gen_shl_tl(cpu_T1, cpu_T1, cpu_tmp4);
1783 tcg_gen_shl_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1785 /* Only needed if count > 16, for Intel behaviour. */
1786 tcg_gen_subfi_tl(cpu_tmp4, 33, count);
1787 tcg_gen_shr_tl(cpu_tmp4, cpu_T1, cpu_tmp4);
1788 tcg_gen_or_tl(cpu_tmp0, cpu_tmp0, cpu_tmp4);
1791 tcg_gen_subfi_tl(cpu_tmp4, mask + 1, count);
1792 tcg_gen_shl_tl(cpu_T0, cpu_T0, count);
1793 tcg_gen_shr_tl(cpu_T1, cpu_T1, cpu_tmp4);
1795 tcg_gen_movi_tl(cpu_tmp4, 0);
1796 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_T1, count, cpu_tmp4,
1798 tcg_gen_or_tl(cpu_T0, cpu_T0, cpu_T1);
1803 gen_op_st_rm_T0_A0(s, ot, op1);
1805 gen_shift_flags(s, ot, cpu_T0, cpu_tmp0, count, is_right);
1806 tcg_temp_free(count);
1809 static void gen_shift(DisasContext *s1, int op, TCGMemOp ot, int d, int s)
1812 gen_op_mov_v_reg(ot, cpu_T1, s);
1815 gen_rot_rm_T1(s1, ot, d, 0);
1818 gen_rot_rm_T1(s1, ot, d, 1);
1822 gen_shift_rm_T1(s1, ot, d, 0, 0);
1825 gen_shift_rm_T1(s1, ot, d, 1, 0);
1828 gen_shift_rm_T1(s1, ot, d, 1, 1);
1831 gen_rotc_rm_T1(s1, ot, d, 0);
1834 gen_rotc_rm_T1(s1, ot, d, 1);
1839 static void gen_shifti(DisasContext *s1, int op, TCGMemOp ot, int d, int c)
1843 gen_rot_rm_im(s1, ot, d, c, 0);
1846 gen_rot_rm_im(s1, ot, d, c, 1);
1850 gen_shift_rm_im(s1, ot, d, c, 0, 0);
1853 gen_shift_rm_im(s1, ot, d, c, 1, 0);
1856 gen_shift_rm_im(s1, ot, d, c, 1, 1);
1859 /* currently not optimized */
1860 tcg_gen_movi_tl(cpu_T1, c);
1861 gen_shift(s1, op, ot, d, OR_TMP1);
1866 /* Decompose an address. */
1868 typedef struct AddressParts {
1876 static AddressParts gen_lea_modrm_0(CPUX86State *env, DisasContext *s,
1879 int def_seg, base, index, scale, mod, rm;
1888 mod = (modrm >> 6) & 3;
1890 base = rm | REX_B(s);
1893 /* Normally filtered out earlier, but including this path
1894 simplifies multi-byte nop, as well as bndcl, bndcu, bndcn. */
1903 int code = cpu_ldub_code(env, s->pc++);
1904 scale = (code >> 6) & 3;
1905 index = ((code >> 3) & 7) | REX_X(s);
1907 index = -1; /* no index */
1909 base = (code & 7) | REX_B(s);
1915 if ((base & 7) == 5) {
1917 disp = (int32_t)cpu_ldl_code(env, s->pc);
1919 if (CODE64(s) && !havesib) {
1921 disp += s->pc + s->rip_offset;
1926 disp = (int8_t)cpu_ldub_code(env, s->pc++);
1930 disp = (int32_t)cpu_ldl_code(env, s->pc);
1935 /* For correct popl handling with esp. */
1936 if (base == R_ESP && s->popl_esp_hack) {
1937 disp += s->popl_esp_hack;
1939 if (base == R_EBP || base == R_ESP) {
1948 disp = cpu_lduw_code(env, s->pc);
1952 } else if (mod == 1) {
1953 disp = (int8_t)cpu_ldub_code(env, s->pc++);
1955 disp = (int16_t)cpu_lduw_code(env, s->pc);
2000 return (AddressParts){ def_seg, base, index, scale, disp };
2003 /* Compute the address, with a minimum number of TCG ops. */
2004 static TCGv gen_lea_modrm_1(AddressParts a)
2011 ea = cpu_regs[a.index];
2013 tcg_gen_shli_tl(cpu_A0, cpu_regs[a.index], a.scale);
2017 tcg_gen_add_tl(cpu_A0, ea, cpu_regs[a.base]);
2020 } else if (a.base >= 0) {
2021 ea = cpu_regs[a.base];
2023 if (TCGV_IS_UNUSED(ea)) {
2024 tcg_gen_movi_tl(cpu_A0, a.disp);
2026 } else if (a.disp != 0) {
2027 tcg_gen_addi_tl(cpu_A0, ea, a.disp);
2034 static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm)
2036 AddressParts a = gen_lea_modrm_0(env, s, modrm);
2037 TCGv ea = gen_lea_modrm_1(a);
2038 gen_lea_v_seg(s, s->aflag, ea, a.def_seg, s->override);
2041 static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm)
2043 (void)gen_lea_modrm_0(env, s, modrm);
2046 /* Used for BNDCL, BNDCU, BNDCN. */
2047 static void gen_bndck(CPUX86State *env, DisasContext *s, int modrm,
2048 TCGCond cond, TCGv_i64 bndv)
2050 TCGv ea = gen_lea_modrm_1(gen_lea_modrm_0(env, s, modrm));
2052 tcg_gen_extu_tl_i64(cpu_tmp1_i64, ea);
2054 tcg_gen_ext32u_i64(cpu_tmp1_i64, cpu_tmp1_i64);
2056 tcg_gen_setcond_i64(cond, cpu_tmp1_i64, cpu_tmp1_i64, bndv);
2057 tcg_gen_extrl_i64_i32(cpu_tmp2_i32, cpu_tmp1_i64);
2058 gen_helper_bndck(cpu_env, cpu_tmp2_i32);
2061 /* used for LEA and MOV AX, mem */
2062 static void gen_add_A0_ds_seg(DisasContext *s)
2064 gen_lea_v_seg(s, s->aflag, cpu_A0, R_DS, s->override);
2067 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2069 static void gen_ldst_modrm(CPUX86State *env, DisasContext *s, int modrm,
2070 TCGMemOp ot, int reg, int is_store)
2074 mod = (modrm >> 6) & 3;
2075 rm = (modrm & 7) | REX_B(s);
2079 gen_op_mov_v_reg(ot, cpu_T0, reg);
2080 gen_op_mov_reg_v(ot, rm, cpu_T0);
2082 gen_op_mov_v_reg(ot, cpu_T0, rm);
2084 gen_op_mov_reg_v(ot, reg, cpu_T0);
2087 gen_lea_modrm(env, s, modrm);
2090 gen_op_mov_v_reg(ot, cpu_T0, reg);
2091 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
2093 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
2095 gen_op_mov_reg_v(ot, reg, cpu_T0);
2100 static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, TCGMemOp ot)
2106 ret = cpu_ldub_code(env, s->pc);
2110 ret = cpu_lduw_code(env, s->pc);
2114 #ifdef TARGET_X86_64
2117 ret = cpu_ldl_code(env, s->pc);
2126 static inline int insn_const_size(TCGMemOp ot)
2135 static inline bool use_goto_tb(DisasContext *s, target_ulong pc)
2137 #ifndef CONFIG_USER_ONLY
2138 return (pc & TARGET_PAGE_MASK) == (s->base.tb->pc & TARGET_PAGE_MASK) ||
2139 (pc & TARGET_PAGE_MASK) == (s->pc_start & TARGET_PAGE_MASK);
2145 static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
2147 target_ulong pc = s->cs_base + eip;
2149 if (use_goto_tb(s, pc)) {
2150 /* jump to same page: we can use a direct jump */
2151 tcg_gen_goto_tb(tb_num);
2153 tcg_gen_exit_tb((uintptr_t)s->base.tb + tb_num);
2154 s->base.is_jmp = DISAS_NORETURN;
2156 /* jump to another page */
2158 gen_jr(s, cpu_tmp0);
2162 static inline void gen_jcc(DisasContext *s, int b,
2163 target_ulong val, target_ulong next_eip)
2168 l1 = gen_new_label();
2171 gen_goto_tb(s, 0, next_eip);
2174 gen_goto_tb(s, 1, val);
2176 l1 = gen_new_label();
2177 l2 = gen_new_label();
2180 gen_jmp_im(next_eip);
2190 static void gen_cmovcc1(CPUX86State *env, DisasContext *s, TCGMemOp ot, int b,
2195 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
2197 cc = gen_prepare_cc(s, b, cpu_T1);
2198 if (cc.mask != -1) {
2199 TCGv t0 = tcg_temp_new();
2200 tcg_gen_andi_tl(t0, cc.reg, cc.mask);
2204 cc.reg2 = tcg_const_tl(cc.imm);
2207 tcg_gen_movcond_tl(cc.cond, cpu_T0, cc.reg, cc.reg2,
2208 cpu_T0, cpu_regs[reg]);
2209 gen_op_mov_reg_v(ot, reg, cpu_T0);
2211 if (cc.mask != -1) {
2212 tcg_temp_free(cc.reg);
2215 tcg_temp_free(cc.reg2);
2219 static inline void gen_op_movl_T0_seg(int seg_reg)
2221 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
2222 offsetof(CPUX86State,segs[seg_reg].selector));
2225 static inline void gen_op_movl_seg_T0_vm(int seg_reg)
2227 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
2228 tcg_gen_st32_tl(cpu_T0, cpu_env,
2229 offsetof(CPUX86State,segs[seg_reg].selector));
2230 tcg_gen_shli_tl(cpu_seg_base[seg_reg], cpu_T0, 4);
2233 /* move T0 to seg_reg and compute if the CPU state may change. Never
2234 call this function with seg_reg == R_CS */
2235 static void gen_movl_seg_T0(DisasContext *s, int seg_reg)
2237 if (s->pe && !s->vm86) {
2238 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
2239 gen_helper_load_seg(cpu_env, tcg_const_i32(seg_reg), cpu_tmp2_i32);
2240 /* abort translation because the addseg value may change or
2241 because ss32 may change. For R_SS, translation must always
2242 stop as a special handling must be done to disable hardware
2243 interrupts for the next instruction */
2244 if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS)) {
2245 s->base.is_jmp = DISAS_TOO_MANY;
2248 gen_op_movl_seg_T0_vm(seg_reg);
2249 if (seg_reg == R_SS) {
2250 s->base.is_jmp = DISAS_TOO_MANY;
2255 static inline int svm_is_rep(int prefixes)
2257 return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0);
2261 gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
2262 uint32_t type, uint64_t param)
2264 /* no SVM activated; fast case */
2265 if (likely(!(s->flags & HF_SVMI_MASK)))
2267 gen_update_cc_op(s);
2268 gen_jmp_im(pc_start - s->cs_base);
2269 gen_helper_svm_check_intercept_param(cpu_env, tcg_const_i32(type),
2270 tcg_const_i64(param));
2274 gen_svm_check_intercept(DisasContext *s, target_ulong pc_start, uint64_t type)
2276 gen_svm_check_intercept_param(s, pc_start, type, 0);
2279 static inline void gen_stack_update(DisasContext *s, int addend)
2281 gen_op_add_reg_im(mo_stacksize(s), R_ESP, addend);
2284 /* Generate a push. It depends on ss32, addseg and dflag. */
2285 static void gen_push_v(DisasContext *s, TCGv val)
2287 TCGMemOp d_ot = mo_pushpop(s, s->dflag);
2288 TCGMemOp a_ot = mo_stacksize(s);
2289 int size = 1 << d_ot;
2290 TCGv new_esp = cpu_A0;
2292 tcg_gen_subi_tl(cpu_A0, cpu_regs[R_ESP], size);
2297 tcg_gen_mov_tl(new_esp, cpu_A0);
2299 gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1);
2302 gen_op_st_v(s, d_ot, val, cpu_A0);
2303 gen_op_mov_reg_v(a_ot, R_ESP, new_esp);
2306 /* two step pop is necessary for precise exceptions */
2307 static TCGMemOp gen_pop_T0(DisasContext *s)
2309 TCGMemOp d_ot = mo_pushpop(s, s->dflag);
2311 gen_lea_v_seg(s, mo_stacksize(s), cpu_regs[R_ESP], R_SS, -1);
2312 gen_op_ld_v(s, d_ot, cpu_T0, cpu_A0);
2317 static inline void gen_pop_update(DisasContext *s, TCGMemOp ot)
2319 gen_stack_update(s, 1 << ot);
2322 static inline void gen_stack_A0(DisasContext *s)
2324 gen_lea_v_seg(s, s->ss32 ? MO_32 : MO_16, cpu_regs[R_ESP], R_SS, -1);
2327 static void gen_pusha(DisasContext *s)
2329 TCGMemOp s_ot = s->ss32 ? MO_32 : MO_16;
2330 TCGMemOp d_ot = s->dflag;
2331 int size = 1 << d_ot;
2334 for (i = 0; i < 8; i++) {
2335 tcg_gen_addi_tl(cpu_A0, cpu_regs[R_ESP], (i - 8) * size);
2336 gen_lea_v_seg(s, s_ot, cpu_A0, R_SS, -1);
2337 gen_op_st_v(s, d_ot, cpu_regs[7 - i], cpu_A0);
2340 gen_stack_update(s, -8 * size);
2343 static void gen_popa(DisasContext *s)
2345 TCGMemOp s_ot = s->ss32 ? MO_32 : MO_16;
2346 TCGMemOp d_ot = s->dflag;
2347 int size = 1 << d_ot;
2350 for (i = 0; i < 8; i++) {
2351 /* ESP is not reloaded */
2352 if (7 - i == R_ESP) {
2355 tcg_gen_addi_tl(cpu_A0, cpu_regs[R_ESP], i * size);
2356 gen_lea_v_seg(s, s_ot, cpu_A0, R_SS, -1);
2357 gen_op_ld_v(s, d_ot, cpu_T0, cpu_A0);
2358 gen_op_mov_reg_v(d_ot, 7 - i, cpu_T0);
2361 gen_stack_update(s, 8 * size);
2364 static void gen_enter(DisasContext *s, int esp_addend, int level)
2366 TCGMemOp d_ot = mo_pushpop(s, s->dflag);
2367 TCGMemOp a_ot = CODE64(s) ? MO_64 : s->ss32 ? MO_32 : MO_16;
2368 int size = 1 << d_ot;
2370 /* Push BP; compute FrameTemp into T1. */
2371 tcg_gen_subi_tl(cpu_T1, cpu_regs[R_ESP], size);
2372 gen_lea_v_seg(s, a_ot, cpu_T1, R_SS, -1);
2373 gen_op_st_v(s, d_ot, cpu_regs[R_EBP], cpu_A0);
2379 /* Copy level-1 pointers from the previous frame. */
2380 for (i = 1; i < level; ++i) {
2381 tcg_gen_subi_tl(cpu_A0, cpu_regs[R_EBP], size * i);
2382 gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1);
2383 gen_op_ld_v(s, d_ot, cpu_tmp0, cpu_A0);
2385 tcg_gen_subi_tl(cpu_A0, cpu_T1, size * i);
2386 gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1);
2387 gen_op_st_v(s, d_ot, cpu_tmp0, cpu_A0);
2390 /* Push the current FrameTemp as the last level. */
2391 tcg_gen_subi_tl(cpu_A0, cpu_T1, size * level);
2392 gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1);
2393 gen_op_st_v(s, d_ot, cpu_T1, cpu_A0);
2396 /* Copy the FrameTemp value to EBP. */
2397 gen_op_mov_reg_v(a_ot, R_EBP, cpu_T1);
2399 /* Compute the final value of ESP. */
2400 tcg_gen_subi_tl(cpu_T1, cpu_T1, esp_addend + size * level);
2401 gen_op_mov_reg_v(a_ot, R_ESP, cpu_T1);
2404 static void gen_leave(DisasContext *s)
2406 TCGMemOp d_ot = mo_pushpop(s, s->dflag);
2407 TCGMemOp a_ot = mo_stacksize(s);
2409 gen_lea_v_seg(s, a_ot, cpu_regs[R_EBP], R_SS, -1);
2410 gen_op_ld_v(s, d_ot, cpu_T0, cpu_A0);
2412 tcg_gen_addi_tl(cpu_T1, cpu_regs[R_EBP], 1 << d_ot);
2414 gen_op_mov_reg_v(d_ot, R_EBP, cpu_T0);
2415 gen_op_mov_reg_v(a_ot, R_ESP, cpu_T1);
2418 static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
2420 gen_update_cc_op(s);
2421 gen_jmp_im(cur_eip);
2422 gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno));
2423 s->base.is_jmp = DISAS_NORETURN;
2426 /* Generate #UD for the current instruction. The assumption here is that
2427 the instruction is known, but it isn't allowed in the current cpu mode. */
2428 static void gen_illegal_opcode(DisasContext *s)
2430 gen_exception(s, EXCP06_ILLOP, s->pc_start - s->cs_base);
2433 /* Similarly, except that the assumption here is that we don't decode
2434 the instruction at all -- either a missing opcode, an unimplemented
2435 feature, or just a bogus instruction stream. */
2436 static void gen_unknown_opcode(CPUX86State *env, DisasContext *s)
2438 gen_illegal_opcode(s);
2440 if (qemu_loglevel_mask(LOG_UNIMP)) {
2441 target_ulong pc = s->pc_start, end = s->pc;
2443 qemu_log("ILLOPC: " TARGET_FMT_lx ":", pc);
2444 for (; pc < end; ++pc) {
2445 qemu_log(" %02x", cpu_ldub_code(env, pc));
2452 /* an interrupt is different from an exception because of the
2454 static void gen_interrupt(DisasContext *s, int intno,
2455 target_ulong cur_eip, target_ulong next_eip)
2457 gen_update_cc_op(s);
2458 gen_jmp_im(cur_eip);
2459 gen_helper_raise_interrupt(cpu_env, tcg_const_i32(intno),
2460 tcg_const_i32(next_eip - cur_eip));
2461 s->base.is_jmp = DISAS_NORETURN;
2464 static void gen_debug(DisasContext *s, target_ulong cur_eip)
2466 gen_update_cc_op(s);
2467 gen_jmp_im(cur_eip);
2468 gen_helper_debug(cpu_env);
2469 s->base.is_jmp = DISAS_NORETURN;
2472 static void gen_set_hflag(DisasContext *s, uint32_t mask)
2474 if ((s->flags & mask) == 0) {
2475 TCGv_i32 t = tcg_temp_new_i32();
2476 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2477 tcg_gen_ori_i32(t, t, mask);
2478 tcg_gen_st_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2479 tcg_temp_free_i32(t);
2484 static void gen_reset_hflag(DisasContext *s, uint32_t mask)
2486 if (s->flags & mask) {
2487 TCGv_i32 t = tcg_temp_new_i32();
2488 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2489 tcg_gen_andi_i32(t, t, ~mask);
2490 tcg_gen_st_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2491 tcg_temp_free_i32(t);
2496 /* Clear BND registers during legacy branches. */
2497 static void gen_bnd_jmp(DisasContext *s)
2499 /* Clear the registers only if BND prefix is missing, MPX is enabled,
2500 and if the BNDREGs are known to be in use (non-zero) already.
2501 The helper itself will check BNDPRESERVE at runtime. */
2502 if ((s->prefix & PREFIX_REPNZ) == 0
2503 && (s->flags & HF_MPX_EN_MASK) != 0
2504 && (s->flags & HF_MPX_IU_MASK) != 0) {
2505 gen_helper_bnd_jmp(cpu_env);
2509 /* Generate an end of block. Trace exception is also generated if needed.
2510 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set.
2511 If RECHECK_TF, emit a rechecking helper for #DB, ignoring the state of
2512 S->TF. This is used by the syscall/sysret insns. */
2514 do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, TCGv jr)
2516 gen_update_cc_op(s);
2518 /* If several instructions disable interrupts, only the first does it. */
2519 if (inhibit && !(s->flags & HF_INHIBIT_IRQ_MASK)) {
2520 gen_set_hflag(s, HF_INHIBIT_IRQ_MASK);
2522 gen_reset_hflag(s, HF_INHIBIT_IRQ_MASK);
2525 if (s->base.tb->flags & HF_RF_MASK) {
2526 gen_helper_reset_rf(cpu_env);
2528 if (s->base.singlestep_enabled) {
2529 gen_helper_debug(cpu_env);
2530 } else if (recheck_tf) {
2531 gen_helper_rechecking_single_step(cpu_env);
2534 gen_helper_single_step(cpu_env);
2535 } else if (!TCGV_IS_UNUSED(jr)) {
2536 TCGv vaddr = tcg_temp_new();
2538 tcg_gen_add_tl(vaddr, jr, cpu_seg_base[R_CS]);
2539 tcg_gen_lookup_and_goto_ptr(vaddr);
2540 tcg_temp_free(vaddr);
2544 s->base.is_jmp = DISAS_NORETURN;
2548 gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf)
2552 TCGV_UNUSED(unused);
2553 do_gen_eob_worker(s, inhibit, recheck_tf, unused);
2557 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set. */
2558 static void gen_eob_inhibit_irq(DisasContext *s, bool inhibit)
2560 gen_eob_worker(s, inhibit, false);
2563 /* End of block, resetting the inhibit irq flag. */
2564 static void gen_eob(DisasContext *s)
2566 gen_eob_worker(s, false, false);
2569 /* Jump to register */
2570 static void gen_jr(DisasContext *s, TCGv dest)
2572 do_gen_eob_worker(s, false, false, dest);
2575 /* generate a jump to eip. No segment change must happen before as a
2576 direct call to the next block may occur */
2577 static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
2579 gen_update_cc_op(s);
2580 set_cc_op(s, CC_OP_DYNAMIC);
2582 gen_goto_tb(s, tb_num, eip);
2589 static void gen_jmp(DisasContext *s, target_ulong eip)
2591 gen_jmp_tb(s, eip, 0);
2594 static inline void gen_ldq_env_A0(DisasContext *s, int offset)
2596 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
2597 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset);
2600 static inline void gen_stq_env_A0(DisasContext *s, int offset)
2602 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset);
2603 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
2606 static inline void gen_ldo_env_A0(DisasContext *s, int offset)
2608 int mem_index = s->mem_index;
2609 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, mem_index, MO_LEQ);
2610 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(0)));
2611 tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2612 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_tmp0, mem_index, MO_LEQ);
2613 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(1)));
2616 static inline void gen_sto_env_A0(DisasContext *s, int offset)
2618 int mem_index = s->mem_index;
2619 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(0)));
2620 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, mem_index, MO_LEQ);
2621 tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2622 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(1)));
2623 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_tmp0, mem_index, MO_LEQ);
2626 static inline void gen_op_movo(int d_offset, int s_offset)
2628 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + offsetof(ZMMReg, ZMM_Q(0)));
2629 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + offsetof(ZMMReg, ZMM_Q(0)));
2630 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + offsetof(ZMMReg, ZMM_Q(1)));
2631 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + offsetof(ZMMReg, ZMM_Q(1)));
2634 static inline void gen_op_movq(int d_offset, int s_offset)
2636 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
2637 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2640 static inline void gen_op_movl(int d_offset, int s_offset)
2642 tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env, s_offset);
2643 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, d_offset);
2646 static inline void gen_op_movq_env_0(int d_offset)
2648 tcg_gen_movi_i64(cpu_tmp1_i64, 0);
2649 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2652 typedef void (*SSEFunc_i_ep)(TCGv_i32 val, TCGv_ptr env, TCGv_ptr reg);
2653 typedef void (*SSEFunc_l_ep)(TCGv_i64 val, TCGv_ptr env, TCGv_ptr reg);
2654 typedef void (*SSEFunc_0_epi)(TCGv_ptr env, TCGv_ptr reg, TCGv_i32 val);
2655 typedef void (*SSEFunc_0_epl)(TCGv_ptr env, TCGv_ptr reg, TCGv_i64 val);
2656 typedef void (*SSEFunc_0_epp)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b);
2657 typedef void (*SSEFunc_0_eppi)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2659 typedef void (*SSEFunc_0_ppi)(TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv_i32 val);
2660 typedef void (*SSEFunc_0_eppt)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2663 #define SSE_SPECIAL ((void *)1)
2664 #define SSE_DUMMY ((void *)2)
2666 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2667 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2668 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2670 static const SSEFunc_0_epp sse_op_table1[256][4] = {
2671 /* 3DNow! extensions */
2672 [0x0e] = { SSE_DUMMY }, /* femms */
2673 [0x0f] = { SSE_DUMMY }, /* pf... */
2674 /* pure SSE operations */
2675 [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2676 [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2677 [0x12] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd, movsldup, movddup */
2678 [0x13] = { SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd */
2679 [0x14] = { gen_helper_punpckldq_xmm, gen_helper_punpcklqdq_xmm },
2680 [0x15] = { gen_helper_punpckhdq_xmm, gen_helper_punpckhqdq_xmm },
2681 [0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movhps, movhpd, movshdup */
2682 [0x17] = { SSE_SPECIAL, SSE_SPECIAL }, /* movhps, movhpd */
2684 [0x28] = { SSE_SPECIAL, SSE_SPECIAL }, /* movaps, movapd */
2685 [0x29] = { SSE_SPECIAL, SSE_SPECIAL }, /* movaps, movapd */
2686 [0x2a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2687 [0x2b] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movntps, movntpd, movntss, movntsd */
2688 [0x2c] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2689 [0x2d] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2690 [0x2e] = { gen_helper_ucomiss, gen_helper_ucomisd },
2691 [0x2f] = { gen_helper_comiss, gen_helper_comisd },
2692 [0x50] = { SSE_SPECIAL, SSE_SPECIAL }, /* movmskps, movmskpd */
2693 [0x51] = SSE_FOP(sqrt),
2694 [0x52] = { gen_helper_rsqrtps, NULL, gen_helper_rsqrtss, NULL },
2695 [0x53] = { gen_helper_rcpps, NULL, gen_helper_rcpss, NULL },
2696 [0x54] = { gen_helper_pand_xmm, gen_helper_pand_xmm }, /* andps, andpd */
2697 [0x55] = { gen_helper_pandn_xmm, gen_helper_pandn_xmm }, /* andnps, andnpd */
2698 [0x56] = { gen_helper_por_xmm, gen_helper_por_xmm }, /* orps, orpd */
2699 [0x57] = { gen_helper_pxor_xmm, gen_helper_pxor_xmm }, /* xorps, xorpd */
2700 [0x58] = SSE_FOP(add),
2701 [0x59] = SSE_FOP(mul),
2702 [0x5a] = { gen_helper_cvtps2pd, gen_helper_cvtpd2ps,
2703 gen_helper_cvtss2sd, gen_helper_cvtsd2ss },
2704 [0x5b] = { gen_helper_cvtdq2ps, gen_helper_cvtps2dq, gen_helper_cvttps2dq },
2705 [0x5c] = SSE_FOP(sub),
2706 [0x5d] = SSE_FOP(min),
2707 [0x5e] = SSE_FOP(div),
2708 [0x5f] = SSE_FOP(max),
2710 [0xc2] = SSE_FOP(cmpeq),
2711 [0xc6] = { (SSEFunc_0_epp)gen_helper_shufps,
2712 (SSEFunc_0_epp)gen_helper_shufpd }, /* XXX: casts */
2714 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */
2715 [0x38] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2716 [0x3a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2718 /* MMX ops and their SSE extensions */
2719 [0x60] = MMX_OP2(punpcklbw),
2720 [0x61] = MMX_OP2(punpcklwd),
2721 [0x62] = MMX_OP2(punpckldq),
2722 [0x63] = MMX_OP2(packsswb),
2723 [0x64] = MMX_OP2(pcmpgtb),
2724 [0x65] = MMX_OP2(pcmpgtw),
2725 [0x66] = MMX_OP2(pcmpgtl),
2726 [0x67] = MMX_OP2(packuswb),
2727 [0x68] = MMX_OP2(punpckhbw),
2728 [0x69] = MMX_OP2(punpckhwd),
2729 [0x6a] = MMX_OP2(punpckhdq),
2730 [0x6b] = MMX_OP2(packssdw),
2731 [0x6c] = { NULL, gen_helper_punpcklqdq_xmm },
2732 [0x6d] = { NULL, gen_helper_punpckhqdq_xmm },
2733 [0x6e] = { SSE_SPECIAL, SSE_SPECIAL }, /* movd mm, ea */
2734 [0x6f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, , movqdu */
2735 [0x70] = { (SSEFunc_0_epp)gen_helper_pshufw_mmx,
2736 (SSEFunc_0_epp)gen_helper_pshufd_xmm,
2737 (SSEFunc_0_epp)gen_helper_pshufhw_xmm,
2738 (SSEFunc_0_epp)gen_helper_pshuflw_xmm }, /* XXX: casts */
2739 [0x71] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftw */
2740 [0x72] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftd */
2741 [0x73] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftq */
2742 [0x74] = MMX_OP2(pcmpeqb),
2743 [0x75] = MMX_OP2(pcmpeqw),
2744 [0x76] = MMX_OP2(pcmpeql),
2745 [0x77] = { SSE_DUMMY }, /* emms */
2746 [0x78] = { NULL, SSE_SPECIAL, NULL, SSE_SPECIAL }, /* extrq_i, insertq_i */
2747 [0x79] = { NULL, gen_helper_extrq_r, NULL, gen_helper_insertq_r },
2748 [0x7c] = { NULL, gen_helper_haddpd, NULL, gen_helper_haddps },
2749 [0x7d] = { NULL, gen_helper_hsubpd, NULL, gen_helper_hsubps },
2750 [0x7e] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movd, movd, , movq */
2751 [0x7f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, movdqu */
2752 [0xc4] = { SSE_SPECIAL, SSE_SPECIAL }, /* pinsrw */
2753 [0xc5] = { SSE_SPECIAL, SSE_SPECIAL }, /* pextrw */
2754 [0xd0] = { NULL, gen_helper_addsubpd, NULL, gen_helper_addsubps },
2755 [0xd1] = MMX_OP2(psrlw),
2756 [0xd2] = MMX_OP2(psrld),
2757 [0xd3] = MMX_OP2(psrlq),
2758 [0xd4] = MMX_OP2(paddq),
2759 [0xd5] = MMX_OP2(pmullw),
2760 [0xd6] = { NULL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2761 [0xd7] = { SSE_SPECIAL, SSE_SPECIAL }, /* pmovmskb */
2762 [0xd8] = MMX_OP2(psubusb),
2763 [0xd9] = MMX_OP2(psubusw),
2764 [0xda] = MMX_OP2(pminub),
2765 [0xdb] = MMX_OP2(pand),
2766 [0xdc] = MMX_OP2(paddusb),
2767 [0xdd] = MMX_OP2(paddusw),
2768 [0xde] = MMX_OP2(pmaxub),
2769 [0xdf] = MMX_OP2(pandn),
2770 [0xe0] = MMX_OP2(pavgb),
2771 [0xe1] = MMX_OP2(psraw),
2772 [0xe2] = MMX_OP2(psrad),
2773 [0xe3] = MMX_OP2(pavgw),
2774 [0xe4] = MMX_OP2(pmulhuw),
2775 [0xe5] = MMX_OP2(pmulhw),
2776 [0xe6] = { NULL, gen_helper_cvttpd2dq, gen_helper_cvtdq2pd, gen_helper_cvtpd2dq },
2777 [0xe7] = { SSE_SPECIAL , SSE_SPECIAL }, /* movntq, movntq */
2778 [0xe8] = MMX_OP2(psubsb),
2779 [0xe9] = MMX_OP2(psubsw),
2780 [0xea] = MMX_OP2(pminsw),
2781 [0xeb] = MMX_OP2(por),
2782 [0xec] = MMX_OP2(paddsb),
2783 [0xed] = MMX_OP2(paddsw),
2784 [0xee] = MMX_OP2(pmaxsw),
2785 [0xef] = MMX_OP2(pxor),
2786 [0xf0] = { NULL, NULL, NULL, SSE_SPECIAL }, /* lddqu */
2787 [0xf1] = MMX_OP2(psllw),
2788 [0xf2] = MMX_OP2(pslld),
2789 [0xf3] = MMX_OP2(psllq),
2790 [0xf4] = MMX_OP2(pmuludq),
2791 [0xf5] = MMX_OP2(pmaddwd),
2792 [0xf6] = MMX_OP2(psadbw),
2793 [0xf7] = { (SSEFunc_0_epp)gen_helper_maskmov_mmx,
2794 (SSEFunc_0_epp)gen_helper_maskmov_xmm }, /* XXX: casts */
2795 [0xf8] = MMX_OP2(psubb),
2796 [0xf9] = MMX_OP2(psubw),
2797 [0xfa] = MMX_OP2(psubl),
2798 [0xfb] = MMX_OP2(psubq),
2799 [0xfc] = MMX_OP2(paddb),
2800 [0xfd] = MMX_OP2(paddw),
2801 [0xfe] = MMX_OP2(paddl),
2804 static const SSEFunc_0_epp sse_op_table2[3 * 8][2] = {
2805 [0 + 2] = MMX_OP2(psrlw),
2806 [0 + 4] = MMX_OP2(psraw),
2807 [0 + 6] = MMX_OP2(psllw),
2808 [8 + 2] = MMX_OP2(psrld),
2809 [8 + 4] = MMX_OP2(psrad),
2810 [8 + 6] = MMX_OP2(pslld),
2811 [16 + 2] = MMX_OP2(psrlq),
2812 [16 + 3] = { NULL, gen_helper_psrldq_xmm },
2813 [16 + 6] = MMX_OP2(psllq),
2814 [16 + 7] = { NULL, gen_helper_pslldq_xmm },
2817 static const SSEFunc_0_epi sse_op_table3ai[] = {
2818 gen_helper_cvtsi2ss,
2822 #ifdef TARGET_X86_64
2823 static const SSEFunc_0_epl sse_op_table3aq[] = {
2824 gen_helper_cvtsq2ss,
2829 static const SSEFunc_i_ep sse_op_table3bi[] = {
2830 gen_helper_cvttss2si,
2831 gen_helper_cvtss2si,
2832 gen_helper_cvttsd2si,
2836 #ifdef TARGET_X86_64
2837 static const SSEFunc_l_ep sse_op_table3bq[] = {
2838 gen_helper_cvttss2sq,
2839 gen_helper_cvtss2sq,
2840 gen_helper_cvttsd2sq,
2845 static const SSEFunc_0_epp sse_op_table4[8][4] = {
2856 static const SSEFunc_0_epp sse_op_table5[256] = {
2857 [0x0c] = gen_helper_pi2fw,
2858 [0x0d] = gen_helper_pi2fd,
2859 [0x1c] = gen_helper_pf2iw,
2860 [0x1d] = gen_helper_pf2id,
2861 [0x8a] = gen_helper_pfnacc,
2862 [0x8e] = gen_helper_pfpnacc,
2863 [0x90] = gen_helper_pfcmpge,
2864 [0x94] = gen_helper_pfmin,
2865 [0x96] = gen_helper_pfrcp,
2866 [0x97] = gen_helper_pfrsqrt,
2867 [0x9a] = gen_helper_pfsub,
2868 [0x9e] = gen_helper_pfadd,
2869 [0xa0] = gen_helper_pfcmpgt,
2870 [0xa4] = gen_helper_pfmax,
2871 [0xa6] = gen_helper_movq, /* pfrcpit1; no need to actually increase precision */
2872 [0xa7] = gen_helper_movq, /* pfrsqit1 */
2873 [0xaa] = gen_helper_pfsubr,
2874 [0xae] = gen_helper_pfacc,
2875 [0xb0] = gen_helper_pfcmpeq,
2876 [0xb4] = gen_helper_pfmul,
2877 [0xb6] = gen_helper_movq, /* pfrcpit2 */
2878 [0xb7] = gen_helper_pmulhrw_mmx,
2879 [0xbb] = gen_helper_pswapd,
2880 [0xbf] = gen_helper_pavgb_mmx /* pavgusb */
2883 struct SSEOpHelper_epp {
2884 SSEFunc_0_epp op[2];
2888 struct SSEOpHelper_eppi {
2889 SSEFunc_0_eppi op[2];
2893 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
2894 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
2895 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
2896 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
2897 #define PCLMULQDQ_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, \
2898 CPUID_EXT_PCLMULQDQ }
2899 #define AESNI_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_AES }
2901 static const struct SSEOpHelper_epp sse_op_table6[256] = {
2902 [0x00] = SSSE3_OP(pshufb),
2903 [0x01] = SSSE3_OP(phaddw),
2904 [0x02] = SSSE3_OP(phaddd),
2905 [0x03] = SSSE3_OP(phaddsw),
2906 [0x04] = SSSE3_OP(pmaddubsw),
2907 [0x05] = SSSE3_OP(phsubw),
2908 [0x06] = SSSE3_OP(phsubd),
2909 [0x07] = SSSE3_OP(phsubsw),
2910 [0x08] = SSSE3_OP(psignb),
2911 [0x09] = SSSE3_OP(psignw),
2912 [0x0a] = SSSE3_OP(psignd),
2913 [0x0b] = SSSE3_OP(pmulhrsw),
2914 [0x10] = SSE41_OP(pblendvb),
2915 [0x14] = SSE41_OP(blendvps),
2916 [0x15] = SSE41_OP(blendvpd),
2917 [0x17] = SSE41_OP(ptest),
2918 [0x1c] = SSSE3_OP(pabsb),
2919 [0x1d] = SSSE3_OP(pabsw),
2920 [0x1e] = SSSE3_OP(pabsd),
2921 [0x20] = SSE41_OP(pmovsxbw),
2922 [0x21] = SSE41_OP(pmovsxbd),
2923 [0x22] = SSE41_OP(pmovsxbq),
2924 [0x23] = SSE41_OP(pmovsxwd),
2925 [0x24] = SSE41_OP(pmovsxwq),
2926 [0x25] = SSE41_OP(pmovsxdq),
2927 [0x28] = SSE41_OP(pmuldq),
2928 [0x29] = SSE41_OP(pcmpeqq),
2929 [0x2a] = SSE41_SPECIAL, /* movntqda */
2930 [0x2b] = SSE41_OP(packusdw),
2931 [0x30] = SSE41_OP(pmovzxbw),
2932 [0x31] = SSE41_OP(pmovzxbd),
2933 [0x32] = SSE41_OP(pmovzxbq),
2934 [0x33] = SSE41_OP(pmovzxwd),
2935 [0x34] = SSE41_OP(pmovzxwq),
2936 [0x35] = SSE41_OP(pmovzxdq),
2937 [0x37] = SSE42_OP(pcmpgtq),
2938 [0x38] = SSE41_OP(pminsb),
2939 [0x39] = SSE41_OP(pminsd),
2940 [0x3a] = SSE41_OP(pminuw),
2941 [0x3b] = SSE41_OP(pminud),
2942 [0x3c] = SSE41_OP(pmaxsb),
2943 [0x3d] = SSE41_OP(pmaxsd),
2944 [0x3e] = SSE41_OP(pmaxuw),
2945 [0x3f] = SSE41_OP(pmaxud),
2946 [0x40] = SSE41_OP(pmulld),
2947 [0x41] = SSE41_OP(phminposuw),
2948 [0xdb] = AESNI_OP(aesimc),
2949 [0xdc] = AESNI_OP(aesenc),
2950 [0xdd] = AESNI_OP(aesenclast),
2951 [0xde] = AESNI_OP(aesdec),
2952 [0xdf] = AESNI_OP(aesdeclast),
2955 static const struct SSEOpHelper_eppi sse_op_table7[256] = {
2956 [0x08] = SSE41_OP(roundps),
2957 [0x09] = SSE41_OP(roundpd),
2958 [0x0a] = SSE41_OP(roundss),
2959 [0x0b] = SSE41_OP(roundsd),
2960 [0x0c] = SSE41_OP(blendps),
2961 [0x0d] = SSE41_OP(blendpd),
2962 [0x0e] = SSE41_OP(pblendw),
2963 [0x0f] = SSSE3_OP(palignr),
2964 [0x14] = SSE41_SPECIAL, /* pextrb */
2965 [0x15] = SSE41_SPECIAL, /* pextrw */
2966 [0x16] = SSE41_SPECIAL, /* pextrd/pextrq */
2967 [0x17] = SSE41_SPECIAL, /* extractps */
2968 [0x20] = SSE41_SPECIAL, /* pinsrb */
2969 [0x21] = SSE41_SPECIAL, /* insertps */
2970 [0x22] = SSE41_SPECIAL, /* pinsrd/pinsrq */
2971 [0x40] = SSE41_OP(dpps),
2972 [0x41] = SSE41_OP(dppd),
2973 [0x42] = SSE41_OP(mpsadbw),
2974 [0x44] = PCLMULQDQ_OP(pclmulqdq),
2975 [0x60] = SSE42_OP(pcmpestrm),
2976 [0x61] = SSE42_OP(pcmpestri),
2977 [0x62] = SSE42_OP(pcmpistrm),
2978 [0x63] = SSE42_OP(pcmpistri),
2979 [0xdf] = AESNI_OP(aeskeygenassist),
2982 static void gen_sse(CPUX86State *env, DisasContext *s, int b,
2983 target_ulong pc_start, int rex_r)
2985 int b1, op1_offset, op2_offset, is_xmm, val;
2986 int modrm, mod, rm, reg;
2987 SSEFunc_0_epp sse_fn_epp;
2988 SSEFunc_0_eppi sse_fn_eppi;
2989 SSEFunc_0_ppi sse_fn_ppi;
2990 SSEFunc_0_eppt sse_fn_eppt;
2994 if (s->prefix & PREFIX_DATA)
2996 else if (s->prefix & PREFIX_REPZ)
2998 else if (s->prefix & PREFIX_REPNZ)
3002 sse_fn_epp = sse_op_table1[b][b1];
3006 if ((b <= 0x5f && b >= 0x10) || b == 0xc6 || b == 0xc2) {
3016 /* simple MMX/SSE operation */
3017 if (s->flags & HF_TS_MASK) {
3018 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
3021 if (s->flags & HF_EM_MASK) {
3023 gen_illegal_opcode(s);
3027 && !(s->flags & HF_OSFXSR_MASK)
3028 && ((b != 0x38 && b != 0x3a) || (s->prefix & PREFIX_DATA))) {
3032 if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) {
3033 /* If we were fully decoding this we might use illegal_op. */
3037 gen_helper_emms(cpu_env);
3042 gen_helper_emms(cpu_env);
3045 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3046 the static cpu state) */
3048 gen_helper_enter_mmx(cpu_env);
3051 modrm = cpu_ldub_code(env, s->pc++);
3052 reg = ((modrm >> 3) & 7);
3055 mod = (modrm >> 6) & 3;
3056 if (sse_fn_epp == SSE_SPECIAL) {
3059 case 0x0e7: /* movntq */
3063 gen_lea_modrm(env, s, modrm);
3064 gen_stq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
3066 case 0x1e7: /* movntdq */
3067 case 0x02b: /* movntps */
3068 case 0x12b: /* movntps */
3071 gen_lea_modrm(env, s, modrm);
3072 gen_sto_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3074 case 0x3f0: /* lddqu */
3077 gen_lea_modrm(env, s, modrm);
3078 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3080 case 0x22b: /* movntss */
3081 case 0x32b: /* movntsd */
3084 gen_lea_modrm(env, s, modrm);
3086 gen_stq_env_A0(s, offsetof(CPUX86State,
3087 xmm_regs[reg].ZMM_Q(0)));
3089 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
3090 xmm_regs[reg].ZMM_L(0)));
3091 gen_op_st_v(s, MO_32, cpu_T0, cpu_A0);
3094 case 0x6e: /* movd mm, ea */
3095 #ifdef TARGET_X86_64
3096 if (s->dflag == MO_64) {
3097 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 0);
3098 tcg_gen_st_tl(cpu_T0, cpu_env, offsetof(CPUX86State,fpregs[reg].mmx));
3102 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 0);
3103 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3104 offsetof(CPUX86State,fpregs[reg].mmx));
3105 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
3106 gen_helper_movl_mm_T0_mmx(cpu_ptr0, cpu_tmp2_i32);
3109 case 0x16e: /* movd xmm, ea */
3110 #ifdef TARGET_X86_64
3111 if (s->dflag == MO_64) {
3112 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 0);
3113 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3114 offsetof(CPUX86State,xmm_regs[reg]));
3115 gen_helper_movq_mm_T0_xmm(cpu_ptr0, cpu_T0);
3119 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 0);
3120 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3121 offsetof(CPUX86State,xmm_regs[reg]));
3122 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
3123 gen_helper_movl_mm_T0_xmm(cpu_ptr0, cpu_tmp2_i32);
3126 case 0x6f: /* movq mm, ea */
3128 gen_lea_modrm(env, s, modrm);
3129 gen_ldq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
3132 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
3133 offsetof(CPUX86State,fpregs[rm].mmx));
3134 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
3135 offsetof(CPUX86State,fpregs[reg].mmx));
3138 case 0x010: /* movups */
3139 case 0x110: /* movupd */
3140 case 0x028: /* movaps */
3141 case 0x128: /* movapd */
3142 case 0x16f: /* movdqa xmm, ea */
3143 case 0x26f: /* movdqu xmm, ea */
3145 gen_lea_modrm(env, s, modrm);
3146 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3148 rm = (modrm & 7) | REX_B(s);
3149 gen_op_movo(offsetof(CPUX86State,xmm_regs[reg]),
3150 offsetof(CPUX86State,xmm_regs[rm]));
3153 case 0x210: /* movss xmm, ea */
3155 gen_lea_modrm(env, s, modrm);
3156 gen_op_ld_v(s, MO_32, cpu_T0, cpu_A0);
3157 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3158 tcg_gen_movi_tl(cpu_T0, 0);
3159 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)));
3160 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)));
3161 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)));
3163 rm = (modrm & 7) | REX_B(s);
3164 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)),
3165 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0)));
3168 case 0x310: /* movsd xmm, ea */
3170 gen_lea_modrm(env, s, modrm);
3171 gen_ldq_env_A0(s, offsetof(CPUX86State,
3172 xmm_regs[reg].ZMM_Q(0)));
3173 tcg_gen_movi_tl(cpu_T0, 0);
3174 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)));
3175 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)));
3177 rm = (modrm & 7) | REX_B(s);
3178 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3179 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3182 case 0x012: /* movlps */
3183 case 0x112: /* movlpd */
3185 gen_lea_modrm(env, s, modrm);
3186 gen_ldq_env_A0(s, offsetof(CPUX86State,
3187 xmm_regs[reg].ZMM_Q(0)));
3190 rm = (modrm & 7) | REX_B(s);
3191 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3192 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(1)));
3195 case 0x212: /* movsldup */
3197 gen_lea_modrm(env, s, modrm);
3198 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3200 rm = (modrm & 7) | REX_B(s);
3201 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)),
3202 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0)));
3203 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)),
3204 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(2)));
3206 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)),
3207 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3208 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)),
3209 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)));
3211 case 0x312: /* movddup */
3213 gen_lea_modrm(env, s, modrm);
3214 gen_ldq_env_A0(s, offsetof(CPUX86State,
3215 xmm_regs[reg].ZMM_Q(0)));
3217 rm = (modrm & 7) | REX_B(s);
3218 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3219 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3221 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)),
3222 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3224 case 0x016: /* movhps */
3225 case 0x116: /* movhpd */
3227 gen_lea_modrm(env, s, modrm);
3228 gen_ldq_env_A0(s, offsetof(CPUX86State,
3229 xmm_regs[reg].ZMM_Q(1)));
3232 rm = (modrm & 7) | REX_B(s);
3233 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)),
3234 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3237 case 0x216: /* movshdup */
3239 gen_lea_modrm(env, s, modrm);
3240 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3242 rm = (modrm & 7) | REX_B(s);
3243 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)),
3244 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(1)));
3245 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)),
3246 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(3)));
3248 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)),
3249 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)));
3250 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)),
3251 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)));
3256 int bit_index, field_length;
3258 if (b1 == 1 && reg != 0)
3260 field_length = cpu_ldub_code(env, s->pc++) & 0x3F;
3261 bit_index = cpu_ldub_code(env, s->pc++) & 0x3F;
3262 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3263 offsetof(CPUX86State,xmm_regs[reg]));
3265 gen_helper_extrq_i(cpu_env, cpu_ptr0,
3266 tcg_const_i32(bit_index),
3267 tcg_const_i32(field_length));
3269 gen_helper_insertq_i(cpu_env, cpu_ptr0,
3270 tcg_const_i32(bit_index),
3271 tcg_const_i32(field_length));
3274 case 0x7e: /* movd ea, mm */
3275 #ifdef TARGET_X86_64
3276 if (s->dflag == MO_64) {
3277 tcg_gen_ld_i64(cpu_T0, cpu_env,
3278 offsetof(CPUX86State,fpregs[reg].mmx));
3279 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 1);
3283 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
3284 offsetof(CPUX86State,fpregs[reg].mmx.MMX_L(0)));
3285 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 1);
3288 case 0x17e: /* movd ea, xmm */
3289 #ifdef TARGET_X86_64
3290 if (s->dflag == MO_64) {
3291 tcg_gen_ld_i64(cpu_T0, cpu_env,
3292 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3293 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 1);
3297 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
3298 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3299 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 1);
3302 case 0x27e: /* movq xmm, ea */
3304 gen_lea_modrm(env, s, modrm);
3305 gen_ldq_env_A0(s, offsetof(CPUX86State,
3306 xmm_regs[reg].ZMM_Q(0)));
3308 rm = (modrm & 7) | REX_B(s);
3309 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3310 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3312 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)));
3314 case 0x7f: /* movq ea, mm */
3316 gen_lea_modrm(env, s, modrm);
3317 gen_stq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
3320 gen_op_movq(offsetof(CPUX86State,fpregs[rm].mmx),
3321 offsetof(CPUX86State,fpregs[reg].mmx));
3324 case 0x011: /* movups */
3325 case 0x111: /* movupd */
3326 case 0x029: /* movaps */
3327 case 0x129: /* movapd */
3328 case 0x17f: /* movdqa ea, xmm */
3329 case 0x27f: /* movdqu ea, xmm */
3331 gen_lea_modrm(env, s, modrm);
3332 gen_sto_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3334 rm = (modrm & 7) | REX_B(s);
3335 gen_op_movo(offsetof(CPUX86State,xmm_regs[rm]),
3336 offsetof(CPUX86State,xmm_regs[reg]));
3339 case 0x211: /* movss ea, xmm */
3341 gen_lea_modrm(env, s, modrm);
3342 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3343 gen_op_st_v(s, MO_32, cpu_T0, cpu_A0);
3345 rm = (modrm & 7) | REX_B(s);
3346 gen_op_movl(offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0)),
3347 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3350 case 0x311: /* movsd ea, xmm */
3352 gen_lea_modrm(env, s, modrm);
3353 gen_stq_env_A0(s, offsetof(CPUX86State,
3354 xmm_regs[reg].ZMM_Q(0)));
3356 rm = (modrm & 7) | REX_B(s);
3357 gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)),
3358 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3361 case 0x013: /* movlps */
3362 case 0x113: /* movlpd */
3364 gen_lea_modrm(env, s, modrm);
3365 gen_stq_env_A0(s, offsetof(CPUX86State,
3366 xmm_regs[reg].ZMM_Q(0)));
3371 case 0x017: /* movhps */
3372 case 0x117: /* movhpd */
3374 gen_lea_modrm(env, s, modrm);
3375 gen_stq_env_A0(s, offsetof(CPUX86State,
3376 xmm_regs[reg].ZMM_Q(1)));
3381 case 0x71: /* shift mm, im */
3384 case 0x171: /* shift xmm, im */
3390 val = cpu_ldub_code(env, s->pc++);
3392 tcg_gen_movi_tl(cpu_T0, val);
3393 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(0)));
3394 tcg_gen_movi_tl(cpu_T0, 0);
3395 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(1)));
3396 op1_offset = offsetof(CPUX86State,xmm_t0);
3398 tcg_gen_movi_tl(cpu_T0, val);
3399 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(0)));
3400 tcg_gen_movi_tl(cpu_T0, 0);
3401 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(1)));
3402 op1_offset = offsetof(CPUX86State,mmx_t0);
3404 sse_fn_epp = sse_op_table2[((b - 1) & 3) * 8 +
3405 (((modrm >> 3)) & 7)][b1];
3410 rm = (modrm & 7) | REX_B(s);
3411 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3414 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3416 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
3417 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op1_offset);
3418 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
3420 case 0x050: /* movmskps */
3421 rm = (modrm & 7) | REX_B(s);
3422 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3423 offsetof(CPUX86State,xmm_regs[rm]));
3424 gen_helper_movmskps(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3425 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
3427 case 0x150: /* movmskpd */
3428 rm = (modrm & 7) | REX_B(s);
3429 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3430 offsetof(CPUX86State,xmm_regs[rm]));
3431 gen_helper_movmskpd(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3432 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
3434 case 0x02a: /* cvtpi2ps */
3435 case 0x12a: /* cvtpi2pd */
3436 gen_helper_enter_mmx(cpu_env);
3438 gen_lea_modrm(env, s, modrm);
3439 op2_offset = offsetof(CPUX86State,mmx_t0);
3440 gen_ldq_env_A0(s, op2_offset);
3443 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3445 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3446 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3447 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3450 gen_helper_cvtpi2ps(cpu_env, cpu_ptr0, cpu_ptr1);
3454 gen_helper_cvtpi2pd(cpu_env, cpu_ptr0, cpu_ptr1);
3458 case 0x22a: /* cvtsi2ss */
3459 case 0x32a: /* cvtsi2sd */
3460 ot = mo_64_32(s->dflag);
3461 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3462 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3463 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3465 SSEFunc_0_epi sse_fn_epi = sse_op_table3ai[(b >> 8) & 1];
3466 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
3467 sse_fn_epi(cpu_env, cpu_ptr0, cpu_tmp2_i32);
3469 #ifdef TARGET_X86_64
3470 SSEFunc_0_epl sse_fn_epl = sse_op_table3aq[(b >> 8) & 1];
3471 sse_fn_epl(cpu_env, cpu_ptr0, cpu_T0);
3477 case 0x02c: /* cvttps2pi */
3478 case 0x12c: /* cvttpd2pi */
3479 case 0x02d: /* cvtps2pi */
3480 case 0x12d: /* cvtpd2pi */
3481 gen_helper_enter_mmx(cpu_env);
3483 gen_lea_modrm(env, s, modrm);
3484 op2_offset = offsetof(CPUX86State,xmm_t0);
3485 gen_ldo_env_A0(s, op2_offset);
3487 rm = (modrm & 7) | REX_B(s);
3488 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3490 op1_offset = offsetof(CPUX86State,fpregs[reg & 7].mmx);
3491 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3492 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3495 gen_helper_cvttps2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3498 gen_helper_cvttpd2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3501 gen_helper_cvtps2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3504 gen_helper_cvtpd2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3508 case 0x22c: /* cvttss2si */
3509 case 0x32c: /* cvttsd2si */
3510 case 0x22d: /* cvtss2si */
3511 case 0x32d: /* cvtsd2si */
3512 ot = mo_64_32(s->dflag);
3514 gen_lea_modrm(env, s, modrm);
3516 gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_Q(0)));
3518 gen_op_ld_v(s, MO_32, cpu_T0, cpu_A0);
3519 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(0)));
3521 op2_offset = offsetof(CPUX86State,xmm_t0);
3523 rm = (modrm & 7) | REX_B(s);
3524 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3526 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
3528 SSEFunc_i_ep sse_fn_i_ep =
3529 sse_op_table3bi[((b >> 7) & 2) | (b & 1)];
3530 sse_fn_i_ep(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3531 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
3533 #ifdef TARGET_X86_64
3534 SSEFunc_l_ep sse_fn_l_ep =
3535 sse_op_table3bq[((b >> 7) & 2) | (b & 1)];
3536 sse_fn_l_ep(cpu_T0, cpu_env, cpu_ptr0);
3541 gen_op_mov_reg_v(ot, reg, cpu_T0);
3543 case 0xc4: /* pinsrw */
3546 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
3547 val = cpu_ldub_code(env, s->pc++);
3550 tcg_gen_st16_tl(cpu_T0, cpu_env,
3551 offsetof(CPUX86State,xmm_regs[reg].ZMM_W(val)));
3554 tcg_gen_st16_tl(cpu_T0, cpu_env,
3555 offsetof(CPUX86State,fpregs[reg].mmx.MMX_W(val)));
3558 case 0xc5: /* pextrw */
3562 ot = mo_64_32(s->dflag);
3563 val = cpu_ldub_code(env, s->pc++);
3566 rm = (modrm & 7) | REX_B(s);
3567 tcg_gen_ld16u_tl(cpu_T0, cpu_env,
3568 offsetof(CPUX86State,xmm_regs[rm].ZMM_W(val)));
3572 tcg_gen_ld16u_tl(cpu_T0, cpu_env,
3573 offsetof(CPUX86State,fpregs[rm].mmx.MMX_W(val)));
3575 reg = ((modrm >> 3) & 7) | rex_r;
3576 gen_op_mov_reg_v(ot, reg, cpu_T0);
3578 case 0x1d6: /* movq ea, xmm */
3580 gen_lea_modrm(env, s, modrm);
3581 gen_stq_env_A0(s, offsetof(CPUX86State,
3582 xmm_regs[reg].ZMM_Q(0)));
3584 rm = (modrm & 7) | REX_B(s);
3585 gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)),
3586 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3587 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(1)));
3590 case 0x2d6: /* movq2dq */
3591 gen_helper_enter_mmx(cpu_env);
3593 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3594 offsetof(CPUX86State,fpregs[rm].mmx));
3595 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)));
3597 case 0x3d6: /* movdq2q */
3598 gen_helper_enter_mmx(cpu_env);
3599 rm = (modrm & 7) | REX_B(s);
3600 gen_op_movq(offsetof(CPUX86State,fpregs[reg & 7].mmx),
3601 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3603 case 0xd7: /* pmovmskb */
3608 rm = (modrm & 7) | REX_B(s);
3609 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[rm]));
3610 gen_helper_pmovmskb_xmm(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3613 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,fpregs[rm].mmx));
3614 gen_helper_pmovmskb_mmx(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3616 reg = ((modrm >> 3) & 7) | rex_r;
3617 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
3623 if ((b & 0xf0) == 0xf0) {
3626 modrm = cpu_ldub_code(env, s->pc++);
3628 reg = ((modrm >> 3) & 7) | rex_r;
3629 mod = (modrm >> 6) & 3;
3634 sse_fn_epp = sse_op_table6[b].op[b1];
3638 if (!(s->cpuid_ext_features & sse_op_table6[b].ext_mask))
3642 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3644 op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
3646 op2_offset = offsetof(CPUX86State,xmm_t0);
3647 gen_lea_modrm(env, s, modrm);
3649 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3650 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3651 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3652 gen_ldq_env_A0(s, op2_offset +
3653 offsetof(ZMMReg, ZMM_Q(0)));
3655 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3656 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3657 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
3658 s->mem_index, MO_LEUL);
3659 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, op2_offset +
3660 offsetof(ZMMReg, ZMM_L(0)));
3662 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3663 tcg_gen_qemu_ld_tl(cpu_tmp0, cpu_A0,
3664 s->mem_index, MO_LEUW);
3665 tcg_gen_st16_tl(cpu_tmp0, cpu_env, op2_offset +
3666 offsetof(ZMMReg, ZMM_W(0)));
3668 case 0x2a: /* movntqda */
3669 gen_ldo_env_A0(s, op1_offset);
3672 gen_ldo_env_A0(s, op2_offset);
3676 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
3678 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3680 op2_offset = offsetof(CPUX86State,mmx_t0);
3681 gen_lea_modrm(env, s, modrm);
3682 gen_ldq_env_A0(s, op2_offset);
3685 if (sse_fn_epp == SSE_SPECIAL) {
3689 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3690 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3691 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
3694 set_cc_op(s, CC_OP_EFLAGS);
3701 /* Various integer extensions at 0f 38 f[0-f]. */
3702 b = modrm | (b1 << 8);
3703 modrm = cpu_ldub_code(env, s->pc++);
3704 reg = ((modrm >> 3) & 7) | rex_r;
3707 case 0x3f0: /* crc32 Gd,Eb */
3708 case 0x3f1: /* crc32 Gd,Ey */
3710 if (!(s->cpuid_ext_features & CPUID_EXT_SSE42)) {
3713 if ((b & 0xff) == 0xf0) {
3715 } else if (s->dflag != MO_64) {
3716 ot = (s->prefix & PREFIX_DATA ? MO_16 : MO_32);
3721 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[reg]);
3722 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3723 gen_helper_crc32(cpu_T0, cpu_tmp2_i32,
3724 cpu_T0, tcg_const_i32(8 << ot));
3726 ot = mo_64_32(s->dflag);
3727 gen_op_mov_reg_v(ot, reg, cpu_T0);
3730 case 0x1f0: /* crc32 or movbe */
3732 /* For these insns, the f3 prefix is supposed to have priority
3733 over the 66 prefix, but that's not what we implement above
3735 if (s->prefix & PREFIX_REPNZ) {
3739 case 0x0f0: /* movbe Gy,My */
3740 case 0x0f1: /* movbe My,Gy */
3741 if (!(s->cpuid_ext_features & CPUID_EXT_MOVBE)) {
3744 if (s->dflag != MO_64) {
3745 ot = (s->prefix & PREFIX_DATA ? MO_16 : MO_32);
3750 gen_lea_modrm(env, s, modrm);
3752 tcg_gen_qemu_ld_tl(cpu_T0, cpu_A0,
3753 s->mem_index, ot | MO_BE);
3754 gen_op_mov_reg_v(ot, reg, cpu_T0);
3756 tcg_gen_qemu_st_tl(cpu_regs[reg], cpu_A0,
3757 s->mem_index, ot | MO_BE);
3761 case 0x0f2: /* andn Gy, By, Ey */
3762 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
3763 || !(s->prefix & PREFIX_VEX)
3767 ot = mo_64_32(s->dflag);
3768 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3769 tcg_gen_andc_tl(cpu_T0, cpu_regs[s->vex_v], cpu_T0);
3770 gen_op_mov_reg_v(ot, reg, cpu_T0);
3771 gen_op_update1_cc();
3772 set_cc_op(s, CC_OP_LOGICB + ot);
3775 case 0x0f7: /* bextr Gy, Ey, By */
3776 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
3777 || !(s->prefix & PREFIX_VEX)
3781 ot = mo_64_32(s->dflag);
3785 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3786 /* Extract START, and shift the operand.
3787 Shifts larger than operand size get zeros. */
3788 tcg_gen_ext8u_tl(cpu_A0, cpu_regs[s->vex_v]);
3789 tcg_gen_shr_tl(cpu_T0, cpu_T0, cpu_A0);
3791 bound = tcg_const_tl(ot == MO_64 ? 63 : 31);
3792 zero = tcg_const_tl(0);
3793 tcg_gen_movcond_tl(TCG_COND_LEU, cpu_T0, cpu_A0, bound,
3795 tcg_temp_free(zero);
3797 /* Extract the LEN into a mask. Lengths larger than
3798 operand size get all ones. */
3799 tcg_gen_extract_tl(cpu_A0, cpu_regs[s->vex_v], 8, 8);
3800 tcg_gen_movcond_tl(TCG_COND_LEU, cpu_A0, cpu_A0, bound,
3802 tcg_temp_free(bound);
3803 tcg_gen_movi_tl(cpu_T1, 1);
3804 tcg_gen_shl_tl(cpu_T1, cpu_T1, cpu_A0);
3805 tcg_gen_subi_tl(cpu_T1, cpu_T1, 1);
3806 tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1);
3808 gen_op_mov_reg_v(ot, reg, cpu_T0);
3809 gen_op_update1_cc();
3810 set_cc_op(s, CC_OP_LOGICB + ot);
3814 case 0x0f5: /* bzhi Gy, Ey, By */
3815 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3816 || !(s->prefix & PREFIX_VEX)
3820 ot = mo_64_32(s->dflag);
3821 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3822 tcg_gen_ext8u_tl(cpu_T1, cpu_regs[s->vex_v]);
3824 TCGv bound = tcg_const_tl(ot == MO_64 ? 63 : 31);
3825 /* Note that since we're using BMILG (in order to get O
3826 cleared) we need to store the inverse into C. */
3827 tcg_gen_setcond_tl(TCG_COND_LT, cpu_cc_src,
3829 tcg_gen_movcond_tl(TCG_COND_GT, cpu_T1, cpu_T1,
3830 bound, bound, cpu_T1);
3831 tcg_temp_free(bound);
3833 tcg_gen_movi_tl(cpu_A0, -1);
3834 tcg_gen_shl_tl(cpu_A0, cpu_A0, cpu_T1);
3835 tcg_gen_andc_tl(cpu_T0, cpu_T0, cpu_A0);
3836 gen_op_mov_reg_v(ot, reg, cpu_T0);
3837 gen_op_update1_cc();
3838 set_cc_op(s, CC_OP_BMILGB + ot);
3841 case 0x3f6: /* mulx By, Gy, rdx, Ey */
3842 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3843 || !(s->prefix & PREFIX_VEX)
3847 ot = mo_64_32(s->dflag);
3848 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3851 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
3852 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_regs[R_EDX]);
3853 tcg_gen_mulu2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
3854 cpu_tmp2_i32, cpu_tmp3_i32);
3855 tcg_gen_extu_i32_tl(cpu_regs[s->vex_v], cpu_tmp2_i32);
3856 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp3_i32);
3858 #ifdef TARGET_X86_64
3860 tcg_gen_mulu2_i64(cpu_T0, cpu_T1,
3861 cpu_T0, cpu_regs[R_EDX]);
3862 tcg_gen_mov_i64(cpu_regs[s->vex_v], cpu_T0);
3863 tcg_gen_mov_i64(cpu_regs[reg], cpu_T1);
3869 case 0x3f5: /* pdep Gy, By, Ey */
3870 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3871 || !(s->prefix & PREFIX_VEX)
3875 ot = mo_64_32(s->dflag);
3876 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3877 /* Note that by zero-extending the mask operand, we
3878 automatically handle zero-extending the result. */
3880 tcg_gen_mov_tl(cpu_T1, cpu_regs[s->vex_v]);
3882 tcg_gen_ext32u_tl(cpu_T1, cpu_regs[s->vex_v]);
3884 gen_helper_pdep(cpu_regs[reg], cpu_T0, cpu_T1);
3887 case 0x2f5: /* pext Gy, By, Ey */
3888 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3889 || !(s->prefix & PREFIX_VEX)
3893 ot = mo_64_32(s->dflag);
3894 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3895 /* Note that by zero-extending the mask operand, we
3896 automatically handle zero-extending the result. */
3898 tcg_gen_mov_tl(cpu_T1, cpu_regs[s->vex_v]);
3900 tcg_gen_ext32u_tl(cpu_T1, cpu_regs[s->vex_v]);
3902 gen_helper_pext(cpu_regs[reg], cpu_T0, cpu_T1);
3905 case 0x1f6: /* adcx Gy, Ey */
3906 case 0x2f6: /* adox Gy, Ey */
3907 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_ADX)) {
3910 TCGv carry_in, carry_out, zero;
3913 ot = mo_64_32(s->dflag);
3914 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3916 /* Re-use the carry-out from a previous round. */
3917 TCGV_UNUSED(carry_in);
3918 carry_out = (b == 0x1f6 ? cpu_cc_dst : cpu_cc_src2);
3922 carry_in = cpu_cc_dst;
3923 end_op = CC_OP_ADCX;
3925 end_op = CC_OP_ADCOX;
3930 end_op = CC_OP_ADCOX;
3932 carry_in = cpu_cc_src2;
3933 end_op = CC_OP_ADOX;
3937 end_op = CC_OP_ADCOX;
3938 carry_in = carry_out;
3941 end_op = (b == 0x1f6 ? CC_OP_ADCX : CC_OP_ADOX);
3944 /* If we can't reuse carry-out, get it out of EFLAGS. */
3945 if (TCGV_IS_UNUSED(carry_in)) {
3946 if (s->cc_op != CC_OP_ADCX && s->cc_op != CC_OP_ADOX) {
3947 gen_compute_eflags(s);
3949 carry_in = cpu_tmp0;
3950 tcg_gen_extract_tl(carry_in, cpu_cc_src,
3951 ctz32(b == 0x1f6 ? CC_C : CC_O), 1);
3955 #ifdef TARGET_X86_64
3957 /* If we know TL is 64-bit, and we want a 32-bit
3958 result, just do everything in 64-bit arithmetic. */
3959 tcg_gen_ext32u_i64(cpu_regs[reg], cpu_regs[reg]);
3960 tcg_gen_ext32u_i64(cpu_T0, cpu_T0);
3961 tcg_gen_add_i64(cpu_T0, cpu_T0, cpu_regs[reg]);
3962 tcg_gen_add_i64(cpu_T0, cpu_T0, carry_in);
3963 tcg_gen_ext32u_i64(cpu_regs[reg], cpu_T0);
3964 tcg_gen_shri_i64(carry_out, cpu_T0, 32);
3968 /* Otherwise compute the carry-out in two steps. */
3969 zero = tcg_const_tl(0);
3970 tcg_gen_add2_tl(cpu_T0, carry_out,
3973 tcg_gen_add2_tl(cpu_regs[reg], carry_out,
3974 cpu_regs[reg], carry_out,
3976 tcg_temp_free(zero);
3979 set_cc_op(s, end_op);
3983 case 0x1f7: /* shlx Gy, Ey, By */
3984 case 0x2f7: /* sarx Gy, Ey, By */
3985 case 0x3f7: /* shrx Gy, Ey, By */
3986 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3987 || !(s->prefix & PREFIX_VEX)
3991 ot = mo_64_32(s->dflag);
3992 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3994 tcg_gen_andi_tl(cpu_T1, cpu_regs[s->vex_v], 63);
3996 tcg_gen_andi_tl(cpu_T1, cpu_regs[s->vex_v], 31);
3999 tcg_gen_shl_tl(cpu_T0, cpu_T0, cpu_T1);
4000 } else if (b == 0x2f7) {
4002 tcg_gen_ext32s_tl(cpu_T0, cpu_T0);
4004 tcg_gen_sar_tl(cpu_T0, cpu_T0, cpu_T1);
4007 tcg_gen_ext32u_tl(cpu_T0, cpu_T0);
4009 tcg_gen_shr_tl(cpu_T0, cpu_T0, cpu_T1);
4011 gen_op_mov_reg_v(ot, reg, cpu_T0);
4017 case 0x3f3: /* Group 17 */
4018 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
4019 || !(s->prefix & PREFIX_VEX)
4023 ot = mo_64_32(s->dflag);
4024 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4027 case 1: /* blsr By,Ey */
4028 tcg_gen_neg_tl(cpu_T1, cpu_T0);
4029 tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1);
4030 gen_op_mov_reg_v(ot, s->vex_v, cpu_T0);
4031 gen_op_update2_cc();
4032 set_cc_op(s, CC_OP_BMILGB + ot);
4035 case 2: /* blsmsk By,Ey */
4036 tcg_gen_mov_tl(cpu_cc_src, cpu_T0);
4037 tcg_gen_subi_tl(cpu_T0, cpu_T0, 1);
4038 tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_cc_src);
4039 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4040 set_cc_op(s, CC_OP_BMILGB + ot);
4043 case 3: /* blsi By, Ey */
4044 tcg_gen_mov_tl(cpu_cc_src, cpu_T0);
4045 tcg_gen_subi_tl(cpu_T0, cpu_T0, 1);
4046 tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_cc_src);
4047 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4048 set_cc_op(s, CC_OP_BMILGB + ot);
4064 modrm = cpu_ldub_code(env, s->pc++);
4066 reg = ((modrm >> 3) & 7) | rex_r;
4067 mod = (modrm >> 6) & 3;
4072 sse_fn_eppi = sse_op_table7[b].op[b1];
4076 if (!(s->cpuid_ext_features & sse_op_table7[b].ext_mask))
4079 if (sse_fn_eppi == SSE_SPECIAL) {
4080 ot = mo_64_32(s->dflag);
4081 rm = (modrm & 7) | REX_B(s);
4084 gen_lea_modrm(env, s, modrm);
4085 reg = ((modrm >> 3) & 7) | rex_r;
4086 val = cpu_ldub_code(env, s->pc++);
4088 case 0x14: /* pextrb */
4089 tcg_gen_ld8u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
4090 xmm_regs[reg].ZMM_B(val & 15)));
4092 gen_op_mov_reg_v(ot, rm, cpu_T0);
4094 tcg_gen_qemu_st_tl(cpu_T0, cpu_A0,
4095 s->mem_index, MO_UB);
4098 case 0x15: /* pextrw */
4099 tcg_gen_ld16u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
4100 xmm_regs[reg].ZMM_W(val & 7)));
4102 gen_op_mov_reg_v(ot, rm, cpu_T0);
4104 tcg_gen_qemu_st_tl(cpu_T0, cpu_A0,
4105 s->mem_index, MO_LEUW);
4109 if (ot == MO_32) { /* pextrd */
4110 tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
4111 offsetof(CPUX86State,
4112 xmm_regs[reg].ZMM_L(val & 3)));
4114 tcg_gen_extu_i32_tl(cpu_regs[rm], cpu_tmp2_i32);
4116 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
4117 s->mem_index, MO_LEUL);
4119 } else { /* pextrq */
4120 #ifdef TARGET_X86_64
4121 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
4122 offsetof(CPUX86State,
4123 xmm_regs[reg].ZMM_Q(val & 1)));
4125 tcg_gen_mov_i64(cpu_regs[rm], cpu_tmp1_i64);
4127 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0,
4128 s->mem_index, MO_LEQ);
4135 case 0x17: /* extractps */
4136 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
4137 xmm_regs[reg].ZMM_L(val & 3)));
4139 gen_op_mov_reg_v(ot, rm, cpu_T0);
4141 tcg_gen_qemu_st_tl(cpu_T0, cpu_A0,
4142 s->mem_index, MO_LEUL);
4145 case 0x20: /* pinsrb */
4147 gen_op_mov_v_reg(MO_32, cpu_T0, rm);
4149 tcg_gen_qemu_ld_tl(cpu_T0, cpu_A0,
4150 s->mem_index, MO_UB);
4152 tcg_gen_st8_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
4153 xmm_regs[reg].ZMM_B(val & 15)));
4155 case 0x21: /* insertps */
4157 tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
4158 offsetof(CPUX86State,xmm_regs[rm]
4159 .ZMM_L((val >> 6) & 3)));
4161 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
4162 s->mem_index, MO_LEUL);
4164 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
4165 offsetof(CPUX86State,xmm_regs[reg]
4166 .ZMM_L((val >> 4) & 3)));
4168 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4169 cpu_env, offsetof(CPUX86State,
4170 xmm_regs[reg].ZMM_L(0)));
4172 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4173 cpu_env, offsetof(CPUX86State,
4174 xmm_regs[reg].ZMM_L(1)));
4176 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4177 cpu_env, offsetof(CPUX86State,
4178 xmm_regs[reg].ZMM_L(2)));
4180 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4181 cpu_env, offsetof(CPUX86State,
4182 xmm_regs[reg].ZMM_L(3)));
4185 if (ot == MO_32) { /* pinsrd */
4187 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[rm]);
4189 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
4190 s->mem_index, MO_LEUL);
4192 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
4193 offsetof(CPUX86State,
4194 xmm_regs[reg].ZMM_L(val & 3)));
4195 } else { /* pinsrq */
4196 #ifdef TARGET_X86_64
4198 gen_op_mov_v_reg(ot, cpu_tmp1_i64, rm);
4200 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0,
4201 s->mem_index, MO_LEQ);
4203 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
4204 offsetof(CPUX86State,
4205 xmm_regs[reg].ZMM_Q(val & 1)));
4216 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
4218 op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
4220 op2_offset = offsetof(CPUX86State,xmm_t0);
4221 gen_lea_modrm(env, s, modrm);
4222 gen_ldo_env_A0(s, op2_offset);
4225 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
4227 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
4229 op2_offset = offsetof(CPUX86State,mmx_t0);
4230 gen_lea_modrm(env, s, modrm);
4231 gen_ldq_env_A0(s, op2_offset);
4234 val = cpu_ldub_code(env, s->pc++);
4236 if ((b & 0xfc) == 0x60) { /* pcmpXstrX */
4237 set_cc_op(s, CC_OP_EFLAGS);
4239 if (s->dflag == MO_64) {
4240 /* The helper must use entire 64-bit gp registers */
4245 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4246 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4247 sse_fn_eppi(cpu_env, cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
4251 /* Various integer extensions at 0f 3a f[0-f]. */
4252 b = modrm | (b1 << 8);
4253 modrm = cpu_ldub_code(env, s->pc++);
4254 reg = ((modrm >> 3) & 7) | rex_r;
4257 case 0x3f0: /* rorx Gy,Ey, Ib */
4258 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
4259 || !(s->prefix & PREFIX_VEX)
4263 ot = mo_64_32(s->dflag);
4264 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4265 b = cpu_ldub_code(env, s->pc++);
4267 tcg_gen_rotri_tl(cpu_T0, cpu_T0, b & 63);
4269 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
4270 tcg_gen_rotri_i32(cpu_tmp2_i32, cpu_tmp2_i32, b & 31);
4271 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
4273 gen_op_mov_reg_v(ot, reg, cpu_T0);
4283 gen_unknown_opcode(env, s);
4287 /* generic MMX or SSE operation */
4289 case 0x70: /* pshufx insn */
4290 case 0xc6: /* pshufx insn */
4291 case 0xc2: /* compare insns */
4298 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
4302 gen_lea_modrm(env, s, modrm);
4303 op2_offset = offsetof(CPUX86State,xmm_t0);
4309 /* Most sse scalar operations. */
4312 } else if (b1 == 3) {
4317 case 0x2e: /* ucomis[sd] */
4318 case 0x2f: /* comis[sd] */
4330 gen_op_ld_v(s, MO_32, cpu_T0, cpu_A0);
4331 tcg_gen_st32_tl(cpu_T0, cpu_env,
4332 offsetof(CPUX86State,xmm_t0.ZMM_L(0)));
4336 gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_D(0)));
4339 /* 128 bit access */
4340 gen_ldo_env_A0(s, op2_offset);
4344 rm = (modrm & 7) | REX_B(s);
4345 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
4348 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
4350 gen_lea_modrm(env, s, modrm);
4351 op2_offset = offsetof(CPUX86State,mmx_t0);
4352 gen_ldq_env_A0(s, op2_offset);
4355 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
4359 case 0x0f: /* 3DNow! data insns */
4360 val = cpu_ldub_code(env, s->pc++);
4361 sse_fn_epp = sse_op_table5[val];
4365 if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) {
4368 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4369 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4370 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4372 case 0x70: /* pshufx insn */
4373 case 0xc6: /* pshufx insn */
4374 val = cpu_ldub_code(env, s->pc++);
4375 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4376 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4377 /* XXX: introduce a new table? */
4378 sse_fn_ppi = (SSEFunc_0_ppi)sse_fn_epp;
4379 sse_fn_ppi(cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
4383 val = cpu_ldub_code(env, s->pc++);
4386 sse_fn_epp = sse_op_table4[val][b1];
4388 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4389 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4390 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4393 /* maskmov : we must prepare A0 */
4396 tcg_gen_mov_tl(cpu_A0, cpu_regs[R_EDI]);
4397 gen_extu(s->aflag, cpu_A0);
4398 gen_add_A0_ds_seg(s);
4400 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4401 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4402 /* XXX: introduce a new table? */
4403 sse_fn_eppt = (SSEFunc_0_eppt)sse_fn_epp;
4404 sse_fn_eppt(cpu_env, cpu_ptr0, cpu_ptr1, cpu_A0);
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);
4412 if (b == 0x2e || b == 0x2f) {
4413 set_cc_op(s, CC_OP_EFLAGS);
4418 /* convert one instruction. s->base.is_jmp is set if the translation must
4419 be stopped. Return the next pc value */
4420 static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
4422 CPUX86State *env = cpu->env_ptr;
4425 TCGMemOp ot, aflag, dflag;
4426 int modrm, reg, rm, mod, op, opreg, val;
4427 target_ulong next_eip, tval;
4429 target_ulong pc_start = s->base.pc_next;
4431 s->pc_start = s->pc = pc_start;
4436 #ifdef TARGET_X86_64
4441 s->rip_offset = 0; /* for relative ip address */
4445 /* x86 has an upper limit of 15 bytes for an instruction. Since we
4446 * do not want to decode and generate IR for an illegal
4447 * instruction, the following check limits the instruction size to
4448 * 25 bytes: 14 prefix + 1 opc + 6 (modrm+sib+ofs) + 4 imm */
4449 if (s->pc - pc_start > 14) {
4452 b = cpu_ldub_code(env, s->pc);
4454 /* Collect prefixes. */
4457 prefixes |= PREFIX_REPZ;
4460 prefixes |= PREFIX_REPNZ;
4463 prefixes |= PREFIX_LOCK;
4484 prefixes |= PREFIX_DATA;
4487 prefixes |= PREFIX_ADR;
4489 #ifdef TARGET_X86_64
4493 rex_w = (b >> 3) & 1;
4494 rex_r = (b & 0x4) << 1;
4495 s->rex_x = (b & 0x2) << 2;
4496 REX_B(s) = (b & 0x1) << 3;
4497 x86_64_hregs = 1; /* select uniform byte register addressing */
4502 case 0xc5: /* 2-byte VEX */
4503 case 0xc4: /* 3-byte VEX */
4504 /* VEX prefixes cannot be used except in 32-bit mode.
4505 Otherwise the instruction is LES or LDS. */
4506 if (s->code32 && !s->vm86) {
4507 static const int pp_prefix[4] = {
4508 0, PREFIX_DATA, PREFIX_REPZ, PREFIX_REPNZ
4510 int vex3, vex2 = cpu_ldub_code(env, s->pc);
4512 if (!CODE64(s) && (vex2 & 0xc0) != 0xc0) {
4513 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4514 otherwise the instruction is LES or LDS. */
4519 /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
4520 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ
4521 | PREFIX_LOCK | PREFIX_DATA)) {
4524 #ifdef TARGET_X86_64
4529 rex_r = (~vex2 >> 4) & 8;
4532 b = cpu_ldub_code(env, s->pc++);
4534 #ifdef TARGET_X86_64
4535 s->rex_x = (~vex2 >> 3) & 8;
4536 s->rex_b = (~vex2 >> 2) & 8;
4538 vex3 = cpu_ldub_code(env, s->pc++);
4539 rex_w = (vex3 >> 7) & 1;
4540 switch (vex2 & 0x1f) {
4541 case 0x01: /* Implied 0f leading opcode bytes. */
4542 b = cpu_ldub_code(env, s->pc++) | 0x100;
4544 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4547 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4550 default: /* Reserved for future use. */
4554 s->vex_v = (~vex3 >> 3) & 0xf;
4555 s->vex_l = (vex3 >> 2) & 1;
4556 prefixes |= pp_prefix[vex3 & 3] | PREFIX_VEX;
4561 /* Post-process prefixes. */
4563 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit
4564 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4565 over 0x66 if both are present. */
4566 dflag = (rex_w > 0 ? MO_64 : prefixes & PREFIX_DATA ? MO_16 : MO_32);
4567 /* In 64-bit mode, 0x67 selects 32-bit addressing. */
4568 aflag = (prefixes & PREFIX_ADR ? MO_32 : MO_64);
4570 /* In 16/32-bit mode, 0x66 selects the opposite data size. */
4571 if (s->code32 ^ ((prefixes & PREFIX_DATA) != 0)) {
4576 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */
4577 if (s->code32 ^ ((prefixes & PREFIX_ADR) != 0)) {
4584 s->prefix = prefixes;
4588 /* now check op code */
4592 /**************************/
4593 /* extended op code */
4594 b = cpu_ldub_code(env, s->pc++) | 0x100;
4597 /**************************/
4612 ot = mo_b_d(b, dflag);
4615 case 0: /* OP Ev, Gv */
4616 modrm = cpu_ldub_code(env, s->pc++);
4617 reg = ((modrm >> 3) & 7) | rex_r;
4618 mod = (modrm >> 6) & 3;
4619 rm = (modrm & 7) | REX_B(s);
4621 gen_lea_modrm(env, s, modrm);
4623 } else if (op == OP_XORL && rm == reg) {
4625 /* xor reg, reg optimisation */
4626 set_cc_op(s, CC_OP_CLR);
4627 tcg_gen_movi_tl(cpu_T0, 0);
4628 gen_op_mov_reg_v(ot, reg, cpu_T0);
4633 gen_op_mov_v_reg(ot, cpu_T1, reg);
4634 gen_op(s, op, ot, opreg);
4636 case 1: /* OP Gv, Ev */
4637 modrm = cpu_ldub_code(env, s->pc++);
4638 mod = (modrm >> 6) & 3;
4639 reg = ((modrm >> 3) & 7) | rex_r;
4640 rm = (modrm & 7) | REX_B(s);
4642 gen_lea_modrm(env, s, modrm);
4643 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
4644 } else if (op == OP_XORL && rm == reg) {
4647 gen_op_mov_v_reg(ot, cpu_T1, rm);
4649 gen_op(s, op, ot, reg);
4651 case 2: /* OP A, Iv */
4652 val = insn_get(env, s, ot);
4653 tcg_gen_movi_tl(cpu_T1, val);
4654 gen_op(s, op, ot, OR_EAX);
4663 case 0x80: /* GRP1 */
4669 ot = mo_b_d(b, dflag);
4671 modrm = cpu_ldub_code(env, s->pc++);
4672 mod = (modrm >> 6) & 3;
4673 rm = (modrm & 7) | REX_B(s);
4674 op = (modrm >> 3) & 7;
4680 s->rip_offset = insn_const_size(ot);
4681 gen_lea_modrm(env, s, modrm);
4692 val = insn_get(env, s, ot);
4695 val = (int8_t)insn_get(env, s, MO_8);
4698 tcg_gen_movi_tl(cpu_T1, val);
4699 gen_op(s, op, ot, opreg);
4703 /**************************/
4704 /* inc, dec, and other misc arith */
4705 case 0x40 ... 0x47: /* inc Gv */
4707 gen_inc(s, ot, OR_EAX + (b & 7), 1);
4709 case 0x48 ... 0x4f: /* dec Gv */
4711 gen_inc(s, ot, OR_EAX + (b & 7), -1);
4713 case 0xf6: /* GRP3 */
4715 ot = mo_b_d(b, dflag);
4717 modrm = cpu_ldub_code(env, s->pc++);
4718 mod = (modrm >> 6) & 3;
4719 rm = (modrm & 7) | REX_B(s);
4720 op = (modrm >> 3) & 7;
4723 s->rip_offset = insn_const_size(ot);
4725 gen_lea_modrm(env, s, modrm);
4726 /* For those below that handle locked memory, don't load here. */
4727 if (!(s->prefix & PREFIX_LOCK)
4729 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
4732 gen_op_mov_v_reg(ot, cpu_T0, rm);
4737 val = insn_get(env, s, ot);
4738 tcg_gen_movi_tl(cpu_T1, val);
4739 gen_op_testl_T0_T1_cc();
4740 set_cc_op(s, CC_OP_LOGICB + ot);
4743 if (s->prefix & PREFIX_LOCK) {
4747 tcg_gen_movi_tl(cpu_T0, ~0);
4748 tcg_gen_atomic_xor_fetch_tl(cpu_T0, cpu_A0, cpu_T0,
4749 s->mem_index, ot | MO_LE);
4751 tcg_gen_not_tl(cpu_T0, cpu_T0);
4753 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
4755 gen_op_mov_reg_v(ot, rm, cpu_T0);
4760 if (s->prefix & PREFIX_LOCK) {
4762 TCGv a0, t0, t1, t2;
4767 a0 = tcg_temp_local_new();
4768 t0 = tcg_temp_local_new();
4769 label1 = gen_new_label();
4771 tcg_gen_mov_tl(a0, cpu_A0);
4772 tcg_gen_mov_tl(t0, cpu_T0);
4774 gen_set_label(label1);
4775 t1 = tcg_temp_new();
4776 t2 = tcg_temp_new();
4777 tcg_gen_mov_tl(t2, t0);
4778 tcg_gen_neg_tl(t1, t0);
4779 tcg_gen_atomic_cmpxchg_tl(t0, a0, t0, t1,
4780 s->mem_index, ot | MO_LE);
4782 tcg_gen_brcond_tl(TCG_COND_NE, t0, t2, label1);
4786 tcg_gen_mov_tl(cpu_T0, t0);
4789 tcg_gen_neg_tl(cpu_T0, cpu_T0);
4791 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
4793 gen_op_mov_reg_v(ot, rm, cpu_T0);
4796 gen_op_update_neg_cc();
4797 set_cc_op(s, CC_OP_SUBB + ot);
4802 gen_op_mov_v_reg(MO_8, cpu_T1, R_EAX);
4803 tcg_gen_ext8u_tl(cpu_T0, cpu_T0);
4804 tcg_gen_ext8u_tl(cpu_T1, cpu_T1);
4805 /* XXX: use 32 bit mul which could be faster */
4806 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
4807 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
4808 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4809 tcg_gen_andi_tl(cpu_cc_src, cpu_T0, 0xff00);
4810 set_cc_op(s, CC_OP_MULB);
4813 gen_op_mov_v_reg(MO_16, cpu_T1, R_EAX);
4814 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
4815 tcg_gen_ext16u_tl(cpu_T1, cpu_T1);
4816 /* XXX: use 32 bit mul which could be faster */
4817 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
4818 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
4819 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4820 tcg_gen_shri_tl(cpu_T0, cpu_T0, 16);
4821 gen_op_mov_reg_v(MO_16, R_EDX, cpu_T0);
4822 tcg_gen_mov_tl(cpu_cc_src, cpu_T0);
4823 set_cc_op(s, CC_OP_MULW);
4827 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
4828 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_regs[R_EAX]);
4829 tcg_gen_mulu2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
4830 cpu_tmp2_i32, cpu_tmp3_i32);
4831 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], cpu_tmp2_i32);
4832 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], cpu_tmp3_i32);
4833 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4834 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]);
4835 set_cc_op(s, CC_OP_MULL);
4837 #ifdef TARGET_X86_64
4839 tcg_gen_mulu2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX],
4840 cpu_T0, cpu_regs[R_EAX]);
4841 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4842 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]);
4843 set_cc_op(s, CC_OP_MULQ);
4851 gen_op_mov_v_reg(MO_8, cpu_T1, R_EAX);
4852 tcg_gen_ext8s_tl(cpu_T0, cpu_T0);
4853 tcg_gen_ext8s_tl(cpu_T1, cpu_T1);
4854 /* XXX: use 32 bit mul which could be faster */
4855 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
4856 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
4857 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4858 tcg_gen_ext8s_tl(cpu_tmp0, cpu_T0);
4859 tcg_gen_sub_tl(cpu_cc_src, cpu_T0, cpu_tmp0);
4860 set_cc_op(s, CC_OP_MULB);
4863 gen_op_mov_v_reg(MO_16, cpu_T1, R_EAX);
4864 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
4865 tcg_gen_ext16s_tl(cpu_T1, cpu_T1);
4866 /* XXX: use 32 bit mul which could be faster */
4867 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
4868 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
4869 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4870 tcg_gen_ext16s_tl(cpu_tmp0, cpu_T0);
4871 tcg_gen_sub_tl(cpu_cc_src, cpu_T0, cpu_tmp0);
4872 tcg_gen_shri_tl(cpu_T0, cpu_T0, 16);
4873 gen_op_mov_reg_v(MO_16, R_EDX, cpu_T0);
4874 set_cc_op(s, CC_OP_MULW);
4878 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
4879 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_regs[R_EAX]);
4880 tcg_gen_muls2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
4881 cpu_tmp2_i32, cpu_tmp3_i32);
4882 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], cpu_tmp2_i32);
4883 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], cpu_tmp3_i32);
4884 tcg_gen_sari_i32(cpu_tmp2_i32, cpu_tmp2_i32, 31);
4885 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4886 tcg_gen_sub_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
4887 tcg_gen_extu_i32_tl(cpu_cc_src, cpu_tmp2_i32);
4888 set_cc_op(s, CC_OP_MULL);
4890 #ifdef TARGET_X86_64
4892 tcg_gen_muls2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX],
4893 cpu_T0, cpu_regs[R_EAX]);
4894 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4895 tcg_gen_sari_tl(cpu_cc_src, cpu_regs[R_EAX], 63);
4896 tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, cpu_regs[R_EDX]);
4897 set_cc_op(s, CC_OP_MULQ);
4905 gen_helper_divb_AL(cpu_env, cpu_T0);
4908 gen_helper_divw_AX(cpu_env, cpu_T0);
4912 gen_helper_divl_EAX(cpu_env, cpu_T0);
4914 #ifdef TARGET_X86_64
4916 gen_helper_divq_EAX(cpu_env, cpu_T0);
4924 gen_helper_idivb_AL(cpu_env, cpu_T0);
4927 gen_helper_idivw_AX(cpu_env, cpu_T0);
4931 gen_helper_idivl_EAX(cpu_env, cpu_T0);
4933 #ifdef TARGET_X86_64
4935 gen_helper_idivq_EAX(cpu_env, cpu_T0);
4945 case 0xfe: /* GRP4 */
4946 case 0xff: /* GRP5 */
4947 ot = mo_b_d(b, dflag);
4949 modrm = cpu_ldub_code(env, s->pc++);
4950 mod = (modrm >> 6) & 3;
4951 rm = (modrm & 7) | REX_B(s);
4952 op = (modrm >> 3) & 7;
4953 if (op >= 2 && b == 0xfe) {
4957 if (op == 2 || op == 4) {
4958 /* operand size for jumps is 64 bit */
4960 } else if (op == 3 || op == 5) {
4961 ot = dflag != MO_16 ? MO_32 + (rex_w == 1) : MO_16;
4962 } else if (op == 6) {
4963 /* default push size is 64 bit */
4964 ot = mo_pushpop(s, dflag);
4968 gen_lea_modrm(env, s, modrm);
4969 if (op >= 2 && op != 3 && op != 5)
4970 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
4972 gen_op_mov_v_reg(ot, cpu_T0, rm);
4976 case 0: /* inc Ev */
4981 gen_inc(s, ot, opreg, 1);
4983 case 1: /* dec Ev */
4988 gen_inc(s, ot, opreg, -1);
4990 case 2: /* call Ev */
4991 /* XXX: optimize if memory (no 'and' is necessary) */
4992 if (dflag == MO_16) {
4993 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
4995 next_eip = s->pc - s->cs_base;
4996 tcg_gen_movi_tl(cpu_T1, next_eip);
4997 gen_push_v(s, cpu_T1);
4998 gen_op_jmp_v(cpu_T0);
5002 case 3: /* lcall Ev */
5003 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
5004 gen_add_A0_im(s, 1 << ot);
5005 gen_op_ld_v(s, MO_16, cpu_T0, cpu_A0);
5007 if (s->pe && !s->vm86) {
5008 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
5009 gen_helper_lcall_protected(cpu_env, cpu_tmp2_i32, cpu_T1,
5010 tcg_const_i32(dflag - 1),
5011 tcg_const_tl(s->pc - s->cs_base));
5013 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
5014 gen_helper_lcall_real(cpu_env, cpu_tmp2_i32, cpu_T1,
5015 tcg_const_i32(dflag - 1),
5016 tcg_const_i32(s->pc - s->cs_base));
5018 tcg_gen_ld_tl(cpu_tmp4, cpu_env, offsetof(CPUX86State, eip));
5019 gen_jr(s, cpu_tmp4);
5021 case 4: /* jmp Ev */
5022 if (dflag == MO_16) {
5023 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
5025 gen_op_jmp_v(cpu_T0);
5029 case 5: /* ljmp Ev */
5030 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
5031 gen_add_A0_im(s, 1 << ot);
5032 gen_op_ld_v(s, MO_16, cpu_T0, cpu_A0);
5034 if (s->pe && !s->vm86) {
5035 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
5036 gen_helper_ljmp_protected(cpu_env, cpu_tmp2_i32, cpu_T1,
5037 tcg_const_tl(s->pc - s->cs_base));
5039 gen_op_movl_seg_T0_vm(R_CS);
5040 gen_op_jmp_v(cpu_T1);
5042 tcg_gen_ld_tl(cpu_tmp4, cpu_env, offsetof(CPUX86State, eip));
5043 gen_jr(s, cpu_tmp4);
5045 case 6: /* push Ev */
5046 gen_push_v(s, cpu_T0);
5053 case 0x84: /* test Ev, Gv */
5055 ot = mo_b_d(b, dflag);
5057 modrm = cpu_ldub_code(env, s->pc++);
5058 reg = ((modrm >> 3) & 7) | rex_r;
5060 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5061 gen_op_mov_v_reg(ot, cpu_T1, reg);
5062 gen_op_testl_T0_T1_cc();
5063 set_cc_op(s, CC_OP_LOGICB + ot);
5066 case 0xa8: /* test eAX, Iv */
5068 ot = mo_b_d(b, dflag);
5069 val = insn_get(env, s, ot);
5071 gen_op_mov_v_reg(ot, cpu_T0, OR_EAX);
5072 tcg_gen_movi_tl(cpu_T1, val);
5073 gen_op_testl_T0_T1_cc();
5074 set_cc_op(s, CC_OP_LOGICB + ot);
5077 case 0x98: /* CWDE/CBW */
5079 #ifdef TARGET_X86_64
5081 gen_op_mov_v_reg(MO_32, cpu_T0, R_EAX);
5082 tcg_gen_ext32s_tl(cpu_T0, cpu_T0);
5083 gen_op_mov_reg_v(MO_64, R_EAX, cpu_T0);
5087 gen_op_mov_v_reg(MO_16, cpu_T0, R_EAX);
5088 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
5089 gen_op_mov_reg_v(MO_32, R_EAX, cpu_T0);
5092 gen_op_mov_v_reg(MO_8, cpu_T0, R_EAX);
5093 tcg_gen_ext8s_tl(cpu_T0, cpu_T0);
5094 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
5100 case 0x99: /* CDQ/CWD */
5102 #ifdef TARGET_X86_64
5104 gen_op_mov_v_reg(MO_64, cpu_T0, R_EAX);
5105 tcg_gen_sari_tl(cpu_T0, cpu_T0, 63);
5106 gen_op_mov_reg_v(MO_64, R_EDX, cpu_T0);
5110 gen_op_mov_v_reg(MO_32, cpu_T0, R_EAX);
5111 tcg_gen_ext32s_tl(cpu_T0, cpu_T0);
5112 tcg_gen_sari_tl(cpu_T0, cpu_T0, 31);
5113 gen_op_mov_reg_v(MO_32, R_EDX, cpu_T0);
5116 gen_op_mov_v_reg(MO_16, cpu_T0, R_EAX);
5117 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
5118 tcg_gen_sari_tl(cpu_T0, cpu_T0, 15);
5119 gen_op_mov_reg_v(MO_16, R_EDX, cpu_T0);
5125 case 0x1af: /* imul Gv, Ev */
5126 case 0x69: /* imul Gv, Ev, I */
5129 modrm = cpu_ldub_code(env, s->pc++);
5130 reg = ((modrm >> 3) & 7) | rex_r;
5132 s->rip_offset = insn_const_size(ot);
5135 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5137 val = insn_get(env, s, ot);
5138 tcg_gen_movi_tl(cpu_T1, val);
5139 } else if (b == 0x6b) {
5140 val = (int8_t)insn_get(env, s, MO_8);
5141 tcg_gen_movi_tl(cpu_T1, val);
5143 gen_op_mov_v_reg(ot, cpu_T1, reg);
5146 #ifdef TARGET_X86_64
5148 tcg_gen_muls2_i64(cpu_regs[reg], cpu_T1, cpu_T0, cpu_T1);
5149 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]);
5150 tcg_gen_sari_tl(cpu_cc_src, cpu_cc_dst, 63);
5151 tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, cpu_T1);
5155 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
5156 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T1);
5157 tcg_gen_muls2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
5158 cpu_tmp2_i32, cpu_tmp3_i32);
5159 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
5160 tcg_gen_sari_i32(cpu_tmp2_i32, cpu_tmp2_i32, 31);
5161 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]);
5162 tcg_gen_sub_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
5163 tcg_gen_extu_i32_tl(cpu_cc_src, cpu_tmp2_i32);
5166 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
5167 tcg_gen_ext16s_tl(cpu_T1, cpu_T1);
5168 /* XXX: use 32 bit mul which could be faster */
5169 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
5170 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
5171 tcg_gen_ext16s_tl(cpu_tmp0, cpu_T0);
5172 tcg_gen_sub_tl(cpu_cc_src, cpu_T0, cpu_tmp0);
5173 gen_op_mov_reg_v(ot, reg, cpu_T0);
5176 set_cc_op(s, CC_OP_MULB + ot);
5179 case 0x1c1: /* xadd Ev, Gv */
5180 ot = mo_b_d(b, dflag);
5181 modrm = cpu_ldub_code(env, s->pc++);
5182 reg = ((modrm >> 3) & 7) | rex_r;
5183 mod = (modrm >> 6) & 3;
5184 gen_op_mov_v_reg(ot, cpu_T0, reg);
5186 rm = (modrm & 7) | REX_B(s);
5187 gen_op_mov_v_reg(ot, cpu_T1, rm);
5188 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
5189 gen_op_mov_reg_v(ot, reg, cpu_T1);
5190 gen_op_mov_reg_v(ot, rm, cpu_T0);
5192 gen_lea_modrm(env, s, modrm);
5193 if (s->prefix & PREFIX_LOCK) {
5194 tcg_gen_atomic_fetch_add_tl(cpu_T1, cpu_A0, cpu_T0,
5195 s->mem_index, ot | MO_LE);
5196 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
5198 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
5199 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
5200 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
5202 gen_op_mov_reg_v(ot, reg, cpu_T1);
5204 gen_op_update2_cc();
5205 set_cc_op(s, CC_OP_ADDB + ot);
5208 case 0x1b1: /* cmpxchg Ev, Gv */
5210 TCGv oldv, newv, cmpv;
5212 ot = mo_b_d(b, dflag);
5213 modrm = cpu_ldub_code(env, s->pc++);
5214 reg = ((modrm >> 3) & 7) | rex_r;
5215 mod = (modrm >> 6) & 3;
5216 oldv = tcg_temp_new();
5217 newv = tcg_temp_new();
5218 cmpv = tcg_temp_new();
5219 gen_op_mov_v_reg(ot, newv, reg);
5220 tcg_gen_mov_tl(cmpv, cpu_regs[R_EAX]);
5222 if (s->prefix & PREFIX_LOCK) {
5226 gen_lea_modrm(env, s, modrm);
5227 tcg_gen_atomic_cmpxchg_tl(oldv, cpu_A0, cmpv, newv,
5228 s->mem_index, ot | MO_LE);
5229 gen_op_mov_reg_v(ot, R_EAX, oldv);
5232 rm = (modrm & 7) | REX_B(s);
5233 gen_op_mov_v_reg(ot, oldv, rm);
5235 gen_lea_modrm(env, s, modrm);
5236 gen_op_ld_v(s, ot, oldv, cpu_A0);
5237 rm = 0; /* avoid warning */
5241 /* store value = (old == cmp ? new : old); */
5242 tcg_gen_movcond_tl(TCG_COND_EQ, newv, oldv, cmpv, newv, oldv);
5244 gen_op_mov_reg_v(ot, R_EAX, oldv);
5245 gen_op_mov_reg_v(ot, rm, newv);
5247 /* Perform an unconditional store cycle like physical cpu;
5248 must be before changing accumulator to ensure
5249 idempotency if the store faults and the instruction
5251 gen_op_st_v(s, ot, newv, cpu_A0);
5252 gen_op_mov_reg_v(ot, R_EAX, oldv);
5255 tcg_gen_mov_tl(cpu_cc_src, oldv);
5256 tcg_gen_mov_tl(cpu_cc_srcT, cmpv);
5257 tcg_gen_sub_tl(cpu_cc_dst, cmpv, oldv);
5258 set_cc_op(s, CC_OP_SUBB + ot);
5259 tcg_temp_free(oldv);
5260 tcg_temp_free(newv);
5261 tcg_temp_free(cmpv);
5264 case 0x1c7: /* cmpxchg8b */
5265 modrm = cpu_ldub_code(env, s->pc++);
5266 mod = (modrm >> 6) & 3;
5267 if ((mod == 3) || ((modrm & 0x38) != 0x8))
5269 #ifdef TARGET_X86_64
5270 if (dflag == MO_64) {
5271 if (!(s->cpuid_ext_features & CPUID_EXT_CX16))
5273 gen_lea_modrm(env, s, modrm);
5274 if ((s->prefix & PREFIX_LOCK) && parallel_cpus) {
5275 gen_helper_cmpxchg16b(cpu_env, cpu_A0);
5277 gen_helper_cmpxchg16b_unlocked(cpu_env, cpu_A0);
5282 if (!(s->cpuid_features & CPUID_CX8))
5284 gen_lea_modrm(env, s, modrm);
5285 if ((s->prefix & PREFIX_LOCK) && parallel_cpus) {
5286 gen_helper_cmpxchg8b(cpu_env, cpu_A0);
5288 gen_helper_cmpxchg8b_unlocked(cpu_env, cpu_A0);
5291 set_cc_op(s, CC_OP_EFLAGS);
5294 /**************************/
5296 case 0x50 ... 0x57: /* push */
5297 gen_op_mov_v_reg(MO_32, cpu_T0, (b & 7) | REX_B(s));
5298 gen_push_v(s, cpu_T0);
5300 case 0x58 ... 0x5f: /* pop */
5302 /* NOTE: order is important for pop %sp */
5303 gen_pop_update(s, ot);
5304 gen_op_mov_reg_v(ot, (b & 7) | REX_B(s), cpu_T0);
5306 case 0x60: /* pusha */
5311 case 0x61: /* popa */
5316 case 0x68: /* push Iv */
5318 ot = mo_pushpop(s, dflag);
5320 val = insn_get(env, s, ot);
5322 val = (int8_t)insn_get(env, s, MO_8);
5323 tcg_gen_movi_tl(cpu_T0, val);
5324 gen_push_v(s, cpu_T0);
5326 case 0x8f: /* pop Ev */
5327 modrm = cpu_ldub_code(env, s->pc++);
5328 mod = (modrm >> 6) & 3;
5331 /* NOTE: order is important for pop %sp */
5332 gen_pop_update(s, ot);
5333 rm = (modrm & 7) | REX_B(s);
5334 gen_op_mov_reg_v(ot, rm, cpu_T0);
5336 /* NOTE: order is important too for MMU exceptions */
5337 s->popl_esp_hack = 1 << ot;
5338 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5339 s->popl_esp_hack = 0;
5340 gen_pop_update(s, ot);
5343 case 0xc8: /* enter */
5346 val = cpu_lduw_code(env, s->pc);
5348 level = cpu_ldub_code(env, s->pc++);
5349 gen_enter(s, val, level);
5352 case 0xc9: /* leave */
5355 case 0x06: /* push es */
5356 case 0x0e: /* push cs */
5357 case 0x16: /* push ss */
5358 case 0x1e: /* push ds */
5361 gen_op_movl_T0_seg(b >> 3);
5362 gen_push_v(s, cpu_T0);
5364 case 0x1a0: /* push fs */
5365 case 0x1a8: /* push gs */
5366 gen_op_movl_T0_seg((b >> 3) & 7);
5367 gen_push_v(s, cpu_T0);
5369 case 0x07: /* pop es */
5370 case 0x17: /* pop ss */
5371 case 0x1f: /* pop ds */
5376 gen_movl_seg_T0(s, reg);
5377 gen_pop_update(s, ot);
5378 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5379 if (s->base.is_jmp) {
5380 gen_jmp_im(s->pc - s->cs_base);
5383 gen_eob_inhibit_irq(s, true);
5389 case 0x1a1: /* pop fs */
5390 case 0x1a9: /* pop gs */
5392 gen_movl_seg_T0(s, (b >> 3) & 7);
5393 gen_pop_update(s, ot);
5394 if (s->base.is_jmp) {
5395 gen_jmp_im(s->pc - s->cs_base);
5400 /**************************/
5403 case 0x89: /* mov Gv, Ev */
5404 ot = mo_b_d(b, dflag);
5405 modrm = cpu_ldub_code(env, s->pc++);
5406 reg = ((modrm >> 3) & 7) | rex_r;
5408 /* generate a generic store */
5409 gen_ldst_modrm(env, s, modrm, ot, reg, 1);
5412 case 0xc7: /* mov Ev, Iv */
5413 ot = mo_b_d(b, dflag);
5414 modrm = cpu_ldub_code(env, s->pc++);
5415 mod = (modrm >> 6) & 3;
5417 s->rip_offset = insn_const_size(ot);
5418 gen_lea_modrm(env, s, modrm);
5420 val = insn_get(env, s, ot);
5421 tcg_gen_movi_tl(cpu_T0, val);
5423 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
5425 gen_op_mov_reg_v(ot, (modrm & 7) | REX_B(s), cpu_T0);
5429 case 0x8b: /* mov Ev, Gv */
5430 ot = mo_b_d(b, dflag);
5431 modrm = cpu_ldub_code(env, s->pc++);
5432 reg = ((modrm >> 3) & 7) | rex_r;
5434 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5435 gen_op_mov_reg_v(ot, reg, cpu_T0);
5437 case 0x8e: /* mov seg, Gv */
5438 modrm = cpu_ldub_code(env, s->pc++);
5439 reg = (modrm >> 3) & 7;
5440 if (reg >= 6 || reg == R_CS)
5442 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
5443 gen_movl_seg_T0(s, reg);
5444 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5445 if (s->base.is_jmp) {
5446 gen_jmp_im(s->pc - s->cs_base);
5449 gen_eob_inhibit_irq(s, true);
5455 case 0x8c: /* mov Gv, seg */
5456 modrm = cpu_ldub_code(env, s->pc++);
5457 reg = (modrm >> 3) & 7;
5458 mod = (modrm >> 6) & 3;
5461 gen_op_movl_T0_seg(reg);
5462 ot = mod == 3 ? dflag : MO_16;
5463 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5466 case 0x1b6: /* movzbS Gv, Eb */
5467 case 0x1b7: /* movzwS Gv, Eb */
5468 case 0x1be: /* movsbS Gv, Eb */
5469 case 0x1bf: /* movswS Gv, Eb */
5474 /* d_ot is the size of destination */
5476 /* ot is the size of source */
5477 ot = (b & 1) + MO_8;
5478 /* s_ot is the sign+size of source */
5479 s_ot = b & 8 ? MO_SIGN | ot : ot;
5481 modrm = cpu_ldub_code(env, s->pc++);
5482 reg = ((modrm >> 3) & 7) | rex_r;
5483 mod = (modrm >> 6) & 3;
5484 rm = (modrm & 7) | REX_B(s);
5487 if (s_ot == MO_SB && byte_reg_is_xH(rm)) {
5488 tcg_gen_sextract_tl(cpu_T0, cpu_regs[rm - 4], 8, 8);
5490 gen_op_mov_v_reg(ot, cpu_T0, rm);
5493 tcg_gen_ext8u_tl(cpu_T0, cpu_T0);
5496 tcg_gen_ext8s_tl(cpu_T0, cpu_T0);
5499 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
5503 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
5507 gen_op_mov_reg_v(d_ot, reg, cpu_T0);
5509 gen_lea_modrm(env, s, modrm);
5510 gen_op_ld_v(s, s_ot, cpu_T0, cpu_A0);
5511 gen_op_mov_reg_v(d_ot, reg, cpu_T0);
5516 case 0x8d: /* lea */
5517 modrm = cpu_ldub_code(env, s->pc++);
5518 mod = (modrm >> 6) & 3;
5521 reg = ((modrm >> 3) & 7) | rex_r;
5523 AddressParts a = gen_lea_modrm_0(env, s, modrm);
5524 TCGv ea = gen_lea_modrm_1(a);
5525 gen_lea_v_seg(s, s->aflag, ea, -1, -1);
5526 gen_op_mov_reg_v(dflag, reg, cpu_A0);
5530 case 0xa0: /* mov EAX, Ov */
5532 case 0xa2: /* mov Ov, EAX */
5535 target_ulong offset_addr;
5537 ot = mo_b_d(b, dflag);
5539 #ifdef TARGET_X86_64
5541 offset_addr = cpu_ldq_code(env, s->pc);
5546 offset_addr = insn_get(env, s, s->aflag);
5549 tcg_gen_movi_tl(cpu_A0, offset_addr);
5550 gen_add_A0_ds_seg(s);
5552 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
5553 gen_op_mov_reg_v(ot, R_EAX, cpu_T0);
5555 gen_op_mov_v_reg(ot, cpu_T0, R_EAX);
5556 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
5560 case 0xd7: /* xlat */
5561 tcg_gen_mov_tl(cpu_A0, cpu_regs[R_EBX]);
5562 tcg_gen_ext8u_tl(cpu_T0, cpu_regs[R_EAX]);
5563 tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T0);
5564 gen_extu(s->aflag, cpu_A0);
5565 gen_add_A0_ds_seg(s);
5566 gen_op_ld_v(s, MO_8, cpu_T0, cpu_A0);
5567 gen_op_mov_reg_v(MO_8, R_EAX, cpu_T0);
5569 case 0xb0 ... 0xb7: /* mov R, Ib */
5570 val = insn_get(env, s, MO_8);
5571 tcg_gen_movi_tl(cpu_T0, val);
5572 gen_op_mov_reg_v(MO_8, (b & 7) | REX_B(s), cpu_T0);
5574 case 0xb8 ... 0xbf: /* mov R, Iv */
5575 #ifdef TARGET_X86_64
5576 if (dflag == MO_64) {
5579 tmp = cpu_ldq_code(env, s->pc);
5581 reg = (b & 7) | REX_B(s);
5582 tcg_gen_movi_tl(cpu_T0, tmp);
5583 gen_op_mov_reg_v(MO_64, reg, cpu_T0);
5588 val = insn_get(env, s, ot);
5589 reg = (b & 7) | REX_B(s);
5590 tcg_gen_movi_tl(cpu_T0, val);
5591 gen_op_mov_reg_v(ot, reg, cpu_T0);
5595 case 0x91 ... 0x97: /* xchg R, EAX */
5598 reg = (b & 7) | REX_B(s);
5602 case 0x87: /* xchg Ev, Gv */
5603 ot = mo_b_d(b, dflag);
5604 modrm = cpu_ldub_code(env, s->pc++);
5605 reg = ((modrm >> 3) & 7) | rex_r;
5606 mod = (modrm >> 6) & 3;
5608 rm = (modrm & 7) | REX_B(s);
5610 gen_op_mov_v_reg(ot, cpu_T0, reg);
5611 gen_op_mov_v_reg(ot, cpu_T1, rm);
5612 gen_op_mov_reg_v(ot, rm, cpu_T0);
5613 gen_op_mov_reg_v(ot, reg, cpu_T1);
5615 gen_lea_modrm(env, s, modrm);
5616 gen_op_mov_v_reg(ot, cpu_T0, reg);
5617 /* for xchg, lock is implicit */
5618 tcg_gen_atomic_xchg_tl(cpu_T1, cpu_A0, cpu_T0,
5619 s->mem_index, ot | MO_LE);
5620 gen_op_mov_reg_v(ot, reg, cpu_T1);
5623 case 0xc4: /* les Gv */
5624 /* In CODE64 this is VEX3; see above. */
5627 case 0xc5: /* lds Gv */
5628 /* In CODE64 this is VEX2; see above. */
5631 case 0x1b2: /* lss Gv */
5634 case 0x1b4: /* lfs Gv */
5637 case 0x1b5: /* lgs Gv */
5640 ot = dflag != MO_16 ? MO_32 : MO_16;
5641 modrm = cpu_ldub_code(env, s->pc++);
5642 reg = ((modrm >> 3) & 7) | rex_r;
5643 mod = (modrm >> 6) & 3;
5646 gen_lea_modrm(env, s, modrm);
5647 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
5648 gen_add_A0_im(s, 1 << ot);
5649 /* load the segment first to handle exceptions properly */
5650 gen_op_ld_v(s, MO_16, cpu_T0, cpu_A0);
5651 gen_movl_seg_T0(s, op);
5652 /* then put the data */
5653 gen_op_mov_reg_v(ot, reg, cpu_T1);
5654 if (s->base.is_jmp) {
5655 gen_jmp_im(s->pc - s->cs_base);
5660 /************************/
5668 ot = mo_b_d(b, dflag);
5669 modrm = cpu_ldub_code(env, s->pc++);
5670 mod = (modrm >> 6) & 3;
5671 op = (modrm >> 3) & 7;
5677 gen_lea_modrm(env, s, modrm);
5680 opreg = (modrm & 7) | REX_B(s);
5685 gen_shift(s, op, ot, opreg, OR_ECX);
5688 shift = cpu_ldub_code(env, s->pc++);
5690 gen_shifti(s, op, ot, opreg, shift);
5705 case 0x1a4: /* shld imm */
5709 case 0x1a5: /* shld cl */
5713 case 0x1ac: /* shrd imm */
5717 case 0x1ad: /* shrd cl */
5722 modrm = cpu_ldub_code(env, s->pc++);
5723 mod = (modrm >> 6) & 3;
5724 rm = (modrm & 7) | REX_B(s);
5725 reg = ((modrm >> 3) & 7) | rex_r;
5727 gen_lea_modrm(env, s, modrm);
5732 gen_op_mov_v_reg(ot, cpu_T1, reg);
5735 TCGv imm = tcg_const_tl(cpu_ldub_code(env, s->pc++));
5736 gen_shiftd_rm_T1(s, ot, opreg, op, imm);
5739 gen_shiftd_rm_T1(s, ot, opreg, op, cpu_regs[R_ECX]);
5743 /************************/
5746 if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
5747 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5748 /* XXX: what to do if illegal op ? */
5749 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
5752 modrm = cpu_ldub_code(env, s->pc++);
5753 mod = (modrm >> 6) & 3;
5755 op = ((b & 7) << 3) | ((modrm >> 3) & 7);
5758 gen_lea_modrm(env, s, modrm);
5760 case 0x00 ... 0x07: /* fxxxs */
5761 case 0x10 ... 0x17: /* fixxxl */
5762 case 0x20 ... 0x27: /* fxxxl */
5763 case 0x30 ... 0x37: /* fixxx */
5770 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5771 s->mem_index, MO_LEUL);
5772 gen_helper_flds_FT0(cpu_env, cpu_tmp2_i32);
5775 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5776 s->mem_index, MO_LEUL);
5777 gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32);
5780 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0,
5781 s->mem_index, MO_LEQ);
5782 gen_helper_fldl_FT0(cpu_env, cpu_tmp1_i64);
5786 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5787 s->mem_index, MO_LESW);
5788 gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32);
5792 gen_helper_fp_arith_ST0_FT0(op1);
5794 /* fcomp needs pop */
5795 gen_helper_fpop(cpu_env);
5799 case 0x08: /* flds */
5800 case 0x0a: /* fsts */
5801 case 0x0b: /* fstps */
5802 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5803 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5804 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5809 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5810 s->mem_index, MO_LEUL);
5811 gen_helper_flds_ST0(cpu_env, cpu_tmp2_i32);
5814 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5815 s->mem_index, MO_LEUL);
5816 gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32);
5819 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0,
5820 s->mem_index, MO_LEQ);
5821 gen_helper_fldl_ST0(cpu_env, cpu_tmp1_i64);
5825 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5826 s->mem_index, MO_LESW);
5827 gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32);
5832 /* XXX: the corresponding CPUID bit must be tested ! */
5835 gen_helper_fisttl_ST0(cpu_tmp2_i32, cpu_env);
5836 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5837 s->mem_index, MO_LEUL);
5840 gen_helper_fisttll_ST0(cpu_tmp1_i64, cpu_env);
5841 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0,
5842 s->mem_index, MO_LEQ);
5846 gen_helper_fistt_ST0(cpu_tmp2_i32, cpu_env);
5847 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5848 s->mem_index, MO_LEUW);
5851 gen_helper_fpop(cpu_env);
5856 gen_helper_fsts_ST0(cpu_tmp2_i32, cpu_env);
5857 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5858 s->mem_index, MO_LEUL);
5861 gen_helper_fistl_ST0(cpu_tmp2_i32, cpu_env);
5862 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5863 s->mem_index, MO_LEUL);
5866 gen_helper_fstl_ST0(cpu_tmp1_i64, cpu_env);
5867 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0,
5868 s->mem_index, MO_LEQ);
5872 gen_helper_fist_ST0(cpu_tmp2_i32, cpu_env);
5873 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5874 s->mem_index, MO_LEUW);
5878 gen_helper_fpop(cpu_env);
5882 case 0x0c: /* fldenv mem */
5883 gen_helper_fldenv(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5885 case 0x0d: /* fldcw mem */
5886 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5887 s->mem_index, MO_LEUW);
5888 gen_helper_fldcw(cpu_env, cpu_tmp2_i32);
5890 case 0x0e: /* fnstenv mem */
5891 gen_helper_fstenv(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5893 case 0x0f: /* fnstcw mem */
5894 gen_helper_fnstcw(cpu_tmp2_i32, cpu_env);
5895 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5896 s->mem_index, MO_LEUW);
5898 case 0x1d: /* fldt mem */
5899 gen_helper_fldt_ST0(cpu_env, cpu_A0);
5901 case 0x1f: /* fstpt mem */
5902 gen_helper_fstt_ST0(cpu_env, cpu_A0);
5903 gen_helper_fpop(cpu_env);
5905 case 0x2c: /* frstor mem */
5906 gen_helper_frstor(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5908 case 0x2e: /* fnsave mem */
5909 gen_helper_fsave(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5911 case 0x2f: /* fnstsw mem */
5912 gen_helper_fnstsw(cpu_tmp2_i32, cpu_env);
5913 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5914 s->mem_index, MO_LEUW);
5916 case 0x3c: /* fbld */
5917 gen_helper_fbld_ST0(cpu_env, cpu_A0);
5919 case 0x3e: /* fbstp */
5920 gen_helper_fbst_ST0(cpu_env, cpu_A0);
5921 gen_helper_fpop(cpu_env);
5923 case 0x3d: /* fildll */
5924 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
5925 gen_helper_fildll_ST0(cpu_env, cpu_tmp1_i64);
5927 case 0x3f: /* fistpll */
5928 gen_helper_fistll_ST0(cpu_tmp1_i64, cpu_env);
5929 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
5930 gen_helper_fpop(cpu_env);
5936 /* register float ops */
5940 case 0x08: /* fld sti */
5941 gen_helper_fpush(cpu_env);
5942 gen_helper_fmov_ST0_STN(cpu_env,
5943 tcg_const_i32((opreg + 1) & 7));
5945 case 0x09: /* fxchg sti */
5946 case 0x29: /* fxchg4 sti, undocumented op */
5947 case 0x39: /* fxchg7 sti, undocumented op */
5948 gen_helper_fxchg_ST0_STN(cpu_env, tcg_const_i32(opreg));
5950 case 0x0a: /* grp d9/2 */
5953 /* check exceptions (FreeBSD FPU probe) */
5954 gen_helper_fwait(cpu_env);
5960 case 0x0c: /* grp d9/4 */
5963 gen_helper_fchs_ST0(cpu_env);
5966 gen_helper_fabs_ST0(cpu_env);
5969 gen_helper_fldz_FT0(cpu_env);
5970 gen_helper_fcom_ST0_FT0(cpu_env);
5973 gen_helper_fxam_ST0(cpu_env);
5979 case 0x0d: /* grp d9/5 */
5983 gen_helper_fpush(cpu_env);
5984 gen_helper_fld1_ST0(cpu_env);
5987 gen_helper_fpush(cpu_env);
5988 gen_helper_fldl2t_ST0(cpu_env);
5991 gen_helper_fpush(cpu_env);
5992 gen_helper_fldl2e_ST0(cpu_env);
5995 gen_helper_fpush(cpu_env);
5996 gen_helper_fldpi_ST0(cpu_env);
5999 gen_helper_fpush(cpu_env);
6000 gen_helper_fldlg2_ST0(cpu_env);
6003 gen_helper_fpush(cpu_env);
6004 gen_helper_fldln2_ST0(cpu_env);
6007 gen_helper_fpush(cpu_env);
6008 gen_helper_fldz_ST0(cpu_env);
6015 case 0x0e: /* grp d9/6 */
6018 gen_helper_f2xm1(cpu_env);
6021 gen_helper_fyl2x(cpu_env);
6024 gen_helper_fptan(cpu_env);
6026 case 3: /* fpatan */
6027 gen_helper_fpatan(cpu_env);
6029 case 4: /* fxtract */
6030 gen_helper_fxtract(cpu_env);
6032 case 5: /* fprem1 */
6033 gen_helper_fprem1(cpu_env);
6035 case 6: /* fdecstp */
6036 gen_helper_fdecstp(cpu_env);
6039 case 7: /* fincstp */
6040 gen_helper_fincstp(cpu_env);
6044 case 0x0f: /* grp d9/7 */
6047 gen_helper_fprem(cpu_env);
6049 case 1: /* fyl2xp1 */
6050 gen_helper_fyl2xp1(cpu_env);
6053 gen_helper_fsqrt(cpu_env);
6055 case 3: /* fsincos */
6056 gen_helper_fsincos(cpu_env);
6058 case 5: /* fscale */
6059 gen_helper_fscale(cpu_env);
6061 case 4: /* frndint */
6062 gen_helper_frndint(cpu_env);
6065 gen_helper_fsin(cpu_env);
6069 gen_helper_fcos(cpu_env);
6073 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6074 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6075 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6081 gen_helper_fp_arith_STN_ST0(op1, opreg);
6083 gen_helper_fpop(cpu_env);
6085 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6086 gen_helper_fp_arith_ST0_FT0(op1);
6090 case 0x02: /* fcom */
6091 case 0x22: /* fcom2, undocumented op */
6092 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6093 gen_helper_fcom_ST0_FT0(cpu_env);
6095 case 0x03: /* fcomp */
6096 case 0x23: /* fcomp3, undocumented op */
6097 case 0x32: /* fcomp5, undocumented op */
6098 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6099 gen_helper_fcom_ST0_FT0(cpu_env);
6100 gen_helper_fpop(cpu_env);
6102 case 0x15: /* da/5 */
6104 case 1: /* fucompp */
6105 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
6106 gen_helper_fucom_ST0_FT0(cpu_env);
6107 gen_helper_fpop(cpu_env);
6108 gen_helper_fpop(cpu_env);
6116 case 0: /* feni (287 only, just do nop here) */
6118 case 1: /* fdisi (287 only, just do nop here) */
6121 gen_helper_fclex(cpu_env);
6123 case 3: /* fninit */
6124 gen_helper_fninit(cpu_env);
6126 case 4: /* fsetpm (287 only, just do nop here) */
6132 case 0x1d: /* fucomi */
6133 if (!(s->cpuid_features & CPUID_CMOV)) {
6136 gen_update_cc_op(s);
6137 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6138 gen_helper_fucomi_ST0_FT0(cpu_env);
6139 set_cc_op(s, CC_OP_EFLAGS);
6141 case 0x1e: /* fcomi */
6142 if (!(s->cpuid_features & CPUID_CMOV)) {
6145 gen_update_cc_op(s);
6146 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6147 gen_helper_fcomi_ST0_FT0(cpu_env);
6148 set_cc_op(s, CC_OP_EFLAGS);
6150 case 0x28: /* ffree sti */
6151 gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
6153 case 0x2a: /* fst sti */
6154 gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
6156 case 0x2b: /* fstp sti */
6157 case 0x0b: /* fstp1 sti, undocumented op */
6158 case 0x3a: /* fstp8 sti, undocumented op */
6159 case 0x3b: /* fstp9 sti, undocumented op */
6160 gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
6161 gen_helper_fpop(cpu_env);
6163 case 0x2c: /* fucom st(i) */
6164 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6165 gen_helper_fucom_ST0_FT0(cpu_env);
6167 case 0x2d: /* fucomp st(i) */
6168 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6169 gen_helper_fucom_ST0_FT0(cpu_env);
6170 gen_helper_fpop(cpu_env);
6172 case 0x33: /* de/3 */
6174 case 1: /* fcompp */
6175 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
6176 gen_helper_fcom_ST0_FT0(cpu_env);
6177 gen_helper_fpop(cpu_env);
6178 gen_helper_fpop(cpu_env);
6184 case 0x38: /* ffreep sti, undocumented op */
6185 gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
6186 gen_helper_fpop(cpu_env);
6188 case 0x3c: /* df/4 */
6191 gen_helper_fnstsw(cpu_tmp2_i32, cpu_env);
6192 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
6193 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
6199 case 0x3d: /* fucomip */
6200 if (!(s->cpuid_features & CPUID_CMOV)) {
6203 gen_update_cc_op(s);
6204 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6205 gen_helper_fucomi_ST0_FT0(cpu_env);
6206 gen_helper_fpop(cpu_env);
6207 set_cc_op(s, CC_OP_EFLAGS);
6209 case 0x3e: /* fcomip */
6210 if (!(s->cpuid_features & CPUID_CMOV)) {
6213 gen_update_cc_op(s);
6214 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6215 gen_helper_fcomi_ST0_FT0(cpu_env);
6216 gen_helper_fpop(cpu_env);
6217 set_cc_op(s, CC_OP_EFLAGS);
6219 case 0x10 ... 0x13: /* fcmovxx */
6224 static const uint8_t fcmov_cc[8] = {
6231 if (!(s->cpuid_features & CPUID_CMOV)) {
6234 op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1);
6235 l1 = gen_new_label();
6236 gen_jcc1_noeob(s, op1, l1);
6237 gen_helper_fmov_ST0_STN(cpu_env, tcg_const_i32(opreg));
6246 /************************/
6249 case 0xa4: /* movsS */
6251 ot = mo_b_d(b, dflag);
6252 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6253 gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6259 case 0xaa: /* stosS */
6261 ot = mo_b_d(b, dflag);
6262 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6263 gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6268 case 0xac: /* lodsS */
6270 ot = mo_b_d(b, dflag);
6271 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6272 gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6277 case 0xae: /* scasS */
6279 ot = mo_b_d(b, dflag);
6280 if (prefixes & PREFIX_REPNZ) {
6281 gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
6282 } else if (prefixes & PREFIX_REPZ) {
6283 gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
6289 case 0xa6: /* cmpsS */
6291 ot = mo_b_d(b, dflag);
6292 if (prefixes & PREFIX_REPNZ) {
6293 gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
6294 } else if (prefixes & PREFIX_REPZ) {
6295 gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
6300 case 0x6c: /* insS */
6302 ot = mo_b_d32(b, dflag);
6303 tcg_gen_ext16u_tl(cpu_T0, cpu_regs[R_EDX]);
6304 gen_check_io(s, ot, pc_start - s->cs_base,
6305 SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) | 4);
6306 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6307 gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6310 if (s->base.tb->cflags & CF_USE_ICOUNT) {
6311 gen_jmp(s, s->pc - s->cs_base);
6315 case 0x6e: /* outsS */
6317 ot = mo_b_d32(b, dflag);
6318 tcg_gen_ext16u_tl(cpu_T0, cpu_regs[R_EDX]);
6319 gen_check_io(s, ot, pc_start - s->cs_base,
6320 svm_is_rep(prefixes) | 4);
6321 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6322 gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6325 if (s->base.tb->cflags & CF_USE_ICOUNT) {
6326 gen_jmp(s, s->pc - s->cs_base);
6331 /************************/
6336 ot = mo_b_d32(b, dflag);
6337 val = cpu_ldub_code(env, s->pc++);
6338 tcg_gen_movi_tl(cpu_T0, val);
6339 gen_check_io(s, ot, pc_start - s->cs_base,
6340 SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6341 if (s->base.tb->cflags & CF_USE_ICOUNT) {
6344 tcg_gen_movi_i32(cpu_tmp2_i32, val);
6345 gen_helper_in_func(ot, cpu_T1, cpu_tmp2_i32);
6346 gen_op_mov_reg_v(ot, R_EAX, cpu_T1);
6347 gen_bpt_io(s, cpu_tmp2_i32, ot);
6348 if (s->base.tb->cflags & CF_USE_ICOUNT) {
6350 gen_jmp(s, s->pc - s->cs_base);
6355 ot = mo_b_d32(b, dflag);
6356 val = cpu_ldub_code(env, s->pc++);
6357 tcg_gen_movi_tl(cpu_T0, val);
6358 gen_check_io(s, ot, pc_start - s->cs_base,
6359 svm_is_rep(prefixes));
6360 gen_op_mov_v_reg(ot, cpu_T1, R_EAX);
6362 if (s->base.tb->cflags & CF_USE_ICOUNT) {
6365 tcg_gen_movi_i32(cpu_tmp2_i32, val);
6366 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T1);
6367 gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6368 gen_bpt_io(s, cpu_tmp2_i32, ot);
6369 if (s->base.tb->cflags & CF_USE_ICOUNT) {
6371 gen_jmp(s, s->pc - s->cs_base);
6376 ot = mo_b_d32(b, dflag);
6377 tcg_gen_ext16u_tl(cpu_T0, cpu_regs[R_EDX]);
6378 gen_check_io(s, ot, pc_start - s->cs_base,
6379 SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6380 if (s->base.tb->cflags & CF_USE_ICOUNT) {
6383 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
6384 gen_helper_in_func(ot, cpu_T1, cpu_tmp2_i32);
6385 gen_op_mov_reg_v(ot, R_EAX, cpu_T1);
6386 gen_bpt_io(s, cpu_tmp2_i32, ot);
6387 if (s->base.tb->cflags & CF_USE_ICOUNT) {
6389 gen_jmp(s, s->pc - s->cs_base);
6394 ot = mo_b_d32(b, dflag);
6395 tcg_gen_ext16u_tl(cpu_T0, cpu_regs[R_EDX]);
6396 gen_check_io(s, ot, pc_start - s->cs_base,
6397 svm_is_rep(prefixes));
6398 gen_op_mov_v_reg(ot, cpu_T1, R_EAX);
6400 if (s->base.tb->cflags & CF_USE_ICOUNT) {
6403 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
6404 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T1);
6405 gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6406 gen_bpt_io(s, cpu_tmp2_i32, ot);
6407 if (s->base.tb->cflags & CF_USE_ICOUNT) {
6409 gen_jmp(s, s->pc - s->cs_base);
6413 /************************/
6415 case 0xc2: /* ret im */
6416 val = cpu_ldsw_code(env, s->pc);
6419 gen_stack_update(s, val + (1 << ot));
6420 /* Note that gen_pop_T0 uses a zero-extending load. */
6421 gen_op_jmp_v(cpu_T0);
6425 case 0xc3: /* ret */
6427 gen_pop_update(s, ot);
6428 /* Note that gen_pop_T0 uses a zero-extending load. */
6429 gen_op_jmp_v(cpu_T0);
6433 case 0xca: /* lret im */
6434 val = cpu_ldsw_code(env, s->pc);
6437 if (s->pe && !s->vm86) {
6438 gen_update_cc_op(s);
6439 gen_jmp_im(pc_start - s->cs_base);
6440 gen_helper_lret_protected(cpu_env, tcg_const_i32(dflag - 1),
6441 tcg_const_i32(val));
6445 gen_op_ld_v(s, dflag, cpu_T0, cpu_A0);
6446 /* NOTE: keeping EIP updated is not a problem in case of
6448 gen_op_jmp_v(cpu_T0);
6450 gen_add_A0_im(s, 1 << dflag);
6451 gen_op_ld_v(s, dflag, cpu_T0, cpu_A0);
6452 gen_op_movl_seg_T0_vm(R_CS);
6453 /* add stack offset */
6454 gen_stack_update(s, val + (2 << dflag));
6458 case 0xcb: /* lret */
6461 case 0xcf: /* iret */
6462 gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET);
6465 gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
6466 set_cc_op(s, CC_OP_EFLAGS);
6467 } else if (s->vm86) {
6469 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6471 gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
6472 set_cc_op(s, CC_OP_EFLAGS);
6475 gen_helper_iret_protected(cpu_env, tcg_const_i32(dflag - 1),
6476 tcg_const_i32(s->pc - s->cs_base));
6477 set_cc_op(s, CC_OP_EFLAGS);
6481 case 0xe8: /* call im */
6483 if (dflag != MO_16) {
6484 tval = (int32_t)insn_get(env, s, MO_32);
6486 tval = (int16_t)insn_get(env, s, MO_16);
6488 next_eip = s->pc - s->cs_base;
6490 if (dflag == MO_16) {
6492 } else if (!CODE64(s)) {
6495 tcg_gen_movi_tl(cpu_T0, next_eip);
6496 gen_push_v(s, cpu_T0);
6501 case 0x9a: /* lcall im */
6503 unsigned int selector, offset;
6508 offset = insn_get(env, s, ot);
6509 selector = insn_get(env, s, MO_16);
6511 tcg_gen_movi_tl(cpu_T0, selector);
6512 tcg_gen_movi_tl(cpu_T1, offset);
6515 case 0xe9: /* jmp im */
6516 if (dflag != MO_16) {
6517 tval = (int32_t)insn_get(env, s, MO_32);
6519 tval = (int16_t)insn_get(env, s, MO_16);
6521 tval += s->pc - s->cs_base;
6522 if (dflag == MO_16) {
6524 } else if (!CODE64(s)) {
6530 case 0xea: /* ljmp im */
6532 unsigned int selector, offset;
6537 offset = insn_get(env, s, ot);
6538 selector = insn_get(env, s, MO_16);
6540 tcg_gen_movi_tl(cpu_T0, selector);
6541 tcg_gen_movi_tl(cpu_T1, offset);
6544 case 0xeb: /* jmp Jb */
6545 tval = (int8_t)insn_get(env, s, MO_8);
6546 tval += s->pc - s->cs_base;
6547 if (dflag == MO_16) {
6552 case 0x70 ... 0x7f: /* jcc Jb */
6553 tval = (int8_t)insn_get(env, s, MO_8);
6555 case 0x180 ... 0x18f: /* jcc Jv */
6556 if (dflag != MO_16) {
6557 tval = (int32_t)insn_get(env, s, MO_32);
6559 tval = (int16_t)insn_get(env, s, MO_16);
6562 next_eip = s->pc - s->cs_base;
6564 if (dflag == MO_16) {
6568 gen_jcc(s, b, tval, next_eip);
6571 case 0x190 ... 0x19f: /* setcc Gv */
6572 modrm = cpu_ldub_code(env, s->pc++);
6573 gen_setcc1(s, b, cpu_T0);
6574 gen_ldst_modrm(env, s, modrm, MO_8, OR_TMP0, 1);
6576 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6577 if (!(s->cpuid_features & CPUID_CMOV)) {
6581 modrm = cpu_ldub_code(env, s->pc++);
6582 reg = ((modrm >> 3) & 7) | rex_r;
6583 gen_cmovcc1(env, s, ot, b, modrm, reg);
6586 /************************/
6588 case 0x9c: /* pushf */
6589 gen_svm_check_intercept(s, pc_start, SVM_EXIT_PUSHF);
6590 if (s->vm86 && s->iopl != 3) {
6591 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6593 gen_update_cc_op(s);
6594 gen_helper_read_eflags(cpu_T0, cpu_env);
6595 gen_push_v(s, cpu_T0);
6598 case 0x9d: /* popf */
6599 gen_svm_check_intercept(s, pc_start, SVM_EXIT_POPF);
6600 if (s->vm86 && s->iopl != 3) {
6601 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6605 if (dflag != MO_16) {
6606 gen_helper_write_eflags(cpu_env, cpu_T0,
6607 tcg_const_i32((TF_MASK | AC_MASK |
6612 gen_helper_write_eflags(cpu_env, cpu_T0,
6613 tcg_const_i32((TF_MASK | AC_MASK |
6615 IF_MASK | IOPL_MASK)
6619 if (s->cpl <= s->iopl) {
6620 if (dflag != MO_16) {
6621 gen_helper_write_eflags(cpu_env, cpu_T0,
6622 tcg_const_i32((TF_MASK |
6628 gen_helper_write_eflags(cpu_env, cpu_T0,
6629 tcg_const_i32((TF_MASK |
6637 if (dflag != MO_16) {
6638 gen_helper_write_eflags(cpu_env, cpu_T0,
6639 tcg_const_i32((TF_MASK | AC_MASK |
6640 ID_MASK | NT_MASK)));
6642 gen_helper_write_eflags(cpu_env, cpu_T0,
6643 tcg_const_i32((TF_MASK | AC_MASK |
6649 gen_pop_update(s, ot);
6650 set_cc_op(s, CC_OP_EFLAGS);
6651 /* abort translation because TF/AC flag may change */
6652 gen_jmp_im(s->pc - s->cs_base);
6656 case 0x9e: /* sahf */
6657 if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6659 gen_op_mov_v_reg(MO_8, cpu_T0, R_AH);
6660 gen_compute_eflags(s);
6661 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O);
6662 tcg_gen_andi_tl(cpu_T0, cpu_T0, CC_S | CC_Z | CC_A | CC_P | CC_C);
6663 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_T0);
6665 case 0x9f: /* lahf */
6666 if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6668 gen_compute_eflags(s);
6669 /* Note: gen_compute_eflags() only gives the condition codes */
6670 tcg_gen_ori_tl(cpu_T0, cpu_cc_src, 0x02);
6671 gen_op_mov_reg_v(MO_8, R_AH, cpu_T0);
6673 case 0xf5: /* cmc */
6674 gen_compute_eflags(s);
6675 tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6677 case 0xf8: /* clc */
6678 gen_compute_eflags(s);
6679 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C);
6681 case 0xf9: /* stc */
6682 gen_compute_eflags(s);
6683 tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6685 case 0xfc: /* cld */
6686 tcg_gen_movi_i32(cpu_tmp2_i32, 1);
6687 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, df));
6689 case 0xfd: /* std */
6690 tcg_gen_movi_i32(cpu_tmp2_i32, -1);
6691 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, df));
6694 /************************/
6695 /* bit operations */
6696 case 0x1ba: /* bt/bts/btr/btc Gv, im */
6698 modrm = cpu_ldub_code(env, s->pc++);
6699 op = (modrm >> 3) & 7;
6700 mod = (modrm >> 6) & 3;
6701 rm = (modrm & 7) | REX_B(s);
6704 gen_lea_modrm(env, s, modrm);
6705 if (!(s->prefix & PREFIX_LOCK)) {
6706 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
6709 gen_op_mov_v_reg(ot, cpu_T0, rm);
6712 val = cpu_ldub_code(env, s->pc++);
6713 tcg_gen_movi_tl(cpu_T1, val);
6718 case 0x1a3: /* bt Gv, Ev */
6721 case 0x1ab: /* bts */
6724 case 0x1b3: /* btr */
6727 case 0x1bb: /* btc */
6731 modrm = cpu_ldub_code(env, s->pc++);
6732 reg = ((modrm >> 3) & 7) | rex_r;
6733 mod = (modrm >> 6) & 3;
6734 rm = (modrm & 7) | REX_B(s);
6735 gen_op_mov_v_reg(MO_32, cpu_T1, reg);
6737 AddressParts a = gen_lea_modrm_0(env, s, modrm);
6738 /* specific case: we need to add a displacement */
6739 gen_exts(ot, cpu_T1);
6740 tcg_gen_sari_tl(cpu_tmp0, cpu_T1, 3 + ot);
6741 tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, ot);
6742 tcg_gen_add_tl(cpu_A0, gen_lea_modrm_1(a), cpu_tmp0);
6743 gen_lea_v_seg(s, s->aflag, cpu_A0, a.def_seg, s->override);
6744 if (!(s->prefix & PREFIX_LOCK)) {
6745 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
6748 gen_op_mov_v_reg(ot, cpu_T0, rm);
6751 tcg_gen_andi_tl(cpu_T1, cpu_T1, (1 << (3 + ot)) - 1);
6752 tcg_gen_movi_tl(cpu_tmp0, 1);
6753 tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T1);
6754 if (s->prefix & PREFIX_LOCK) {
6757 /* Needs no atomic ops; we surpressed the normal
6758 memory load for LOCK above so do it now. */
6759 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
6762 tcg_gen_atomic_fetch_or_tl(cpu_T0, cpu_A0, cpu_tmp0,
6763 s->mem_index, ot | MO_LE);
6766 tcg_gen_not_tl(cpu_tmp0, cpu_tmp0);
6767 tcg_gen_atomic_fetch_and_tl(cpu_T0, cpu_A0, cpu_tmp0,
6768 s->mem_index, ot | MO_LE);
6772 tcg_gen_atomic_fetch_xor_tl(cpu_T0, cpu_A0, cpu_tmp0,
6773 s->mem_index, ot | MO_LE);
6776 tcg_gen_shr_tl(cpu_tmp4, cpu_T0, cpu_T1);
6778 tcg_gen_shr_tl(cpu_tmp4, cpu_T0, cpu_T1);
6781 /* Data already loaded; nothing to do. */
6784 tcg_gen_or_tl(cpu_T0, cpu_T0, cpu_tmp0);
6787 tcg_gen_andc_tl(cpu_T0, cpu_T0, cpu_tmp0);
6791 tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_tmp0);
6796 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
6798 gen_op_mov_reg_v(ot, rm, cpu_T0);
6803 /* Delay all CC updates until after the store above. Note that
6804 C is the result of the test, Z is unchanged, and the others
6805 are all undefined. */
6807 case CC_OP_MULB ... CC_OP_MULQ:
6808 case CC_OP_ADDB ... CC_OP_ADDQ:
6809 case CC_OP_ADCB ... CC_OP_ADCQ:
6810 case CC_OP_SUBB ... CC_OP_SUBQ:
6811 case CC_OP_SBBB ... CC_OP_SBBQ:
6812 case CC_OP_LOGICB ... CC_OP_LOGICQ:
6813 case CC_OP_INCB ... CC_OP_INCQ:
6814 case CC_OP_DECB ... CC_OP_DECQ:
6815 case CC_OP_SHLB ... CC_OP_SHLQ:
6816 case CC_OP_SARB ... CC_OP_SARQ:
6817 case CC_OP_BMILGB ... CC_OP_BMILGQ:
6818 /* Z was going to be computed from the non-zero status of CC_DST.
6819 We can get that same Z value (and the new C value) by leaving
6820 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
6822 tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
6823 set_cc_op(s, ((s->cc_op - CC_OP_MULB) & 3) + CC_OP_SARB);
6826 /* Otherwise, generate EFLAGS and replace the C bit. */
6827 gen_compute_eflags(s);
6828 tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, cpu_tmp4,
6833 case 0x1bc: /* bsf / tzcnt */
6834 case 0x1bd: /* bsr / lzcnt */
6836 modrm = cpu_ldub_code(env, s->pc++);
6837 reg = ((modrm >> 3) & 7) | rex_r;
6838 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
6839 gen_extu(ot, cpu_T0);
6841 /* Note that lzcnt and tzcnt are in different extensions. */
6842 if ((prefixes & PREFIX_REPZ)
6844 ? s->cpuid_ext3_features & CPUID_EXT3_ABM
6845 : s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)) {
6847 /* For lzcnt/tzcnt, C bit is defined related to the input. */
6848 tcg_gen_mov_tl(cpu_cc_src, cpu_T0);
6850 /* For lzcnt, reduce the target_ulong result by the
6851 number of zeros that we expect to find at the top. */
6852 tcg_gen_clzi_tl(cpu_T0, cpu_T0, TARGET_LONG_BITS);
6853 tcg_gen_subi_tl(cpu_T0, cpu_T0, TARGET_LONG_BITS - size);
6855 /* For tzcnt, a zero input must return the operand size. */
6856 tcg_gen_ctzi_tl(cpu_T0, cpu_T0, size);
6858 /* For lzcnt/tzcnt, Z bit is defined related to the result. */
6859 gen_op_update1_cc();
6860 set_cc_op(s, CC_OP_BMILGB + ot);
6862 /* For bsr/bsf, only the Z bit is defined and it is related
6863 to the input and not the result. */
6864 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
6865 set_cc_op(s, CC_OP_LOGICB + ot);
6867 /* ??? The manual says that the output is undefined when the
6868 input is zero, but real hardware leaves it unchanged, and
6869 real programs appear to depend on that. Accomplish this
6870 by passing the output as the value to return upon zero. */
6872 /* For bsr, return the bit index of the first 1 bit,
6873 not the count of leading zeros. */
6874 tcg_gen_xori_tl(cpu_T1, cpu_regs[reg], TARGET_LONG_BITS - 1);
6875 tcg_gen_clz_tl(cpu_T0, cpu_T0, cpu_T1);
6876 tcg_gen_xori_tl(cpu_T0, cpu_T0, TARGET_LONG_BITS - 1);
6878 tcg_gen_ctz_tl(cpu_T0, cpu_T0, cpu_regs[reg]);
6881 gen_op_mov_reg_v(ot, reg, cpu_T0);
6883 /************************/
6885 case 0x27: /* daa */
6888 gen_update_cc_op(s);
6889 gen_helper_daa(cpu_env);
6890 set_cc_op(s, CC_OP_EFLAGS);
6892 case 0x2f: /* das */
6895 gen_update_cc_op(s);
6896 gen_helper_das(cpu_env);
6897 set_cc_op(s, CC_OP_EFLAGS);
6899 case 0x37: /* aaa */
6902 gen_update_cc_op(s);
6903 gen_helper_aaa(cpu_env);
6904 set_cc_op(s, CC_OP_EFLAGS);
6906 case 0x3f: /* aas */
6909 gen_update_cc_op(s);
6910 gen_helper_aas(cpu_env);
6911 set_cc_op(s, CC_OP_EFLAGS);
6913 case 0xd4: /* aam */
6916 val = cpu_ldub_code(env, s->pc++);
6918 gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base);
6920 gen_helper_aam(cpu_env, tcg_const_i32(val));
6921 set_cc_op(s, CC_OP_LOGICB);
6924 case 0xd5: /* aad */
6927 val = cpu_ldub_code(env, s->pc++);
6928 gen_helper_aad(cpu_env, tcg_const_i32(val));
6929 set_cc_op(s, CC_OP_LOGICB);
6931 /************************/
6933 case 0x90: /* nop */
6934 /* XXX: correct lock test for all insn */
6935 if (prefixes & PREFIX_LOCK) {
6938 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
6940 goto do_xchg_reg_eax;
6942 if (prefixes & PREFIX_REPZ) {
6943 gen_update_cc_op(s);
6944 gen_jmp_im(pc_start - s->cs_base);
6945 gen_helper_pause(cpu_env, tcg_const_i32(s->pc - pc_start));
6946 s->base.is_jmp = DISAS_NORETURN;
6949 case 0x9b: /* fwait */
6950 if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
6951 (HF_MP_MASK | HF_TS_MASK)) {
6952 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
6954 gen_helper_fwait(cpu_env);
6957 case 0xcc: /* int3 */
6958 gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
6960 case 0xcd: /* int N */
6961 val = cpu_ldub_code(env, s->pc++);
6962 if (s->vm86 && s->iopl != 3) {
6963 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6965 gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
6968 case 0xce: /* into */
6971 gen_update_cc_op(s);
6972 gen_jmp_im(pc_start - s->cs_base);
6973 gen_helper_into(cpu_env, tcg_const_i32(s->pc - pc_start));
6976 case 0xf1: /* icebp (undocumented, exits to external debugger) */
6977 gen_svm_check_intercept(s, pc_start, SVM_EXIT_ICEBP);
6979 gen_debug(s, pc_start - s->cs_base);
6982 tb_flush(CPU(x86_env_get_cpu(env)));
6983 qemu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM);
6987 case 0xfa: /* cli */
6989 if (s->cpl <= s->iopl) {
6990 gen_helper_cli(cpu_env);
6992 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6996 gen_helper_cli(cpu_env);
6998 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7002 case 0xfb: /* sti */
7003 if (s->vm86 ? s->iopl == 3 : s->cpl <= s->iopl) {
7004 gen_helper_sti(cpu_env);
7005 /* interruptions are enabled only the first insn after sti */
7006 gen_jmp_im(s->pc - s->cs_base);
7007 gen_eob_inhibit_irq(s, true);
7009 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7012 case 0x62: /* bound */
7016 modrm = cpu_ldub_code(env, s->pc++);
7017 reg = (modrm >> 3) & 7;
7018 mod = (modrm >> 6) & 3;
7021 gen_op_mov_v_reg(ot, cpu_T0, reg);
7022 gen_lea_modrm(env, s, modrm);
7023 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
7025 gen_helper_boundw(cpu_env, cpu_A0, cpu_tmp2_i32);
7027 gen_helper_boundl(cpu_env, cpu_A0, cpu_tmp2_i32);
7030 case 0x1c8 ... 0x1cf: /* bswap reg */
7031 reg = (b & 7) | REX_B(s);
7032 #ifdef TARGET_X86_64
7033 if (dflag == MO_64) {
7034 gen_op_mov_v_reg(MO_64, cpu_T0, reg);
7035 tcg_gen_bswap64_i64(cpu_T0, cpu_T0);
7036 gen_op_mov_reg_v(MO_64, reg, cpu_T0);
7040 gen_op_mov_v_reg(MO_32, cpu_T0, reg);
7041 tcg_gen_ext32u_tl(cpu_T0, cpu_T0);
7042 tcg_gen_bswap32_tl(cpu_T0, cpu_T0);
7043 gen_op_mov_reg_v(MO_32, reg, cpu_T0);
7046 case 0xd6: /* salc */
7049 gen_compute_eflags_c(s, cpu_T0);
7050 tcg_gen_neg_tl(cpu_T0, cpu_T0);
7051 gen_op_mov_reg_v(MO_8, R_EAX, cpu_T0);
7053 case 0xe0: /* loopnz */
7054 case 0xe1: /* loopz */
7055 case 0xe2: /* loop */
7056 case 0xe3: /* jecxz */
7058 TCGLabel *l1, *l2, *l3;
7060 tval = (int8_t)insn_get(env, s, MO_8);
7061 next_eip = s->pc - s->cs_base;
7063 if (dflag == MO_16) {
7067 l1 = gen_new_label();
7068 l2 = gen_new_label();
7069 l3 = gen_new_label();
7072 case 0: /* loopnz */
7074 gen_op_add_reg_im(s->aflag, R_ECX, -1);
7075 gen_op_jz_ecx(s->aflag, l3);
7076 gen_jcc1(s, (JCC_Z << 1) | (b ^ 1), l1);
7079 gen_op_add_reg_im(s->aflag, R_ECX, -1);
7080 gen_op_jnz_ecx(s->aflag, l1);
7084 gen_op_jz_ecx(s->aflag, l1);
7089 gen_jmp_im(next_eip);
7098 case 0x130: /* wrmsr */
7099 case 0x132: /* rdmsr */
7101 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7103 gen_update_cc_op(s);
7104 gen_jmp_im(pc_start - s->cs_base);
7106 gen_helper_rdmsr(cpu_env);
7108 gen_helper_wrmsr(cpu_env);
7112 case 0x131: /* rdtsc */
7113 gen_update_cc_op(s);
7114 gen_jmp_im(pc_start - s->cs_base);
7115 if (s->base.tb->cflags & CF_USE_ICOUNT) {
7118 gen_helper_rdtsc(cpu_env);
7119 if (s->base.tb->cflags & CF_USE_ICOUNT) {
7121 gen_jmp(s, s->pc - s->cs_base);
7124 case 0x133: /* rdpmc */
7125 gen_update_cc_op(s);
7126 gen_jmp_im(pc_start - s->cs_base);
7127 gen_helper_rdpmc(cpu_env);
7129 case 0x134: /* sysenter */
7130 /* For Intel SYSENTER is valid on 64-bit */
7131 if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
7134 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7136 gen_helper_sysenter(cpu_env);
7140 case 0x135: /* sysexit */
7141 /* For Intel SYSEXIT is valid on 64-bit */
7142 if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
7145 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7147 gen_helper_sysexit(cpu_env, tcg_const_i32(dflag - 1));
7151 #ifdef TARGET_X86_64
7152 case 0x105: /* syscall */
7153 /* XXX: is it usable in real mode ? */
7154 gen_update_cc_op(s);
7155 gen_jmp_im(pc_start - s->cs_base);
7156 gen_helper_syscall(cpu_env, tcg_const_i32(s->pc - pc_start));
7157 /* TF handling for the syscall insn is different. The TF bit is checked
7158 after the syscall insn completes. This allows #DB to not be
7159 generated after one has entered CPL0 if TF is set in FMASK. */
7160 gen_eob_worker(s, false, true);
7162 case 0x107: /* sysret */
7164 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7166 gen_helper_sysret(cpu_env, tcg_const_i32(dflag - 1));
7167 /* condition codes are modified only in long mode */
7169 set_cc_op(s, CC_OP_EFLAGS);
7171 /* TF handling for the sysret insn is different. The TF bit is
7172 checked after the sysret insn completes. This allows #DB to be
7173 generated "as if" the syscall insn in userspace has just
7175 gen_eob_worker(s, false, true);
7179 case 0x1a2: /* cpuid */
7180 gen_update_cc_op(s);
7181 gen_jmp_im(pc_start - s->cs_base);
7182 gen_helper_cpuid(cpu_env);
7184 case 0xf4: /* hlt */
7186 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7188 gen_update_cc_op(s);
7189 gen_jmp_im(pc_start - s->cs_base);
7190 gen_helper_hlt(cpu_env, tcg_const_i32(s->pc - pc_start));
7191 s->base.is_jmp = DISAS_NORETURN;
7195 modrm = cpu_ldub_code(env, s->pc++);
7196 mod = (modrm >> 6) & 3;
7197 op = (modrm >> 3) & 7;
7200 if (!s->pe || s->vm86)
7202 gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_READ);
7203 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
7204 offsetof(CPUX86State, ldt.selector));
7205 ot = mod == 3 ? dflag : MO_16;
7206 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7209 if (!s->pe || s->vm86)
7212 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7214 gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_WRITE);
7215 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7216 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
7217 gen_helper_lldt(cpu_env, cpu_tmp2_i32);
7221 if (!s->pe || s->vm86)
7223 gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_READ);
7224 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
7225 offsetof(CPUX86State, tr.selector));
7226 ot = mod == 3 ? dflag : MO_16;
7227 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7230 if (!s->pe || s->vm86)
7233 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7235 gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_WRITE);
7236 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7237 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
7238 gen_helper_ltr(cpu_env, cpu_tmp2_i32);
7243 if (!s->pe || s->vm86)
7245 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7246 gen_update_cc_op(s);
7248 gen_helper_verr(cpu_env, cpu_T0);
7250 gen_helper_verw(cpu_env, cpu_T0);
7252 set_cc_op(s, CC_OP_EFLAGS);
7260 modrm = cpu_ldub_code(env, s->pc++);
7262 CASE_MODRM_MEM_OP(0): /* sgdt */
7263 gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_READ);
7264 gen_lea_modrm(env, s, modrm);
7265 tcg_gen_ld32u_tl(cpu_T0,
7266 cpu_env, offsetof(CPUX86State, gdt.limit));
7267 gen_op_st_v(s, MO_16, cpu_T0, cpu_A0);
7268 gen_add_A0_im(s, 2);
7269 tcg_gen_ld_tl(cpu_T0, cpu_env, offsetof(CPUX86State, gdt.base));
7270 if (dflag == MO_16) {
7271 tcg_gen_andi_tl(cpu_T0, cpu_T0, 0xffffff);
7273 gen_op_st_v(s, CODE64(s) + MO_32, cpu_T0, cpu_A0);
7276 case 0xc8: /* monitor */
7277 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || s->cpl != 0) {
7280 gen_update_cc_op(s);
7281 gen_jmp_im(pc_start - s->cs_base);
7282 tcg_gen_mov_tl(cpu_A0, cpu_regs[R_EAX]);
7283 gen_extu(s->aflag, cpu_A0);
7284 gen_add_A0_ds_seg(s);
7285 gen_helper_monitor(cpu_env, cpu_A0);
7288 case 0xc9: /* mwait */
7289 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || s->cpl != 0) {
7292 gen_update_cc_op(s);
7293 gen_jmp_im(pc_start - s->cs_base);
7294 gen_helper_mwait(cpu_env, tcg_const_i32(s->pc - pc_start));
7298 case 0xca: /* clac */
7299 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)
7303 gen_helper_clac(cpu_env);
7304 gen_jmp_im(s->pc - s->cs_base);
7308 case 0xcb: /* stac */
7309 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)
7313 gen_helper_stac(cpu_env);
7314 gen_jmp_im(s->pc - s->cs_base);
7318 CASE_MODRM_MEM_OP(1): /* sidt */
7319 gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_READ);
7320 gen_lea_modrm(env, s, modrm);
7321 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State, idt.limit));
7322 gen_op_st_v(s, MO_16, cpu_T0, cpu_A0);
7323 gen_add_A0_im(s, 2);
7324 tcg_gen_ld_tl(cpu_T0, cpu_env, offsetof(CPUX86State, idt.base));
7325 if (dflag == MO_16) {
7326 tcg_gen_andi_tl(cpu_T0, cpu_T0, 0xffffff);
7328 gen_op_st_v(s, CODE64(s) + MO_32, cpu_T0, cpu_A0);
7331 case 0xd0: /* xgetbv */
7332 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
7333 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA
7334 | PREFIX_REPZ | PREFIX_REPNZ))) {
7337 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_ECX]);
7338 gen_helper_xgetbv(cpu_tmp1_i64, cpu_env, cpu_tmp2_i32);
7339 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], cpu_tmp1_i64);
7342 case 0xd1: /* xsetbv */
7343 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
7344 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA
7345 | PREFIX_REPZ | PREFIX_REPNZ))) {
7349 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7352 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
7354 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_ECX]);
7355 gen_helper_xsetbv(cpu_env, cpu_tmp2_i32, cpu_tmp1_i64);
7356 /* End TB because translation flags may change. */
7357 gen_jmp_im(s->pc - s->cs_base);
7361 case 0xd8: /* VMRUN */
7362 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7366 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7369 gen_update_cc_op(s);
7370 gen_jmp_im(pc_start - s->cs_base);
7371 gen_helper_vmrun(cpu_env, tcg_const_i32(s->aflag - 1),
7372 tcg_const_i32(s->pc - pc_start));
7374 s->base.is_jmp = DISAS_NORETURN;
7377 case 0xd9: /* VMMCALL */
7378 if (!(s->flags & HF_SVME_MASK)) {
7381 gen_update_cc_op(s);
7382 gen_jmp_im(pc_start - s->cs_base);
7383 gen_helper_vmmcall(cpu_env);
7386 case 0xda: /* VMLOAD */
7387 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7391 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7394 gen_update_cc_op(s);
7395 gen_jmp_im(pc_start - s->cs_base);
7396 gen_helper_vmload(cpu_env, tcg_const_i32(s->aflag - 1));
7399 case 0xdb: /* VMSAVE */
7400 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7404 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7407 gen_update_cc_op(s);
7408 gen_jmp_im(pc_start - s->cs_base);
7409 gen_helper_vmsave(cpu_env, tcg_const_i32(s->aflag - 1));
7412 case 0xdc: /* STGI */
7413 if ((!(s->flags & HF_SVME_MASK)
7414 && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
7419 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7422 gen_update_cc_op(s);
7423 gen_jmp_im(pc_start - s->cs_base);
7424 gen_helper_stgi(cpu_env);
7427 case 0xdd: /* CLGI */
7428 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7432 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7435 gen_update_cc_op(s);
7436 gen_jmp_im(pc_start - s->cs_base);
7437 gen_helper_clgi(cpu_env);
7440 case 0xde: /* SKINIT */
7441 if ((!(s->flags & HF_SVME_MASK)
7442 && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
7446 gen_update_cc_op(s);
7447 gen_jmp_im(pc_start - s->cs_base);
7448 gen_helper_skinit(cpu_env);
7451 case 0xdf: /* INVLPGA */
7452 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7456 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7459 gen_update_cc_op(s);
7460 gen_jmp_im(pc_start - s->cs_base);
7461 gen_helper_invlpga(cpu_env, tcg_const_i32(s->aflag - 1));
7464 CASE_MODRM_MEM_OP(2): /* lgdt */
7466 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7469 gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_WRITE);
7470 gen_lea_modrm(env, s, modrm);
7471 gen_op_ld_v(s, MO_16, cpu_T1, cpu_A0);
7472 gen_add_A0_im(s, 2);
7473 gen_op_ld_v(s, CODE64(s) + MO_32, cpu_T0, cpu_A0);
7474 if (dflag == MO_16) {
7475 tcg_gen_andi_tl(cpu_T0, cpu_T0, 0xffffff);
7477 tcg_gen_st_tl(cpu_T0, cpu_env, offsetof(CPUX86State, gdt.base));
7478 tcg_gen_st32_tl(cpu_T1, cpu_env, offsetof(CPUX86State, gdt.limit));
7481 CASE_MODRM_MEM_OP(3): /* lidt */
7483 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7486 gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_WRITE);
7487 gen_lea_modrm(env, s, modrm);
7488 gen_op_ld_v(s, MO_16, cpu_T1, cpu_A0);
7489 gen_add_A0_im(s, 2);
7490 gen_op_ld_v(s, CODE64(s) + MO_32, cpu_T0, cpu_A0);
7491 if (dflag == MO_16) {
7492 tcg_gen_andi_tl(cpu_T0, cpu_T0, 0xffffff);
7494 tcg_gen_st_tl(cpu_T0, cpu_env, offsetof(CPUX86State, idt.base));
7495 tcg_gen_st32_tl(cpu_T1, cpu_env, offsetof(CPUX86State, idt.limit));
7498 CASE_MODRM_OP(4): /* smsw */
7499 gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0);
7500 tcg_gen_ld_tl(cpu_T0, cpu_env, offsetof(CPUX86State, cr[0]));
7502 mod = (modrm >> 6) & 3;
7503 ot = (mod != 3 ? MO_16 : s->dflag);
7507 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7509 case 0xee: /* rdpkru */
7510 if (prefixes & PREFIX_LOCK) {
7513 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_ECX]);
7514 gen_helper_rdpkru(cpu_tmp1_i64, cpu_env, cpu_tmp2_i32);
7515 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], cpu_tmp1_i64);
7517 case 0xef: /* wrpkru */
7518 if (prefixes & PREFIX_LOCK) {
7521 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
7523 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_ECX]);
7524 gen_helper_wrpkru(cpu_env, cpu_tmp2_i32, cpu_tmp1_i64);
7526 CASE_MODRM_OP(6): /* lmsw */
7528 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7531 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
7532 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7533 gen_helper_lmsw(cpu_env, cpu_T0);
7534 gen_jmp_im(s->pc - s->cs_base);
7538 CASE_MODRM_MEM_OP(7): /* invlpg */
7540 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7543 gen_update_cc_op(s);
7544 gen_jmp_im(pc_start - s->cs_base);
7545 gen_lea_modrm(env, s, modrm);
7546 gen_helper_invlpg(cpu_env, cpu_A0);
7547 gen_jmp_im(s->pc - s->cs_base);
7551 case 0xf8: /* swapgs */
7552 #ifdef TARGET_X86_64
7555 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7557 tcg_gen_mov_tl(cpu_T0, cpu_seg_base[R_GS]);
7558 tcg_gen_ld_tl(cpu_seg_base[R_GS], cpu_env,
7559 offsetof(CPUX86State, kernelgsbase));
7560 tcg_gen_st_tl(cpu_T0, cpu_env,
7561 offsetof(CPUX86State, kernelgsbase));
7568 case 0xf9: /* rdtscp */
7569 if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP)) {
7572 gen_update_cc_op(s);
7573 gen_jmp_im(pc_start - s->cs_base);
7574 if (s->base.tb->cflags & CF_USE_ICOUNT) {
7577 gen_helper_rdtscp(cpu_env);
7578 if (s->base.tb->cflags & CF_USE_ICOUNT) {
7580 gen_jmp(s, s->pc - s->cs_base);
7589 case 0x108: /* invd */
7590 case 0x109: /* wbinvd */
7592 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7594 gen_svm_check_intercept(s, pc_start, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD);
7598 case 0x63: /* arpl or movslS (x86_64) */
7599 #ifdef TARGET_X86_64
7602 /* d_ot is the size of destination */
7605 modrm = cpu_ldub_code(env, s->pc++);
7606 reg = ((modrm >> 3) & 7) | rex_r;
7607 mod = (modrm >> 6) & 3;
7608 rm = (modrm & 7) | REX_B(s);
7611 gen_op_mov_v_reg(MO_32, cpu_T0, rm);
7613 if (d_ot == MO_64) {
7614 tcg_gen_ext32s_tl(cpu_T0, cpu_T0);
7616 gen_op_mov_reg_v(d_ot, reg, cpu_T0);
7618 gen_lea_modrm(env, s, modrm);
7619 gen_op_ld_v(s, MO_32 | MO_SIGN, cpu_T0, cpu_A0);
7620 gen_op_mov_reg_v(d_ot, reg, cpu_T0);
7626 TCGv t0, t1, t2, a0;
7628 if (!s->pe || s->vm86)
7630 t0 = tcg_temp_local_new();
7631 t1 = tcg_temp_local_new();
7632 t2 = tcg_temp_local_new();
7634 modrm = cpu_ldub_code(env, s->pc++);
7635 reg = (modrm >> 3) & 7;
7636 mod = (modrm >> 6) & 3;
7639 gen_lea_modrm(env, s, modrm);
7640 gen_op_ld_v(s, ot, t0, cpu_A0);
7641 a0 = tcg_temp_local_new();
7642 tcg_gen_mov_tl(a0, cpu_A0);
7644 gen_op_mov_v_reg(ot, t0, rm);
7647 gen_op_mov_v_reg(ot, t1, reg);
7648 tcg_gen_andi_tl(cpu_tmp0, t0, 3);
7649 tcg_gen_andi_tl(t1, t1, 3);
7650 tcg_gen_movi_tl(t2, 0);
7651 label1 = gen_new_label();
7652 tcg_gen_brcond_tl(TCG_COND_GE, cpu_tmp0, t1, label1);
7653 tcg_gen_andi_tl(t0, t0, ~3);
7654 tcg_gen_or_tl(t0, t0, t1);
7655 tcg_gen_movi_tl(t2, CC_Z);
7656 gen_set_label(label1);
7658 gen_op_st_v(s, ot, t0, a0);
7661 gen_op_mov_reg_v(ot, rm, t0);
7663 gen_compute_eflags(s);
7664 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z);
7665 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t2);
7671 case 0x102: /* lar */
7672 case 0x103: /* lsl */
7676 if (!s->pe || s->vm86)
7678 ot = dflag != MO_16 ? MO_32 : MO_16;
7679 modrm = cpu_ldub_code(env, s->pc++);
7680 reg = ((modrm >> 3) & 7) | rex_r;
7681 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7682 t0 = tcg_temp_local_new();
7683 gen_update_cc_op(s);
7685 gen_helper_lar(t0, cpu_env, cpu_T0);
7687 gen_helper_lsl(t0, cpu_env, cpu_T0);
7689 tcg_gen_andi_tl(cpu_tmp0, cpu_cc_src, CC_Z);
7690 label1 = gen_new_label();
7691 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
7692 gen_op_mov_reg_v(ot, reg, t0);
7693 gen_set_label(label1);
7694 set_cc_op(s, CC_OP_EFLAGS);
7699 modrm = cpu_ldub_code(env, s->pc++);
7700 mod = (modrm >> 6) & 3;
7701 op = (modrm >> 3) & 7;
7703 case 0: /* prefetchnta */
7704 case 1: /* prefetchnt0 */
7705 case 2: /* prefetchnt0 */
7706 case 3: /* prefetchnt0 */
7709 gen_nop_modrm(env, s, modrm);
7710 /* nothing more to do */
7712 default: /* nop (multi byte) */
7713 gen_nop_modrm(env, s, modrm);
7718 modrm = cpu_ldub_code(env, s->pc++);
7719 if (s->flags & HF_MPX_EN_MASK) {
7720 mod = (modrm >> 6) & 3;
7721 reg = ((modrm >> 3) & 7) | rex_r;
7722 if (prefixes & PREFIX_REPZ) {
7725 || (prefixes & PREFIX_LOCK)
7726 || s->aflag == MO_16) {
7729 gen_bndck(env, s, modrm, TCG_COND_LTU, cpu_bndl[reg]);
7730 } else if (prefixes & PREFIX_REPNZ) {
7733 || (prefixes & PREFIX_LOCK)
7734 || s->aflag == MO_16) {
7737 TCGv_i64 notu = tcg_temp_new_i64();
7738 tcg_gen_not_i64(notu, cpu_bndu[reg]);
7739 gen_bndck(env, s, modrm, TCG_COND_GTU, notu);
7740 tcg_temp_free_i64(notu);
7741 } else if (prefixes & PREFIX_DATA) {
7742 /* bndmov -- from reg/mem */
7743 if (reg >= 4 || s->aflag == MO_16) {
7747 int reg2 = (modrm & 7) | REX_B(s);
7748 if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) {
7751 if (s->flags & HF_MPX_IU_MASK) {
7752 tcg_gen_mov_i64(cpu_bndl[reg], cpu_bndl[reg2]);
7753 tcg_gen_mov_i64(cpu_bndu[reg], cpu_bndu[reg2]);
7756 gen_lea_modrm(env, s, modrm);
7758 tcg_gen_qemu_ld_i64(cpu_bndl[reg], cpu_A0,
7759 s->mem_index, MO_LEQ);
7760 tcg_gen_addi_tl(cpu_A0, cpu_A0, 8);
7761 tcg_gen_qemu_ld_i64(cpu_bndu[reg], cpu_A0,
7762 s->mem_index, MO_LEQ);
7764 tcg_gen_qemu_ld_i64(cpu_bndl[reg], cpu_A0,
7765 s->mem_index, MO_LEUL);
7766 tcg_gen_addi_tl(cpu_A0, cpu_A0, 4);
7767 tcg_gen_qemu_ld_i64(cpu_bndu[reg], cpu_A0,
7768 s->mem_index, MO_LEUL);
7770 /* bnd registers are now in-use */
7771 gen_set_hflag(s, HF_MPX_IU_MASK);
7773 } else if (mod != 3) {
7775 AddressParts a = gen_lea_modrm_0(env, s, modrm);
7777 || (prefixes & PREFIX_LOCK)
7778 || s->aflag == MO_16
7783 tcg_gen_addi_tl(cpu_A0, cpu_regs[a.base], a.disp);
7785 tcg_gen_movi_tl(cpu_A0, 0);
7787 gen_lea_v_seg(s, s->aflag, cpu_A0, a.def_seg, s->override);
7789 tcg_gen_mov_tl(cpu_T0, cpu_regs[a.index]);
7791 tcg_gen_movi_tl(cpu_T0, 0);
7794 gen_helper_bndldx64(cpu_bndl[reg], cpu_env, cpu_A0, cpu_T0);
7795 tcg_gen_ld_i64(cpu_bndu[reg], cpu_env,
7796 offsetof(CPUX86State, mmx_t0.MMX_Q(0)));
7798 gen_helper_bndldx32(cpu_bndu[reg], cpu_env, cpu_A0, cpu_T0);
7799 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndu[reg]);
7800 tcg_gen_shri_i64(cpu_bndu[reg], cpu_bndu[reg], 32);
7802 gen_set_hflag(s, HF_MPX_IU_MASK);
7805 gen_nop_modrm(env, s, modrm);
7808 modrm = cpu_ldub_code(env, s->pc++);
7809 if (s->flags & HF_MPX_EN_MASK) {
7810 mod = (modrm >> 6) & 3;
7811 reg = ((modrm >> 3) & 7) | rex_r;
7812 if (mod != 3 && (prefixes & PREFIX_REPZ)) {
7815 || (prefixes & PREFIX_LOCK)
7816 || s->aflag == MO_16) {
7819 AddressParts a = gen_lea_modrm_0(env, s, modrm);
7821 tcg_gen_extu_tl_i64(cpu_bndl[reg], cpu_regs[a.base]);
7823 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndl[reg]);
7825 } else if (a.base == -1) {
7826 /* no base register has lower bound of 0 */
7827 tcg_gen_movi_i64(cpu_bndl[reg], 0);
7829 /* rip-relative generates #ud */
7832 tcg_gen_not_tl(cpu_A0, gen_lea_modrm_1(a));
7834 tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
7836 tcg_gen_extu_tl_i64(cpu_bndu[reg], cpu_A0);
7837 /* bnd registers are now in-use */
7838 gen_set_hflag(s, HF_MPX_IU_MASK);
7840 } else if (prefixes & PREFIX_REPNZ) {
7843 || (prefixes & PREFIX_LOCK)
7844 || s->aflag == MO_16) {
7847 gen_bndck(env, s, modrm, TCG_COND_GTU, cpu_bndu[reg]);
7848 } else if (prefixes & PREFIX_DATA) {
7849 /* bndmov -- to reg/mem */
7850 if (reg >= 4 || s->aflag == MO_16) {
7854 int reg2 = (modrm & 7) | REX_B(s);
7855 if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) {
7858 if (s->flags & HF_MPX_IU_MASK) {
7859 tcg_gen_mov_i64(cpu_bndl[reg2], cpu_bndl[reg]);
7860 tcg_gen_mov_i64(cpu_bndu[reg2], cpu_bndu[reg]);
7863 gen_lea_modrm(env, s, modrm);
7865 tcg_gen_qemu_st_i64(cpu_bndl[reg], cpu_A0,
7866 s->mem_index, MO_LEQ);
7867 tcg_gen_addi_tl(cpu_A0, cpu_A0, 8);
7868 tcg_gen_qemu_st_i64(cpu_bndu[reg], cpu_A0,
7869 s->mem_index, MO_LEQ);
7871 tcg_gen_qemu_st_i64(cpu_bndl[reg], cpu_A0,
7872 s->mem_index, MO_LEUL);
7873 tcg_gen_addi_tl(cpu_A0, cpu_A0, 4);
7874 tcg_gen_qemu_st_i64(cpu_bndu[reg], cpu_A0,
7875 s->mem_index, MO_LEUL);
7878 } else if (mod != 3) {
7880 AddressParts a = gen_lea_modrm_0(env, s, modrm);
7882 || (prefixes & PREFIX_LOCK)
7883 || s->aflag == MO_16
7888 tcg_gen_addi_tl(cpu_A0, cpu_regs[a.base], a.disp);
7890 tcg_gen_movi_tl(cpu_A0, 0);
7892 gen_lea_v_seg(s, s->aflag, cpu_A0, a.def_seg, s->override);
7894 tcg_gen_mov_tl(cpu_T0, cpu_regs[a.index]);
7896 tcg_gen_movi_tl(cpu_T0, 0);
7899 gen_helper_bndstx64(cpu_env, cpu_A0, cpu_T0,
7900 cpu_bndl[reg], cpu_bndu[reg]);
7902 gen_helper_bndstx32(cpu_env, cpu_A0, cpu_T0,
7903 cpu_bndl[reg], cpu_bndu[reg]);
7907 gen_nop_modrm(env, s, modrm);
7909 case 0x119: case 0x11c ... 0x11f: /* nop (multi byte) */
7910 modrm = cpu_ldub_code(env, s->pc++);
7911 gen_nop_modrm(env, s, modrm);
7913 case 0x120: /* mov reg, crN */
7914 case 0x122: /* mov crN, reg */
7916 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7918 modrm = cpu_ldub_code(env, s->pc++);
7919 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7920 * AMD documentation (24594.pdf) and testing of
7921 * intel 386 and 486 processors all show that the mod bits
7922 * are assumed to be 1's, regardless of actual values.
7924 rm = (modrm & 7) | REX_B(s);
7925 reg = ((modrm >> 3) & 7) | rex_r;
7930 if ((prefixes & PREFIX_LOCK) && (reg == 0) &&
7931 (s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) {
7940 gen_update_cc_op(s);
7941 gen_jmp_im(pc_start - s->cs_base);
7943 if (s->base.tb->cflags & CF_USE_ICOUNT) {
7946 gen_op_mov_v_reg(ot, cpu_T0, rm);
7947 gen_helper_write_crN(cpu_env, tcg_const_i32(reg),
7949 if (s->base.tb->cflags & CF_USE_ICOUNT) {
7952 gen_jmp_im(s->pc - s->cs_base);
7955 if (s->base.tb->cflags & CF_USE_ICOUNT) {
7958 gen_helper_read_crN(cpu_T0, cpu_env, tcg_const_i32(reg));
7959 gen_op_mov_reg_v(ot, rm, cpu_T0);
7960 if (s->base.tb->cflags & CF_USE_ICOUNT) {
7970 case 0x121: /* mov reg, drN */
7971 case 0x123: /* mov drN, reg */
7973 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7975 modrm = cpu_ldub_code(env, s->pc++);
7976 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7977 * AMD documentation (24594.pdf) and testing of
7978 * intel 386 and 486 processors all show that the mod bits
7979 * are assumed to be 1's, regardless of actual values.
7981 rm = (modrm & 7) | REX_B(s);
7982 reg = ((modrm >> 3) & 7) | rex_r;
7991 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
7992 gen_op_mov_v_reg(ot, cpu_T0, rm);
7993 tcg_gen_movi_i32(cpu_tmp2_i32, reg);
7994 gen_helper_set_dr(cpu_env, cpu_tmp2_i32, cpu_T0);
7995 gen_jmp_im(s->pc - s->cs_base);
7998 gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_DR0 + reg);
7999 tcg_gen_movi_i32(cpu_tmp2_i32, reg);
8000 gen_helper_get_dr(cpu_T0, cpu_env, cpu_tmp2_i32);
8001 gen_op_mov_reg_v(ot, rm, cpu_T0);
8005 case 0x106: /* clts */
8007 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
8009 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
8010 gen_helper_clts(cpu_env);
8011 /* abort block because static cpu state changed */
8012 gen_jmp_im(s->pc - s->cs_base);
8016 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
8017 case 0x1c3: /* MOVNTI reg, mem */
8018 if (!(s->cpuid_features & CPUID_SSE2))
8020 ot = mo_64_32(dflag);
8021 modrm = cpu_ldub_code(env, s->pc++);
8022 mod = (modrm >> 6) & 3;
8025 reg = ((modrm >> 3) & 7) | rex_r;
8026 /* generate a generic store */
8027 gen_ldst_modrm(env, s, modrm, ot, reg, 1);
8030 modrm = cpu_ldub_code(env, s->pc++);
8032 CASE_MODRM_MEM_OP(0): /* fxsave */
8033 if (!(s->cpuid_features & CPUID_FXSR)
8034 || (prefixes & PREFIX_LOCK)) {
8037 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
8038 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
8041 gen_lea_modrm(env, s, modrm);
8042 gen_helper_fxsave(cpu_env, cpu_A0);
8045 CASE_MODRM_MEM_OP(1): /* fxrstor */
8046 if (!(s->cpuid_features & CPUID_FXSR)
8047 || (prefixes & PREFIX_LOCK)) {
8050 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
8051 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
8054 gen_lea_modrm(env, s, modrm);
8055 gen_helper_fxrstor(cpu_env, cpu_A0);
8058 CASE_MODRM_MEM_OP(2): /* ldmxcsr */
8059 if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) {
8062 if (s->flags & HF_TS_MASK) {
8063 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
8066 gen_lea_modrm(env, s, modrm);
8067 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0, s->mem_index, MO_LEUL);
8068 gen_helper_ldmxcsr(cpu_env, cpu_tmp2_i32);
8071 CASE_MODRM_MEM_OP(3): /* stmxcsr */
8072 if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) {
8075 if (s->flags & HF_TS_MASK) {
8076 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
8079 gen_lea_modrm(env, s, modrm);
8080 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State, mxcsr));
8081 gen_op_st_v(s, MO_32, cpu_T0, cpu_A0);
8084 CASE_MODRM_MEM_OP(4): /* xsave */
8085 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
8086 || (prefixes & (PREFIX_LOCK | PREFIX_DATA
8087 | PREFIX_REPZ | PREFIX_REPNZ))) {
8090 gen_lea_modrm(env, s, modrm);
8091 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
8093 gen_helper_xsave(cpu_env, cpu_A0, cpu_tmp1_i64);
8096 CASE_MODRM_MEM_OP(5): /* xrstor */
8097 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
8098 || (prefixes & (PREFIX_LOCK | PREFIX_DATA
8099 | PREFIX_REPZ | PREFIX_REPNZ))) {
8102 gen_lea_modrm(env, s, modrm);
8103 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
8105 gen_helper_xrstor(cpu_env, cpu_A0, cpu_tmp1_i64);
8106 /* XRSTOR is how MPX is enabled, which changes how
8107 we translate. Thus we need to end the TB. */
8108 gen_update_cc_op(s);
8109 gen_jmp_im(s->pc - s->cs_base);
8113 CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */
8114 if (prefixes & PREFIX_LOCK) {
8117 if (prefixes & PREFIX_DATA) {
8119 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLWB)) {
8122 gen_nop_modrm(env, s, modrm);
8125 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
8126 || (s->cpuid_xsave_features & CPUID_XSAVE_XSAVEOPT) == 0
8127 || (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))) {
8130 gen_lea_modrm(env, s, modrm);
8131 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
8133 gen_helper_xsaveopt(cpu_env, cpu_A0, cpu_tmp1_i64);
8137 CASE_MODRM_MEM_OP(7): /* clflush / clflushopt */
8138 if (prefixes & PREFIX_LOCK) {
8141 if (prefixes & PREFIX_DATA) {
8143 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLFLUSHOPT)) {
8148 if ((s->prefix & (PREFIX_REPZ | PREFIX_REPNZ))
8149 || !(s->cpuid_features & CPUID_CLFLUSH)) {
8153 gen_nop_modrm(env, s, modrm);
8156 case 0xc0 ... 0xc7: /* rdfsbase (f3 0f ae /0) */
8157 case 0xc8 ... 0xc8: /* rdgsbase (f3 0f ae /1) */
8158 case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */
8159 case 0xd8 ... 0xd8: /* wrgsbase (f3 0f ae /3) */
8161 && (prefixes & PREFIX_REPZ)
8162 && !(prefixes & PREFIX_LOCK)
8163 && (s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_FSGSBASE)) {
8164 TCGv base, treg, src, dst;
8166 /* Preserve hflags bits by testing CR4 at runtime. */
8167 tcg_gen_movi_i32(cpu_tmp2_i32, CR4_FSGSBASE_MASK);
8168 gen_helper_cr4_testbit(cpu_env, cpu_tmp2_i32);
8170 base = cpu_seg_base[modrm & 8 ? R_GS : R_FS];
8171 treg = cpu_regs[(modrm & 7) | REX_B(s)];
8175 dst = base, src = treg;
8178 dst = treg, src = base;
8181 if (s->dflag == MO_32) {
8182 tcg_gen_ext32u_tl(dst, src);
8184 tcg_gen_mov_tl(dst, src);
8190 case 0xf8: /* sfence / pcommit */
8191 if (prefixes & PREFIX_DATA) {
8193 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_PCOMMIT)
8194 || (prefixes & PREFIX_LOCK)) {
8200 case 0xf9 ... 0xff: /* sfence */
8201 if (!(s->cpuid_features & CPUID_SSE)
8202 || (prefixes & PREFIX_LOCK)) {
8205 tcg_gen_mb(TCG_MO_ST_ST | TCG_BAR_SC);
8207 case 0xe8 ... 0xef: /* lfence */
8208 if (!(s->cpuid_features & CPUID_SSE)
8209 || (prefixes & PREFIX_LOCK)) {
8212 tcg_gen_mb(TCG_MO_LD_LD | TCG_BAR_SC);
8214 case 0xf0 ... 0xf7: /* mfence */
8215 if (!(s->cpuid_features & CPUID_SSE2)
8216 || (prefixes & PREFIX_LOCK)) {
8219 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8227 case 0x10d: /* 3DNow! prefetch(w) */
8228 modrm = cpu_ldub_code(env, s->pc++);
8229 mod = (modrm >> 6) & 3;
8232 gen_nop_modrm(env, s, modrm);
8234 case 0x1aa: /* rsm */
8235 gen_svm_check_intercept(s, pc_start, SVM_EXIT_RSM);
8236 if (!(s->flags & HF_SMM_MASK))
8238 gen_update_cc_op(s);
8239 gen_jmp_im(s->pc - s->cs_base);
8240 gen_helper_rsm(cpu_env);
8243 case 0x1b8: /* SSE4.2 popcnt */
8244 if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) !=
8247 if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT))
8250 modrm = cpu_ldub_code(env, s->pc++);
8251 reg = ((modrm >> 3) & 7) | rex_r;
8253 if (s->prefix & PREFIX_DATA) {
8256 ot = mo_64_32(dflag);
8259 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
8260 gen_extu(ot, cpu_T0);
8261 tcg_gen_mov_tl(cpu_cc_src, cpu_T0);
8262 tcg_gen_ctpop_tl(cpu_T0, cpu_T0);
8263 gen_op_mov_reg_v(ot, reg, cpu_T0);
8265 set_cc_op(s, CC_OP_POPCNT);
8267 case 0x10e ... 0x10f:
8268 /* 3DNow! instructions, ignore prefixes */
8269 s->prefix &= ~(PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA);
8270 case 0x110 ... 0x117:
8271 case 0x128 ... 0x12f:
8272 case 0x138 ... 0x13a:
8273 case 0x150 ... 0x179:
8274 case 0x17c ... 0x17f:
8276 case 0x1c4 ... 0x1c6:
8277 case 0x1d0 ... 0x1fe:
8278 gen_sse(env, s, b, pc_start, rex_r);
8285 gen_illegal_opcode(s);
8288 gen_unknown_opcode(env, s);
8292 void tcg_x86_init(void)
8294 static const char reg_names[CPU_NB_REGS][4] = {
8295 #ifdef TARGET_X86_64
8323 static const char seg_base_names[6][8] = {
8331 static const char bnd_regl_names[4][8] = {
8332 "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb"
8334 static const char bnd_regu_names[4][8] = {
8335 "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub"
8338 static bool initialized;
8345 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
8346 tcg_ctx.tcg_env = cpu_env;
8347 cpu_cc_op = tcg_global_mem_new_i32(cpu_env,
8348 offsetof(CPUX86State, cc_op), "cc_op");
8349 cpu_cc_dst = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_dst),
8351 cpu_cc_src = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src),
8353 cpu_cc_src2 = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src2),
8356 for (i = 0; i < CPU_NB_REGS; ++i) {
8357 cpu_regs[i] = tcg_global_mem_new(cpu_env,
8358 offsetof(CPUX86State, regs[i]),
8362 for (i = 0; i < 6; ++i) {
8364 = tcg_global_mem_new(cpu_env,
8365 offsetof(CPUX86State, segs[i].base),
8369 for (i = 0; i < 4; ++i) {
8371 = tcg_global_mem_new_i64(cpu_env,
8372 offsetof(CPUX86State, bnd_regs[i].lb),
8375 = tcg_global_mem_new_i64(cpu_env,
8376 offsetof(CPUX86State, bnd_regs[i].ub),
8381 static int i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu,
8384 DisasContext *dc = container_of(dcbase, DisasContext, base);
8385 CPUX86State *env = cpu->env_ptr;
8386 uint32_t flags = dc->base.tb->flags;
8387 target_ulong cs_base = dc->base.tb->cs_base;
8389 dc->pe = (flags >> HF_PE_SHIFT) & 1;
8390 dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
8391 dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
8392 dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
8394 dc->vm86 = (flags >> VM_SHIFT) & 1;
8395 dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
8396 dc->iopl = (flags >> IOPL_SHIFT) & 3;
8397 dc->tf = (flags >> TF_SHIFT) & 1;
8398 dc->cc_op = CC_OP_DYNAMIC;
8399 dc->cc_op_dirty = false;
8400 dc->cs_base = cs_base;
8401 dc->popl_esp_hack = 0;
8402 /* select memory access functions */
8404 #ifdef CONFIG_SOFTMMU
8405 dc->mem_index = cpu_mmu_index(env, false);
8407 dc->cpuid_features = env->features[FEAT_1_EDX];
8408 dc->cpuid_ext_features = env->features[FEAT_1_ECX];
8409 dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX];
8410 dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX];
8411 dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX];
8412 dc->cpuid_xsave_features = env->features[FEAT_XSAVE];
8413 #ifdef TARGET_X86_64
8414 dc->lma = (flags >> HF_LMA_SHIFT) & 1;
8415 dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
8418 dc->jmp_opt = !(dc->tf || dc->base.singlestep_enabled ||
8419 (flags & HF_INHIBIT_IRQ_MASK));
8420 /* Do not optimize repz jumps at all in icount mode, because
8421 rep movsS instructions are execured with different paths
8422 in !repz_opt and repz_opt modes. The first one was used
8423 always except single step mode. And this setting
8424 disables jumps optimization and control paths become
8425 equivalent in run and single step modes.
8426 Now there will be no jump optimization for repz in
8427 record/replay modes and there will always be an
8428 additional step for ecx=0 when icount is enabled.
8430 dc->repz_opt = !dc->jmp_opt && !(dc->base.tb->cflags & CF_USE_ICOUNT);
8432 /* check addseg logic */
8433 if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
8434 printf("ERROR addseg\n");
8437 cpu_T0 = tcg_temp_new();
8438 cpu_T1 = tcg_temp_new();
8439 cpu_A0 = tcg_temp_new();
8441 cpu_tmp0 = tcg_temp_new();
8442 cpu_tmp1_i64 = tcg_temp_new_i64();
8443 cpu_tmp2_i32 = tcg_temp_new_i32();
8444 cpu_tmp3_i32 = tcg_temp_new_i32();
8445 cpu_tmp4 = tcg_temp_new();
8446 cpu_ptr0 = tcg_temp_new_ptr();
8447 cpu_ptr1 = tcg_temp_new_ptr();
8448 cpu_cc_srcT = tcg_temp_local_new();
8453 static void i386_tr_tb_start(DisasContextBase *db, CPUState *cpu)
8457 static void i386_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
8459 DisasContext *dc = container_of(dcbase, DisasContext, base);
8461 tcg_gen_insn_start(dc->base.pc_next, dc->cc_op);
8464 static bool i386_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
8465 const CPUBreakpoint *bp)
8467 DisasContext *dc = container_of(dcbase, DisasContext, base);
8468 /* If RF is set, suppress an internally generated breakpoint. */
8469 int flags = dc->base.tb->flags & HF_RF_MASK ? BP_GDB : BP_ANY;
8470 if (bp->flags & flags) {
8471 gen_debug(dc, dc->base.pc_next - dc->cs_base);
8472 dc->base.is_jmp = DISAS_NORETURN;
8473 /* The address covered by the breakpoint must be included in
8474 [tb->pc, tb->pc + tb->size) in order to for it to be
8475 properly cleared -- thus we increment the PC here so that
8476 the generic logic setting tb->size later does the right thing. */
8477 dc->base.pc_next += 1;
8484 static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
8486 DisasContext *dc = container_of(dcbase, DisasContext, base);
8487 target_ulong pc_next = disas_insn(dc, cpu);
8489 if (dc->tf || (dc->base.tb->flags & HF_INHIBIT_IRQ_MASK)) {
8490 /* if single step mode, we generate only one instruction and
8491 generate an exception */
8492 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
8493 the flag and abort the translation to give the irqs a
8495 dc->base.is_jmp = DISAS_TOO_MANY;
8496 } else if ((dc->base.tb->cflags & CF_USE_ICOUNT)
8497 && ((dc->base.pc_next & TARGET_PAGE_MASK)
8498 != ((dc->base.pc_next + TARGET_MAX_INSN_SIZE - 1)
8500 || (dc->base.pc_next & ~TARGET_PAGE_MASK) == 0)) {
8501 /* Do not cross the boundary of the pages in icount mode,
8502 it can cause an exception. Do it only when boundary is
8503 crossed by the first instruction in the block.
8504 If current instruction already crossed the bound - it's ok,
8505 because an exception hasn't stopped this code.
8507 dc->base.is_jmp = DISAS_TOO_MANY;
8508 } else if ((pc_next - dc->base.pc_first) >= (TARGET_PAGE_SIZE - 32)) {
8509 dc->base.is_jmp = DISAS_TOO_MANY;
8512 dc->base.pc_next = pc_next;
8515 static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
8517 DisasContext *dc = container_of(dcbase, DisasContext, base);
8519 if (dc->base.is_jmp == DISAS_TOO_MANY) {
8520 gen_jmp_im(dc->base.pc_next - dc->cs_base);
8525 static void i386_tr_disas_log(const DisasContextBase *dcbase,
8528 DisasContext *dc = container_of(dcbase, DisasContext, base);
8529 int disas_flags = !dc->code32;
8531 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
8532 #ifdef TARGET_X86_64
8537 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size, disas_flags);
8540 static const TranslatorOps i386_tr_ops = {
8541 .init_disas_context = i386_tr_init_disas_context,
8542 .tb_start = i386_tr_tb_start,
8543 .insn_start = i386_tr_insn_start,
8544 .breakpoint_check = i386_tr_breakpoint_check,
8545 .translate_insn = i386_tr_translate_insn,
8546 .tb_stop = i386_tr_tb_stop,
8547 .disas_log = i386_tr_disas_log,
8550 /* generate intermediate code for basic block 'tb'. */
8551 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
8555 translator_loop(&i386_tr_ops, &dc.base, cpu, tb);
8558 void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb,
8561 int cc_op = data[1];
8562 env->eip = data[0] - tb->cs_base;
8563 if (cc_op != CC_OP_DYNAMIC) {