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"
25 #include "exec/cpu_ldst.h"
27 #include "exec/helper-proto.h"
28 #include "exec/helper-gen.h"
30 #include "trace-tcg.h"
34 #define PREFIX_REPZ 0x01
35 #define PREFIX_REPNZ 0x02
36 #define PREFIX_LOCK 0x04
37 #define PREFIX_DATA 0x08
38 #define PREFIX_ADR 0x10
39 #define PREFIX_VEX 0x20
42 #define CODE64(s) ((s)->code64)
43 #define REX_X(s) ((s)->rex_x)
44 #define REX_B(s) ((s)->rex_b)
59 //#define MACRO_TEST 1
61 /* global register indexes */
62 static TCGv_ptr cpu_env;
64 static TCGv cpu_cc_dst, cpu_cc_src, cpu_cc_src2, cpu_cc_srcT;
65 static TCGv_i32 cpu_cc_op;
66 static TCGv cpu_regs[CPU_NB_REGS];
67 static TCGv cpu_seg_base[6];
70 /* local register indexes (only used inside old micro ops) */
71 static TCGv cpu_tmp0, cpu_tmp4;
72 static TCGv_ptr cpu_ptr0, cpu_ptr1;
73 static TCGv_i32 cpu_tmp2_i32, cpu_tmp3_i32;
74 static TCGv_i64 cpu_tmp1_i64;
76 #include "exec/gen-icount.h"
79 static int x86_64_hregs;
82 typedef struct DisasContext {
83 /* current insn context */
84 int override; /* -1 if no override */
88 target_ulong pc; /* pc = eip + cs_base */
89 int is_jmp; /* 1 = means jump (stop translation), 2 means CPU
90 static state change (stop translation) */
91 /* current block context */
92 target_ulong cs_base; /* base of CS segment */
93 int pe; /* protected mode */
94 int code32; /* 32 bit code segment */
96 int lma; /* long mode active */
97 int code64; /* 64 bit code segment */
100 int vex_l; /* vex vector length */
101 int vex_v; /* vex vvvv register, without 1's compliment. */
102 int ss32; /* 32 bit stack segment */
103 CCOp cc_op; /* current CC operation */
105 int addseg; /* non zero if either DS/ES/SS have a non zero base */
106 int f_st; /* currently unused */
107 int vm86; /* vm86 mode */
110 int tf; /* TF cpu flag */
111 int singlestep_enabled; /* "hardware" single step enabled */
112 int jmp_opt; /* use direct block chaining for direct jumps */
113 int repz_opt; /* optimize jumps within repz instructions */
114 int mem_index; /* select memory access functions */
115 uint64_t flags; /* all execution flags */
116 struct TranslationBlock *tb;
117 int popl_esp_hack; /* for correct popl with esp base handling */
118 int rip_offset; /* only used in x86_64, but left for simplicity */
120 int cpuid_ext_features;
121 int cpuid_ext2_features;
122 int cpuid_ext3_features;
123 int cpuid_7_0_ebx_features;
126 static void gen_eob(DisasContext *s);
127 static void gen_jmp(DisasContext *s, target_ulong eip);
128 static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num);
129 static void gen_op(DisasContext *s1, int op, TCGMemOp ot, int d);
131 /* i386 arith/logic operations */
151 OP_SHL1, /* undocumented */
167 /* I386 int registers */
168 OR_EAX, /* MUST be even numbered */
177 OR_TMP0 = 16, /* temporary operand register */
179 OR_A0, /* temporary register used when doing address evaluation */
189 /* Bit set if the global variable is live after setting CC_OP to X. */
190 static const uint8_t cc_op_live[CC_OP_NB] = {
191 [CC_OP_DYNAMIC] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
192 [CC_OP_EFLAGS] = USES_CC_SRC,
193 [CC_OP_MULB ... CC_OP_MULQ] = USES_CC_DST | USES_CC_SRC,
194 [CC_OP_ADDB ... CC_OP_ADDQ] = USES_CC_DST | USES_CC_SRC,
195 [CC_OP_ADCB ... CC_OP_ADCQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
196 [CC_OP_SUBB ... CC_OP_SUBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRCT,
197 [CC_OP_SBBB ... CC_OP_SBBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
198 [CC_OP_LOGICB ... CC_OP_LOGICQ] = USES_CC_DST,
199 [CC_OP_INCB ... CC_OP_INCQ] = USES_CC_DST | USES_CC_SRC,
200 [CC_OP_DECB ... CC_OP_DECQ] = USES_CC_DST | USES_CC_SRC,
201 [CC_OP_SHLB ... CC_OP_SHLQ] = USES_CC_DST | USES_CC_SRC,
202 [CC_OP_SARB ... CC_OP_SARQ] = USES_CC_DST | USES_CC_SRC,
203 [CC_OP_BMILGB ... CC_OP_BMILGQ] = USES_CC_DST | USES_CC_SRC,
204 [CC_OP_ADCX] = USES_CC_DST | USES_CC_SRC,
205 [CC_OP_ADOX] = USES_CC_SRC | USES_CC_SRC2,
206 [CC_OP_ADCOX] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
210 static void set_cc_op(DisasContext *s, CCOp op)
214 if (s->cc_op == op) {
218 /* Discard CC computation that will no longer be used. */
219 dead = cc_op_live[s->cc_op] & ~cc_op_live[op];
220 if (dead & USES_CC_DST) {
221 tcg_gen_discard_tl(cpu_cc_dst);
223 if (dead & USES_CC_SRC) {
224 tcg_gen_discard_tl(cpu_cc_src);
226 if (dead & USES_CC_SRC2) {
227 tcg_gen_discard_tl(cpu_cc_src2);
229 if (dead & USES_CC_SRCT) {
230 tcg_gen_discard_tl(cpu_cc_srcT);
233 if (op == CC_OP_DYNAMIC) {
234 /* The DYNAMIC setting is translator only, and should never be
235 stored. Thus we always consider it clean. */
236 s->cc_op_dirty = false;
238 /* Discard any computed CC_OP value (see shifts). */
239 if (s->cc_op == CC_OP_DYNAMIC) {
240 tcg_gen_discard_i32(cpu_cc_op);
242 s->cc_op_dirty = true;
247 static void gen_update_cc_op(DisasContext *s)
249 if (s->cc_op_dirty) {
250 tcg_gen_movi_i32(cpu_cc_op, s->cc_op);
251 s->cc_op_dirty = false;
257 #define NB_OP_SIZES 4
259 #else /* !TARGET_X86_64 */
261 #define NB_OP_SIZES 3
263 #endif /* !TARGET_X86_64 */
265 #if defined(HOST_WORDS_BIGENDIAN)
266 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
267 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
268 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
269 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
270 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
272 #define REG_B_OFFSET 0
273 #define REG_H_OFFSET 1
274 #define REG_W_OFFSET 0
275 #define REG_L_OFFSET 0
276 #define REG_LH_OFFSET 4
279 /* In instruction encodings for byte register accesses the
280 * register number usually indicates "low 8 bits of register N";
281 * however there are some special cases where N 4..7 indicates
282 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
283 * true for this special case, false otherwise.
285 static inline bool byte_reg_is_xH(int reg)
291 if (reg >= 8 || x86_64_hregs) {
298 /* Select the size of a push/pop operation. */
299 static inline TCGMemOp mo_pushpop(DisasContext *s, TCGMemOp ot)
302 return ot == MO_16 ? MO_16 : MO_64;
308 /* Select the size of the stack pointer. */
309 static inline TCGMemOp mo_stacksize(DisasContext *s)
311 return CODE64(s) ? MO_64 : s->ss32 ? MO_32 : MO_16;
314 /* Select only size 64 else 32. Used for SSE operand sizes. */
315 static inline TCGMemOp mo_64_32(TCGMemOp ot)
318 return ot == MO_64 ? MO_64 : MO_32;
324 /* Select size 8 if lsb of B is clear, else OT. Used for decoding
325 byte vs word opcodes. */
326 static inline TCGMemOp mo_b_d(int b, TCGMemOp ot)
328 return b & 1 ? ot : MO_8;
331 /* Select size 8 if lsb of B is clear, else OT capped at 32.
332 Used for decoding operand size of port opcodes. */
333 static inline TCGMemOp mo_b_d32(int b, TCGMemOp ot)
335 return b & 1 ? (ot == MO_16 ? MO_16 : MO_32) : MO_8;
338 static void gen_op_mov_reg_v(TCGMemOp ot, int reg, TCGv t0)
342 if (!byte_reg_is_xH(reg)) {
343 tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 8);
345 tcg_gen_deposit_tl(cpu_regs[reg - 4], cpu_regs[reg - 4], t0, 8, 8);
349 tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 16);
352 /* For x86_64, this sets the higher half of register to zero.
353 For i386, this is equivalent to a mov. */
354 tcg_gen_ext32u_tl(cpu_regs[reg], t0);
358 tcg_gen_mov_tl(cpu_regs[reg], t0);
366 static inline void gen_op_mov_v_reg(TCGMemOp ot, TCGv t0, int reg)
368 if (ot == MO_8 && byte_reg_is_xH(reg)) {
369 tcg_gen_shri_tl(t0, cpu_regs[reg - 4], 8);
370 tcg_gen_ext8u_tl(t0, t0);
372 tcg_gen_mov_tl(t0, cpu_regs[reg]);
376 static inline void gen_op_movl_A0_reg(int reg)
378 tcg_gen_mov_tl(cpu_A0, cpu_regs[reg]);
381 static inline void gen_op_addl_A0_im(int32_t val)
383 tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
385 tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
390 static inline void gen_op_addq_A0_im(int64_t val)
392 tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
396 static void gen_add_A0_im(DisasContext *s, int val)
400 gen_op_addq_A0_im(val);
403 gen_op_addl_A0_im(val);
406 static inline void gen_op_jmp_v(TCGv dest)
408 tcg_gen_st_tl(dest, cpu_env, offsetof(CPUX86State, eip));
411 static inline void gen_op_add_reg_im(TCGMemOp size, int reg, int32_t val)
413 tcg_gen_addi_tl(cpu_tmp0, cpu_regs[reg], val);
414 gen_op_mov_reg_v(size, reg, cpu_tmp0);
417 static inline void gen_op_add_reg_T0(TCGMemOp size, int reg)
419 tcg_gen_add_tl(cpu_tmp0, cpu_regs[reg], cpu_T[0]);
420 gen_op_mov_reg_v(size, reg, cpu_tmp0);
423 static inline void gen_op_addl_A0_seg(DisasContext *s, int reg)
426 tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
427 tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_seg_base[reg]);
429 tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_seg_base[reg]);
430 tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
434 static inline void gen_op_ld_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
436 tcg_gen_qemu_ld_tl(t0, a0, s->mem_index, idx | MO_LE);
439 static inline void gen_op_st_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
441 tcg_gen_qemu_st_tl(t0, a0, s->mem_index, idx | MO_LE);
444 static inline void gen_op_st_rm_T0_A0(DisasContext *s, int idx, int d)
447 gen_op_st_v(s, idx, cpu_T[0], cpu_A0);
449 gen_op_mov_reg_v(idx, d, cpu_T[0]);
453 static inline void gen_jmp_im(target_ulong pc)
455 tcg_gen_movi_tl(cpu_tmp0, pc);
456 gen_op_jmp_v(cpu_tmp0);
459 /* Compute SEG:REG into A0. SEG is selected from the override segment
460 (OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to
461 indicate no override. */
462 static void gen_lea_v_seg(DisasContext *s, TCGMemOp aflag, TCGv a0,
463 int def_seg, int ovr_seg)
469 tcg_gen_mov_tl(cpu_A0, a0);
480 tcg_gen_ext32u_tl(cpu_A0, a0);
490 tcg_gen_ext16u_tl(cpu_A0, a0);
491 /* ADDSEG will only be false in 16-bit mode for LEA. */
502 TCGv seg = cpu_seg_base[ovr_seg];
504 if (aflag == MO_64) {
505 tcg_gen_add_tl(cpu_A0, a0, seg);
506 } else if (CODE64(s)) {
507 tcg_gen_ext32u_tl(cpu_A0, a0);
508 tcg_gen_add_tl(cpu_A0, cpu_A0, seg);
510 tcg_gen_add_tl(cpu_A0, a0, seg);
511 tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
516 static inline void gen_string_movl_A0_ESI(DisasContext *s)
518 gen_lea_v_seg(s, s->aflag, cpu_regs[R_ESI], R_DS, s->override);
521 static inline void gen_string_movl_A0_EDI(DisasContext *s)
523 gen_lea_v_seg(s, s->aflag, cpu_regs[R_EDI], R_ES, -1);
526 static inline void gen_op_movl_T0_Dshift(TCGMemOp ot)
528 tcg_gen_ld32s_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, df));
529 tcg_gen_shli_tl(cpu_T[0], cpu_T[0], ot);
532 static TCGv gen_ext_tl(TCGv dst, TCGv src, TCGMemOp size, bool sign)
537 tcg_gen_ext8s_tl(dst, src);
539 tcg_gen_ext8u_tl(dst, src);
544 tcg_gen_ext16s_tl(dst, src);
546 tcg_gen_ext16u_tl(dst, src);
552 tcg_gen_ext32s_tl(dst, src);
554 tcg_gen_ext32u_tl(dst, src);
563 static void gen_extu(TCGMemOp ot, TCGv reg)
565 gen_ext_tl(reg, reg, ot, false);
568 static void gen_exts(TCGMemOp ot, TCGv reg)
570 gen_ext_tl(reg, reg, ot, true);
573 static inline void gen_op_jnz_ecx(TCGMemOp size, TCGLabel *label1)
575 tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
576 gen_extu(size, cpu_tmp0);
577 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_tmp0, 0, label1);
580 static inline void gen_op_jz_ecx(TCGMemOp size, TCGLabel *label1)
582 tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
583 gen_extu(size, cpu_tmp0);
584 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
587 static void gen_helper_in_func(TCGMemOp ot, TCGv v, TCGv_i32 n)
591 gen_helper_inb(v, cpu_env, n);
594 gen_helper_inw(v, cpu_env, n);
597 gen_helper_inl(v, cpu_env, n);
604 static void gen_helper_out_func(TCGMemOp ot, TCGv_i32 v, TCGv_i32 n)
608 gen_helper_outb(cpu_env, v, n);
611 gen_helper_outw(cpu_env, v, n);
614 gen_helper_outl(cpu_env, v, n);
621 static void gen_check_io(DisasContext *s, TCGMemOp ot, target_ulong cur_eip,
624 target_ulong next_eip;
626 if (s->pe && (s->cpl > s->iopl || s->vm86)) {
627 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
630 gen_helper_check_iob(cpu_env, cpu_tmp2_i32);
633 gen_helper_check_iow(cpu_env, cpu_tmp2_i32);
636 gen_helper_check_iol(cpu_env, cpu_tmp2_i32);
642 if(s->flags & HF_SVMI_MASK) {
645 svm_flags |= (1 << (4 + ot));
646 next_eip = s->pc - s->cs_base;
647 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
648 gen_helper_svm_check_io(cpu_env, cpu_tmp2_i32,
649 tcg_const_i32(svm_flags),
650 tcg_const_i32(next_eip - cur_eip));
654 static inline void gen_movs(DisasContext *s, TCGMemOp ot)
656 gen_string_movl_A0_ESI(s);
657 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
658 gen_string_movl_A0_EDI(s);
659 gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
660 gen_op_movl_T0_Dshift(ot);
661 gen_op_add_reg_T0(s->aflag, R_ESI);
662 gen_op_add_reg_T0(s->aflag, R_EDI);
665 static void gen_op_update1_cc(void)
667 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
670 static void gen_op_update2_cc(void)
672 tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
673 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
676 static void gen_op_update3_cc(TCGv reg)
678 tcg_gen_mov_tl(cpu_cc_src2, reg);
679 tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
680 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
683 static inline void gen_op_testl_T0_T1_cc(void)
685 tcg_gen_and_tl(cpu_cc_dst, cpu_T[0], cpu_T[1]);
688 static void gen_op_update_neg_cc(void)
690 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
691 tcg_gen_neg_tl(cpu_cc_src, cpu_T[0]);
692 tcg_gen_movi_tl(cpu_cc_srcT, 0);
695 /* compute all eflags to cc_src */
696 static void gen_compute_eflags(DisasContext *s)
698 TCGv zero, dst, src1, src2;
701 if (s->cc_op == CC_OP_EFLAGS) {
704 if (s->cc_op == CC_OP_CLR) {
705 tcg_gen_movi_tl(cpu_cc_src, CC_Z | CC_P);
706 set_cc_op(s, CC_OP_EFLAGS);
715 /* Take care to not read values that are not live. */
716 live = cc_op_live[s->cc_op] & ~USES_CC_SRCT;
717 dead = live ^ (USES_CC_DST | USES_CC_SRC | USES_CC_SRC2);
719 zero = tcg_const_tl(0);
720 if (dead & USES_CC_DST) {
723 if (dead & USES_CC_SRC) {
726 if (dead & USES_CC_SRC2) {
732 gen_helper_cc_compute_all(cpu_cc_src, dst, src1, src2, cpu_cc_op);
733 set_cc_op(s, CC_OP_EFLAGS);
740 typedef struct CCPrepare {
750 /* compute eflags.C to reg */
751 static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg)
757 case CC_OP_SUBB ... CC_OP_SUBQ:
758 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
759 size = s->cc_op - CC_OP_SUBB;
760 t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
761 /* If no temporary was used, be careful not to alias t1 and t0. */
762 t0 = TCGV_EQUAL(t1, cpu_cc_src) ? cpu_tmp0 : reg;
763 tcg_gen_mov_tl(t0, cpu_cc_srcT);
767 case CC_OP_ADDB ... CC_OP_ADDQ:
768 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
769 size = s->cc_op - CC_OP_ADDB;
770 t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
771 t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
773 return (CCPrepare) { .cond = TCG_COND_LTU, .reg = t0,
774 .reg2 = t1, .mask = -1, .use_reg2 = true };
776 case CC_OP_LOGICB ... CC_OP_LOGICQ:
778 return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
780 case CC_OP_INCB ... CC_OP_INCQ:
781 case CC_OP_DECB ... CC_OP_DECQ:
782 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
783 .mask = -1, .no_setcond = true };
785 case CC_OP_SHLB ... CC_OP_SHLQ:
786 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
787 size = s->cc_op - CC_OP_SHLB;
788 shift = (8 << size) - 1;
789 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
790 .mask = (target_ulong)1 << shift };
792 case CC_OP_MULB ... CC_OP_MULQ:
793 return (CCPrepare) { .cond = TCG_COND_NE,
794 .reg = cpu_cc_src, .mask = -1 };
796 case CC_OP_BMILGB ... CC_OP_BMILGQ:
797 size = s->cc_op - CC_OP_BMILGB;
798 t0 = gen_ext_tl(reg, cpu_cc_src, size, false);
799 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 };
803 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_dst,
804 .mask = -1, .no_setcond = true };
807 case CC_OP_SARB ... CC_OP_SARQ:
809 return (CCPrepare) { .cond = TCG_COND_NE,
810 .reg = cpu_cc_src, .mask = CC_C };
813 /* The need to compute only C from CC_OP_DYNAMIC is important
814 in efficiently implementing e.g. INC at the start of a TB. */
816 gen_helper_cc_compute_c(reg, cpu_cc_dst, cpu_cc_src,
817 cpu_cc_src2, cpu_cc_op);
818 return (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
819 .mask = -1, .no_setcond = true };
823 /* compute eflags.P to reg */
824 static CCPrepare gen_prepare_eflags_p(DisasContext *s, TCGv reg)
826 gen_compute_eflags(s);
827 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
831 /* compute eflags.S to reg */
832 static CCPrepare gen_prepare_eflags_s(DisasContext *s, TCGv reg)
836 gen_compute_eflags(s);
842 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
845 return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
848 TCGMemOp size = (s->cc_op - CC_OP_ADDB) & 3;
849 TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, true);
850 return (CCPrepare) { .cond = TCG_COND_LT, .reg = t0, .mask = -1 };
855 /* compute eflags.O to reg */
856 static CCPrepare gen_prepare_eflags_o(DisasContext *s, TCGv reg)
861 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src2,
862 .mask = -1, .no_setcond = true };
864 return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
866 gen_compute_eflags(s);
867 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
872 /* compute eflags.Z to reg */
873 static CCPrepare gen_prepare_eflags_z(DisasContext *s, TCGv reg)
877 gen_compute_eflags(s);
883 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
886 return (CCPrepare) { .cond = TCG_COND_ALWAYS, .mask = -1 };
889 TCGMemOp size = (s->cc_op - CC_OP_ADDB) & 3;
890 TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
891 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 };
896 /* perform a conditional store into register 'reg' according to jump opcode
897 value 'b'. In the fast case, T0 is guaranted not to be used. */
898 static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg)
900 int inv, jcc_op, cond;
906 jcc_op = (b >> 1) & 7;
909 case CC_OP_SUBB ... CC_OP_SUBQ:
910 /* We optimize relational operators for the cmp/jcc case. */
911 size = s->cc_op - CC_OP_SUBB;
914 tcg_gen_mov_tl(cpu_tmp4, cpu_cc_srcT);
915 gen_extu(size, cpu_tmp4);
916 t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
917 cc = (CCPrepare) { .cond = TCG_COND_LEU, .reg = cpu_tmp4,
918 .reg2 = t0, .mask = -1, .use_reg2 = true };
927 tcg_gen_mov_tl(cpu_tmp4, cpu_cc_srcT);
928 gen_exts(size, cpu_tmp4);
929 t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, true);
930 cc = (CCPrepare) { .cond = cond, .reg = cpu_tmp4,
931 .reg2 = t0, .mask = -1, .use_reg2 = true };
941 /* This actually generates good code for JC, JZ and JS. */
944 cc = gen_prepare_eflags_o(s, reg);
947 cc = gen_prepare_eflags_c(s, reg);
950 cc = gen_prepare_eflags_z(s, reg);
953 gen_compute_eflags(s);
954 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
955 .mask = CC_Z | CC_C };
958 cc = gen_prepare_eflags_s(s, reg);
961 cc = gen_prepare_eflags_p(s, reg);
964 gen_compute_eflags(s);
965 if (TCGV_EQUAL(reg, cpu_cc_src)) {
968 tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */
969 tcg_gen_xor_tl(reg, reg, cpu_cc_src);
970 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
975 gen_compute_eflags(s);
976 if (TCGV_EQUAL(reg, cpu_cc_src)) {
979 tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */
980 tcg_gen_xor_tl(reg, reg, cpu_cc_src);
981 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
982 .mask = CC_S | CC_Z };
989 cc.cond = tcg_invert_cond(cc.cond);
994 static void gen_setcc1(DisasContext *s, int b, TCGv reg)
996 CCPrepare cc = gen_prepare_cc(s, b, reg);
999 if (cc.cond == TCG_COND_EQ) {
1000 tcg_gen_xori_tl(reg, cc.reg, 1);
1002 tcg_gen_mov_tl(reg, cc.reg);
1007 if (cc.cond == TCG_COND_NE && !cc.use_reg2 && cc.imm == 0 &&
1008 cc.mask != 0 && (cc.mask & (cc.mask - 1)) == 0) {
1009 tcg_gen_shri_tl(reg, cc.reg, ctztl(cc.mask));
1010 tcg_gen_andi_tl(reg, reg, 1);
1013 if (cc.mask != -1) {
1014 tcg_gen_andi_tl(reg, cc.reg, cc.mask);
1018 tcg_gen_setcond_tl(cc.cond, reg, cc.reg, cc.reg2);
1020 tcg_gen_setcondi_tl(cc.cond, reg, cc.reg, cc.imm);
1024 static inline void gen_compute_eflags_c(DisasContext *s, TCGv reg)
1026 gen_setcc1(s, JCC_B << 1, reg);
1029 /* generate a conditional jump to label 'l1' according to jump opcode
1030 value 'b'. In the fast case, T0 is guaranted not to be used. */
1031 static inline void gen_jcc1_noeob(DisasContext *s, int b, TCGLabel *l1)
1033 CCPrepare cc = gen_prepare_cc(s, b, cpu_T[0]);
1035 if (cc.mask != -1) {
1036 tcg_gen_andi_tl(cpu_T[0], cc.reg, cc.mask);
1040 tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1042 tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1046 /* Generate a conditional jump to label 'l1' according to jump opcode
1047 value 'b'. In the fast case, T0 is guaranted not to be used.
1048 A translation block must end soon. */
1049 static inline void gen_jcc1(DisasContext *s, int b, TCGLabel *l1)
1051 CCPrepare cc = gen_prepare_cc(s, b, cpu_T[0]);
1053 gen_update_cc_op(s);
1054 if (cc.mask != -1) {
1055 tcg_gen_andi_tl(cpu_T[0], cc.reg, cc.mask);
1058 set_cc_op(s, CC_OP_DYNAMIC);
1060 tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1062 tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1066 /* XXX: does not work with gdbstub "ice" single step - not a
1068 static TCGLabel *gen_jz_ecx_string(DisasContext *s, target_ulong next_eip)
1070 TCGLabel *l1 = gen_new_label();
1071 TCGLabel *l2 = gen_new_label();
1072 gen_op_jnz_ecx(s->aflag, l1);
1074 gen_jmp_tb(s, next_eip, 1);
1079 static inline void gen_stos(DisasContext *s, TCGMemOp ot)
1081 gen_op_mov_v_reg(MO_32, cpu_T[0], R_EAX);
1082 gen_string_movl_A0_EDI(s);
1083 gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
1084 gen_op_movl_T0_Dshift(ot);
1085 gen_op_add_reg_T0(s->aflag, R_EDI);
1088 static inline void gen_lods(DisasContext *s, TCGMemOp ot)
1090 gen_string_movl_A0_ESI(s);
1091 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
1092 gen_op_mov_reg_v(ot, R_EAX, cpu_T[0]);
1093 gen_op_movl_T0_Dshift(ot);
1094 gen_op_add_reg_T0(s->aflag, R_ESI);
1097 static inline void gen_scas(DisasContext *s, TCGMemOp ot)
1099 gen_string_movl_A0_EDI(s);
1100 gen_op_ld_v(s, ot, cpu_T[1], cpu_A0);
1101 gen_op(s, OP_CMPL, ot, R_EAX);
1102 gen_op_movl_T0_Dshift(ot);
1103 gen_op_add_reg_T0(s->aflag, R_EDI);
1106 static inline void gen_cmps(DisasContext *s, TCGMemOp ot)
1108 gen_string_movl_A0_EDI(s);
1109 gen_op_ld_v(s, ot, cpu_T[1], cpu_A0);
1110 gen_string_movl_A0_ESI(s);
1111 gen_op(s, OP_CMPL, ot, OR_TMP0);
1112 gen_op_movl_T0_Dshift(ot);
1113 gen_op_add_reg_T0(s->aflag, R_ESI);
1114 gen_op_add_reg_T0(s->aflag, R_EDI);
1117 static void gen_bpt_io(DisasContext *s, TCGv_i32 t_port, int ot)
1119 if (s->flags & HF_IOBPT_MASK) {
1120 TCGv_i32 t_size = tcg_const_i32(1 << ot);
1121 TCGv t_next = tcg_const_tl(s->pc - s->cs_base);
1123 gen_helper_bpt_io(cpu_env, t_port, t_size, t_next);
1124 tcg_temp_free_i32(t_size);
1125 tcg_temp_free(t_next);
1130 static inline void gen_ins(DisasContext *s, TCGMemOp ot)
1132 if (s->tb->cflags & CF_USE_ICOUNT) {
1135 gen_string_movl_A0_EDI(s);
1136 /* Note: we must do this dummy write first to be restartable in
1137 case of page fault. */
1138 tcg_gen_movi_tl(cpu_T[0], 0);
1139 gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
1140 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_EDX]);
1141 tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1142 gen_helper_in_func(ot, cpu_T[0], cpu_tmp2_i32);
1143 gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
1144 gen_op_movl_T0_Dshift(ot);
1145 gen_op_add_reg_T0(s->aflag, R_EDI);
1146 gen_bpt_io(s, cpu_tmp2_i32, ot);
1147 if (s->tb->cflags & CF_USE_ICOUNT) {
1152 static inline void gen_outs(DisasContext *s, TCGMemOp ot)
1154 if (s->tb->cflags & CF_USE_ICOUNT) {
1157 gen_string_movl_A0_ESI(s);
1158 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
1160 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_EDX]);
1161 tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1162 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[0]);
1163 gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
1164 gen_op_movl_T0_Dshift(ot);
1165 gen_op_add_reg_T0(s->aflag, R_ESI);
1166 gen_bpt_io(s, cpu_tmp2_i32, ot);
1167 if (s->tb->cflags & CF_USE_ICOUNT) {
1172 /* same method as Valgrind : we generate jumps to current or next
1174 #define GEN_REPZ(op) \
1175 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1176 target_ulong cur_eip, target_ulong next_eip) \
1179 gen_update_cc_op(s); \
1180 l2 = gen_jz_ecx_string(s, next_eip); \
1181 gen_ ## op(s, ot); \
1182 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1183 /* a loop would cause two single step exceptions if ECX = 1 \
1184 before rep string_insn */ \
1186 gen_op_jz_ecx(s->aflag, l2); \
1187 gen_jmp(s, cur_eip); \
1190 #define GEN_REPZ2(op) \
1191 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1192 target_ulong cur_eip, \
1193 target_ulong next_eip, \
1197 gen_update_cc_op(s); \
1198 l2 = gen_jz_ecx_string(s, next_eip); \
1199 gen_ ## op(s, ot); \
1200 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1201 gen_update_cc_op(s); \
1202 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
1204 gen_op_jz_ecx(s->aflag, l2); \
1205 gen_jmp(s, cur_eip); \
1216 static void gen_helper_fp_arith_ST0_FT0(int op)
1220 gen_helper_fadd_ST0_FT0(cpu_env);
1223 gen_helper_fmul_ST0_FT0(cpu_env);
1226 gen_helper_fcom_ST0_FT0(cpu_env);
1229 gen_helper_fcom_ST0_FT0(cpu_env);
1232 gen_helper_fsub_ST0_FT0(cpu_env);
1235 gen_helper_fsubr_ST0_FT0(cpu_env);
1238 gen_helper_fdiv_ST0_FT0(cpu_env);
1241 gen_helper_fdivr_ST0_FT0(cpu_env);
1246 /* NOTE the exception in "r" op ordering */
1247 static void gen_helper_fp_arith_STN_ST0(int op, int opreg)
1249 TCGv_i32 tmp = tcg_const_i32(opreg);
1252 gen_helper_fadd_STN_ST0(cpu_env, tmp);
1255 gen_helper_fmul_STN_ST0(cpu_env, tmp);
1258 gen_helper_fsubr_STN_ST0(cpu_env, tmp);
1261 gen_helper_fsub_STN_ST0(cpu_env, tmp);
1264 gen_helper_fdivr_STN_ST0(cpu_env, tmp);
1267 gen_helper_fdiv_STN_ST0(cpu_env, tmp);
1272 /* if d == OR_TMP0, it means memory operand (address in A0) */
1273 static void gen_op(DisasContext *s1, int op, TCGMemOp ot, int d)
1276 gen_op_mov_v_reg(ot, cpu_T[0], d);
1278 gen_op_ld_v(s1, ot, cpu_T[0], cpu_A0);
1282 gen_compute_eflags_c(s1, cpu_tmp4);
1283 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1284 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_tmp4);
1285 gen_op_st_rm_T0_A0(s1, ot, d);
1286 gen_op_update3_cc(cpu_tmp4);
1287 set_cc_op(s1, CC_OP_ADCB + ot);
1290 gen_compute_eflags_c(s1, cpu_tmp4);
1291 tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1292 tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_tmp4);
1293 gen_op_st_rm_T0_A0(s1, ot, d);
1294 gen_op_update3_cc(cpu_tmp4);
1295 set_cc_op(s1, CC_OP_SBBB + ot);
1298 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1299 gen_op_st_rm_T0_A0(s1, ot, d);
1300 gen_op_update2_cc();
1301 set_cc_op(s1, CC_OP_ADDB + ot);
1304 tcg_gen_mov_tl(cpu_cc_srcT, cpu_T[0]);
1305 tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1306 gen_op_st_rm_T0_A0(s1, ot, d);
1307 gen_op_update2_cc();
1308 set_cc_op(s1, CC_OP_SUBB + ot);
1312 tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1313 gen_op_st_rm_T0_A0(s1, ot, d);
1314 gen_op_update1_cc();
1315 set_cc_op(s1, CC_OP_LOGICB + ot);
1318 tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1319 gen_op_st_rm_T0_A0(s1, ot, d);
1320 gen_op_update1_cc();
1321 set_cc_op(s1, CC_OP_LOGICB + ot);
1324 tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1325 gen_op_st_rm_T0_A0(s1, ot, d);
1326 gen_op_update1_cc();
1327 set_cc_op(s1, CC_OP_LOGICB + ot);
1330 tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
1331 tcg_gen_mov_tl(cpu_cc_srcT, cpu_T[0]);
1332 tcg_gen_sub_tl(cpu_cc_dst, cpu_T[0], cpu_T[1]);
1333 set_cc_op(s1, CC_OP_SUBB + ot);
1338 /* if d == OR_TMP0, it means memory operand (address in A0) */
1339 static void gen_inc(DisasContext *s1, TCGMemOp ot, int d, int c)
1342 gen_op_mov_v_reg(ot, cpu_T[0], d);
1344 gen_op_ld_v(s1, ot, cpu_T[0], cpu_A0);
1346 gen_compute_eflags_c(s1, cpu_cc_src);
1348 tcg_gen_addi_tl(cpu_T[0], cpu_T[0], 1);
1349 set_cc_op(s1, CC_OP_INCB + ot);
1351 tcg_gen_addi_tl(cpu_T[0], cpu_T[0], -1);
1352 set_cc_op(s1, CC_OP_DECB + ot);
1354 gen_op_st_rm_T0_A0(s1, ot, d);
1355 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
1358 static void gen_shift_flags(DisasContext *s, TCGMemOp ot, TCGv result,
1359 TCGv shm1, TCGv count, bool is_right)
1361 TCGv_i32 z32, s32, oldop;
1364 /* Store the results into the CC variables. If we know that the
1365 variable must be dead, store unconditionally. Otherwise we'll
1366 need to not disrupt the current contents. */
1367 z_tl = tcg_const_tl(0);
1368 if (cc_op_live[s->cc_op] & USES_CC_DST) {
1369 tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_dst, count, z_tl,
1370 result, cpu_cc_dst);
1372 tcg_gen_mov_tl(cpu_cc_dst, result);
1374 if (cc_op_live[s->cc_op] & USES_CC_SRC) {
1375 tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_src, count, z_tl,
1378 tcg_gen_mov_tl(cpu_cc_src, shm1);
1380 tcg_temp_free(z_tl);
1382 /* Get the two potential CC_OP values into temporaries. */
1383 tcg_gen_movi_i32(cpu_tmp2_i32, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot);
1384 if (s->cc_op == CC_OP_DYNAMIC) {
1387 tcg_gen_movi_i32(cpu_tmp3_i32, s->cc_op);
1388 oldop = cpu_tmp3_i32;
1391 /* Conditionally store the CC_OP value. */
1392 z32 = tcg_const_i32(0);
1393 s32 = tcg_temp_new_i32();
1394 tcg_gen_trunc_tl_i32(s32, count);
1395 tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, s32, z32, cpu_tmp2_i32, oldop);
1396 tcg_temp_free_i32(z32);
1397 tcg_temp_free_i32(s32);
1399 /* The CC_OP value is no longer predictable. */
1400 set_cc_op(s, CC_OP_DYNAMIC);
1403 static void gen_shift_rm_T1(DisasContext *s, TCGMemOp ot, int op1,
1404 int is_right, int is_arith)
1406 target_ulong mask = (ot == MO_64 ? 0x3f : 0x1f);
1409 if (op1 == OR_TMP0) {
1410 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
1412 gen_op_mov_v_reg(ot, cpu_T[0], op1);
1415 tcg_gen_andi_tl(cpu_T[1], cpu_T[1], mask);
1416 tcg_gen_subi_tl(cpu_tmp0, cpu_T[1], 1);
1420 gen_exts(ot, cpu_T[0]);
1421 tcg_gen_sar_tl(cpu_tmp0, cpu_T[0], cpu_tmp0);
1422 tcg_gen_sar_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1424 gen_extu(ot, cpu_T[0]);
1425 tcg_gen_shr_tl(cpu_tmp0, cpu_T[0], cpu_tmp0);
1426 tcg_gen_shr_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1429 tcg_gen_shl_tl(cpu_tmp0, cpu_T[0], cpu_tmp0);
1430 tcg_gen_shl_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1434 gen_op_st_rm_T0_A0(s, ot, op1);
1436 gen_shift_flags(s, ot, cpu_T[0], cpu_tmp0, cpu_T[1], is_right);
1439 static void gen_shift_rm_im(DisasContext *s, TCGMemOp ot, int op1, int op2,
1440 int is_right, int is_arith)
1442 int mask = (ot == MO_64 ? 0x3f : 0x1f);
1446 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
1448 gen_op_mov_v_reg(ot, cpu_T[0], op1);
1454 gen_exts(ot, cpu_T[0]);
1455 tcg_gen_sari_tl(cpu_tmp4, cpu_T[0], op2 - 1);
1456 tcg_gen_sari_tl(cpu_T[0], cpu_T[0], op2);
1458 gen_extu(ot, cpu_T[0]);
1459 tcg_gen_shri_tl(cpu_tmp4, cpu_T[0], op2 - 1);
1460 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], op2);
1463 tcg_gen_shli_tl(cpu_tmp4, cpu_T[0], op2 - 1);
1464 tcg_gen_shli_tl(cpu_T[0], cpu_T[0], op2);
1469 gen_op_st_rm_T0_A0(s, ot, op1);
1471 /* update eflags if non zero shift */
1473 tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
1474 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
1475 set_cc_op(s, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot);
1479 static void gen_rot_rm_T1(DisasContext *s, TCGMemOp ot, int op1, int is_right)
1481 target_ulong mask = (ot == MO_64 ? 0x3f : 0x1f);
1485 if (op1 == OR_TMP0) {
1486 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
1488 gen_op_mov_v_reg(ot, cpu_T[0], op1);
1491 tcg_gen_andi_tl(cpu_T[1], cpu_T[1], mask);
1495 /* Replicate the 8-bit input so that a 32-bit rotate works. */
1496 tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]);
1497 tcg_gen_muli_tl(cpu_T[0], cpu_T[0], 0x01010101);
1500 /* Replicate the 16-bit input so that a 32-bit rotate works. */
1501 tcg_gen_deposit_tl(cpu_T[0], cpu_T[0], cpu_T[0], 16, 16);
1504 #ifdef TARGET_X86_64
1506 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
1507 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
1509 tcg_gen_rotr_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
1511 tcg_gen_rotl_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
1513 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
1518 tcg_gen_rotr_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1520 tcg_gen_rotl_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1526 gen_op_st_rm_T0_A0(s, ot, op1);
1528 /* We'll need the flags computed into CC_SRC. */
1529 gen_compute_eflags(s);
1531 /* The value that was "rotated out" is now present at the other end
1532 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1533 since we've computed the flags into CC_SRC, these variables are
1536 tcg_gen_shri_tl(cpu_cc_src2, cpu_T[0], mask - 1);
1537 tcg_gen_shri_tl(cpu_cc_dst, cpu_T[0], mask);
1538 tcg_gen_andi_tl(cpu_cc_dst, cpu_cc_dst, 1);
1540 tcg_gen_shri_tl(cpu_cc_src2, cpu_T[0], mask);
1541 tcg_gen_andi_tl(cpu_cc_dst, cpu_T[0], 1);
1543 tcg_gen_andi_tl(cpu_cc_src2, cpu_cc_src2, 1);
1544 tcg_gen_xor_tl(cpu_cc_src2, cpu_cc_src2, cpu_cc_dst);
1546 /* Now conditionally store the new CC_OP value. If the shift count
1547 is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1548 Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1549 exactly as we computed above. */
1550 t0 = tcg_const_i32(0);
1551 t1 = tcg_temp_new_i32();
1552 tcg_gen_trunc_tl_i32(t1, cpu_T[1]);
1553 tcg_gen_movi_i32(cpu_tmp2_i32, CC_OP_ADCOX);
1554 tcg_gen_movi_i32(cpu_tmp3_i32, CC_OP_EFLAGS);
1555 tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, t1, t0,
1556 cpu_tmp2_i32, cpu_tmp3_i32);
1557 tcg_temp_free_i32(t0);
1558 tcg_temp_free_i32(t1);
1560 /* The CC_OP value is no longer predictable. */
1561 set_cc_op(s, CC_OP_DYNAMIC);
1564 static void gen_rot_rm_im(DisasContext *s, TCGMemOp ot, int op1, int op2,
1567 int mask = (ot == MO_64 ? 0x3f : 0x1f);
1571 if (op1 == OR_TMP0) {
1572 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
1574 gen_op_mov_v_reg(ot, cpu_T[0], op1);
1580 #ifdef TARGET_X86_64
1582 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
1584 tcg_gen_rotri_i32(cpu_tmp2_i32, cpu_tmp2_i32, op2);
1586 tcg_gen_rotli_i32(cpu_tmp2_i32, cpu_tmp2_i32, op2);
1588 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
1593 tcg_gen_rotri_tl(cpu_T[0], cpu_T[0], op2);
1595 tcg_gen_rotli_tl(cpu_T[0], cpu_T[0], op2);
1606 shift = mask + 1 - shift;
1608 gen_extu(ot, cpu_T[0]);
1609 tcg_gen_shli_tl(cpu_tmp0, cpu_T[0], shift);
1610 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], mask + 1 - shift);
1611 tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
1617 gen_op_st_rm_T0_A0(s, ot, op1);
1620 /* Compute the flags into CC_SRC. */
1621 gen_compute_eflags(s);
1623 /* The value that was "rotated out" is now present at the other end
1624 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1625 since we've computed the flags into CC_SRC, these variables are
1628 tcg_gen_shri_tl(cpu_cc_src2, cpu_T[0], mask - 1);
1629 tcg_gen_shri_tl(cpu_cc_dst, cpu_T[0], mask);
1630 tcg_gen_andi_tl(cpu_cc_dst, cpu_cc_dst, 1);
1632 tcg_gen_shri_tl(cpu_cc_src2, cpu_T[0], mask);
1633 tcg_gen_andi_tl(cpu_cc_dst, cpu_T[0], 1);
1635 tcg_gen_andi_tl(cpu_cc_src2, cpu_cc_src2, 1);
1636 tcg_gen_xor_tl(cpu_cc_src2, cpu_cc_src2, cpu_cc_dst);
1637 set_cc_op(s, CC_OP_ADCOX);
1641 /* XXX: add faster immediate = 1 case */
1642 static void gen_rotc_rm_T1(DisasContext *s, TCGMemOp ot, int op1,
1645 gen_compute_eflags(s);
1646 assert(s->cc_op == CC_OP_EFLAGS);
1650 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
1652 gen_op_mov_v_reg(ot, cpu_T[0], op1);
1657 gen_helper_rcrb(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1660 gen_helper_rcrw(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1663 gen_helper_rcrl(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1665 #ifdef TARGET_X86_64
1667 gen_helper_rcrq(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1676 gen_helper_rclb(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1679 gen_helper_rclw(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1682 gen_helper_rcll(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1684 #ifdef TARGET_X86_64
1686 gen_helper_rclq(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1694 gen_op_st_rm_T0_A0(s, ot, op1);
1697 /* XXX: add faster immediate case */
1698 static void gen_shiftd_rm_T1(DisasContext *s, TCGMemOp ot, int op1,
1699 bool is_right, TCGv count_in)
1701 target_ulong mask = (ot == MO_64 ? 63 : 31);
1705 if (op1 == OR_TMP0) {
1706 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
1708 gen_op_mov_v_reg(ot, cpu_T[0], op1);
1711 count = tcg_temp_new();
1712 tcg_gen_andi_tl(count, count_in, mask);
1716 /* Note: we implement the Intel behaviour for shift count > 16.
1717 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A
1718 portion by constructing it as a 32-bit value. */
1720 tcg_gen_deposit_tl(cpu_tmp0, cpu_T[0], cpu_T[1], 16, 16);
1721 tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
1722 tcg_gen_mov_tl(cpu_T[0], cpu_tmp0);
1724 tcg_gen_deposit_tl(cpu_T[1], cpu_T[0], cpu_T[1], 16, 16);
1727 #ifdef TARGET_X86_64
1729 /* Concatenate the two 32-bit values and use a 64-bit shift. */
1730 tcg_gen_subi_tl(cpu_tmp0, count, 1);
1732 tcg_gen_concat_tl_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
1733 tcg_gen_shr_i64(cpu_tmp0, cpu_T[0], cpu_tmp0);
1734 tcg_gen_shr_i64(cpu_T[0], cpu_T[0], count);
1736 tcg_gen_concat_tl_i64(cpu_T[0], cpu_T[1], cpu_T[0]);
1737 tcg_gen_shl_i64(cpu_tmp0, cpu_T[0], cpu_tmp0);
1738 tcg_gen_shl_i64(cpu_T[0], cpu_T[0], count);
1739 tcg_gen_shri_i64(cpu_tmp0, cpu_tmp0, 32);
1740 tcg_gen_shri_i64(cpu_T[0], cpu_T[0], 32);
1745 tcg_gen_subi_tl(cpu_tmp0, count, 1);
1747 tcg_gen_shr_tl(cpu_tmp0, cpu_T[0], cpu_tmp0);
1749 tcg_gen_subfi_tl(cpu_tmp4, mask + 1, count);
1750 tcg_gen_shr_tl(cpu_T[0], cpu_T[0], count);
1751 tcg_gen_shl_tl(cpu_T[1], cpu_T[1], cpu_tmp4);
1753 tcg_gen_shl_tl(cpu_tmp0, cpu_T[0], cpu_tmp0);
1755 /* Only needed if count > 16, for Intel behaviour. */
1756 tcg_gen_subfi_tl(cpu_tmp4, 33, count);
1757 tcg_gen_shr_tl(cpu_tmp4, cpu_T[1], cpu_tmp4);
1758 tcg_gen_or_tl(cpu_tmp0, cpu_tmp0, cpu_tmp4);
1761 tcg_gen_subfi_tl(cpu_tmp4, mask + 1, count);
1762 tcg_gen_shl_tl(cpu_T[0], cpu_T[0], count);
1763 tcg_gen_shr_tl(cpu_T[1], cpu_T[1], cpu_tmp4);
1765 tcg_gen_movi_tl(cpu_tmp4, 0);
1766 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_T[1], count, cpu_tmp4,
1767 cpu_tmp4, cpu_T[1]);
1768 tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1773 gen_op_st_rm_T0_A0(s, ot, op1);
1775 gen_shift_flags(s, ot, cpu_T[0], cpu_tmp0, count, is_right);
1776 tcg_temp_free(count);
1779 static void gen_shift(DisasContext *s1, int op, TCGMemOp ot, int d, int s)
1782 gen_op_mov_v_reg(ot, cpu_T[1], s);
1785 gen_rot_rm_T1(s1, ot, d, 0);
1788 gen_rot_rm_T1(s1, ot, d, 1);
1792 gen_shift_rm_T1(s1, ot, d, 0, 0);
1795 gen_shift_rm_T1(s1, ot, d, 1, 0);
1798 gen_shift_rm_T1(s1, ot, d, 1, 1);
1801 gen_rotc_rm_T1(s1, ot, d, 0);
1804 gen_rotc_rm_T1(s1, ot, d, 1);
1809 static void gen_shifti(DisasContext *s1, int op, TCGMemOp ot, int d, int c)
1813 gen_rot_rm_im(s1, ot, d, c, 0);
1816 gen_rot_rm_im(s1, ot, d, c, 1);
1820 gen_shift_rm_im(s1, ot, d, c, 0, 0);
1823 gen_shift_rm_im(s1, ot, d, c, 1, 0);
1826 gen_shift_rm_im(s1, ot, d, c, 1, 1);
1829 /* currently not optimized */
1830 tcg_gen_movi_tl(cpu_T[1], c);
1831 gen_shift(s1, op, ot, d, OR_TMP1);
1836 static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm)
1839 int havesib, base, index, scale;
1840 int mod, rm, code, def_seg, ovr_seg;
1844 ovr_seg = s->override;
1845 mod = (modrm >> 6) & 3;
1858 code = cpu_ldub_code(env, s->pc++);
1859 scale = (code >> 6) & 3;
1860 index = ((code >> 3) & 7) | REX_X(s);
1862 index = -1; /* no index */
1870 if ((base & 7) == 5) {
1872 disp = (int32_t)cpu_ldl_code(env, s->pc);
1874 if (CODE64(s) && !havesib) {
1875 disp += s->pc + s->rip_offset;
1882 disp = (int8_t)cpu_ldub_code(env, s->pc++);
1886 disp = (int32_t)cpu_ldl_code(env, s->pc);
1891 /* For correct popl handling with esp. */
1892 if (base == R_ESP && s->popl_esp_hack) {
1893 disp += s->popl_esp_hack;
1896 /* Compute the address, with a minimum number of TCG ops. */
1900 sum = cpu_regs[index];
1902 tcg_gen_shli_tl(cpu_A0, cpu_regs[index], scale);
1906 tcg_gen_add_tl(cpu_A0, sum, cpu_regs[base]);
1909 } else if (base >= 0) {
1910 sum = cpu_regs[base];
1912 if (TCGV_IS_UNUSED(sum)) {
1913 tcg_gen_movi_tl(cpu_A0, disp);
1915 } else if (disp != 0) {
1916 tcg_gen_addi_tl(cpu_A0, sum, disp);
1920 if (base == R_EBP || base == R_ESP) {
1929 disp = cpu_lduw_code(env, s->pc);
1931 tcg_gen_movi_tl(cpu_A0, disp);
1935 } else if (mod == 1) {
1936 disp = (int8_t)cpu_ldub_code(env, s->pc++);
1938 disp = (int16_t)cpu_lduw_code(env, s->pc);
1944 tcg_gen_add_tl(cpu_A0, cpu_regs[R_EBX], cpu_regs[R_ESI]);
1947 tcg_gen_add_tl(cpu_A0, cpu_regs[R_EBX], cpu_regs[R_EDI]);
1950 tcg_gen_add_tl(cpu_A0, cpu_regs[R_EBP], cpu_regs[R_ESI]);
1954 tcg_gen_add_tl(cpu_A0, cpu_regs[R_EBP], cpu_regs[R_EDI]);
1958 sum = cpu_regs[R_ESI];
1961 sum = cpu_regs[R_EDI];
1964 sum = cpu_regs[R_EBP];
1969 sum = cpu_regs[R_EBX];
1973 tcg_gen_addi_tl(cpu_A0, sum, disp);
1982 gen_lea_v_seg(s, s->aflag, sum, def_seg, ovr_seg);
1985 static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm)
1987 int mod, rm, base, code;
1989 mod = (modrm >> 6) & 3;
2000 code = cpu_ldub_code(env, s->pc++);
2042 /* used for LEA and MOV AX, mem */
2043 static void gen_add_A0_ds_seg(DisasContext *s)
2045 gen_lea_v_seg(s, s->aflag, cpu_A0, R_DS, s->override);
2048 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2050 static void gen_ldst_modrm(CPUX86State *env, DisasContext *s, int modrm,
2051 TCGMemOp ot, int reg, int is_store)
2055 mod = (modrm >> 6) & 3;
2056 rm = (modrm & 7) | REX_B(s);
2060 gen_op_mov_v_reg(ot, cpu_T[0], reg);
2061 gen_op_mov_reg_v(ot, rm, cpu_T[0]);
2063 gen_op_mov_v_reg(ot, cpu_T[0], rm);
2065 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
2068 gen_lea_modrm(env, s, modrm);
2071 gen_op_mov_v_reg(ot, cpu_T[0], reg);
2072 gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
2074 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
2076 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
2081 static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, TCGMemOp ot)
2087 ret = cpu_ldub_code(env, s->pc);
2091 ret = cpu_lduw_code(env, s->pc);
2095 #ifdef TARGET_X86_64
2098 ret = cpu_ldl_code(env, s->pc);
2107 static inline int insn_const_size(TCGMemOp ot)
2116 static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
2118 TranslationBlock *tb;
2121 pc = s->cs_base + eip;
2123 /* NOTE: we handle the case where the TB spans two pages here */
2124 if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) ||
2125 (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK)) {
2126 /* jump to same page: we can use a direct jump */
2127 tcg_gen_goto_tb(tb_num);
2129 tcg_gen_exit_tb((uintptr_t)tb + tb_num);
2131 /* jump to another page: currently not optimized */
2137 static inline void gen_jcc(DisasContext *s, int b,
2138 target_ulong val, target_ulong next_eip)
2143 l1 = gen_new_label();
2146 gen_goto_tb(s, 0, next_eip);
2149 gen_goto_tb(s, 1, val);
2150 s->is_jmp = DISAS_TB_JUMP;
2152 l1 = gen_new_label();
2153 l2 = gen_new_label();
2156 gen_jmp_im(next_eip);
2166 static void gen_cmovcc1(CPUX86State *env, DisasContext *s, TCGMemOp ot, int b,
2171 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
2173 cc = gen_prepare_cc(s, b, cpu_T[1]);
2174 if (cc.mask != -1) {
2175 TCGv t0 = tcg_temp_new();
2176 tcg_gen_andi_tl(t0, cc.reg, cc.mask);
2180 cc.reg2 = tcg_const_tl(cc.imm);
2183 tcg_gen_movcond_tl(cc.cond, cpu_T[0], cc.reg, cc.reg2,
2184 cpu_T[0], cpu_regs[reg]);
2185 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
2187 if (cc.mask != -1) {
2188 tcg_temp_free(cc.reg);
2191 tcg_temp_free(cc.reg2);
2195 static inline void gen_op_movl_T0_seg(int seg_reg)
2197 tcg_gen_ld32u_tl(cpu_T[0], cpu_env,
2198 offsetof(CPUX86State,segs[seg_reg].selector));
2201 static inline void gen_op_movl_seg_T0_vm(int seg_reg)
2203 tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
2204 tcg_gen_st32_tl(cpu_T[0], cpu_env,
2205 offsetof(CPUX86State,segs[seg_reg].selector));
2206 tcg_gen_shli_tl(cpu_seg_base[seg_reg], cpu_T[0], 4);
2209 /* move T0 to seg_reg and compute if the CPU state may change. Never
2210 call this function with seg_reg == R_CS */
2211 static void gen_movl_seg_T0(DisasContext *s, int seg_reg)
2213 if (s->pe && !s->vm86) {
2214 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
2215 gen_helper_load_seg(cpu_env, tcg_const_i32(seg_reg), cpu_tmp2_i32);
2216 /* abort translation because the addseg value may change or
2217 because ss32 may change. For R_SS, translation must always
2218 stop as a special handling must be done to disable hardware
2219 interrupts for the next instruction */
2220 if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS))
2221 s->is_jmp = DISAS_TB_JUMP;
2223 gen_op_movl_seg_T0_vm(seg_reg);
2224 if (seg_reg == R_SS)
2225 s->is_jmp = DISAS_TB_JUMP;
2229 static inline int svm_is_rep(int prefixes)
2231 return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0);
2235 gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
2236 uint32_t type, uint64_t param)
2238 /* no SVM activated; fast case */
2239 if (likely(!(s->flags & HF_SVMI_MASK)))
2241 gen_update_cc_op(s);
2242 gen_jmp_im(pc_start - s->cs_base);
2243 gen_helper_svm_check_intercept_param(cpu_env, tcg_const_i32(type),
2244 tcg_const_i64(param));
2248 gen_svm_check_intercept(DisasContext *s, target_ulong pc_start, uint64_t type)
2250 gen_svm_check_intercept_param(s, pc_start, type, 0);
2253 static inline void gen_stack_update(DisasContext *s, int addend)
2255 gen_op_add_reg_im(mo_stacksize(s), R_ESP, addend);
2258 /* Generate a push. It depends on ss32, addseg and dflag. */
2259 static void gen_push_v(DisasContext *s, TCGv val)
2261 TCGMemOp d_ot = mo_pushpop(s, s->dflag);
2262 TCGMemOp a_ot = mo_stacksize(s);
2263 int size = 1 << d_ot;
2264 TCGv new_esp = cpu_A0;
2266 tcg_gen_subi_tl(cpu_A0, cpu_regs[R_ESP], size);
2271 tcg_gen_mov_tl(new_esp, cpu_A0);
2273 gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1);
2276 gen_op_st_v(s, d_ot, val, cpu_A0);
2277 gen_op_mov_reg_v(a_ot, R_ESP, new_esp);
2280 /* two step pop is necessary for precise exceptions */
2281 static TCGMemOp gen_pop_T0(DisasContext *s)
2283 TCGMemOp d_ot = mo_pushpop(s, s->dflag);
2285 gen_lea_v_seg(s, mo_stacksize(s), cpu_regs[R_ESP], R_SS, -1);
2286 gen_op_ld_v(s, d_ot, cpu_T[0], cpu_A0);
2291 static inline void gen_pop_update(DisasContext *s, TCGMemOp ot)
2293 gen_stack_update(s, 1 << ot);
2296 static inline void gen_stack_A0(DisasContext *s)
2298 gen_lea_v_seg(s, s->ss32 ? MO_32 : MO_16, cpu_regs[R_ESP], R_SS, -1);
2301 static void gen_pusha(DisasContext *s)
2303 TCGMemOp s_ot = s->ss32 ? MO_32 : MO_16;
2304 TCGMemOp d_ot = s->dflag;
2305 int size = 1 << d_ot;
2308 for (i = 0; i < 8; i++) {
2309 tcg_gen_addi_tl(cpu_A0, cpu_regs[R_ESP], (i - 8) * size);
2310 gen_lea_v_seg(s, s_ot, cpu_A0, R_SS, -1);
2311 gen_op_st_v(s, d_ot, cpu_regs[7 - i], cpu_A0);
2314 gen_stack_update(s, -8 * size);
2317 static void gen_popa(DisasContext *s)
2319 TCGMemOp s_ot = s->ss32 ? MO_32 : MO_16;
2320 TCGMemOp d_ot = s->dflag;
2321 int size = 1 << d_ot;
2324 for (i = 0; i < 8; i++) {
2325 /* ESP is not reloaded */
2326 if (7 - i == R_ESP) {
2329 tcg_gen_addi_tl(cpu_A0, cpu_regs[R_ESP], i * size);
2330 gen_lea_v_seg(s, s_ot, cpu_A0, R_SS, -1);
2331 gen_op_ld_v(s, d_ot, cpu_T[0], cpu_A0);
2332 gen_op_mov_reg_v(d_ot, 7 - i, cpu_T[0]);
2335 gen_stack_update(s, 8 * size);
2338 static void gen_enter(DisasContext *s, int esp_addend, int level)
2340 TCGMemOp ot = mo_pushpop(s, s->dflag);
2341 int opsize = 1 << ot;
2344 #ifdef TARGET_X86_64
2346 gen_op_movl_A0_reg(R_ESP);
2347 gen_op_addq_A0_im(-opsize);
2348 tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2351 gen_op_mov_v_reg(MO_32, cpu_T[0], R_EBP);
2352 gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
2354 /* XXX: must save state */
2355 gen_helper_enter64_level(cpu_env, tcg_const_i32(level),
2356 tcg_const_i32((ot == MO_64)),
2359 gen_op_mov_reg_v(ot, R_EBP, cpu_T[1]);
2360 tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level));
2361 gen_op_mov_reg_v(MO_64, R_ESP, cpu_T[1]);
2365 gen_op_movl_A0_reg(R_ESP);
2366 gen_op_addl_A0_im(-opsize);
2368 tcg_gen_ext16u_tl(cpu_A0, cpu_A0);
2369 tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2371 gen_op_addl_A0_seg(s, R_SS);
2373 gen_op_mov_v_reg(MO_32, cpu_T[0], R_EBP);
2374 gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
2376 /* XXX: must save state */
2377 gen_helper_enter_level(cpu_env, tcg_const_i32(level),
2378 tcg_const_i32(s->dflag - 1),
2381 gen_op_mov_reg_v(ot, R_EBP, cpu_T[1]);
2382 tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level));
2383 gen_op_mov_reg_v(MO_16 + s->ss32, R_ESP, cpu_T[1]);
2387 static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
2389 gen_update_cc_op(s);
2390 gen_jmp_im(cur_eip);
2391 gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno));
2392 s->is_jmp = DISAS_TB_JUMP;
2395 /* an interrupt is different from an exception because of the
2397 static void gen_interrupt(DisasContext *s, int intno,
2398 target_ulong cur_eip, target_ulong next_eip)
2400 gen_update_cc_op(s);
2401 gen_jmp_im(cur_eip);
2402 gen_helper_raise_interrupt(cpu_env, tcg_const_i32(intno),
2403 tcg_const_i32(next_eip - cur_eip));
2404 s->is_jmp = DISAS_TB_JUMP;
2407 static void gen_debug(DisasContext *s, target_ulong cur_eip)
2409 gen_update_cc_op(s);
2410 gen_jmp_im(cur_eip);
2411 gen_helper_debug(cpu_env);
2412 s->is_jmp = DISAS_TB_JUMP;
2415 /* generate a generic end of block. Trace exception is also generated
2417 static void gen_eob(DisasContext *s)
2419 gen_update_cc_op(s);
2420 if (s->tb->flags & HF_INHIBIT_IRQ_MASK) {
2421 gen_helper_reset_inhibit_irq(cpu_env);
2423 if (s->tb->flags & HF_RF_MASK) {
2424 gen_helper_reset_rf(cpu_env);
2426 if (s->singlestep_enabled) {
2427 gen_helper_debug(cpu_env);
2429 gen_helper_single_step(cpu_env);
2433 s->is_jmp = DISAS_TB_JUMP;
2436 /* generate a jump to eip. No segment change must happen before as a
2437 direct call to the next block may occur */
2438 static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
2440 gen_update_cc_op(s);
2441 set_cc_op(s, CC_OP_DYNAMIC);
2443 gen_goto_tb(s, tb_num, eip);
2444 s->is_jmp = DISAS_TB_JUMP;
2451 static void gen_jmp(DisasContext *s, target_ulong eip)
2453 gen_jmp_tb(s, eip, 0);
2456 static inline void gen_ldq_env_A0(DisasContext *s, int offset)
2458 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
2459 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset);
2462 static inline void gen_stq_env_A0(DisasContext *s, int offset)
2464 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset);
2465 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
2468 static inline void gen_ldo_env_A0(DisasContext *s, int offset)
2470 int mem_index = s->mem_index;
2471 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, mem_index, MO_LEQ);
2472 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(0)));
2473 tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2474 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_tmp0, mem_index, MO_LEQ);
2475 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(1)));
2478 static inline void gen_sto_env_A0(DisasContext *s, int offset)
2480 int mem_index = s->mem_index;
2481 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(0)));
2482 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, mem_index, MO_LEQ);
2483 tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2484 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(1)));
2485 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_tmp0, mem_index, MO_LEQ);
2488 static inline void gen_op_movo(int d_offset, int s_offset)
2490 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + offsetof(ZMMReg, ZMM_Q(0)));
2491 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + offsetof(ZMMReg, ZMM_Q(0)));
2492 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + offsetof(ZMMReg, ZMM_Q(1)));
2493 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + offsetof(ZMMReg, ZMM_Q(1)));
2496 static inline void gen_op_movq(int d_offset, int s_offset)
2498 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
2499 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2502 static inline void gen_op_movl(int d_offset, int s_offset)
2504 tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env, s_offset);
2505 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, d_offset);
2508 static inline void gen_op_movq_env_0(int d_offset)
2510 tcg_gen_movi_i64(cpu_tmp1_i64, 0);
2511 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2514 typedef void (*SSEFunc_i_ep)(TCGv_i32 val, TCGv_ptr env, TCGv_ptr reg);
2515 typedef void (*SSEFunc_l_ep)(TCGv_i64 val, TCGv_ptr env, TCGv_ptr reg);
2516 typedef void (*SSEFunc_0_epi)(TCGv_ptr env, TCGv_ptr reg, TCGv_i32 val);
2517 typedef void (*SSEFunc_0_epl)(TCGv_ptr env, TCGv_ptr reg, TCGv_i64 val);
2518 typedef void (*SSEFunc_0_epp)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b);
2519 typedef void (*SSEFunc_0_eppi)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2521 typedef void (*SSEFunc_0_ppi)(TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv_i32 val);
2522 typedef void (*SSEFunc_0_eppt)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2525 #define SSE_SPECIAL ((void *)1)
2526 #define SSE_DUMMY ((void *)2)
2528 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2529 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2530 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2532 static const SSEFunc_0_epp sse_op_table1[256][4] = {
2533 /* 3DNow! extensions */
2534 [0x0e] = { SSE_DUMMY }, /* femms */
2535 [0x0f] = { SSE_DUMMY }, /* pf... */
2536 /* pure SSE operations */
2537 [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2538 [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2539 [0x12] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd, movsldup, movddup */
2540 [0x13] = { SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd */
2541 [0x14] = { gen_helper_punpckldq_xmm, gen_helper_punpcklqdq_xmm },
2542 [0x15] = { gen_helper_punpckhdq_xmm, gen_helper_punpckhqdq_xmm },
2543 [0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movhps, movhpd, movshdup */
2544 [0x17] = { SSE_SPECIAL, SSE_SPECIAL }, /* movhps, movhpd */
2546 [0x28] = { SSE_SPECIAL, SSE_SPECIAL }, /* movaps, movapd */
2547 [0x29] = { SSE_SPECIAL, SSE_SPECIAL }, /* movaps, movapd */
2548 [0x2a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2549 [0x2b] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movntps, movntpd, movntss, movntsd */
2550 [0x2c] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2551 [0x2d] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2552 [0x2e] = { gen_helper_ucomiss, gen_helper_ucomisd },
2553 [0x2f] = { gen_helper_comiss, gen_helper_comisd },
2554 [0x50] = { SSE_SPECIAL, SSE_SPECIAL }, /* movmskps, movmskpd */
2555 [0x51] = SSE_FOP(sqrt),
2556 [0x52] = { gen_helper_rsqrtps, NULL, gen_helper_rsqrtss, NULL },
2557 [0x53] = { gen_helper_rcpps, NULL, gen_helper_rcpss, NULL },
2558 [0x54] = { gen_helper_pand_xmm, gen_helper_pand_xmm }, /* andps, andpd */
2559 [0x55] = { gen_helper_pandn_xmm, gen_helper_pandn_xmm }, /* andnps, andnpd */
2560 [0x56] = { gen_helper_por_xmm, gen_helper_por_xmm }, /* orps, orpd */
2561 [0x57] = { gen_helper_pxor_xmm, gen_helper_pxor_xmm }, /* xorps, xorpd */
2562 [0x58] = SSE_FOP(add),
2563 [0x59] = SSE_FOP(mul),
2564 [0x5a] = { gen_helper_cvtps2pd, gen_helper_cvtpd2ps,
2565 gen_helper_cvtss2sd, gen_helper_cvtsd2ss },
2566 [0x5b] = { gen_helper_cvtdq2ps, gen_helper_cvtps2dq, gen_helper_cvttps2dq },
2567 [0x5c] = SSE_FOP(sub),
2568 [0x5d] = SSE_FOP(min),
2569 [0x5e] = SSE_FOP(div),
2570 [0x5f] = SSE_FOP(max),
2572 [0xc2] = SSE_FOP(cmpeq),
2573 [0xc6] = { (SSEFunc_0_epp)gen_helper_shufps,
2574 (SSEFunc_0_epp)gen_helper_shufpd }, /* XXX: casts */
2576 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */
2577 [0x38] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2578 [0x3a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2580 /* MMX ops and their SSE extensions */
2581 [0x60] = MMX_OP2(punpcklbw),
2582 [0x61] = MMX_OP2(punpcklwd),
2583 [0x62] = MMX_OP2(punpckldq),
2584 [0x63] = MMX_OP2(packsswb),
2585 [0x64] = MMX_OP2(pcmpgtb),
2586 [0x65] = MMX_OP2(pcmpgtw),
2587 [0x66] = MMX_OP2(pcmpgtl),
2588 [0x67] = MMX_OP2(packuswb),
2589 [0x68] = MMX_OP2(punpckhbw),
2590 [0x69] = MMX_OP2(punpckhwd),
2591 [0x6a] = MMX_OP2(punpckhdq),
2592 [0x6b] = MMX_OP2(packssdw),
2593 [0x6c] = { NULL, gen_helper_punpcklqdq_xmm },
2594 [0x6d] = { NULL, gen_helper_punpckhqdq_xmm },
2595 [0x6e] = { SSE_SPECIAL, SSE_SPECIAL }, /* movd mm, ea */
2596 [0x6f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, , movqdu */
2597 [0x70] = { (SSEFunc_0_epp)gen_helper_pshufw_mmx,
2598 (SSEFunc_0_epp)gen_helper_pshufd_xmm,
2599 (SSEFunc_0_epp)gen_helper_pshufhw_xmm,
2600 (SSEFunc_0_epp)gen_helper_pshuflw_xmm }, /* XXX: casts */
2601 [0x71] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftw */
2602 [0x72] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftd */
2603 [0x73] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftq */
2604 [0x74] = MMX_OP2(pcmpeqb),
2605 [0x75] = MMX_OP2(pcmpeqw),
2606 [0x76] = MMX_OP2(pcmpeql),
2607 [0x77] = { SSE_DUMMY }, /* emms */
2608 [0x78] = { NULL, SSE_SPECIAL, NULL, SSE_SPECIAL }, /* extrq_i, insertq_i */
2609 [0x79] = { NULL, gen_helper_extrq_r, NULL, gen_helper_insertq_r },
2610 [0x7c] = { NULL, gen_helper_haddpd, NULL, gen_helper_haddps },
2611 [0x7d] = { NULL, gen_helper_hsubpd, NULL, gen_helper_hsubps },
2612 [0x7e] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movd, movd, , movq */
2613 [0x7f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, movdqu */
2614 [0xc4] = { SSE_SPECIAL, SSE_SPECIAL }, /* pinsrw */
2615 [0xc5] = { SSE_SPECIAL, SSE_SPECIAL }, /* pextrw */
2616 [0xd0] = { NULL, gen_helper_addsubpd, NULL, gen_helper_addsubps },
2617 [0xd1] = MMX_OP2(psrlw),
2618 [0xd2] = MMX_OP2(psrld),
2619 [0xd3] = MMX_OP2(psrlq),
2620 [0xd4] = MMX_OP2(paddq),
2621 [0xd5] = MMX_OP2(pmullw),
2622 [0xd6] = { NULL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2623 [0xd7] = { SSE_SPECIAL, SSE_SPECIAL }, /* pmovmskb */
2624 [0xd8] = MMX_OP2(psubusb),
2625 [0xd9] = MMX_OP2(psubusw),
2626 [0xda] = MMX_OP2(pminub),
2627 [0xdb] = MMX_OP2(pand),
2628 [0xdc] = MMX_OP2(paddusb),
2629 [0xdd] = MMX_OP2(paddusw),
2630 [0xde] = MMX_OP2(pmaxub),
2631 [0xdf] = MMX_OP2(pandn),
2632 [0xe0] = MMX_OP2(pavgb),
2633 [0xe1] = MMX_OP2(psraw),
2634 [0xe2] = MMX_OP2(psrad),
2635 [0xe3] = MMX_OP2(pavgw),
2636 [0xe4] = MMX_OP2(pmulhuw),
2637 [0xe5] = MMX_OP2(pmulhw),
2638 [0xe6] = { NULL, gen_helper_cvttpd2dq, gen_helper_cvtdq2pd, gen_helper_cvtpd2dq },
2639 [0xe7] = { SSE_SPECIAL , SSE_SPECIAL }, /* movntq, movntq */
2640 [0xe8] = MMX_OP2(psubsb),
2641 [0xe9] = MMX_OP2(psubsw),
2642 [0xea] = MMX_OP2(pminsw),
2643 [0xeb] = MMX_OP2(por),
2644 [0xec] = MMX_OP2(paddsb),
2645 [0xed] = MMX_OP2(paddsw),
2646 [0xee] = MMX_OP2(pmaxsw),
2647 [0xef] = MMX_OP2(pxor),
2648 [0xf0] = { NULL, NULL, NULL, SSE_SPECIAL }, /* lddqu */
2649 [0xf1] = MMX_OP2(psllw),
2650 [0xf2] = MMX_OP2(pslld),
2651 [0xf3] = MMX_OP2(psllq),
2652 [0xf4] = MMX_OP2(pmuludq),
2653 [0xf5] = MMX_OP2(pmaddwd),
2654 [0xf6] = MMX_OP2(psadbw),
2655 [0xf7] = { (SSEFunc_0_epp)gen_helper_maskmov_mmx,
2656 (SSEFunc_0_epp)gen_helper_maskmov_xmm }, /* XXX: casts */
2657 [0xf8] = MMX_OP2(psubb),
2658 [0xf9] = MMX_OP2(psubw),
2659 [0xfa] = MMX_OP2(psubl),
2660 [0xfb] = MMX_OP2(psubq),
2661 [0xfc] = MMX_OP2(paddb),
2662 [0xfd] = MMX_OP2(paddw),
2663 [0xfe] = MMX_OP2(paddl),
2666 static const SSEFunc_0_epp sse_op_table2[3 * 8][2] = {
2667 [0 + 2] = MMX_OP2(psrlw),
2668 [0 + 4] = MMX_OP2(psraw),
2669 [0 + 6] = MMX_OP2(psllw),
2670 [8 + 2] = MMX_OP2(psrld),
2671 [8 + 4] = MMX_OP2(psrad),
2672 [8 + 6] = MMX_OP2(pslld),
2673 [16 + 2] = MMX_OP2(psrlq),
2674 [16 + 3] = { NULL, gen_helper_psrldq_xmm },
2675 [16 + 6] = MMX_OP2(psllq),
2676 [16 + 7] = { NULL, gen_helper_pslldq_xmm },
2679 static const SSEFunc_0_epi sse_op_table3ai[] = {
2680 gen_helper_cvtsi2ss,
2684 #ifdef TARGET_X86_64
2685 static const SSEFunc_0_epl sse_op_table3aq[] = {
2686 gen_helper_cvtsq2ss,
2691 static const SSEFunc_i_ep sse_op_table3bi[] = {
2692 gen_helper_cvttss2si,
2693 gen_helper_cvtss2si,
2694 gen_helper_cvttsd2si,
2698 #ifdef TARGET_X86_64
2699 static const SSEFunc_l_ep sse_op_table3bq[] = {
2700 gen_helper_cvttss2sq,
2701 gen_helper_cvtss2sq,
2702 gen_helper_cvttsd2sq,
2707 static const SSEFunc_0_epp sse_op_table4[8][4] = {
2718 static const SSEFunc_0_epp sse_op_table5[256] = {
2719 [0x0c] = gen_helper_pi2fw,
2720 [0x0d] = gen_helper_pi2fd,
2721 [0x1c] = gen_helper_pf2iw,
2722 [0x1d] = gen_helper_pf2id,
2723 [0x8a] = gen_helper_pfnacc,
2724 [0x8e] = gen_helper_pfpnacc,
2725 [0x90] = gen_helper_pfcmpge,
2726 [0x94] = gen_helper_pfmin,
2727 [0x96] = gen_helper_pfrcp,
2728 [0x97] = gen_helper_pfrsqrt,
2729 [0x9a] = gen_helper_pfsub,
2730 [0x9e] = gen_helper_pfadd,
2731 [0xa0] = gen_helper_pfcmpgt,
2732 [0xa4] = gen_helper_pfmax,
2733 [0xa6] = gen_helper_movq, /* pfrcpit1; no need to actually increase precision */
2734 [0xa7] = gen_helper_movq, /* pfrsqit1 */
2735 [0xaa] = gen_helper_pfsubr,
2736 [0xae] = gen_helper_pfacc,
2737 [0xb0] = gen_helper_pfcmpeq,
2738 [0xb4] = gen_helper_pfmul,
2739 [0xb6] = gen_helper_movq, /* pfrcpit2 */
2740 [0xb7] = gen_helper_pmulhrw_mmx,
2741 [0xbb] = gen_helper_pswapd,
2742 [0xbf] = gen_helper_pavgb_mmx /* pavgusb */
2745 struct SSEOpHelper_epp {
2746 SSEFunc_0_epp op[2];
2750 struct SSEOpHelper_eppi {
2751 SSEFunc_0_eppi op[2];
2755 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
2756 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
2757 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
2758 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
2759 #define PCLMULQDQ_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, \
2760 CPUID_EXT_PCLMULQDQ }
2761 #define AESNI_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_AES }
2763 static const struct SSEOpHelper_epp sse_op_table6[256] = {
2764 [0x00] = SSSE3_OP(pshufb),
2765 [0x01] = SSSE3_OP(phaddw),
2766 [0x02] = SSSE3_OP(phaddd),
2767 [0x03] = SSSE3_OP(phaddsw),
2768 [0x04] = SSSE3_OP(pmaddubsw),
2769 [0x05] = SSSE3_OP(phsubw),
2770 [0x06] = SSSE3_OP(phsubd),
2771 [0x07] = SSSE3_OP(phsubsw),
2772 [0x08] = SSSE3_OP(psignb),
2773 [0x09] = SSSE3_OP(psignw),
2774 [0x0a] = SSSE3_OP(psignd),
2775 [0x0b] = SSSE3_OP(pmulhrsw),
2776 [0x10] = SSE41_OP(pblendvb),
2777 [0x14] = SSE41_OP(blendvps),
2778 [0x15] = SSE41_OP(blendvpd),
2779 [0x17] = SSE41_OP(ptest),
2780 [0x1c] = SSSE3_OP(pabsb),
2781 [0x1d] = SSSE3_OP(pabsw),
2782 [0x1e] = SSSE3_OP(pabsd),
2783 [0x20] = SSE41_OP(pmovsxbw),
2784 [0x21] = SSE41_OP(pmovsxbd),
2785 [0x22] = SSE41_OP(pmovsxbq),
2786 [0x23] = SSE41_OP(pmovsxwd),
2787 [0x24] = SSE41_OP(pmovsxwq),
2788 [0x25] = SSE41_OP(pmovsxdq),
2789 [0x28] = SSE41_OP(pmuldq),
2790 [0x29] = SSE41_OP(pcmpeqq),
2791 [0x2a] = SSE41_SPECIAL, /* movntqda */
2792 [0x2b] = SSE41_OP(packusdw),
2793 [0x30] = SSE41_OP(pmovzxbw),
2794 [0x31] = SSE41_OP(pmovzxbd),
2795 [0x32] = SSE41_OP(pmovzxbq),
2796 [0x33] = SSE41_OP(pmovzxwd),
2797 [0x34] = SSE41_OP(pmovzxwq),
2798 [0x35] = SSE41_OP(pmovzxdq),
2799 [0x37] = SSE42_OP(pcmpgtq),
2800 [0x38] = SSE41_OP(pminsb),
2801 [0x39] = SSE41_OP(pminsd),
2802 [0x3a] = SSE41_OP(pminuw),
2803 [0x3b] = SSE41_OP(pminud),
2804 [0x3c] = SSE41_OP(pmaxsb),
2805 [0x3d] = SSE41_OP(pmaxsd),
2806 [0x3e] = SSE41_OP(pmaxuw),
2807 [0x3f] = SSE41_OP(pmaxud),
2808 [0x40] = SSE41_OP(pmulld),
2809 [0x41] = SSE41_OP(phminposuw),
2810 [0xdb] = AESNI_OP(aesimc),
2811 [0xdc] = AESNI_OP(aesenc),
2812 [0xdd] = AESNI_OP(aesenclast),
2813 [0xde] = AESNI_OP(aesdec),
2814 [0xdf] = AESNI_OP(aesdeclast),
2817 static const struct SSEOpHelper_eppi sse_op_table7[256] = {
2818 [0x08] = SSE41_OP(roundps),
2819 [0x09] = SSE41_OP(roundpd),
2820 [0x0a] = SSE41_OP(roundss),
2821 [0x0b] = SSE41_OP(roundsd),
2822 [0x0c] = SSE41_OP(blendps),
2823 [0x0d] = SSE41_OP(blendpd),
2824 [0x0e] = SSE41_OP(pblendw),
2825 [0x0f] = SSSE3_OP(palignr),
2826 [0x14] = SSE41_SPECIAL, /* pextrb */
2827 [0x15] = SSE41_SPECIAL, /* pextrw */
2828 [0x16] = SSE41_SPECIAL, /* pextrd/pextrq */
2829 [0x17] = SSE41_SPECIAL, /* extractps */
2830 [0x20] = SSE41_SPECIAL, /* pinsrb */
2831 [0x21] = SSE41_SPECIAL, /* insertps */
2832 [0x22] = SSE41_SPECIAL, /* pinsrd/pinsrq */
2833 [0x40] = SSE41_OP(dpps),
2834 [0x41] = SSE41_OP(dppd),
2835 [0x42] = SSE41_OP(mpsadbw),
2836 [0x44] = PCLMULQDQ_OP(pclmulqdq),
2837 [0x60] = SSE42_OP(pcmpestrm),
2838 [0x61] = SSE42_OP(pcmpestri),
2839 [0x62] = SSE42_OP(pcmpistrm),
2840 [0x63] = SSE42_OP(pcmpistri),
2841 [0xdf] = AESNI_OP(aeskeygenassist),
2844 static void gen_sse(CPUX86State *env, DisasContext *s, int b,
2845 target_ulong pc_start, int rex_r)
2847 int b1, op1_offset, op2_offset, is_xmm, val;
2848 int modrm, mod, rm, reg;
2849 SSEFunc_0_epp sse_fn_epp;
2850 SSEFunc_0_eppi sse_fn_eppi;
2851 SSEFunc_0_ppi sse_fn_ppi;
2852 SSEFunc_0_eppt sse_fn_eppt;
2856 if (s->prefix & PREFIX_DATA)
2858 else if (s->prefix & PREFIX_REPZ)
2860 else if (s->prefix & PREFIX_REPNZ)
2864 sse_fn_epp = sse_op_table1[b][b1];
2868 if ((b <= 0x5f && b >= 0x10) || b == 0xc6 || b == 0xc2) {
2878 /* simple MMX/SSE operation */
2879 if (s->flags & HF_TS_MASK) {
2880 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
2883 if (s->flags & HF_EM_MASK) {
2885 gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
2888 if (is_xmm && !(s->flags & HF_OSFXSR_MASK))
2889 if ((b != 0x38 && b != 0x3a) || (s->prefix & PREFIX_DATA))
2892 if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW))
2895 gen_helper_emms(cpu_env);
2900 gen_helper_emms(cpu_env);
2903 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
2904 the static cpu state) */
2906 gen_helper_enter_mmx(cpu_env);
2909 modrm = cpu_ldub_code(env, s->pc++);
2910 reg = ((modrm >> 3) & 7);
2913 mod = (modrm >> 6) & 3;
2914 if (sse_fn_epp == SSE_SPECIAL) {
2917 case 0x0e7: /* movntq */
2920 gen_lea_modrm(env, s, modrm);
2921 gen_stq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
2923 case 0x1e7: /* movntdq */
2924 case 0x02b: /* movntps */
2925 case 0x12b: /* movntps */
2928 gen_lea_modrm(env, s, modrm);
2929 gen_sto_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
2931 case 0x3f0: /* lddqu */
2934 gen_lea_modrm(env, s, modrm);
2935 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
2937 case 0x22b: /* movntss */
2938 case 0x32b: /* movntsd */
2941 gen_lea_modrm(env, s, modrm);
2943 gen_stq_env_A0(s, offsetof(CPUX86State,
2944 xmm_regs[reg].ZMM_Q(0)));
2946 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
2947 xmm_regs[reg].ZMM_L(0)));
2948 gen_op_st_v(s, MO_32, cpu_T[0], cpu_A0);
2951 case 0x6e: /* movd mm, ea */
2952 #ifdef TARGET_X86_64
2953 if (s->dflag == MO_64) {
2954 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 0);
2955 tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,fpregs[reg].mmx));
2959 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 0);
2960 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
2961 offsetof(CPUX86State,fpregs[reg].mmx));
2962 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
2963 gen_helper_movl_mm_T0_mmx(cpu_ptr0, cpu_tmp2_i32);
2966 case 0x16e: /* movd xmm, ea */
2967 #ifdef TARGET_X86_64
2968 if (s->dflag == MO_64) {
2969 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 0);
2970 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
2971 offsetof(CPUX86State,xmm_regs[reg]));
2972 gen_helper_movq_mm_T0_xmm(cpu_ptr0, cpu_T[0]);
2976 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 0);
2977 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
2978 offsetof(CPUX86State,xmm_regs[reg]));
2979 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
2980 gen_helper_movl_mm_T0_xmm(cpu_ptr0, cpu_tmp2_i32);
2983 case 0x6f: /* movq mm, ea */
2985 gen_lea_modrm(env, s, modrm);
2986 gen_ldq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
2989 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
2990 offsetof(CPUX86State,fpregs[rm].mmx));
2991 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
2992 offsetof(CPUX86State,fpregs[reg].mmx));
2995 case 0x010: /* movups */
2996 case 0x110: /* movupd */
2997 case 0x028: /* movaps */
2998 case 0x128: /* movapd */
2999 case 0x16f: /* movdqa xmm, ea */
3000 case 0x26f: /* movdqu xmm, ea */
3002 gen_lea_modrm(env, s, modrm);
3003 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3005 rm = (modrm & 7) | REX_B(s);
3006 gen_op_movo(offsetof(CPUX86State,xmm_regs[reg]),
3007 offsetof(CPUX86State,xmm_regs[rm]));
3010 case 0x210: /* movss xmm, ea */
3012 gen_lea_modrm(env, s, modrm);
3013 gen_op_ld_v(s, MO_32, cpu_T[0], cpu_A0);
3014 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3015 tcg_gen_movi_tl(cpu_T[0], 0);
3016 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)));
3017 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)));
3018 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)));
3020 rm = (modrm & 7) | REX_B(s);
3021 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)),
3022 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0)));
3025 case 0x310: /* movsd xmm, ea */
3027 gen_lea_modrm(env, s, modrm);
3028 gen_ldq_env_A0(s, offsetof(CPUX86State,
3029 xmm_regs[reg].ZMM_Q(0)));
3030 tcg_gen_movi_tl(cpu_T[0], 0);
3031 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)));
3032 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)));
3034 rm = (modrm & 7) | REX_B(s);
3035 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3036 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3039 case 0x012: /* movlps */
3040 case 0x112: /* movlpd */
3042 gen_lea_modrm(env, s, modrm);
3043 gen_ldq_env_A0(s, offsetof(CPUX86State,
3044 xmm_regs[reg].ZMM_Q(0)));
3047 rm = (modrm & 7) | REX_B(s);
3048 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3049 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(1)));
3052 case 0x212: /* movsldup */
3054 gen_lea_modrm(env, s, modrm);
3055 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3057 rm = (modrm & 7) | REX_B(s);
3058 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)),
3059 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0)));
3060 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)),
3061 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(2)));
3063 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)),
3064 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3065 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)),
3066 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)));
3068 case 0x312: /* movddup */
3070 gen_lea_modrm(env, s, modrm);
3071 gen_ldq_env_A0(s, offsetof(CPUX86State,
3072 xmm_regs[reg].ZMM_Q(0)));
3074 rm = (modrm & 7) | REX_B(s);
3075 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3076 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3078 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)),
3079 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3081 case 0x016: /* movhps */
3082 case 0x116: /* movhpd */
3084 gen_lea_modrm(env, s, modrm);
3085 gen_ldq_env_A0(s, offsetof(CPUX86State,
3086 xmm_regs[reg].ZMM_Q(1)));
3089 rm = (modrm & 7) | REX_B(s);
3090 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)),
3091 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3094 case 0x216: /* movshdup */
3096 gen_lea_modrm(env, s, modrm);
3097 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3099 rm = (modrm & 7) | REX_B(s);
3100 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)),
3101 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(1)));
3102 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)),
3103 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(3)));
3105 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)),
3106 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)));
3107 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)),
3108 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)));
3113 int bit_index, field_length;
3115 if (b1 == 1 && reg != 0)
3117 field_length = cpu_ldub_code(env, s->pc++) & 0x3F;
3118 bit_index = cpu_ldub_code(env, s->pc++) & 0x3F;
3119 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3120 offsetof(CPUX86State,xmm_regs[reg]));
3122 gen_helper_extrq_i(cpu_env, cpu_ptr0,
3123 tcg_const_i32(bit_index),
3124 tcg_const_i32(field_length));
3126 gen_helper_insertq_i(cpu_env, cpu_ptr0,
3127 tcg_const_i32(bit_index),
3128 tcg_const_i32(field_length));
3131 case 0x7e: /* movd ea, mm */
3132 #ifdef TARGET_X86_64
3133 if (s->dflag == MO_64) {
3134 tcg_gen_ld_i64(cpu_T[0], cpu_env,
3135 offsetof(CPUX86State,fpregs[reg].mmx));
3136 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 1);
3140 tcg_gen_ld32u_tl(cpu_T[0], cpu_env,
3141 offsetof(CPUX86State,fpregs[reg].mmx.MMX_L(0)));
3142 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 1);
3145 case 0x17e: /* movd ea, xmm */
3146 #ifdef TARGET_X86_64
3147 if (s->dflag == MO_64) {
3148 tcg_gen_ld_i64(cpu_T[0], cpu_env,
3149 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3150 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 1);
3154 tcg_gen_ld32u_tl(cpu_T[0], cpu_env,
3155 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3156 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 1);
3159 case 0x27e: /* movq xmm, ea */
3161 gen_lea_modrm(env, s, modrm);
3162 gen_ldq_env_A0(s, offsetof(CPUX86State,
3163 xmm_regs[reg].ZMM_Q(0)));
3165 rm = (modrm & 7) | REX_B(s);
3166 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3167 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3169 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)));
3171 case 0x7f: /* movq ea, mm */
3173 gen_lea_modrm(env, s, modrm);
3174 gen_stq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
3177 gen_op_movq(offsetof(CPUX86State,fpregs[rm].mmx),
3178 offsetof(CPUX86State,fpregs[reg].mmx));
3181 case 0x011: /* movups */
3182 case 0x111: /* movupd */
3183 case 0x029: /* movaps */
3184 case 0x129: /* movapd */
3185 case 0x17f: /* movdqa ea, xmm */
3186 case 0x27f: /* movdqu ea, xmm */
3188 gen_lea_modrm(env, s, modrm);
3189 gen_sto_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3191 rm = (modrm & 7) | REX_B(s);
3192 gen_op_movo(offsetof(CPUX86State,xmm_regs[rm]),
3193 offsetof(CPUX86State,xmm_regs[reg]));
3196 case 0x211: /* movss ea, xmm */
3198 gen_lea_modrm(env, s, modrm);
3199 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3200 gen_op_st_v(s, MO_32, cpu_T[0], cpu_A0);
3202 rm = (modrm & 7) | REX_B(s);
3203 gen_op_movl(offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0)),
3204 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3207 case 0x311: /* movsd ea, xmm */
3209 gen_lea_modrm(env, s, modrm);
3210 gen_stq_env_A0(s, offsetof(CPUX86State,
3211 xmm_regs[reg].ZMM_Q(0)));
3213 rm = (modrm & 7) | REX_B(s);
3214 gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)),
3215 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3218 case 0x013: /* movlps */
3219 case 0x113: /* movlpd */
3221 gen_lea_modrm(env, s, modrm);
3222 gen_stq_env_A0(s, offsetof(CPUX86State,
3223 xmm_regs[reg].ZMM_Q(0)));
3228 case 0x017: /* movhps */
3229 case 0x117: /* movhpd */
3231 gen_lea_modrm(env, s, modrm);
3232 gen_stq_env_A0(s, offsetof(CPUX86State,
3233 xmm_regs[reg].ZMM_Q(1)));
3238 case 0x71: /* shift mm, im */
3241 case 0x171: /* shift xmm, im */
3247 val = cpu_ldub_code(env, s->pc++);
3249 tcg_gen_movi_tl(cpu_T[0], val);
3250 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(0)));
3251 tcg_gen_movi_tl(cpu_T[0], 0);
3252 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(1)));
3253 op1_offset = offsetof(CPUX86State,xmm_t0);
3255 tcg_gen_movi_tl(cpu_T[0], val);
3256 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(0)));
3257 tcg_gen_movi_tl(cpu_T[0], 0);
3258 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(1)));
3259 op1_offset = offsetof(CPUX86State,mmx_t0);
3261 sse_fn_epp = sse_op_table2[((b - 1) & 3) * 8 +
3262 (((modrm >> 3)) & 7)][b1];
3267 rm = (modrm & 7) | REX_B(s);
3268 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3271 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3273 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
3274 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op1_offset);
3275 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
3277 case 0x050: /* movmskps */
3278 rm = (modrm & 7) | REX_B(s);
3279 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3280 offsetof(CPUX86State,xmm_regs[rm]));
3281 gen_helper_movmskps(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3282 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
3284 case 0x150: /* movmskpd */
3285 rm = (modrm & 7) | REX_B(s);
3286 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3287 offsetof(CPUX86State,xmm_regs[rm]));
3288 gen_helper_movmskpd(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3289 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
3291 case 0x02a: /* cvtpi2ps */
3292 case 0x12a: /* cvtpi2pd */
3293 gen_helper_enter_mmx(cpu_env);
3295 gen_lea_modrm(env, s, modrm);
3296 op2_offset = offsetof(CPUX86State,mmx_t0);
3297 gen_ldq_env_A0(s, op2_offset);
3300 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3302 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3303 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3304 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3307 gen_helper_cvtpi2ps(cpu_env, cpu_ptr0, cpu_ptr1);
3311 gen_helper_cvtpi2pd(cpu_env, cpu_ptr0, cpu_ptr1);
3315 case 0x22a: /* cvtsi2ss */
3316 case 0x32a: /* cvtsi2sd */
3317 ot = mo_64_32(s->dflag);
3318 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3319 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3320 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3322 SSEFunc_0_epi sse_fn_epi = sse_op_table3ai[(b >> 8) & 1];
3323 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
3324 sse_fn_epi(cpu_env, cpu_ptr0, cpu_tmp2_i32);
3326 #ifdef TARGET_X86_64
3327 SSEFunc_0_epl sse_fn_epl = sse_op_table3aq[(b >> 8) & 1];
3328 sse_fn_epl(cpu_env, cpu_ptr0, cpu_T[0]);
3334 case 0x02c: /* cvttps2pi */
3335 case 0x12c: /* cvttpd2pi */
3336 case 0x02d: /* cvtps2pi */
3337 case 0x12d: /* cvtpd2pi */
3338 gen_helper_enter_mmx(cpu_env);
3340 gen_lea_modrm(env, s, modrm);
3341 op2_offset = offsetof(CPUX86State,xmm_t0);
3342 gen_ldo_env_A0(s, op2_offset);
3344 rm = (modrm & 7) | REX_B(s);
3345 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3347 op1_offset = offsetof(CPUX86State,fpregs[reg & 7].mmx);
3348 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3349 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3352 gen_helper_cvttps2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3355 gen_helper_cvttpd2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3358 gen_helper_cvtps2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3361 gen_helper_cvtpd2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3365 case 0x22c: /* cvttss2si */
3366 case 0x32c: /* cvttsd2si */
3367 case 0x22d: /* cvtss2si */
3368 case 0x32d: /* cvtsd2si */
3369 ot = mo_64_32(s->dflag);
3371 gen_lea_modrm(env, s, modrm);
3373 gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_Q(0)));
3375 gen_op_ld_v(s, MO_32, cpu_T[0], cpu_A0);
3376 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(0)));
3378 op2_offset = offsetof(CPUX86State,xmm_t0);
3380 rm = (modrm & 7) | REX_B(s);
3381 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3383 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
3385 SSEFunc_i_ep sse_fn_i_ep =
3386 sse_op_table3bi[((b >> 7) & 2) | (b & 1)];
3387 sse_fn_i_ep(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3388 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
3390 #ifdef TARGET_X86_64
3391 SSEFunc_l_ep sse_fn_l_ep =
3392 sse_op_table3bq[((b >> 7) & 2) | (b & 1)];
3393 sse_fn_l_ep(cpu_T[0], cpu_env, cpu_ptr0);
3398 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
3400 case 0xc4: /* pinsrw */
3403 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
3404 val = cpu_ldub_code(env, s->pc++);
3407 tcg_gen_st16_tl(cpu_T[0], cpu_env,
3408 offsetof(CPUX86State,xmm_regs[reg].ZMM_W(val)));
3411 tcg_gen_st16_tl(cpu_T[0], cpu_env,
3412 offsetof(CPUX86State,fpregs[reg].mmx.MMX_W(val)));
3415 case 0xc5: /* pextrw */
3419 ot = mo_64_32(s->dflag);
3420 val = cpu_ldub_code(env, s->pc++);
3423 rm = (modrm & 7) | REX_B(s);
3424 tcg_gen_ld16u_tl(cpu_T[0], cpu_env,
3425 offsetof(CPUX86State,xmm_regs[rm].ZMM_W(val)));
3429 tcg_gen_ld16u_tl(cpu_T[0], cpu_env,
3430 offsetof(CPUX86State,fpregs[rm].mmx.MMX_W(val)));
3432 reg = ((modrm >> 3) & 7) | rex_r;
3433 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
3435 case 0x1d6: /* movq ea, xmm */
3437 gen_lea_modrm(env, s, modrm);
3438 gen_stq_env_A0(s, offsetof(CPUX86State,
3439 xmm_regs[reg].ZMM_Q(0)));
3441 rm = (modrm & 7) | REX_B(s);
3442 gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)),
3443 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3444 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(1)));
3447 case 0x2d6: /* movq2dq */
3448 gen_helper_enter_mmx(cpu_env);
3450 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3451 offsetof(CPUX86State,fpregs[rm].mmx));
3452 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)));
3454 case 0x3d6: /* movdq2q */
3455 gen_helper_enter_mmx(cpu_env);
3456 rm = (modrm & 7) | REX_B(s);
3457 gen_op_movq(offsetof(CPUX86State,fpregs[reg & 7].mmx),
3458 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3460 case 0xd7: /* pmovmskb */
3465 rm = (modrm & 7) | REX_B(s);
3466 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[rm]));
3467 gen_helper_pmovmskb_xmm(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3470 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,fpregs[rm].mmx));
3471 gen_helper_pmovmskb_mmx(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3473 reg = ((modrm >> 3) & 7) | rex_r;
3474 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
3480 if ((b & 0xf0) == 0xf0) {
3483 modrm = cpu_ldub_code(env, s->pc++);
3485 reg = ((modrm >> 3) & 7) | rex_r;
3486 mod = (modrm >> 6) & 3;
3491 sse_fn_epp = sse_op_table6[b].op[b1];
3495 if (!(s->cpuid_ext_features & sse_op_table6[b].ext_mask))
3499 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3501 op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
3503 op2_offset = offsetof(CPUX86State,xmm_t0);
3504 gen_lea_modrm(env, s, modrm);
3506 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3507 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3508 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3509 gen_ldq_env_A0(s, op2_offset +
3510 offsetof(ZMMReg, ZMM_Q(0)));
3512 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3513 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3514 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
3515 s->mem_index, MO_LEUL);
3516 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, op2_offset +
3517 offsetof(ZMMReg, ZMM_L(0)));
3519 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3520 tcg_gen_qemu_ld_tl(cpu_tmp0, cpu_A0,
3521 s->mem_index, MO_LEUW);
3522 tcg_gen_st16_tl(cpu_tmp0, cpu_env, op2_offset +
3523 offsetof(ZMMReg, ZMM_W(0)));
3525 case 0x2a: /* movntqda */
3526 gen_ldo_env_A0(s, op1_offset);
3529 gen_ldo_env_A0(s, op2_offset);
3533 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
3535 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3537 op2_offset = offsetof(CPUX86State,mmx_t0);
3538 gen_lea_modrm(env, s, modrm);
3539 gen_ldq_env_A0(s, op2_offset);
3542 if (sse_fn_epp == SSE_SPECIAL) {
3546 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3547 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3548 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
3551 set_cc_op(s, CC_OP_EFLAGS);
3558 /* Various integer extensions at 0f 38 f[0-f]. */
3559 b = modrm | (b1 << 8);
3560 modrm = cpu_ldub_code(env, s->pc++);
3561 reg = ((modrm >> 3) & 7) | rex_r;
3564 case 0x3f0: /* crc32 Gd,Eb */
3565 case 0x3f1: /* crc32 Gd,Ey */
3567 if (!(s->cpuid_ext_features & CPUID_EXT_SSE42)) {
3570 if ((b & 0xff) == 0xf0) {
3572 } else if (s->dflag != MO_64) {
3573 ot = (s->prefix & PREFIX_DATA ? MO_16 : MO_32);
3578 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[reg]);
3579 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3580 gen_helper_crc32(cpu_T[0], cpu_tmp2_i32,
3581 cpu_T[0], tcg_const_i32(8 << ot));
3583 ot = mo_64_32(s->dflag);
3584 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
3587 case 0x1f0: /* crc32 or movbe */
3589 /* For these insns, the f3 prefix is supposed to have priority
3590 over the 66 prefix, but that's not what we implement above
3592 if (s->prefix & PREFIX_REPNZ) {
3596 case 0x0f0: /* movbe Gy,My */
3597 case 0x0f1: /* movbe My,Gy */
3598 if (!(s->cpuid_ext_features & CPUID_EXT_MOVBE)) {
3601 if (s->dflag != MO_64) {
3602 ot = (s->prefix & PREFIX_DATA ? MO_16 : MO_32);
3607 gen_lea_modrm(env, s, modrm);
3609 tcg_gen_qemu_ld_tl(cpu_T[0], cpu_A0,
3610 s->mem_index, ot | MO_BE);
3611 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
3613 tcg_gen_qemu_st_tl(cpu_regs[reg], cpu_A0,
3614 s->mem_index, ot | MO_BE);
3618 case 0x0f2: /* andn Gy, By, Ey */
3619 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
3620 || !(s->prefix & PREFIX_VEX)
3624 ot = mo_64_32(s->dflag);
3625 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3626 tcg_gen_andc_tl(cpu_T[0], cpu_regs[s->vex_v], cpu_T[0]);
3627 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
3628 gen_op_update1_cc();
3629 set_cc_op(s, CC_OP_LOGICB + ot);
3632 case 0x0f7: /* bextr Gy, Ey, By */
3633 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
3634 || !(s->prefix & PREFIX_VEX)
3638 ot = mo_64_32(s->dflag);
3642 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3643 /* Extract START, and shift the operand.
3644 Shifts larger than operand size get zeros. */
3645 tcg_gen_ext8u_tl(cpu_A0, cpu_regs[s->vex_v]);
3646 tcg_gen_shr_tl(cpu_T[0], cpu_T[0], cpu_A0);
3648 bound = tcg_const_tl(ot == MO_64 ? 63 : 31);
3649 zero = tcg_const_tl(0);
3650 tcg_gen_movcond_tl(TCG_COND_LEU, cpu_T[0], cpu_A0, bound,
3652 tcg_temp_free(zero);
3654 /* Extract the LEN into a mask. Lengths larger than
3655 operand size get all ones. */
3656 tcg_gen_shri_tl(cpu_A0, cpu_regs[s->vex_v], 8);
3657 tcg_gen_ext8u_tl(cpu_A0, cpu_A0);
3658 tcg_gen_movcond_tl(TCG_COND_LEU, cpu_A0, cpu_A0, bound,
3660 tcg_temp_free(bound);
3661 tcg_gen_movi_tl(cpu_T[1], 1);
3662 tcg_gen_shl_tl(cpu_T[1], cpu_T[1], cpu_A0);
3663 tcg_gen_subi_tl(cpu_T[1], cpu_T[1], 1);
3664 tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3666 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
3667 gen_op_update1_cc();
3668 set_cc_op(s, CC_OP_LOGICB + ot);
3672 case 0x0f5: /* bzhi Gy, Ey, By */
3673 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3674 || !(s->prefix & PREFIX_VEX)
3678 ot = mo_64_32(s->dflag);
3679 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3680 tcg_gen_ext8u_tl(cpu_T[1], cpu_regs[s->vex_v]);
3682 TCGv bound = tcg_const_tl(ot == MO_64 ? 63 : 31);
3683 /* Note that since we're using BMILG (in order to get O
3684 cleared) we need to store the inverse into C. */
3685 tcg_gen_setcond_tl(TCG_COND_LT, cpu_cc_src,
3687 tcg_gen_movcond_tl(TCG_COND_GT, cpu_T[1], cpu_T[1],
3688 bound, bound, cpu_T[1]);
3689 tcg_temp_free(bound);
3691 tcg_gen_movi_tl(cpu_A0, -1);
3692 tcg_gen_shl_tl(cpu_A0, cpu_A0, cpu_T[1]);
3693 tcg_gen_andc_tl(cpu_T[0], cpu_T[0], cpu_A0);
3694 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
3695 gen_op_update1_cc();
3696 set_cc_op(s, CC_OP_BMILGB + ot);
3699 case 0x3f6: /* mulx By, Gy, rdx, Ey */
3700 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3701 || !(s->prefix & PREFIX_VEX)
3705 ot = mo_64_32(s->dflag);
3706 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3709 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
3710 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_regs[R_EDX]);
3711 tcg_gen_mulu2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
3712 cpu_tmp2_i32, cpu_tmp3_i32);
3713 tcg_gen_extu_i32_tl(cpu_regs[s->vex_v], cpu_tmp2_i32);
3714 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp3_i32);
3716 #ifdef TARGET_X86_64
3718 tcg_gen_mulu2_i64(cpu_T[0], cpu_T[1],
3719 cpu_T[0], cpu_regs[R_EDX]);
3720 tcg_gen_mov_i64(cpu_regs[s->vex_v], cpu_T[0]);
3721 tcg_gen_mov_i64(cpu_regs[reg], cpu_T[1]);
3727 case 0x3f5: /* pdep Gy, By, Ey */
3728 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3729 || !(s->prefix & PREFIX_VEX)
3733 ot = mo_64_32(s->dflag);
3734 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3735 /* Note that by zero-extending the mask operand, we
3736 automatically handle zero-extending the result. */
3738 tcg_gen_mov_tl(cpu_T[1], cpu_regs[s->vex_v]);
3740 tcg_gen_ext32u_tl(cpu_T[1], cpu_regs[s->vex_v]);
3742 gen_helper_pdep(cpu_regs[reg], cpu_T[0], cpu_T[1]);
3745 case 0x2f5: /* pext Gy, By, Ey */
3746 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3747 || !(s->prefix & PREFIX_VEX)
3751 ot = mo_64_32(s->dflag);
3752 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3753 /* Note that by zero-extending the mask operand, we
3754 automatically handle zero-extending the result. */
3756 tcg_gen_mov_tl(cpu_T[1], cpu_regs[s->vex_v]);
3758 tcg_gen_ext32u_tl(cpu_T[1], cpu_regs[s->vex_v]);
3760 gen_helper_pext(cpu_regs[reg], cpu_T[0], cpu_T[1]);
3763 case 0x1f6: /* adcx Gy, Ey */
3764 case 0x2f6: /* adox Gy, Ey */
3765 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_ADX)) {
3768 TCGv carry_in, carry_out, zero;
3771 ot = mo_64_32(s->dflag);
3772 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3774 /* Re-use the carry-out from a previous round. */
3775 TCGV_UNUSED(carry_in);
3776 carry_out = (b == 0x1f6 ? cpu_cc_dst : cpu_cc_src2);
3780 carry_in = cpu_cc_dst;
3781 end_op = CC_OP_ADCX;
3783 end_op = CC_OP_ADCOX;
3788 end_op = CC_OP_ADCOX;
3790 carry_in = cpu_cc_src2;
3791 end_op = CC_OP_ADOX;
3795 end_op = CC_OP_ADCOX;
3796 carry_in = carry_out;
3799 end_op = (b == 0x1f6 ? CC_OP_ADCX : CC_OP_ADOX);
3802 /* If we can't reuse carry-out, get it out of EFLAGS. */
3803 if (TCGV_IS_UNUSED(carry_in)) {
3804 if (s->cc_op != CC_OP_ADCX && s->cc_op != CC_OP_ADOX) {
3805 gen_compute_eflags(s);
3807 carry_in = cpu_tmp0;
3808 tcg_gen_shri_tl(carry_in, cpu_cc_src,
3809 ctz32(b == 0x1f6 ? CC_C : CC_O));
3810 tcg_gen_andi_tl(carry_in, carry_in, 1);
3814 #ifdef TARGET_X86_64
3816 /* If we know TL is 64-bit, and we want a 32-bit
3817 result, just do everything in 64-bit arithmetic. */
3818 tcg_gen_ext32u_i64(cpu_regs[reg], cpu_regs[reg]);
3819 tcg_gen_ext32u_i64(cpu_T[0], cpu_T[0]);
3820 tcg_gen_add_i64(cpu_T[0], cpu_T[0], cpu_regs[reg]);
3821 tcg_gen_add_i64(cpu_T[0], cpu_T[0], carry_in);
3822 tcg_gen_ext32u_i64(cpu_regs[reg], cpu_T[0]);
3823 tcg_gen_shri_i64(carry_out, cpu_T[0], 32);
3827 /* Otherwise compute the carry-out in two steps. */
3828 zero = tcg_const_tl(0);
3829 tcg_gen_add2_tl(cpu_T[0], carry_out,
3832 tcg_gen_add2_tl(cpu_regs[reg], carry_out,
3833 cpu_regs[reg], carry_out,
3835 tcg_temp_free(zero);
3838 set_cc_op(s, end_op);
3842 case 0x1f7: /* shlx Gy, Ey, By */
3843 case 0x2f7: /* sarx Gy, Ey, By */
3844 case 0x3f7: /* shrx Gy, Ey, By */
3845 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3846 || !(s->prefix & PREFIX_VEX)
3850 ot = mo_64_32(s->dflag);
3851 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3853 tcg_gen_andi_tl(cpu_T[1], cpu_regs[s->vex_v], 63);
3855 tcg_gen_andi_tl(cpu_T[1], cpu_regs[s->vex_v], 31);
3858 tcg_gen_shl_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3859 } else if (b == 0x2f7) {
3861 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
3863 tcg_gen_sar_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3866 tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
3868 tcg_gen_shr_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3870 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
3876 case 0x3f3: /* Group 17 */
3877 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
3878 || !(s->prefix & PREFIX_VEX)
3882 ot = mo_64_32(s->dflag);
3883 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3886 case 1: /* blsr By,Ey */
3887 tcg_gen_neg_tl(cpu_T[1], cpu_T[0]);
3888 tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3889 gen_op_mov_reg_v(ot, s->vex_v, cpu_T[0]);
3890 gen_op_update2_cc();
3891 set_cc_op(s, CC_OP_BMILGB + ot);
3894 case 2: /* blsmsk By,Ey */
3895 tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
3896 tcg_gen_subi_tl(cpu_T[0], cpu_T[0], 1);
3897 tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_cc_src);
3898 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
3899 set_cc_op(s, CC_OP_BMILGB + ot);
3902 case 3: /* blsi By, Ey */
3903 tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
3904 tcg_gen_subi_tl(cpu_T[0], cpu_T[0], 1);
3905 tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_cc_src);
3906 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
3907 set_cc_op(s, CC_OP_BMILGB + ot);
3923 modrm = cpu_ldub_code(env, s->pc++);
3925 reg = ((modrm >> 3) & 7) | rex_r;
3926 mod = (modrm >> 6) & 3;
3931 sse_fn_eppi = sse_op_table7[b].op[b1];
3935 if (!(s->cpuid_ext_features & sse_op_table7[b].ext_mask))
3938 if (sse_fn_eppi == SSE_SPECIAL) {
3939 ot = mo_64_32(s->dflag);
3940 rm = (modrm & 7) | REX_B(s);
3942 gen_lea_modrm(env, s, modrm);
3943 reg = ((modrm >> 3) & 7) | rex_r;
3944 val = cpu_ldub_code(env, s->pc++);
3946 case 0x14: /* pextrb */
3947 tcg_gen_ld8u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
3948 xmm_regs[reg].ZMM_B(val & 15)));
3950 gen_op_mov_reg_v(ot, rm, cpu_T[0]);
3952 tcg_gen_qemu_st_tl(cpu_T[0], cpu_A0,
3953 s->mem_index, MO_UB);
3956 case 0x15: /* pextrw */
3957 tcg_gen_ld16u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
3958 xmm_regs[reg].ZMM_W(val & 7)));
3960 gen_op_mov_reg_v(ot, rm, cpu_T[0]);
3962 tcg_gen_qemu_st_tl(cpu_T[0], cpu_A0,
3963 s->mem_index, MO_LEUW);
3967 if (ot == MO_32) { /* pextrd */
3968 tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
3969 offsetof(CPUX86State,
3970 xmm_regs[reg].ZMM_L(val & 3)));
3972 tcg_gen_extu_i32_tl(cpu_regs[rm], cpu_tmp2_i32);
3974 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
3975 s->mem_index, MO_LEUL);
3977 } else { /* pextrq */
3978 #ifdef TARGET_X86_64
3979 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
3980 offsetof(CPUX86State,
3981 xmm_regs[reg].ZMM_Q(val & 1)));
3983 tcg_gen_mov_i64(cpu_regs[rm], cpu_tmp1_i64);
3985 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0,
3986 s->mem_index, MO_LEQ);
3993 case 0x17: /* extractps */
3994 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
3995 xmm_regs[reg].ZMM_L(val & 3)));
3997 gen_op_mov_reg_v(ot, rm, cpu_T[0]);
3999 tcg_gen_qemu_st_tl(cpu_T[0], cpu_A0,
4000 s->mem_index, MO_LEUL);
4003 case 0x20: /* pinsrb */
4005 gen_op_mov_v_reg(MO_32, cpu_T[0], rm);
4007 tcg_gen_qemu_ld_tl(cpu_T[0], cpu_A0,
4008 s->mem_index, MO_UB);
4010 tcg_gen_st8_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
4011 xmm_regs[reg].ZMM_B(val & 15)));
4013 case 0x21: /* insertps */
4015 tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
4016 offsetof(CPUX86State,xmm_regs[rm]
4017 .ZMM_L((val >> 6) & 3)));
4019 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
4020 s->mem_index, MO_LEUL);
4022 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
4023 offsetof(CPUX86State,xmm_regs[reg]
4024 .ZMM_L((val >> 4) & 3)));
4026 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4027 cpu_env, offsetof(CPUX86State,
4028 xmm_regs[reg].ZMM_L(0)));
4030 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4031 cpu_env, offsetof(CPUX86State,
4032 xmm_regs[reg].ZMM_L(1)));
4034 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4035 cpu_env, offsetof(CPUX86State,
4036 xmm_regs[reg].ZMM_L(2)));
4038 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4039 cpu_env, offsetof(CPUX86State,
4040 xmm_regs[reg].ZMM_L(3)));
4043 if (ot == MO_32) { /* pinsrd */
4045 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[rm]);
4047 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
4048 s->mem_index, MO_LEUL);
4050 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
4051 offsetof(CPUX86State,
4052 xmm_regs[reg].ZMM_L(val & 3)));
4053 } else { /* pinsrq */
4054 #ifdef TARGET_X86_64
4056 gen_op_mov_v_reg(ot, cpu_tmp1_i64, rm);
4058 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0,
4059 s->mem_index, MO_LEQ);
4061 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
4062 offsetof(CPUX86State,
4063 xmm_regs[reg].ZMM_Q(val & 1)));
4074 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
4076 op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
4078 op2_offset = offsetof(CPUX86State,xmm_t0);
4079 gen_lea_modrm(env, s, modrm);
4080 gen_ldo_env_A0(s, op2_offset);
4083 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
4085 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
4087 op2_offset = offsetof(CPUX86State,mmx_t0);
4088 gen_lea_modrm(env, s, modrm);
4089 gen_ldq_env_A0(s, op2_offset);
4092 val = cpu_ldub_code(env, s->pc++);
4094 if ((b & 0xfc) == 0x60) { /* pcmpXstrX */
4095 set_cc_op(s, CC_OP_EFLAGS);
4097 if (s->dflag == MO_64) {
4098 /* The helper must use entire 64-bit gp registers */
4103 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4104 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4105 sse_fn_eppi(cpu_env, cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
4109 /* Various integer extensions at 0f 3a f[0-f]. */
4110 b = modrm | (b1 << 8);
4111 modrm = cpu_ldub_code(env, s->pc++);
4112 reg = ((modrm >> 3) & 7) | rex_r;
4115 case 0x3f0: /* rorx Gy,Ey, Ib */
4116 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
4117 || !(s->prefix & PREFIX_VEX)
4121 ot = mo_64_32(s->dflag);
4122 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4123 b = cpu_ldub_code(env, s->pc++);
4125 tcg_gen_rotri_tl(cpu_T[0], cpu_T[0], b & 63);
4127 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4128 tcg_gen_rotri_i32(cpu_tmp2_i32, cpu_tmp2_i32, b & 31);
4129 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
4131 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
4143 /* generic MMX or SSE operation */
4145 case 0x70: /* pshufx insn */
4146 case 0xc6: /* pshufx insn */
4147 case 0xc2: /* compare insns */
4154 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
4158 gen_lea_modrm(env, s, modrm);
4159 op2_offset = offsetof(CPUX86State,xmm_t0);
4165 /* Most sse scalar operations. */
4168 } else if (b1 == 3) {
4173 case 0x2e: /* ucomis[sd] */
4174 case 0x2f: /* comis[sd] */
4186 gen_op_ld_v(s, MO_32, cpu_T[0], cpu_A0);
4187 tcg_gen_st32_tl(cpu_T[0], cpu_env,
4188 offsetof(CPUX86State,xmm_t0.ZMM_L(0)));
4192 gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_D(0)));
4195 /* 128 bit access */
4196 gen_ldo_env_A0(s, op2_offset);
4200 rm = (modrm & 7) | REX_B(s);
4201 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
4204 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
4206 gen_lea_modrm(env, s, modrm);
4207 op2_offset = offsetof(CPUX86State,mmx_t0);
4208 gen_ldq_env_A0(s, op2_offset);
4211 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
4215 case 0x0f: /* 3DNow! data insns */
4216 if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW))
4218 val = cpu_ldub_code(env, s->pc++);
4219 sse_fn_epp = sse_op_table5[val];
4223 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4224 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4225 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4227 case 0x70: /* pshufx insn */
4228 case 0xc6: /* pshufx insn */
4229 val = cpu_ldub_code(env, s->pc++);
4230 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4231 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4232 /* XXX: introduce a new table? */
4233 sse_fn_ppi = (SSEFunc_0_ppi)sse_fn_epp;
4234 sse_fn_ppi(cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
4238 val = cpu_ldub_code(env, s->pc++);
4241 sse_fn_epp = sse_op_table4[val][b1];
4243 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4244 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4245 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4248 /* maskmov : we must prepare A0 */
4251 tcg_gen_mov_tl(cpu_A0, cpu_regs[R_EDI]);
4252 gen_extu(s->aflag, cpu_A0);
4253 gen_add_A0_ds_seg(s);
4255 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4256 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4257 /* XXX: introduce a new table? */
4258 sse_fn_eppt = (SSEFunc_0_eppt)sse_fn_epp;
4259 sse_fn_eppt(cpu_env, cpu_ptr0, cpu_ptr1, cpu_A0);
4262 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4263 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4264 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4267 if (b == 0x2e || b == 0x2f) {
4268 set_cc_op(s, CC_OP_EFLAGS);
4273 /* convert one instruction. s->is_jmp is set if the translation must
4274 be stopped. Return the next pc value */
4275 static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
4276 target_ulong pc_start)
4280 TCGMemOp ot, aflag, dflag;
4281 int modrm, reg, rm, mod, op, opreg, val;
4282 target_ulong next_eip, tval;
4290 #ifdef TARGET_X86_64
4295 s->rip_offset = 0; /* for relative ip address */
4299 b = cpu_ldub_code(env, s->pc);
4301 /* Collect prefixes. */
4304 prefixes |= PREFIX_REPZ;
4307 prefixes |= PREFIX_REPNZ;
4310 prefixes |= PREFIX_LOCK;
4331 prefixes |= PREFIX_DATA;
4334 prefixes |= PREFIX_ADR;
4336 #ifdef TARGET_X86_64
4340 rex_w = (b >> 3) & 1;
4341 rex_r = (b & 0x4) << 1;
4342 s->rex_x = (b & 0x2) << 2;
4343 REX_B(s) = (b & 0x1) << 3;
4344 x86_64_hregs = 1; /* select uniform byte register addressing */
4349 case 0xc5: /* 2-byte VEX */
4350 case 0xc4: /* 3-byte VEX */
4351 /* VEX prefixes cannot be used except in 32-bit mode.
4352 Otherwise the instruction is LES or LDS. */
4353 if (s->code32 && !s->vm86) {
4354 static const int pp_prefix[4] = {
4355 0, PREFIX_DATA, PREFIX_REPZ, PREFIX_REPNZ
4357 int vex3, vex2 = cpu_ldub_code(env, s->pc);
4359 if (!CODE64(s) && (vex2 & 0xc0) != 0xc0) {
4360 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4361 otherwise the instruction is LES or LDS. */
4366 /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
4367 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ
4368 | PREFIX_LOCK | PREFIX_DATA)) {
4371 #ifdef TARGET_X86_64
4376 rex_r = (~vex2 >> 4) & 8;
4379 b = cpu_ldub_code(env, s->pc++);
4381 #ifdef TARGET_X86_64
4382 s->rex_x = (~vex2 >> 3) & 8;
4383 s->rex_b = (~vex2 >> 2) & 8;
4385 vex3 = cpu_ldub_code(env, s->pc++);
4386 rex_w = (vex3 >> 7) & 1;
4387 switch (vex2 & 0x1f) {
4388 case 0x01: /* Implied 0f leading opcode bytes. */
4389 b = cpu_ldub_code(env, s->pc++) | 0x100;
4391 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4394 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4397 default: /* Reserved for future use. */
4401 s->vex_v = (~vex3 >> 3) & 0xf;
4402 s->vex_l = (vex3 >> 2) & 1;
4403 prefixes |= pp_prefix[vex3 & 3] | PREFIX_VEX;
4408 /* Post-process prefixes. */
4410 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit
4411 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4412 over 0x66 if both are present. */
4413 dflag = (rex_w > 0 ? MO_64 : prefixes & PREFIX_DATA ? MO_16 : MO_32);
4414 /* In 64-bit mode, 0x67 selects 32-bit addressing. */
4415 aflag = (prefixes & PREFIX_ADR ? MO_32 : MO_64);
4417 /* In 16/32-bit mode, 0x66 selects the opposite data size. */
4418 if (s->code32 ^ ((prefixes & PREFIX_DATA) != 0)) {
4423 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */
4424 if (s->code32 ^ ((prefixes & PREFIX_ADR) != 0)) {
4431 s->prefix = prefixes;
4435 /* lock generation */
4436 if (prefixes & PREFIX_LOCK)
4439 /* now check op code */
4443 /**************************/
4444 /* extended op code */
4445 b = cpu_ldub_code(env, s->pc++) | 0x100;
4448 /**************************/
4463 ot = mo_b_d(b, dflag);
4466 case 0: /* OP Ev, Gv */
4467 modrm = cpu_ldub_code(env, s->pc++);
4468 reg = ((modrm >> 3) & 7) | rex_r;
4469 mod = (modrm >> 6) & 3;
4470 rm = (modrm & 7) | REX_B(s);
4472 gen_lea_modrm(env, s, modrm);
4474 } else if (op == OP_XORL && rm == reg) {
4476 /* xor reg, reg optimisation */
4477 set_cc_op(s, CC_OP_CLR);
4478 tcg_gen_movi_tl(cpu_T[0], 0);
4479 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
4484 gen_op_mov_v_reg(ot, cpu_T[1], reg);
4485 gen_op(s, op, ot, opreg);
4487 case 1: /* OP Gv, Ev */
4488 modrm = cpu_ldub_code(env, s->pc++);
4489 mod = (modrm >> 6) & 3;
4490 reg = ((modrm >> 3) & 7) | rex_r;
4491 rm = (modrm & 7) | REX_B(s);
4493 gen_lea_modrm(env, s, modrm);
4494 gen_op_ld_v(s, ot, cpu_T[1], cpu_A0);
4495 } else if (op == OP_XORL && rm == reg) {
4498 gen_op_mov_v_reg(ot, cpu_T[1], rm);
4500 gen_op(s, op, ot, reg);
4502 case 2: /* OP A, Iv */
4503 val = insn_get(env, s, ot);
4504 tcg_gen_movi_tl(cpu_T[1], val);
4505 gen_op(s, op, ot, OR_EAX);
4514 case 0x80: /* GRP1 */
4520 ot = mo_b_d(b, dflag);
4522 modrm = cpu_ldub_code(env, s->pc++);
4523 mod = (modrm >> 6) & 3;
4524 rm = (modrm & 7) | REX_B(s);
4525 op = (modrm >> 3) & 7;
4531 s->rip_offset = insn_const_size(ot);
4532 gen_lea_modrm(env, s, modrm);
4543 val = insn_get(env, s, ot);
4546 val = (int8_t)insn_get(env, s, MO_8);
4549 tcg_gen_movi_tl(cpu_T[1], val);
4550 gen_op(s, op, ot, opreg);
4554 /**************************/
4555 /* inc, dec, and other misc arith */
4556 case 0x40 ... 0x47: /* inc Gv */
4558 gen_inc(s, ot, OR_EAX + (b & 7), 1);
4560 case 0x48 ... 0x4f: /* dec Gv */
4562 gen_inc(s, ot, OR_EAX + (b & 7), -1);
4564 case 0xf6: /* GRP3 */
4566 ot = mo_b_d(b, dflag);
4568 modrm = cpu_ldub_code(env, s->pc++);
4569 mod = (modrm >> 6) & 3;
4570 rm = (modrm & 7) | REX_B(s);
4571 op = (modrm >> 3) & 7;
4574 s->rip_offset = insn_const_size(ot);
4575 gen_lea_modrm(env, s, modrm);
4576 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
4578 gen_op_mov_v_reg(ot, cpu_T[0], rm);
4583 val = insn_get(env, s, ot);
4584 tcg_gen_movi_tl(cpu_T[1], val);
4585 gen_op_testl_T0_T1_cc();
4586 set_cc_op(s, CC_OP_LOGICB + ot);
4589 tcg_gen_not_tl(cpu_T[0], cpu_T[0]);
4591 gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
4593 gen_op_mov_reg_v(ot, rm, cpu_T[0]);
4597 tcg_gen_neg_tl(cpu_T[0], cpu_T[0]);
4599 gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
4601 gen_op_mov_reg_v(ot, rm, cpu_T[0]);
4603 gen_op_update_neg_cc();
4604 set_cc_op(s, CC_OP_SUBB + ot);
4609 gen_op_mov_v_reg(MO_8, cpu_T[1], R_EAX);
4610 tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]);
4611 tcg_gen_ext8u_tl(cpu_T[1], cpu_T[1]);
4612 /* XXX: use 32 bit mul which could be faster */
4613 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4614 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T[0]);
4615 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4616 tcg_gen_andi_tl(cpu_cc_src, cpu_T[0], 0xff00);
4617 set_cc_op(s, CC_OP_MULB);
4620 gen_op_mov_v_reg(MO_16, cpu_T[1], R_EAX);
4621 tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
4622 tcg_gen_ext16u_tl(cpu_T[1], cpu_T[1]);
4623 /* XXX: use 32 bit mul which could be faster */
4624 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4625 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T[0]);
4626 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4627 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 16);
4628 gen_op_mov_reg_v(MO_16, R_EDX, cpu_T[0]);
4629 tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
4630 set_cc_op(s, CC_OP_MULW);
4634 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4635 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_regs[R_EAX]);
4636 tcg_gen_mulu2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
4637 cpu_tmp2_i32, cpu_tmp3_i32);
4638 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], cpu_tmp2_i32);
4639 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], cpu_tmp3_i32);
4640 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4641 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]);
4642 set_cc_op(s, CC_OP_MULL);
4644 #ifdef TARGET_X86_64
4646 tcg_gen_mulu2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX],
4647 cpu_T[0], cpu_regs[R_EAX]);
4648 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4649 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]);
4650 set_cc_op(s, CC_OP_MULQ);
4658 gen_op_mov_v_reg(MO_8, cpu_T[1], R_EAX);
4659 tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
4660 tcg_gen_ext8s_tl(cpu_T[1], cpu_T[1]);
4661 /* XXX: use 32 bit mul which could be faster */
4662 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4663 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T[0]);
4664 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4665 tcg_gen_ext8s_tl(cpu_tmp0, cpu_T[0]);
4666 tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4667 set_cc_op(s, CC_OP_MULB);
4670 gen_op_mov_v_reg(MO_16, cpu_T[1], R_EAX);
4671 tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4672 tcg_gen_ext16s_tl(cpu_T[1], cpu_T[1]);
4673 /* XXX: use 32 bit mul which could be faster */
4674 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4675 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T[0]);
4676 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4677 tcg_gen_ext16s_tl(cpu_tmp0, cpu_T[0]);
4678 tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4679 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 16);
4680 gen_op_mov_reg_v(MO_16, R_EDX, cpu_T[0]);
4681 set_cc_op(s, CC_OP_MULW);
4685 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4686 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_regs[R_EAX]);
4687 tcg_gen_muls2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
4688 cpu_tmp2_i32, cpu_tmp3_i32);
4689 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], cpu_tmp2_i32);
4690 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], cpu_tmp3_i32);
4691 tcg_gen_sari_i32(cpu_tmp2_i32, cpu_tmp2_i32, 31);
4692 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4693 tcg_gen_sub_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
4694 tcg_gen_extu_i32_tl(cpu_cc_src, cpu_tmp2_i32);
4695 set_cc_op(s, CC_OP_MULL);
4697 #ifdef TARGET_X86_64
4699 tcg_gen_muls2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX],
4700 cpu_T[0], cpu_regs[R_EAX]);
4701 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4702 tcg_gen_sari_tl(cpu_cc_src, cpu_regs[R_EAX], 63);
4703 tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, cpu_regs[R_EDX]);
4704 set_cc_op(s, CC_OP_MULQ);
4712 gen_helper_divb_AL(cpu_env, cpu_T[0]);
4715 gen_helper_divw_AX(cpu_env, cpu_T[0]);
4719 gen_helper_divl_EAX(cpu_env, cpu_T[0]);
4721 #ifdef TARGET_X86_64
4723 gen_helper_divq_EAX(cpu_env, cpu_T[0]);
4731 gen_helper_idivb_AL(cpu_env, cpu_T[0]);
4734 gen_helper_idivw_AX(cpu_env, cpu_T[0]);
4738 gen_helper_idivl_EAX(cpu_env, cpu_T[0]);
4740 #ifdef TARGET_X86_64
4742 gen_helper_idivq_EAX(cpu_env, cpu_T[0]);
4752 case 0xfe: /* GRP4 */
4753 case 0xff: /* GRP5 */
4754 ot = mo_b_d(b, dflag);
4756 modrm = cpu_ldub_code(env, s->pc++);
4757 mod = (modrm >> 6) & 3;
4758 rm = (modrm & 7) | REX_B(s);
4759 op = (modrm >> 3) & 7;
4760 if (op >= 2 && b == 0xfe) {
4764 if (op == 2 || op == 4) {
4765 /* operand size for jumps is 64 bit */
4767 } else if (op == 3 || op == 5) {
4768 ot = dflag != MO_16 ? MO_32 + (rex_w == 1) : MO_16;
4769 } else if (op == 6) {
4770 /* default push size is 64 bit */
4771 ot = mo_pushpop(s, dflag);
4775 gen_lea_modrm(env, s, modrm);
4776 if (op >= 2 && op != 3 && op != 5)
4777 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
4779 gen_op_mov_v_reg(ot, cpu_T[0], rm);
4783 case 0: /* inc Ev */
4788 gen_inc(s, ot, opreg, 1);
4790 case 1: /* dec Ev */
4795 gen_inc(s, ot, opreg, -1);
4797 case 2: /* call Ev */
4798 /* XXX: optimize if memory (no 'and' is necessary) */
4799 if (dflag == MO_16) {
4800 tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
4802 next_eip = s->pc - s->cs_base;
4803 tcg_gen_movi_tl(cpu_T[1], next_eip);
4804 gen_push_v(s, cpu_T[1]);
4805 gen_op_jmp_v(cpu_T[0]);
4808 case 3: /* lcall Ev */
4809 gen_op_ld_v(s, ot, cpu_T[1], cpu_A0);
4810 gen_add_A0_im(s, 1 << ot);
4811 gen_op_ld_v(s, MO_16, cpu_T[0], cpu_A0);
4813 if (s->pe && !s->vm86) {
4814 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4815 gen_helper_lcall_protected(cpu_env, cpu_tmp2_i32, cpu_T[1],
4816 tcg_const_i32(dflag - 1),
4817 tcg_const_tl(s->pc - s->cs_base));
4819 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4820 gen_helper_lcall_real(cpu_env, cpu_tmp2_i32, cpu_T[1],
4821 tcg_const_i32(dflag - 1),
4822 tcg_const_i32(s->pc - s->cs_base));
4826 case 4: /* jmp Ev */
4827 if (dflag == MO_16) {
4828 tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
4830 gen_op_jmp_v(cpu_T[0]);
4833 case 5: /* ljmp Ev */
4834 gen_op_ld_v(s, ot, cpu_T[1], cpu_A0);
4835 gen_add_A0_im(s, 1 << ot);
4836 gen_op_ld_v(s, MO_16, cpu_T[0], cpu_A0);
4838 if (s->pe && !s->vm86) {
4839 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4840 gen_helper_ljmp_protected(cpu_env, cpu_tmp2_i32, cpu_T[1],
4841 tcg_const_tl(s->pc - s->cs_base));
4843 gen_op_movl_seg_T0_vm(R_CS);
4844 gen_op_jmp_v(cpu_T[1]);
4848 case 6: /* push Ev */
4849 gen_push_v(s, cpu_T[0]);
4856 case 0x84: /* test Ev, Gv */
4858 ot = mo_b_d(b, dflag);
4860 modrm = cpu_ldub_code(env, s->pc++);
4861 reg = ((modrm >> 3) & 7) | rex_r;
4863 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4864 gen_op_mov_v_reg(ot, cpu_T[1], reg);
4865 gen_op_testl_T0_T1_cc();
4866 set_cc_op(s, CC_OP_LOGICB + ot);
4869 case 0xa8: /* test eAX, Iv */
4871 ot = mo_b_d(b, dflag);
4872 val = insn_get(env, s, ot);
4874 gen_op_mov_v_reg(ot, cpu_T[0], OR_EAX);
4875 tcg_gen_movi_tl(cpu_T[1], val);
4876 gen_op_testl_T0_T1_cc();
4877 set_cc_op(s, CC_OP_LOGICB + ot);
4880 case 0x98: /* CWDE/CBW */
4882 #ifdef TARGET_X86_64
4884 gen_op_mov_v_reg(MO_32, cpu_T[0], R_EAX);
4885 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4886 gen_op_mov_reg_v(MO_64, R_EAX, cpu_T[0]);
4890 gen_op_mov_v_reg(MO_16, cpu_T[0], R_EAX);
4891 tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4892 gen_op_mov_reg_v(MO_32, R_EAX, cpu_T[0]);
4895 gen_op_mov_v_reg(MO_8, cpu_T[0], R_EAX);
4896 tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
4897 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T[0]);
4903 case 0x99: /* CDQ/CWD */
4905 #ifdef TARGET_X86_64
4907 gen_op_mov_v_reg(MO_64, cpu_T[0], R_EAX);
4908 tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 63);
4909 gen_op_mov_reg_v(MO_64, R_EDX, cpu_T[0]);
4913 gen_op_mov_v_reg(MO_32, cpu_T[0], R_EAX);
4914 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
4915 tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 31);
4916 gen_op_mov_reg_v(MO_32, R_EDX, cpu_T[0]);
4919 gen_op_mov_v_reg(MO_16, cpu_T[0], R_EAX);
4920 tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4921 tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 15);
4922 gen_op_mov_reg_v(MO_16, R_EDX, cpu_T[0]);
4928 case 0x1af: /* imul Gv, Ev */
4929 case 0x69: /* imul Gv, Ev, I */
4932 modrm = cpu_ldub_code(env, s->pc++);
4933 reg = ((modrm >> 3) & 7) | rex_r;
4935 s->rip_offset = insn_const_size(ot);
4938 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4940 val = insn_get(env, s, ot);
4941 tcg_gen_movi_tl(cpu_T[1], val);
4942 } else if (b == 0x6b) {
4943 val = (int8_t)insn_get(env, s, MO_8);
4944 tcg_gen_movi_tl(cpu_T[1], val);
4946 gen_op_mov_v_reg(ot, cpu_T[1], reg);
4949 #ifdef TARGET_X86_64
4951 tcg_gen_muls2_i64(cpu_regs[reg], cpu_T[1], cpu_T[0], cpu_T[1]);
4952 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]);
4953 tcg_gen_sari_tl(cpu_cc_src, cpu_cc_dst, 63);
4954 tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, cpu_T[1]);
4958 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4959 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
4960 tcg_gen_muls2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
4961 cpu_tmp2_i32, cpu_tmp3_i32);
4962 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
4963 tcg_gen_sari_i32(cpu_tmp2_i32, cpu_tmp2_i32, 31);
4964 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]);
4965 tcg_gen_sub_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
4966 tcg_gen_extu_i32_tl(cpu_cc_src, cpu_tmp2_i32);
4969 tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4970 tcg_gen_ext16s_tl(cpu_T[1], cpu_T[1]);
4971 /* XXX: use 32 bit mul which could be faster */
4972 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4973 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4974 tcg_gen_ext16s_tl(cpu_tmp0, cpu_T[0]);
4975 tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4976 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
4979 set_cc_op(s, CC_OP_MULB + ot);
4982 case 0x1c1: /* xadd Ev, Gv */
4983 ot = mo_b_d(b, dflag);
4984 modrm = cpu_ldub_code(env, s->pc++);
4985 reg = ((modrm >> 3) & 7) | rex_r;
4986 mod = (modrm >> 6) & 3;
4988 rm = (modrm & 7) | REX_B(s);
4989 gen_op_mov_v_reg(ot, cpu_T[0], reg);
4990 gen_op_mov_v_reg(ot, cpu_T[1], rm);
4991 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4992 gen_op_mov_reg_v(ot, reg, cpu_T[1]);
4993 gen_op_mov_reg_v(ot, rm, cpu_T[0]);
4995 gen_lea_modrm(env, s, modrm);
4996 gen_op_mov_v_reg(ot, cpu_T[0], reg);
4997 gen_op_ld_v(s, ot, cpu_T[1], cpu_A0);
4998 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4999 gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
5000 gen_op_mov_reg_v(ot, reg, cpu_T[1]);
5002 gen_op_update2_cc();
5003 set_cc_op(s, CC_OP_ADDB + ot);
5006 case 0x1b1: /* cmpxchg Ev, Gv */
5008 TCGLabel *label1, *label2;
5009 TCGv t0, t1, t2, a0;
5011 ot = mo_b_d(b, dflag);
5012 modrm = cpu_ldub_code(env, s->pc++);
5013 reg = ((modrm >> 3) & 7) | rex_r;
5014 mod = (modrm >> 6) & 3;
5015 t0 = tcg_temp_local_new();
5016 t1 = tcg_temp_local_new();
5017 t2 = tcg_temp_local_new();
5018 a0 = tcg_temp_local_new();
5019 gen_op_mov_v_reg(ot, t1, reg);
5021 rm = (modrm & 7) | REX_B(s);
5022 gen_op_mov_v_reg(ot, t0, rm);
5024 gen_lea_modrm(env, s, modrm);
5025 tcg_gen_mov_tl(a0, cpu_A0);
5026 gen_op_ld_v(s, ot, t0, a0);
5027 rm = 0; /* avoid warning */
5029 label1 = gen_new_label();
5030 tcg_gen_mov_tl(t2, cpu_regs[R_EAX]);
5033 tcg_gen_brcond_tl(TCG_COND_EQ, t2, t0, label1);
5034 label2 = gen_new_label();
5036 gen_op_mov_reg_v(ot, R_EAX, t0);
5038 gen_set_label(label1);
5039 gen_op_mov_reg_v(ot, rm, t1);
5041 /* perform no-op store cycle like physical cpu; must be
5042 before changing accumulator to ensure idempotency if
5043 the store faults and the instruction is restarted */
5044 gen_op_st_v(s, ot, t0, a0);
5045 gen_op_mov_reg_v(ot, R_EAX, t0);
5047 gen_set_label(label1);
5048 gen_op_st_v(s, ot, t1, a0);
5050 gen_set_label(label2);
5051 tcg_gen_mov_tl(cpu_cc_src, t0);
5052 tcg_gen_mov_tl(cpu_cc_srcT, t2);
5053 tcg_gen_sub_tl(cpu_cc_dst, t2, t0);
5054 set_cc_op(s, CC_OP_SUBB + ot);
5061 case 0x1c7: /* cmpxchg8b */
5062 modrm = cpu_ldub_code(env, s->pc++);
5063 mod = (modrm >> 6) & 3;
5064 if ((mod == 3) || ((modrm & 0x38) != 0x8))
5066 #ifdef TARGET_X86_64
5067 if (dflag == MO_64) {
5068 if (!(s->cpuid_ext_features & CPUID_EXT_CX16))
5070 gen_lea_modrm(env, s, modrm);
5071 gen_helper_cmpxchg16b(cpu_env, cpu_A0);
5075 if (!(s->cpuid_features & CPUID_CX8))
5077 gen_lea_modrm(env, s, modrm);
5078 gen_helper_cmpxchg8b(cpu_env, cpu_A0);
5080 set_cc_op(s, CC_OP_EFLAGS);
5083 /**************************/
5085 case 0x50 ... 0x57: /* push */
5086 gen_op_mov_v_reg(MO_32, cpu_T[0], (b & 7) | REX_B(s));
5087 gen_push_v(s, cpu_T[0]);
5089 case 0x58 ... 0x5f: /* pop */
5091 /* NOTE: order is important for pop %sp */
5092 gen_pop_update(s, ot);
5093 gen_op_mov_reg_v(ot, (b & 7) | REX_B(s), cpu_T[0]);
5095 case 0x60: /* pusha */
5100 case 0x61: /* popa */
5105 case 0x68: /* push Iv */
5107 ot = mo_pushpop(s, dflag);
5109 val = insn_get(env, s, ot);
5111 val = (int8_t)insn_get(env, s, MO_8);
5112 tcg_gen_movi_tl(cpu_T[0], val);
5113 gen_push_v(s, cpu_T[0]);
5115 case 0x8f: /* pop Ev */
5116 modrm = cpu_ldub_code(env, s->pc++);
5117 mod = (modrm >> 6) & 3;
5120 /* NOTE: order is important for pop %sp */
5121 gen_pop_update(s, ot);
5122 rm = (modrm & 7) | REX_B(s);
5123 gen_op_mov_reg_v(ot, rm, cpu_T[0]);
5125 /* NOTE: order is important too for MMU exceptions */
5126 s->popl_esp_hack = 1 << ot;
5127 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5128 s->popl_esp_hack = 0;
5129 gen_pop_update(s, ot);
5132 case 0xc8: /* enter */
5135 val = cpu_lduw_code(env, s->pc);
5137 level = cpu_ldub_code(env, s->pc++);
5138 gen_enter(s, val, level);
5141 case 0xc9: /* leave */
5142 /* XXX: exception not precise (ESP is updated before potential exception) */
5144 gen_op_mov_v_reg(MO_64, cpu_T[0], R_EBP);
5145 gen_op_mov_reg_v(MO_64, R_ESP, cpu_T[0]);
5146 } else if (s->ss32) {
5147 gen_op_mov_v_reg(MO_32, cpu_T[0], R_EBP);
5148 gen_op_mov_reg_v(MO_32, R_ESP, cpu_T[0]);
5150 gen_op_mov_v_reg(MO_16, cpu_T[0], R_EBP);
5151 gen_op_mov_reg_v(MO_16, R_ESP, cpu_T[0]);
5154 gen_op_mov_reg_v(ot, R_EBP, cpu_T[0]);
5155 gen_pop_update(s, ot);
5157 case 0x06: /* push es */
5158 case 0x0e: /* push cs */
5159 case 0x16: /* push ss */
5160 case 0x1e: /* push ds */
5163 gen_op_movl_T0_seg(b >> 3);
5164 gen_push_v(s, cpu_T[0]);
5166 case 0x1a0: /* push fs */
5167 case 0x1a8: /* push gs */
5168 gen_op_movl_T0_seg((b >> 3) & 7);
5169 gen_push_v(s, cpu_T[0]);
5171 case 0x07: /* pop es */
5172 case 0x17: /* pop ss */
5173 case 0x1f: /* pop ds */
5178 gen_movl_seg_T0(s, reg);
5179 gen_pop_update(s, ot);
5181 /* if reg == SS, inhibit interrupts/trace. */
5182 /* If several instructions disable interrupts, only the
5184 if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
5185 gen_helper_set_inhibit_irq(cpu_env);
5189 gen_jmp_im(s->pc - s->cs_base);
5193 case 0x1a1: /* pop fs */
5194 case 0x1a9: /* pop gs */
5196 gen_movl_seg_T0(s, (b >> 3) & 7);
5197 gen_pop_update(s, ot);
5199 gen_jmp_im(s->pc - s->cs_base);
5204 /**************************/
5207 case 0x89: /* mov Gv, Ev */
5208 ot = mo_b_d(b, dflag);
5209 modrm = cpu_ldub_code(env, s->pc++);
5210 reg = ((modrm >> 3) & 7) | rex_r;
5212 /* generate a generic store */
5213 gen_ldst_modrm(env, s, modrm, ot, reg, 1);
5216 case 0xc7: /* mov Ev, Iv */
5217 ot = mo_b_d(b, dflag);
5218 modrm = cpu_ldub_code(env, s->pc++);
5219 mod = (modrm >> 6) & 3;
5221 s->rip_offset = insn_const_size(ot);
5222 gen_lea_modrm(env, s, modrm);
5224 val = insn_get(env, s, ot);
5225 tcg_gen_movi_tl(cpu_T[0], val);
5227 gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
5229 gen_op_mov_reg_v(ot, (modrm & 7) | REX_B(s), cpu_T[0]);
5233 case 0x8b: /* mov Ev, Gv */
5234 ot = mo_b_d(b, dflag);
5235 modrm = cpu_ldub_code(env, s->pc++);
5236 reg = ((modrm >> 3) & 7) | rex_r;
5238 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5239 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
5241 case 0x8e: /* mov seg, Gv */
5242 modrm = cpu_ldub_code(env, s->pc++);
5243 reg = (modrm >> 3) & 7;
5244 if (reg >= 6 || reg == R_CS)
5246 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
5247 gen_movl_seg_T0(s, reg);
5249 /* if reg == SS, inhibit interrupts/trace */
5250 /* If several instructions disable interrupts, only the
5252 if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
5253 gen_helper_set_inhibit_irq(cpu_env);
5257 gen_jmp_im(s->pc - s->cs_base);
5261 case 0x8c: /* mov Gv, seg */
5262 modrm = cpu_ldub_code(env, s->pc++);
5263 reg = (modrm >> 3) & 7;
5264 mod = (modrm >> 6) & 3;
5267 gen_op_movl_T0_seg(reg);
5268 ot = mod == 3 ? dflag : MO_16;
5269 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5272 case 0x1b6: /* movzbS Gv, Eb */
5273 case 0x1b7: /* movzwS Gv, Eb */
5274 case 0x1be: /* movsbS Gv, Eb */
5275 case 0x1bf: /* movswS Gv, Eb */
5280 /* d_ot is the size of destination */
5282 /* ot is the size of source */
5283 ot = (b & 1) + MO_8;
5284 /* s_ot is the sign+size of source */
5285 s_ot = b & 8 ? MO_SIGN | ot : ot;
5287 modrm = cpu_ldub_code(env, s->pc++);
5288 reg = ((modrm >> 3) & 7) | rex_r;
5289 mod = (modrm >> 6) & 3;
5290 rm = (modrm & 7) | REX_B(s);
5293 gen_op_mov_v_reg(ot, cpu_T[0], rm);
5296 tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]);
5299 tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
5302 tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
5306 tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
5309 gen_op_mov_reg_v(d_ot, reg, cpu_T[0]);
5311 gen_lea_modrm(env, s, modrm);
5312 gen_op_ld_v(s, s_ot, cpu_T[0], cpu_A0);
5313 gen_op_mov_reg_v(d_ot, reg, cpu_T[0]);
5318 case 0x8d: /* lea */
5320 modrm = cpu_ldub_code(env, s->pc++);
5321 mod = (modrm >> 6) & 3;
5324 reg = ((modrm >> 3) & 7) | rex_r;
5325 /* we must ensure that no segment is added */
5329 gen_lea_modrm(env, s, modrm);
5331 gen_op_mov_reg_v(ot, reg, cpu_A0);
5334 case 0xa0: /* mov EAX, Ov */
5336 case 0xa2: /* mov Ov, EAX */
5339 target_ulong offset_addr;
5341 ot = mo_b_d(b, dflag);
5343 #ifdef TARGET_X86_64
5345 offset_addr = cpu_ldq_code(env, s->pc);
5350 offset_addr = insn_get(env, s, s->aflag);
5353 tcg_gen_movi_tl(cpu_A0, offset_addr);
5354 gen_add_A0_ds_seg(s);
5356 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
5357 gen_op_mov_reg_v(ot, R_EAX, cpu_T[0]);
5359 gen_op_mov_v_reg(ot, cpu_T[0], R_EAX);
5360 gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
5364 case 0xd7: /* xlat */
5365 tcg_gen_mov_tl(cpu_A0, cpu_regs[R_EBX]);
5366 tcg_gen_ext8u_tl(cpu_T[0], cpu_regs[R_EAX]);
5367 tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T[0]);
5368 gen_extu(s->aflag, cpu_A0);
5369 gen_add_A0_ds_seg(s);
5370 gen_op_ld_v(s, MO_8, cpu_T[0], cpu_A0);
5371 gen_op_mov_reg_v(MO_8, R_EAX, cpu_T[0]);
5373 case 0xb0 ... 0xb7: /* mov R, Ib */
5374 val = insn_get(env, s, MO_8);
5375 tcg_gen_movi_tl(cpu_T[0], val);
5376 gen_op_mov_reg_v(MO_8, (b & 7) | REX_B(s), cpu_T[0]);
5378 case 0xb8 ... 0xbf: /* mov R, Iv */
5379 #ifdef TARGET_X86_64
5380 if (dflag == MO_64) {
5383 tmp = cpu_ldq_code(env, s->pc);
5385 reg = (b & 7) | REX_B(s);
5386 tcg_gen_movi_tl(cpu_T[0], tmp);
5387 gen_op_mov_reg_v(MO_64, reg, cpu_T[0]);
5392 val = insn_get(env, s, ot);
5393 reg = (b & 7) | REX_B(s);
5394 tcg_gen_movi_tl(cpu_T[0], val);
5395 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
5399 case 0x91 ... 0x97: /* xchg R, EAX */
5402 reg = (b & 7) | REX_B(s);
5406 case 0x87: /* xchg Ev, Gv */
5407 ot = mo_b_d(b, dflag);
5408 modrm = cpu_ldub_code(env, s->pc++);
5409 reg = ((modrm >> 3) & 7) | rex_r;
5410 mod = (modrm >> 6) & 3;
5412 rm = (modrm & 7) | REX_B(s);
5414 gen_op_mov_v_reg(ot, cpu_T[0], reg);
5415 gen_op_mov_v_reg(ot, cpu_T[1], rm);
5416 gen_op_mov_reg_v(ot, rm, cpu_T[0]);
5417 gen_op_mov_reg_v(ot, reg, cpu_T[1]);
5419 gen_lea_modrm(env, s, modrm);
5420 gen_op_mov_v_reg(ot, cpu_T[0], reg);
5421 /* for xchg, lock is implicit */
5422 if (!(prefixes & PREFIX_LOCK))
5424 gen_op_ld_v(s, ot, cpu_T[1], cpu_A0);
5425 gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
5426 if (!(prefixes & PREFIX_LOCK))
5427 gen_helper_unlock();
5428 gen_op_mov_reg_v(ot, reg, cpu_T[1]);
5431 case 0xc4: /* les Gv */
5432 /* In CODE64 this is VEX3; see above. */
5435 case 0xc5: /* lds Gv */
5436 /* In CODE64 this is VEX2; see above. */
5439 case 0x1b2: /* lss Gv */
5442 case 0x1b4: /* lfs Gv */
5445 case 0x1b5: /* lgs Gv */
5448 ot = dflag != MO_16 ? MO_32 : MO_16;
5449 modrm = cpu_ldub_code(env, s->pc++);
5450 reg = ((modrm >> 3) & 7) | rex_r;
5451 mod = (modrm >> 6) & 3;
5454 gen_lea_modrm(env, s, modrm);
5455 gen_op_ld_v(s, ot, cpu_T[1], cpu_A0);
5456 gen_add_A0_im(s, 1 << ot);
5457 /* load the segment first to handle exceptions properly */
5458 gen_op_ld_v(s, MO_16, cpu_T[0], cpu_A0);
5459 gen_movl_seg_T0(s, op);
5460 /* then put the data */
5461 gen_op_mov_reg_v(ot, reg, cpu_T[1]);
5463 gen_jmp_im(s->pc - s->cs_base);
5468 /************************/
5476 ot = mo_b_d(b, dflag);
5477 modrm = cpu_ldub_code(env, s->pc++);
5478 mod = (modrm >> 6) & 3;
5479 op = (modrm >> 3) & 7;
5485 gen_lea_modrm(env, s, modrm);
5488 opreg = (modrm & 7) | REX_B(s);
5493 gen_shift(s, op, ot, opreg, OR_ECX);
5496 shift = cpu_ldub_code(env, s->pc++);
5498 gen_shifti(s, op, ot, opreg, shift);
5513 case 0x1a4: /* shld imm */
5517 case 0x1a5: /* shld cl */
5521 case 0x1ac: /* shrd imm */
5525 case 0x1ad: /* shrd cl */
5530 modrm = cpu_ldub_code(env, s->pc++);
5531 mod = (modrm >> 6) & 3;
5532 rm = (modrm & 7) | REX_B(s);
5533 reg = ((modrm >> 3) & 7) | rex_r;
5535 gen_lea_modrm(env, s, modrm);
5540 gen_op_mov_v_reg(ot, cpu_T[1], reg);
5543 TCGv imm = tcg_const_tl(cpu_ldub_code(env, s->pc++));
5544 gen_shiftd_rm_T1(s, ot, opreg, op, imm);
5547 gen_shiftd_rm_T1(s, ot, opreg, op, cpu_regs[R_ECX]);
5551 /************************/
5554 if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
5555 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5556 /* XXX: what to do if illegal op ? */
5557 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
5560 modrm = cpu_ldub_code(env, s->pc++);
5561 mod = (modrm >> 6) & 3;
5563 op = ((b & 7) << 3) | ((modrm >> 3) & 7);
5566 gen_lea_modrm(env, s, modrm);
5568 case 0x00 ... 0x07: /* fxxxs */
5569 case 0x10 ... 0x17: /* fixxxl */
5570 case 0x20 ... 0x27: /* fxxxl */
5571 case 0x30 ... 0x37: /* fixxx */
5578 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5579 s->mem_index, MO_LEUL);
5580 gen_helper_flds_FT0(cpu_env, cpu_tmp2_i32);
5583 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5584 s->mem_index, MO_LEUL);
5585 gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32);
5588 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0,
5589 s->mem_index, MO_LEQ);
5590 gen_helper_fldl_FT0(cpu_env, cpu_tmp1_i64);
5594 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5595 s->mem_index, MO_LESW);
5596 gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32);
5600 gen_helper_fp_arith_ST0_FT0(op1);
5602 /* fcomp needs pop */
5603 gen_helper_fpop(cpu_env);
5607 case 0x08: /* flds */
5608 case 0x0a: /* fsts */
5609 case 0x0b: /* fstps */
5610 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5611 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5612 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5617 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5618 s->mem_index, MO_LEUL);
5619 gen_helper_flds_ST0(cpu_env, cpu_tmp2_i32);
5622 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5623 s->mem_index, MO_LEUL);
5624 gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32);
5627 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0,
5628 s->mem_index, MO_LEQ);
5629 gen_helper_fldl_ST0(cpu_env, cpu_tmp1_i64);
5633 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5634 s->mem_index, MO_LESW);
5635 gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32);
5640 /* XXX: the corresponding CPUID bit must be tested ! */
5643 gen_helper_fisttl_ST0(cpu_tmp2_i32, cpu_env);
5644 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5645 s->mem_index, MO_LEUL);
5648 gen_helper_fisttll_ST0(cpu_tmp1_i64, cpu_env);
5649 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0,
5650 s->mem_index, MO_LEQ);
5654 gen_helper_fistt_ST0(cpu_tmp2_i32, cpu_env);
5655 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5656 s->mem_index, MO_LEUW);
5659 gen_helper_fpop(cpu_env);
5664 gen_helper_fsts_ST0(cpu_tmp2_i32, cpu_env);
5665 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5666 s->mem_index, MO_LEUL);
5669 gen_helper_fistl_ST0(cpu_tmp2_i32, cpu_env);
5670 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5671 s->mem_index, MO_LEUL);
5674 gen_helper_fstl_ST0(cpu_tmp1_i64, cpu_env);
5675 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0,
5676 s->mem_index, MO_LEQ);
5680 gen_helper_fist_ST0(cpu_tmp2_i32, cpu_env);
5681 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5682 s->mem_index, MO_LEUW);
5686 gen_helper_fpop(cpu_env);
5690 case 0x0c: /* fldenv mem */
5691 gen_helper_fldenv(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5693 case 0x0d: /* fldcw mem */
5694 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5695 s->mem_index, MO_LEUW);
5696 gen_helper_fldcw(cpu_env, cpu_tmp2_i32);
5698 case 0x0e: /* fnstenv mem */
5699 gen_helper_fstenv(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5701 case 0x0f: /* fnstcw mem */
5702 gen_helper_fnstcw(cpu_tmp2_i32, cpu_env);
5703 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5704 s->mem_index, MO_LEUW);
5706 case 0x1d: /* fldt mem */
5707 gen_helper_fldt_ST0(cpu_env, cpu_A0);
5709 case 0x1f: /* fstpt mem */
5710 gen_helper_fstt_ST0(cpu_env, cpu_A0);
5711 gen_helper_fpop(cpu_env);
5713 case 0x2c: /* frstor mem */
5714 gen_helper_frstor(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5716 case 0x2e: /* fnsave mem */
5717 gen_helper_fsave(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5719 case 0x2f: /* fnstsw mem */
5720 gen_helper_fnstsw(cpu_tmp2_i32, cpu_env);
5721 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5722 s->mem_index, MO_LEUW);
5724 case 0x3c: /* fbld */
5725 gen_helper_fbld_ST0(cpu_env, cpu_A0);
5727 case 0x3e: /* fbstp */
5728 gen_helper_fbst_ST0(cpu_env, cpu_A0);
5729 gen_helper_fpop(cpu_env);
5731 case 0x3d: /* fildll */
5732 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
5733 gen_helper_fildll_ST0(cpu_env, cpu_tmp1_i64);
5735 case 0x3f: /* fistpll */
5736 gen_helper_fistll_ST0(cpu_tmp1_i64, cpu_env);
5737 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
5738 gen_helper_fpop(cpu_env);
5744 /* register float ops */
5748 case 0x08: /* fld sti */
5749 gen_helper_fpush(cpu_env);
5750 gen_helper_fmov_ST0_STN(cpu_env,
5751 tcg_const_i32((opreg + 1) & 7));
5753 case 0x09: /* fxchg sti */
5754 case 0x29: /* fxchg4 sti, undocumented op */
5755 case 0x39: /* fxchg7 sti, undocumented op */
5756 gen_helper_fxchg_ST0_STN(cpu_env, tcg_const_i32(opreg));
5758 case 0x0a: /* grp d9/2 */
5761 /* check exceptions (FreeBSD FPU probe) */
5762 gen_helper_fwait(cpu_env);
5768 case 0x0c: /* grp d9/4 */
5771 gen_helper_fchs_ST0(cpu_env);
5774 gen_helper_fabs_ST0(cpu_env);
5777 gen_helper_fldz_FT0(cpu_env);
5778 gen_helper_fcom_ST0_FT0(cpu_env);
5781 gen_helper_fxam_ST0(cpu_env);
5787 case 0x0d: /* grp d9/5 */
5791 gen_helper_fpush(cpu_env);
5792 gen_helper_fld1_ST0(cpu_env);
5795 gen_helper_fpush(cpu_env);
5796 gen_helper_fldl2t_ST0(cpu_env);
5799 gen_helper_fpush(cpu_env);
5800 gen_helper_fldl2e_ST0(cpu_env);
5803 gen_helper_fpush(cpu_env);
5804 gen_helper_fldpi_ST0(cpu_env);
5807 gen_helper_fpush(cpu_env);
5808 gen_helper_fldlg2_ST0(cpu_env);
5811 gen_helper_fpush(cpu_env);
5812 gen_helper_fldln2_ST0(cpu_env);
5815 gen_helper_fpush(cpu_env);
5816 gen_helper_fldz_ST0(cpu_env);
5823 case 0x0e: /* grp d9/6 */
5826 gen_helper_f2xm1(cpu_env);
5829 gen_helper_fyl2x(cpu_env);
5832 gen_helper_fptan(cpu_env);
5834 case 3: /* fpatan */
5835 gen_helper_fpatan(cpu_env);
5837 case 4: /* fxtract */
5838 gen_helper_fxtract(cpu_env);
5840 case 5: /* fprem1 */
5841 gen_helper_fprem1(cpu_env);
5843 case 6: /* fdecstp */
5844 gen_helper_fdecstp(cpu_env);
5847 case 7: /* fincstp */
5848 gen_helper_fincstp(cpu_env);
5852 case 0x0f: /* grp d9/7 */
5855 gen_helper_fprem(cpu_env);
5857 case 1: /* fyl2xp1 */
5858 gen_helper_fyl2xp1(cpu_env);
5861 gen_helper_fsqrt(cpu_env);
5863 case 3: /* fsincos */
5864 gen_helper_fsincos(cpu_env);
5866 case 5: /* fscale */
5867 gen_helper_fscale(cpu_env);
5869 case 4: /* frndint */
5870 gen_helper_frndint(cpu_env);
5873 gen_helper_fsin(cpu_env);
5877 gen_helper_fcos(cpu_env);
5881 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
5882 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
5883 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
5889 gen_helper_fp_arith_STN_ST0(op1, opreg);
5891 gen_helper_fpop(cpu_env);
5893 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
5894 gen_helper_fp_arith_ST0_FT0(op1);
5898 case 0x02: /* fcom */
5899 case 0x22: /* fcom2, undocumented op */
5900 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
5901 gen_helper_fcom_ST0_FT0(cpu_env);
5903 case 0x03: /* fcomp */
5904 case 0x23: /* fcomp3, undocumented op */
5905 case 0x32: /* fcomp5, undocumented op */
5906 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
5907 gen_helper_fcom_ST0_FT0(cpu_env);
5908 gen_helper_fpop(cpu_env);
5910 case 0x15: /* da/5 */
5912 case 1: /* fucompp */
5913 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
5914 gen_helper_fucom_ST0_FT0(cpu_env);
5915 gen_helper_fpop(cpu_env);
5916 gen_helper_fpop(cpu_env);
5924 case 0: /* feni (287 only, just do nop here) */
5926 case 1: /* fdisi (287 only, just do nop here) */
5929 gen_helper_fclex(cpu_env);
5931 case 3: /* fninit */
5932 gen_helper_fninit(cpu_env);
5934 case 4: /* fsetpm (287 only, just do nop here) */
5940 case 0x1d: /* fucomi */
5941 if (!(s->cpuid_features & CPUID_CMOV)) {
5944 gen_update_cc_op(s);
5945 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
5946 gen_helper_fucomi_ST0_FT0(cpu_env);
5947 set_cc_op(s, CC_OP_EFLAGS);
5949 case 0x1e: /* fcomi */
5950 if (!(s->cpuid_features & CPUID_CMOV)) {
5953 gen_update_cc_op(s);
5954 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
5955 gen_helper_fcomi_ST0_FT0(cpu_env);
5956 set_cc_op(s, CC_OP_EFLAGS);
5958 case 0x28: /* ffree sti */
5959 gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
5961 case 0x2a: /* fst sti */
5962 gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
5964 case 0x2b: /* fstp sti */
5965 case 0x0b: /* fstp1 sti, undocumented op */
5966 case 0x3a: /* fstp8 sti, undocumented op */
5967 case 0x3b: /* fstp9 sti, undocumented op */
5968 gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
5969 gen_helper_fpop(cpu_env);
5971 case 0x2c: /* fucom st(i) */
5972 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
5973 gen_helper_fucom_ST0_FT0(cpu_env);
5975 case 0x2d: /* fucomp st(i) */
5976 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
5977 gen_helper_fucom_ST0_FT0(cpu_env);
5978 gen_helper_fpop(cpu_env);
5980 case 0x33: /* de/3 */
5982 case 1: /* fcompp */
5983 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
5984 gen_helper_fcom_ST0_FT0(cpu_env);
5985 gen_helper_fpop(cpu_env);
5986 gen_helper_fpop(cpu_env);
5992 case 0x38: /* ffreep sti, undocumented op */
5993 gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
5994 gen_helper_fpop(cpu_env);
5996 case 0x3c: /* df/4 */
5999 gen_helper_fnstsw(cpu_tmp2_i32, cpu_env);
6000 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
6001 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T[0]);
6007 case 0x3d: /* fucomip */
6008 if (!(s->cpuid_features & CPUID_CMOV)) {
6011 gen_update_cc_op(s);
6012 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6013 gen_helper_fucomi_ST0_FT0(cpu_env);
6014 gen_helper_fpop(cpu_env);
6015 set_cc_op(s, CC_OP_EFLAGS);
6017 case 0x3e: /* fcomip */
6018 if (!(s->cpuid_features & CPUID_CMOV)) {
6021 gen_update_cc_op(s);
6022 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6023 gen_helper_fcomi_ST0_FT0(cpu_env);
6024 gen_helper_fpop(cpu_env);
6025 set_cc_op(s, CC_OP_EFLAGS);
6027 case 0x10 ... 0x13: /* fcmovxx */
6032 static const uint8_t fcmov_cc[8] = {
6039 if (!(s->cpuid_features & CPUID_CMOV)) {
6042 op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1);
6043 l1 = gen_new_label();
6044 gen_jcc1_noeob(s, op1, l1);
6045 gen_helper_fmov_ST0_STN(cpu_env, tcg_const_i32(opreg));
6054 /************************/
6057 case 0xa4: /* movsS */
6059 ot = mo_b_d(b, dflag);
6060 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6061 gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6067 case 0xaa: /* stosS */
6069 ot = mo_b_d(b, dflag);
6070 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6071 gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6076 case 0xac: /* lodsS */
6078 ot = mo_b_d(b, dflag);
6079 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6080 gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6085 case 0xae: /* scasS */
6087 ot = mo_b_d(b, dflag);
6088 if (prefixes & PREFIX_REPNZ) {
6089 gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
6090 } else if (prefixes & PREFIX_REPZ) {
6091 gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
6097 case 0xa6: /* cmpsS */
6099 ot = mo_b_d(b, dflag);
6100 if (prefixes & PREFIX_REPNZ) {
6101 gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
6102 } else if (prefixes & PREFIX_REPZ) {
6103 gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
6108 case 0x6c: /* insS */
6110 ot = mo_b_d32(b, dflag);
6111 tcg_gen_ext16u_tl(cpu_T[0], cpu_regs[R_EDX]);
6112 gen_check_io(s, ot, pc_start - s->cs_base,
6113 SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) | 4);
6114 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6115 gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6118 if (s->tb->cflags & CF_USE_ICOUNT) {
6119 gen_jmp(s, s->pc - s->cs_base);
6123 case 0x6e: /* outsS */
6125 ot = mo_b_d32(b, dflag);
6126 tcg_gen_ext16u_tl(cpu_T[0], cpu_regs[R_EDX]);
6127 gen_check_io(s, ot, pc_start - s->cs_base,
6128 svm_is_rep(prefixes) | 4);
6129 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6130 gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6133 if (s->tb->cflags & CF_USE_ICOUNT) {
6134 gen_jmp(s, s->pc - s->cs_base);
6139 /************************/
6144 ot = mo_b_d32(b, dflag);
6145 val = cpu_ldub_code(env, s->pc++);
6146 tcg_gen_movi_tl(cpu_T[0], val);
6147 gen_check_io(s, ot, pc_start - s->cs_base,
6148 SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6149 if (s->tb->cflags & CF_USE_ICOUNT) {
6152 tcg_gen_movi_i32(cpu_tmp2_i32, val);
6153 gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32);
6154 gen_op_mov_reg_v(ot, R_EAX, cpu_T[1]);
6155 gen_bpt_io(s, cpu_tmp2_i32, ot);
6156 if (s->tb->cflags & CF_USE_ICOUNT) {
6158 gen_jmp(s, s->pc - s->cs_base);
6163 ot = mo_b_d32(b, dflag);
6164 val = cpu_ldub_code(env, s->pc++);
6165 tcg_gen_movi_tl(cpu_T[0], val);
6166 gen_check_io(s, ot, pc_start - s->cs_base,
6167 svm_is_rep(prefixes));
6168 gen_op_mov_v_reg(ot, cpu_T[1], R_EAX);
6170 if (s->tb->cflags & CF_USE_ICOUNT) {
6173 tcg_gen_movi_i32(cpu_tmp2_i32, val);
6174 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
6175 gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6176 gen_bpt_io(s, cpu_tmp2_i32, ot);
6177 if (s->tb->cflags & CF_USE_ICOUNT) {
6179 gen_jmp(s, s->pc - s->cs_base);
6184 ot = mo_b_d32(b, dflag);
6185 tcg_gen_ext16u_tl(cpu_T[0], cpu_regs[R_EDX]);
6186 gen_check_io(s, ot, pc_start - s->cs_base,
6187 SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6188 if (s->tb->cflags & CF_USE_ICOUNT) {
6191 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6192 gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32);
6193 gen_op_mov_reg_v(ot, R_EAX, cpu_T[1]);
6194 gen_bpt_io(s, cpu_tmp2_i32, ot);
6195 if (s->tb->cflags & CF_USE_ICOUNT) {
6197 gen_jmp(s, s->pc - s->cs_base);
6202 ot = mo_b_d32(b, dflag);
6203 tcg_gen_ext16u_tl(cpu_T[0], cpu_regs[R_EDX]);
6204 gen_check_io(s, ot, pc_start - s->cs_base,
6205 svm_is_rep(prefixes));
6206 gen_op_mov_v_reg(ot, cpu_T[1], R_EAX);
6208 if (s->tb->cflags & CF_USE_ICOUNT) {
6211 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6212 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
6213 gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6214 gen_bpt_io(s, cpu_tmp2_i32, ot);
6215 if (s->tb->cflags & CF_USE_ICOUNT) {
6217 gen_jmp(s, s->pc - s->cs_base);
6221 /************************/
6223 case 0xc2: /* ret im */
6224 val = cpu_ldsw_code(env, s->pc);
6227 gen_stack_update(s, val + (1 << ot));
6228 /* Note that gen_pop_T0 uses a zero-extending load. */
6229 gen_op_jmp_v(cpu_T[0]);
6232 case 0xc3: /* ret */
6234 gen_pop_update(s, ot);
6235 /* Note that gen_pop_T0 uses a zero-extending load. */
6236 gen_op_jmp_v(cpu_T[0]);
6239 case 0xca: /* lret im */
6240 val = cpu_ldsw_code(env, s->pc);
6243 if (s->pe && !s->vm86) {
6244 gen_update_cc_op(s);
6245 gen_jmp_im(pc_start - s->cs_base);
6246 gen_helper_lret_protected(cpu_env, tcg_const_i32(dflag - 1),
6247 tcg_const_i32(val));
6251 gen_op_ld_v(s, dflag, cpu_T[0], cpu_A0);
6252 /* NOTE: keeping EIP updated is not a problem in case of
6254 gen_op_jmp_v(cpu_T[0]);
6256 gen_op_addl_A0_im(1 << dflag);
6257 gen_op_ld_v(s, dflag, cpu_T[0], cpu_A0);
6258 gen_op_movl_seg_T0_vm(R_CS);
6259 /* add stack offset */
6260 gen_stack_update(s, val + (2 << dflag));
6264 case 0xcb: /* lret */
6267 case 0xcf: /* iret */
6268 gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET);
6271 gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
6272 set_cc_op(s, CC_OP_EFLAGS);
6273 } else if (s->vm86) {
6275 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6277 gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
6278 set_cc_op(s, CC_OP_EFLAGS);
6281 gen_helper_iret_protected(cpu_env, tcg_const_i32(dflag - 1),
6282 tcg_const_i32(s->pc - s->cs_base));
6283 set_cc_op(s, CC_OP_EFLAGS);
6287 case 0xe8: /* call im */
6289 if (dflag != MO_16) {
6290 tval = (int32_t)insn_get(env, s, MO_32);
6292 tval = (int16_t)insn_get(env, s, MO_16);
6294 next_eip = s->pc - s->cs_base;
6296 if (dflag == MO_16) {
6298 } else if (!CODE64(s)) {
6301 tcg_gen_movi_tl(cpu_T[0], next_eip);
6302 gen_push_v(s, cpu_T[0]);
6306 case 0x9a: /* lcall im */
6308 unsigned int selector, offset;
6313 offset = insn_get(env, s, ot);
6314 selector = insn_get(env, s, MO_16);
6316 tcg_gen_movi_tl(cpu_T[0], selector);
6317 tcg_gen_movi_tl(cpu_T[1], offset);
6320 case 0xe9: /* jmp im */
6321 if (dflag != MO_16) {
6322 tval = (int32_t)insn_get(env, s, MO_32);
6324 tval = (int16_t)insn_get(env, s, MO_16);
6326 tval += s->pc - s->cs_base;
6327 if (dflag == MO_16) {
6329 } else if (!CODE64(s)) {
6334 case 0xea: /* ljmp im */
6336 unsigned int selector, offset;
6341 offset = insn_get(env, s, ot);
6342 selector = insn_get(env, s, MO_16);
6344 tcg_gen_movi_tl(cpu_T[0], selector);
6345 tcg_gen_movi_tl(cpu_T[1], offset);
6348 case 0xeb: /* jmp Jb */
6349 tval = (int8_t)insn_get(env, s, MO_8);
6350 tval += s->pc - s->cs_base;
6351 if (dflag == MO_16) {
6356 case 0x70 ... 0x7f: /* jcc Jb */
6357 tval = (int8_t)insn_get(env, s, MO_8);
6359 case 0x180 ... 0x18f: /* jcc Jv */
6360 if (dflag != MO_16) {
6361 tval = (int32_t)insn_get(env, s, MO_32);
6363 tval = (int16_t)insn_get(env, s, MO_16);
6366 next_eip = s->pc - s->cs_base;
6368 if (dflag == MO_16) {
6371 gen_jcc(s, b, tval, next_eip);
6374 case 0x190 ... 0x19f: /* setcc Gv */
6375 modrm = cpu_ldub_code(env, s->pc++);
6376 gen_setcc1(s, b, cpu_T[0]);
6377 gen_ldst_modrm(env, s, modrm, MO_8, OR_TMP0, 1);
6379 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6380 if (!(s->cpuid_features & CPUID_CMOV)) {
6384 modrm = cpu_ldub_code(env, s->pc++);
6385 reg = ((modrm >> 3) & 7) | rex_r;
6386 gen_cmovcc1(env, s, ot, b, modrm, reg);
6389 /************************/
6391 case 0x9c: /* pushf */
6392 gen_svm_check_intercept(s, pc_start, SVM_EXIT_PUSHF);
6393 if (s->vm86 && s->iopl != 3) {
6394 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6396 gen_update_cc_op(s);
6397 gen_helper_read_eflags(cpu_T[0], cpu_env);
6398 gen_push_v(s, cpu_T[0]);
6401 case 0x9d: /* popf */
6402 gen_svm_check_intercept(s, pc_start, SVM_EXIT_POPF);
6403 if (s->vm86 && s->iopl != 3) {
6404 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6408 if (dflag != MO_16) {
6409 gen_helper_write_eflags(cpu_env, cpu_T[0],
6410 tcg_const_i32((TF_MASK | AC_MASK |
6415 gen_helper_write_eflags(cpu_env, cpu_T[0],
6416 tcg_const_i32((TF_MASK | AC_MASK |
6418 IF_MASK | IOPL_MASK)
6422 if (s->cpl <= s->iopl) {
6423 if (dflag != MO_16) {
6424 gen_helper_write_eflags(cpu_env, cpu_T[0],
6425 tcg_const_i32((TF_MASK |
6431 gen_helper_write_eflags(cpu_env, cpu_T[0],
6432 tcg_const_i32((TF_MASK |
6440 if (dflag != MO_16) {
6441 gen_helper_write_eflags(cpu_env, cpu_T[0],
6442 tcg_const_i32((TF_MASK | AC_MASK |
6443 ID_MASK | NT_MASK)));
6445 gen_helper_write_eflags(cpu_env, cpu_T[0],
6446 tcg_const_i32((TF_MASK | AC_MASK |
6452 gen_pop_update(s, ot);
6453 set_cc_op(s, CC_OP_EFLAGS);
6454 /* abort translation because TF/AC flag may change */
6455 gen_jmp_im(s->pc - s->cs_base);
6459 case 0x9e: /* sahf */
6460 if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6462 gen_op_mov_v_reg(MO_8, cpu_T[0], R_AH);
6463 gen_compute_eflags(s);
6464 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O);
6465 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], CC_S | CC_Z | CC_A | CC_P | CC_C);
6466 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_T[0]);
6468 case 0x9f: /* lahf */
6469 if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6471 gen_compute_eflags(s);
6472 /* Note: gen_compute_eflags() only gives the condition codes */
6473 tcg_gen_ori_tl(cpu_T[0], cpu_cc_src, 0x02);
6474 gen_op_mov_reg_v(MO_8, R_AH, cpu_T[0]);
6476 case 0xf5: /* cmc */
6477 gen_compute_eflags(s);
6478 tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6480 case 0xf8: /* clc */
6481 gen_compute_eflags(s);
6482 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C);
6484 case 0xf9: /* stc */
6485 gen_compute_eflags(s);
6486 tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6488 case 0xfc: /* cld */
6489 tcg_gen_movi_i32(cpu_tmp2_i32, 1);
6490 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, df));
6492 case 0xfd: /* std */
6493 tcg_gen_movi_i32(cpu_tmp2_i32, -1);
6494 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, df));
6497 /************************/
6498 /* bit operations */
6499 case 0x1ba: /* bt/bts/btr/btc Gv, im */
6501 modrm = cpu_ldub_code(env, s->pc++);
6502 op = (modrm >> 3) & 7;
6503 mod = (modrm >> 6) & 3;
6504 rm = (modrm & 7) | REX_B(s);
6507 gen_lea_modrm(env, s, modrm);
6508 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
6510 gen_op_mov_v_reg(ot, cpu_T[0], rm);
6513 val = cpu_ldub_code(env, s->pc++);
6514 tcg_gen_movi_tl(cpu_T[1], val);
6519 case 0x1a3: /* bt Gv, Ev */
6522 case 0x1ab: /* bts */
6525 case 0x1b3: /* btr */
6528 case 0x1bb: /* btc */
6532 modrm = cpu_ldub_code(env, s->pc++);
6533 reg = ((modrm >> 3) & 7) | rex_r;
6534 mod = (modrm >> 6) & 3;
6535 rm = (modrm & 7) | REX_B(s);
6536 gen_op_mov_v_reg(MO_32, cpu_T[1], reg);
6538 gen_lea_modrm(env, s, modrm);
6539 /* specific case: we need to add a displacement */
6540 gen_exts(ot, cpu_T[1]);
6541 tcg_gen_sari_tl(cpu_tmp0, cpu_T[1], 3 + ot);
6542 tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, ot);
6543 tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
6544 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
6546 gen_op_mov_v_reg(ot, cpu_T[0], rm);
6549 tcg_gen_andi_tl(cpu_T[1], cpu_T[1], (1 << (3 + ot)) - 1);
6550 tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
6555 tcg_gen_movi_tl(cpu_tmp0, 1);
6556 tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
6557 tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
6560 tcg_gen_movi_tl(cpu_tmp0, 1);
6561 tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
6562 tcg_gen_andc_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
6566 tcg_gen_movi_tl(cpu_tmp0, 1);
6567 tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
6568 tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
6573 gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
6575 gen_op_mov_reg_v(ot, rm, cpu_T[0]);
6579 /* Delay all CC updates until after the store above. Note that
6580 C is the result of the test, Z is unchanged, and the others
6581 are all undefined. */
6583 case CC_OP_MULB ... CC_OP_MULQ:
6584 case CC_OP_ADDB ... CC_OP_ADDQ:
6585 case CC_OP_ADCB ... CC_OP_ADCQ:
6586 case CC_OP_SUBB ... CC_OP_SUBQ:
6587 case CC_OP_SBBB ... CC_OP_SBBQ:
6588 case CC_OP_LOGICB ... CC_OP_LOGICQ:
6589 case CC_OP_INCB ... CC_OP_INCQ:
6590 case CC_OP_DECB ... CC_OP_DECQ:
6591 case CC_OP_SHLB ... CC_OP_SHLQ:
6592 case CC_OP_SARB ... CC_OP_SARQ:
6593 case CC_OP_BMILGB ... CC_OP_BMILGQ:
6594 /* Z was going to be computed from the non-zero status of CC_DST.
6595 We can get that same Z value (and the new C value) by leaving
6596 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
6598 tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
6599 set_cc_op(s, ((s->cc_op - CC_OP_MULB) & 3) + CC_OP_SARB);
6602 /* Otherwise, generate EFLAGS and replace the C bit. */
6603 gen_compute_eflags(s);
6604 tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, cpu_tmp4,
6609 case 0x1bc: /* bsf / tzcnt */
6610 case 0x1bd: /* bsr / lzcnt */
6612 modrm = cpu_ldub_code(env, s->pc++);
6613 reg = ((modrm >> 3) & 7) | rex_r;
6614 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
6615 gen_extu(ot, cpu_T[0]);
6617 /* Note that lzcnt and tzcnt are in different extensions. */
6618 if ((prefixes & PREFIX_REPZ)
6620 ? s->cpuid_ext3_features & CPUID_EXT3_ABM
6621 : s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)) {
6623 tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
6625 /* For lzcnt, reduce the target_ulong result by the
6626 number of zeros that we expect to find at the top. */
6627 gen_helper_clz(cpu_T[0], cpu_T[0]);
6628 tcg_gen_subi_tl(cpu_T[0], cpu_T[0], TARGET_LONG_BITS - size);
6630 /* For tzcnt, a zero input must return the operand size:
6631 force all bits outside the operand size to 1. */
6632 target_ulong mask = (target_ulong)-2 << (size - 1);
6633 tcg_gen_ori_tl(cpu_T[0], cpu_T[0], mask);
6634 gen_helper_ctz(cpu_T[0], cpu_T[0]);
6636 /* For lzcnt/tzcnt, C and Z bits are defined and are
6637 related to the result. */
6638 gen_op_update1_cc();
6639 set_cc_op(s, CC_OP_BMILGB + ot);
6641 /* For bsr/bsf, only the Z bit is defined and it is related
6642 to the input and not the result. */
6643 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
6644 set_cc_op(s, CC_OP_LOGICB + ot);
6646 /* For bsr, return the bit index of the first 1 bit,
6647 not the count of leading zeros. */
6648 gen_helper_clz(cpu_T[0], cpu_T[0]);
6649 tcg_gen_xori_tl(cpu_T[0], cpu_T[0], TARGET_LONG_BITS - 1);
6651 gen_helper_ctz(cpu_T[0], cpu_T[0]);
6653 /* ??? The manual says that the output is undefined when the
6654 input is zero, but real hardware leaves it unchanged, and
6655 real programs appear to depend on that. */
6656 tcg_gen_movi_tl(cpu_tmp0, 0);
6657 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_T[0], cpu_cc_dst, cpu_tmp0,
6658 cpu_regs[reg], cpu_T[0]);
6660 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
6662 /************************/
6664 case 0x27: /* daa */
6667 gen_update_cc_op(s);
6668 gen_helper_daa(cpu_env);
6669 set_cc_op(s, CC_OP_EFLAGS);
6671 case 0x2f: /* das */
6674 gen_update_cc_op(s);
6675 gen_helper_das(cpu_env);
6676 set_cc_op(s, CC_OP_EFLAGS);
6678 case 0x37: /* aaa */
6681 gen_update_cc_op(s);
6682 gen_helper_aaa(cpu_env);
6683 set_cc_op(s, CC_OP_EFLAGS);
6685 case 0x3f: /* aas */
6688 gen_update_cc_op(s);
6689 gen_helper_aas(cpu_env);
6690 set_cc_op(s, CC_OP_EFLAGS);
6692 case 0xd4: /* aam */
6695 val = cpu_ldub_code(env, s->pc++);
6697 gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base);
6699 gen_helper_aam(cpu_env, tcg_const_i32(val));
6700 set_cc_op(s, CC_OP_LOGICB);
6703 case 0xd5: /* aad */
6706 val = cpu_ldub_code(env, s->pc++);
6707 gen_helper_aad(cpu_env, tcg_const_i32(val));
6708 set_cc_op(s, CC_OP_LOGICB);
6710 /************************/
6712 case 0x90: /* nop */
6713 /* XXX: correct lock test for all insn */
6714 if (prefixes & PREFIX_LOCK) {
6717 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
6719 goto do_xchg_reg_eax;
6721 if (prefixes & PREFIX_REPZ) {
6722 gen_update_cc_op(s);
6723 gen_jmp_im(pc_start - s->cs_base);
6724 gen_helper_pause(cpu_env, tcg_const_i32(s->pc - pc_start));
6725 s->is_jmp = DISAS_TB_JUMP;
6728 case 0x9b: /* fwait */
6729 if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
6730 (HF_MP_MASK | HF_TS_MASK)) {
6731 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
6733 gen_helper_fwait(cpu_env);
6736 case 0xcc: /* int3 */
6737 gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
6739 case 0xcd: /* int N */
6740 val = cpu_ldub_code(env, s->pc++);
6741 if (s->vm86 && s->iopl != 3) {
6742 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6744 gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
6747 case 0xce: /* into */
6750 gen_update_cc_op(s);
6751 gen_jmp_im(pc_start - s->cs_base);
6752 gen_helper_into(cpu_env, tcg_const_i32(s->pc - pc_start));
6755 case 0xf1: /* icebp (undocumented, exits to external debugger) */
6756 gen_svm_check_intercept(s, pc_start, SVM_EXIT_ICEBP);
6758 gen_debug(s, pc_start - s->cs_base);
6761 tb_flush(CPU(x86_env_get_cpu(env)));
6762 qemu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM);
6766 case 0xfa: /* cli */
6768 if (s->cpl <= s->iopl) {
6769 gen_helper_cli(cpu_env);
6771 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6775 gen_helper_cli(cpu_env);
6777 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6781 case 0xfb: /* sti */
6783 if (s->cpl <= s->iopl) {
6785 gen_helper_sti(cpu_env);
6786 /* interruptions are enabled only the first insn after sti */
6787 /* If several instructions disable interrupts, only the
6789 if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
6790 gen_helper_set_inhibit_irq(cpu_env);
6791 /* give a chance to handle pending irqs */
6792 gen_jmp_im(s->pc - s->cs_base);
6795 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6801 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6805 case 0x62: /* bound */
6809 modrm = cpu_ldub_code(env, s->pc++);
6810 reg = (modrm >> 3) & 7;
6811 mod = (modrm >> 6) & 3;
6814 gen_op_mov_v_reg(ot, cpu_T[0], reg);
6815 gen_lea_modrm(env, s, modrm);
6816 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6818 gen_helper_boundw(cpu_env, cpu_A0, cpu_tmp2_i32);
6820 gen_helper_boundl(cpu_env, cpu_A0, cpu_tmp2_i32);
6823 case 0x1c8 ... 0x1cf: /* bswap reg */
6824 reg = (b & 7) | REX_B(s);
6825 #ifdef TARGET_X86_64
6826 if (dflag == MO_64) {
6827 gen_op_mov_v_reg(MO_64, cpu_T[0], reg);
6828 tcg_gen_bswap64_i64(cpu_T[0], cpu_T[0]);
6829 gen_op_mov_reg_v(MO_64, reg, cpu_T[0]);
6833 gen_op_mov_v_reg(MO_32, cpu_T[0], reg);
6834 tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
6835 tcg_gen_bswap32_tl(cpu_T[0], cpu_T[0]);
6836 gen_op_mov_reg_v(MO_32, reg, cpu_T[0]);
6839 case 0xd6: /* salc */
6842 gen_compute_eflags_c(s, cpu_T[0]);
6843 tcg_gen_neg_tl(cpu_T[0], cpu_T[0]);
6844 gen_op_mov_reg_v(MO_8, R_EAX, cpu_T[0]);
6846 case 0xe0: /* loopnz */
6847 case 0xe1: /* loopz */
6848 case 0xe2: /* loop */
6849 case 0xe3: /* jecxz */
6851 TCGLabel *l1, *l2, *l3;
6853 tval = (int8_t)insn_get(env, s, MO_8);
6854 next_eip = s->pc - s->cs_base;
6856 if (dflag == MO_16) {
6860 l1 = gen_new_label();
6861 l2 = gen_new_label();
6862 l3 = gen_new_label();
6865 case 0: /* loopnz */
6867 gen_op_add_reg_im(s->aflag, R_ECX, -1);
6868 gen_op_jz_ecx(s->aflag, l3);
6869 gen_jcc1(s, (JCC_Z << 1) | (b ^ 1), l1);
6872 gen_op_add_reg_im(s->aflag, R_ECX, -1);
6873 gen_op_jnz_ecx(s->aflag, l1);
6877 gen_op_jz_ecx(s->aflag, l1);
6882 gen_jmp_im(next_eip);
6891 case 0x130: /* wrmsr */
6892 case 0x132: /* rdmsr */
6894 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6896 gen_update_cc_op(s);
6897 gen_jmp_im(pc_start - s->cs_base);
6899 gen_helper_rdmsr(cpu_env);
6901 gen_helper_wrmsr(cpu_env);
6905 case 0x131: /* rdtsc */
6906 gen_update_cc_op(s);
6907 gen_jmp_im(pc_start - s->cs_base);
6908 if (s->tb->cflags & CF_USE_ICOUNT) {
6911 gen_helper_rdtsc(cpu_env);
6912 if (s->tb->cflags & CF_USE_ICOUNT) {
6914 gen_jmp(s, s->pc - s->cs_base);
6917 case 0x133: /* rdpmc */
6918 gen_update_cc_op(s);
6919 gen_jmp_im(pc_start - s->cs_base);
6920 gen_helper_rdpmc(cpu_env);
6922 case 0x134: /* sysenter */
6923 /* For Intel SYSENTER is valid on 64-bit */
6924 if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
6927 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6929 gen_helper_sysenter(cpu_env);
6933 case 0x135: /* sysexit */
6934 /* For Intel SYSEXIT is valid on 64-bit */
6935 if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
6938 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6940 gen_helper_sysexit(cpu_env, tcg_const_i32(dflag - 1));
6944 #ifdef TARGET_X86_64
6945 case 0x105: /* syscall */
6946 /* XXX: is it usable in real mode ? */
6947 gen_update_cc_op(s);
6948 gen_jmp_im(pc_start - s->cs_base);
6949 gen_helper_syscall(cpu_env, tcg_const_i32(s->pc - pc_start));
6952 case 0x107: /* sysret */
6954 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6956 gen_helper_sysret(cpu_env, tcg_const_i32(dflag - 1));
6957 /* condition codes are modified only in long mode */
6959 set_cc_op(s, CC_OP_EFLAGS);
6965 case 0x1a2: /* cpuid */
6966 gen_update_cc_op(s);
6967 gen_jmp_im(pc_start - s->cs_base);
6968 gen_helper_cpuid(cpu_env);
6970 case 0xf4: /* hlt */
6972 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6974 gen_update_cc_op(s);
6975 gen_jmp_im(pc_start - s->cs_base);
6976 gen_helper_hlt(cpu_env, tcg_const_i32(s->pc - pc_start));
6977 s->is_jmp = DISAS_TB_JUMP;
6981 modrm = cpu_ldub_code(env, s->pc++);
6982 mod = (modrm >> 6) & 3;
6983 op = (modrm >> 3) & 7;
6986 if (!s->pe || s->vm86)
6988 gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_READ);
6989 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,ldt.selector));
6990 ot = mod == 3 ? dflag : MO_16;
6991 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
6994 if (!s->pe || s->vm86)
6997 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6999 gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_WRITE);
7000 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7001 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
7002 gen_helper_lldt(cpu_env, cpu_tmp2_i32);
7006 if (!s->pe || s->vm86)
7008 gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_READ);
7009 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,tr.selector));
7010 ot = mod == 3 ? dflag : MO_16;
7011 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7014 if (!s->pe || s->vm86)
7017 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7019 gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_WRITE);
7020 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7021 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
7022 gen_helper_ltr(cpu_env, cpu_tmp2_i32);
7027 if (!s->pe || s->vm86)
7029 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7030 gen_update_cc_op(s);
7032 gen_helper_verr(cpu_env, cpu_T[0]);
7034 gen_helper_verw(cpu_env, cpu_T[0]);
7036 set_cc_op(s, CC_OP_EFLAGS);
7043 modrm = cpu_ldub_code(env, s->pc++);
7044 mod = (modrm >> 6) & 3;
7045 op = (modrm >> 3) & 7;
7051 gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_READ);
7052 gen_lea_modrm(env, s, modrm);
7053 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, gdt.limit));
7054 gen_op_st_v(s, MO_16, cpu_T[0], cpu_A0);
7055 gen_add_A0_im(s, 2);
7056 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, gdt.base));
7057 if (dflag == MO_16) {
7058 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffffff);
7060 gen_op_st_v(s, CODE64(s) + MO_32, cpu_T[0], cpu_A0);
7065 case 0: /* monitor */
7066 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) ||
7069 gen_update_cc_op(s);
7070 gen_jmp_im(pc_start - s->cs_base);
7071 tcg_gen_mov_tl(cpu_A0, cpu_regs[R_EAX]);
7072 gen_extu(s->aflag, cpu_A0);
7073 gen_add_A0_ds_seg(s);
7074 gen_helper_monitor(cpu_env, cpu_A0);
7077 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) ||
7080 gen_update_cc_op(s);
7081 gen_jmp_im(pc_start - s->cs_base);
7082 gen_helper_mwait(cpu_env, tcg_const_i32(s->pc - pc_start));
7086 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP) ||
7090 gen_helper_clac(cpu_env);
7091 gen_jmp_im(s->pc - s->cs_base);
7095 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP) ||
7099 gen_helper_stac(cpu_env);
7100 gen_jmp_im(s->pc - s->cs_base);
7107 gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_READ);
7108 gen_lea_modrm(env, s, modrm);
7109 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, idt.limit));
7110 gen_op_st_v(s, MO_16, cpu_T[0], cpu_A0);
7111 gen_add_A0_im(s, 2);
7112 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, idt.base));
7113 if (dflag == MO_16) {
7114 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffffff);
7116 gen_op_st_v(s, CODE64(s) + MO_32, cpu_T[0], cpu_A0);
7122 gen_update_cc_op(s);
7123 gen_jmp_im(pc_start - s->cs_base);
7126 if (!(s->flags & HF_SVME_MASK) || !s->pe)
7129 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7132 gen_helper_vmrun(cpu_env, tcg_const_i32(s->aflag - 1),
7133 tcg_const_i32(s->pc - pc_start));
7135 s->is_jmp = DISAS_TB_JUMP;
7138 case 1: /* VMMCALL */
7139 if (!(s->flags & HF_SVME_MASK))
7141 gen_helper_vmmcall(cpu_env);
7143 case 2: /* VMLOAD */
7144 if (!(s->flags & HF_SVME_MASK) || !s->pe)
7147 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7150 gen_helper_vmload(cpu_env, tcg_const_i32(s->aflag - 1));
7153 case 3: /* VMSAVE */
7154 if (!(s->flags & HF_SVME_MASK) || !s->pe)
7157 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7160 gen_helper_vmsave(cpu_env, tcg_const_i32(s->aflag - 1));
7164 if ((!(s->flags & HF_SVME_MASK) &&
7165 !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) ||
7169 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7172 gen_helper_stgi(cpu_env);
7176 if (!(s->flags & HF_SVME_MASK) || !s->pe)
7179 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7182 gen_helper_clgi(cpu_env);
7185 case 6: /* SKINIT */
7186 if ((!(s->flags & HF_SVME_MASK) &&
7187 !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) ||
7190 gen_helper_skinit(cpu_env);
7192 case 7: /* INVLPGA */
7193 if (!(s->flags & HF_SVME_MASK) || !s->pe)
7196 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7199 gen_helper_invlpga(cpu_env,
7200 tcg_const_i32(s->aflag - 1));
7206 } else if (s->cpl != 0) {
7207 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7209 gen_svm_check_intercept(s, pc_start,
7210 op==2 ? SVM_EXIT_GDTR_WRITE : SVM_EXIT_IDTR_WRITE);
7211 gen_lea_modrm(env, s, modrm);
7212 gen_op_ld_v(s, MO_16, cpu_T[1], cpu_A0);
7213 gen_add_A0_im(s, 2);
7214 gen_op_ld_v(s, CODE64(s) + MO_32, cpu_T[0], cpu_A0);
7215 if (dflag == MO_16) {
7216 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffffff);
7219 tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,gdt.base));
7220 tcg_gen_st32_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,gdt.limit));
7222 tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,idt.base));
7223 tcg_gen_st32_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,idt.limit));
7228 gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0);
7229 #if defined TARGET_X86_64 && defined HOST_WORDS_BIGENDIAN
7230 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,cr[0]) + 4);
7232 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,cr[0]));
7234 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 1);
7238 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7240 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
7241 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7242 gen_helper_lmsw(cpu_env, cpu_T[0]);
7243 gen_jmp_im(s->pc - s->cs_base);
7248 if (mod != 3) { /* invlpg */
7250 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7252 gen_update_cc_op(s);
7253 gen_jmp_im(pc_start - s->cs_base);
7254 gen_lea_modrm(env, s, modrm);
7255 gen_helper_invlpg(cpu_env, cpu_A0);
7256 gen_jmp_im(s->pc - s->cs_base);
7261 case 0: /* swapgs */
7262 #ifdef TARGET_X86_64
7265 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7267 tcg_gen_mov_tl(cpu_T[0], cpu_seg_base[R_GS]);
7268 tcg_gen_ld_tl(cpu_seg_base[R_GS], cpu_env,
7269 offsetof(CPUX86State, kernelgsbase));
7270 tcg_gen_st_tl(cpu_T[0], cpu_env,
7271 offsetof(CPUX86State, kernelgsbase));
7277 case 1: /* rdtscp */
7278 if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP))
7280 gen_update_cc_op(s);
7281 gen_jmp_im(pc_start - s->cs_base);
7282 if (s->tb->cflags & CF_USE_ICOUNT) {
7285 gen_helper_rdtscp(cpu_env);
7286 if (s->tb->cflags & CF_USE_ICOUNT) {
7288 gen_jmp(s, s->pc - s->cs_base);
7300 case 0x108: /* invd */
7301 case 0x109: /* wbinvd */
7303 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7305 gen_svm_check_intercept(s, pc_start, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD);
7309 case 0x63: /* arpl or movslS (x86_64) */
7310 #ifdef TARGET_X86_64
7313 /* d_ot is the size of destination */
7316 modrm = cpu_ldub_code(env, s->pc++);
7317 reg = ((modrm >> 3) & 7) | rex_r;
7318 mod = (modrm >> 6) & 3;
7319 rm = (modrm & 7) | REX_B(s);
7322 gen_op_mov_v_reg(MO_32, cpu_T[0], rm);
7324 if (d_ot == MO_64) {
7325 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
7327 gen_op_mov_reg_v(d_ot, reg, cpu_T[0]);
7329 gen_lea_modrm(env, s, modrm);
7330 gen_op_ld_v(s, MO_32 | MO_SIGN, cpu_T[0], cpu_A0);
7331 gen_op_mov_reg_v(d_ot, reg, cpu_T[0]);
7337 TCGv t0, t1, t2, a0;
7339 if (!s->pe || s->vm86)
7341 t0 = tcg_temp_local_new();
7342 t1 = tcg_temp_local_new();
7343 t2 = tcg_temp_local_new();
7345 modrm = cpu_ldub_code(env, s->pc++);
7346 reg = (modrm >> 3) & 7;
7347 mod = (modrm >> 6) & 3;
7350 gen_lea_modrm(env, s, modrm);
7351 gen_op_ld_v(s, ot, t0, cpu_A0);
7352 a0 = tcg_temp_local_new();
7353 tcg_gen_mov_tl(a0, cpu_A0);
7355 gen_op_mov_v_reg(ot, t0, rm);
7358 gen_op_mov_v_reg(ot, t1, reg);
7359 tcg_gen_andi_tl(cpu_tmp0, t0, 3);
7360 tcg_gen_andi_tl(t1, t1, 3);
7361 tcg_gen_movi_tl(t2, 0);
7362 label1 = gen_new_label();
7363 tcg_gen_brcond_tl(TCG_COND_GE, cpu_tmp0, t1, label1);
7364 tcg_gen_andi_tl(t0, t0, ~3);
7365 tcg_gen_or_tl(t0, t0, t1);
7366 tcg_gen_movi_tl(t2, CC_Z);
7367 gen_set_label(label1);
7369 gen_op_st_v(s, ot, t0, a0);
7372 gen_op_mov_reg_v(ot, rm, t0);
7374 gen_compute_eflags(s);
7375 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z);
7376 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t2);
7382 case 0x102: /* lar */
7383 case 0x103: /* lsl */
7387 if (!s->pe || s->vm86)
7389 ot = dflag != MO_16 ? MO_32 : MO_16;
7390 modrm = cpu_ldub_code(env, s->pc++);
7391 reg = ((modrm >> 3) & 7) | rex_r;
7392 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7393 t0 = tcg_temp_local_new();
7394 gen_update_cc_op(s);
7396 gen_helper_lar(t0, cpu_env, cpu_T[0]);
7398 gen_helper_lsl(t0, cpu_env, cpu_T[0]);
7400 tcg_gen_andi_tl(cpu_tmp0, cpu_cc_src, CC_Z);
7401 label1 = gen_new_label();
7402 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
7403 gen_op_mov_reg_v(ot, reg, t0);
7404 gen_set_label(label1);
7405 set_cc_op(s, CC_OP_EFLAGS);
7410 modrm = cpu_ldub_code(env, s->pc++);
7411 mod = (modrm >> 6) & 3;
7412 op = (modrm >> 3) & 7;
7414 case 0: /* prefetchnta */
7415 case 1: /* prefetchnt0 */
7416 case 2: /* prefetchnt0 */
7417 case 3: /* prefetchnt0 */
7420 gen_lea_modrm(env, s, modrm);
7421 /* nothing more to do */
7423 default: /* nop (multi byte) */
7424 gen_nop_modrm(env, s, modrm);
7428 case 0x119 ... 0x11f: /* nop (multi byte) */
7429 modrm = cpu_ldub_code(env, s->pc++);
7430 gen_nop_modrm(env, s, modrm);
7432 case 0x120: /* mov reg, crN */
7433 case 0x122: /* mov crN, reg */
7435 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7437 modrm = cpu_ldub_code(env, s->pc++);
7438 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7439 * AMD documentation (24594.pdf) and testing of
7440 * intel 386 and 486 processors all show that the mod bits
7441 * are assumed to be 1's, regardless of actual values.
7443 rm = (modrm & 7) | REX_B(s);
7444 reg = ((modrm >> 3) & 7) | rex_r;
7449 if ((prefixes & PREFIX_LOCK) && (reg == 0) &&
7450 (s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) {
7459 gen_update_cc_op(s);
7460 gen_jmp_im(pc_start - s->cs_base);
7462 gen_op_mov_v_reg(ot, cpu_T[0], rm);
7463 gen_helper_write_crN(cpu_env, tcg_const_i32(reg),
7465 gen_jmp_im(s->pc - s->cs_base);
7468 gen_helper_read_crN(cpu_T[0], cpu_env, tcg_const_i32(reg));
7469 gen_op_mov_reg_v(ot, rm, cpu_T[0]);
7477 case 0x121: /* mov reg, drN */
7478 case 0x123: /* mov drN, reg */
7480 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7482 modrm = cpu_ldub_code(env, s->pc++);
7483 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7484 * AMD documentation (24594.pdf) and testing of
7485 * intel 386 and 486 processors all show that the mod bits
7486 * are assumed to be 1's, regardless of actual values.
7488 rm = (modrm & 7) | REX_B(s);
7489 reg = ((modrm >> 3) & 7) | rex_r;
7498 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
7499 gen_op_mov_v_reg(ot, cpu_T[0], rm);
7500 tcg_gen_movi_i32(cpu_tmp2_i32, reg);
7501 gen_helper_set_dr(cpu_env, cpu_tmp2_i32, cpu_T[0]);
7502 gen_jmp_im(s->pc - s->cs_base);
7505 gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_DR0 + reg);
7506 tcg_gen_movi_i32(cpu_tmp2_i32, reg);
7507 gen_helper_get_dr(cpu_T[0], cpu_env, cpu_tmp2_i32);
7508 gen_op_mov_reg_v(ot, rm, cpu_T[0]);
7512 case 0x106: /* clts */
7514 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7516 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
7517 gen_helper_clts(cpu_env);
7518 /* abort block because static cpu state changed */
7519 gen_jmp_im(s->pc - s->cs_base);
7523 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
7524 case 0x1c3: /* MOVNTI reg, mem */
7525 if (!(s->cpuid_features & CPUID_SSE2))
7527 ot = mo_64_32(dflag);
7528 modrm = cpu_ldub_code(env, s->pc++);
7529 mod = (modrm >> 6) & 3;
7532 reg = ((modrm >> 3) & 7) | rex_r;
7533 /* generate a generic store */
7534 gen_ldst_modrm(env, s, modrm, ot, reg, 1);
7537 modrm = cpu_ldub_code(env, s->pc++);
7538 mod = (modrm >> 6) & 3;
7539 op = (modrm >> 3) & 7;
7541 case 0: /* fxsave */
7542 if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
7543 (s->prefix & PREFIX_LOCK))
7545 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
7546 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
7549 gen_lea_modrm(env, s, modrm);
7550 gen_helper_fxsave(cpu_env, cpu_A0, tcg_const_i32(dflag == MO_64));
7552 case 1: /* fxrstor */
7553 if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
7554 (s->prefix & PREFIX_LOCK))
7556 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
7557 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
7560 gen_lea_modrm(env, s, modrm);
7561 gen_helper_fxrstor(cpu_env, cpu_A0, tcg_const_i32(dflag == MO_64));
7563 case 2: /* ldmxcsr */
7564 case 3: /* stmxcsr */
7565 if (s->flags & HF_TS_MASK) {
7566 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
7569 if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK) ||
7572 gen_lea_modrm(env, s, modrm);
7574 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
7575 s->mem_index, MO_LEUL);
7576 gen_helper_ldmxcsr(cpu_env, cpu_tmp2_i32);
7578 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, mxcsr));
7579 gen_op_st_v(s, MO_32, cpu_T[0], cpu_A0);
7582 case 5: /* lfence */
7583 if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE2))
7586 case 6: /* mfence/clwb */
7587 if (s->prefix & PREFIX_DATA) {
7589 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLWB))
7591 gen_nop_modrm(env, s, modrm);
7594 if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE2))
7598 case 7: /* sfence / clflush / clflushopt / pcommit */
7599 if ((modrm & 0xc7) == 0xc0) {
7600 if (s->prefix & PREFIX_DATA) {
7602 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_PCOMMIT))
7606 /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX */
7607 if (!(s->cpuid_features & CPUID_SSE))
7611 if (s->prefix & PREFIX_DATA) {
7613 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLFLUSHOPT))
7617 if (!(s->cpuid_features & CPUID_CLFLUSH))
7620 gen_lea_modrm(env, s, modrm);
7627 case 0x10d: /* 3DNow! prefetch(w) */
7628 modrm = cpu_ldub_code(env, s->pc++);
7629 mod = (modrm >> 6) & 3;
7632 gen_lea_modrm(env, s, modrm);
7633 /* ignore for now */
7635 case 0x1aa: /* rsm */
7636 gen_svm_check_intercept(s, pc_start, SVM_EXIT_RSM);
7637 if (!(s->flags & HF_SMM_MASK))
7639 gen_update_cc_op(s);
7640 gen_jmp_im(s->pc - s->cs_base);
7641 gen_helper_rsm(cpu_env);
7644 case 0x1b8: /* SSE4.2 popcnt */
7645 if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) !=
7648 if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT))
7651 modrm = cpu_ldub_code(env, s->pc++);
7652 reg = ((modrm >> 3) & 7) | rex_r;
7654 if (s->prefix & PREFIX_DATA) {
7657 ot = mo_64_32(dflag);
7660 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
7661 gen_helper_popcnt(cpu_T[0], cpu_env, cpu_T[0], tcg_const_i32(ot));
7662 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
7664 set_cc_op(s, CC_OP_EFLAGS);
7666 case 0x10e ... 0x10f:
7667 /* 3DNow! instructions, ignore prefixes */
7668 s->prefix &= ~(PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA);
7669 case 0x110 ... 0x117:
7670 case 0x128 ... 0x12f:
7671 case 0x138 ... 0x13a:
7672 case 0x150 ... 0x179:
7673 case 0x17c ... 0x17f:
7675 case 0x1c4 ... 0x1c6:
7676 case 0x1d0 ... 0x1fe:
7677 gen_sse(env, s, b, pc_start, rex_r);
7682 /* lock generation */
7683 if (s->prefix & PREFIX_LOCK)
7684 gen_helper_unlock();
7687 if (s->prefix & PREFIX_LOCK)
7688 gen_helper_unlock();
7689 /* XXX: ensure that no lock was generated */
7690 gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
7694 void tcg_x86_init(void)
7696 static const char reg_names[CPU_NB_REGS][4] = {
7697 #ifdef TARGET_X86_64
7725 static const char seg_base_names[6][8] = {
7735 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
7736 cpu_cc_op = tcg_global_mem_new_i32(cpu_env,
7737 offsetof(CPUX86State, cc_op), "cc_op");
7738 cpu_cc_dst = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_dst),
7740 cpu_cc_src = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src),
7742 cpu_cc_src2 = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src2),
7745 for (i = 0; i < CPU_NB_REGS; ++i) {
7746 cpu_regs[i] = tcg_global_mem_new(cpu_env,
7747 offsetof(CPUX86State, regs[i]),
7751 for (i = 0; i < 6; ++i) {
7753 = tcg_global_mem_new(cpu_env,
7754 offsetof(CPUX86State, segs[i].base),
7761 /* generate intermediate code for basic block 'tb'. */
7762 void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb)
7764 X86CPU *cpu = x86_env_get_cpu(env);
7765 CPUState *cs = CPU(cpu);
7766 DisasContext dc1, *dc = &dc1;
7767 target_ulong pc_ptr;
7769 target_ulong pc_start;
7770 target_ulong cs_base;
7774 /* generate intermediate code */
7776 cs_base = tb->cs_base;
7779 dc->pe = (flags >> HF_PE_SHIFT) & 1;
7780 dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
7781 dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
7782 dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
7784 dc->vm86 = (flags >> VM_SHIFT) & 1;
7785 dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
7786 dc->iopl = (flags >> IOPL_SHIFT) & 3;
7787 dc->tf = (flags >> TF_SHIFT) & 1;
7788 dc->singlestep_enabled = cs->singlestep_enabled;
7789 dc->cc_op = CC_OP_DYNAMIC;
7790 dc->cc_op_dirty = false;
7791 dc->cs_base = cs_base;
7793 dc->popl_esp_hack = 0;
7794 /* select memory access functions */
7796 if (flags & HF_SOFTMMU_MASK) {
7797 dc->mem_index = cpu_mmu_index(env, false);
7799 dc->cpuid_features = env->features[FEAT_1_EDX];
7800 dc->cpuid_ext_features = env->features[FEAT_1_ECX];
7801 dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX];
7802 dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX];
7803 dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX];
7804 #ifdef TARGET_X86_64
7805 dc->lma = (flags >> HF_LMA_SHIFT) & 1;
7806 dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
7809 dc->jmp_opt = !(dc->tf || cs->singlestep_enabled ||
7810 (flags & HF_INHIBIT_IRQ_MASK)
7811 #ifndef CONFIG_SOFTMMU
7812 || (flags & HF_SOFTMMU_MASK)
7815 /* Do not optimize repz jumps at all in icount mode, because
7816 rep movsS instructions are execured with different paths
7817 in !repz_opt and repz_opt modes. The first one was used
7818 always except single step mode. And this setting
7819 disables jumps optimization and control paths become
7820 equivalent in run and single step modes.
7821 Now there will be no jump optimization for repz in
7822 record/replay modes and there will always be an
7823 additional step for ecx=0 when icount is enabled.
7825 dc->repz_opt = !dc->jmp_opt && !(tb->cflags & CF_USE_ICOUNT);
7827 /* check addseg logic */
7828 if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
7829 printf("ERROR addseg\n");
7832 cpu_T[0] = tcg_temp_new();
7833 cpu_T[1] = tcg_temp_new();
7834 cpu_A0 = tcg_temp_new();
7836 cpu_tmp0 = tcg_temp_new();
7837 cpu_tmp1_i64 = tcg_temp_new_i64();
7838 cpu_tmp2_i32 = tcg_temp_new_i32();
7839 cpu_tmp3_i32 = tcg_temp_new_i32();
7840 cpu_tmp4 = tcg_temp_new();
7841 cpu_ptr0 = tcg_temp_new_ptr();
7842 cpu_ptr1 = tcg_temp_new_ptr();
7843 cpu_cc_srcT = tcg_temp_local_new();
7845 dc->is_jmp = DISAS_NEXT;
7848 max_insns = tb->cflags & CF_COUNT_MASK;
7849 if (max_insns == 0) {
7850 max_insns = CF_COUNT_MASK;
7852 if (max_insns > TCG_MAX_INSNS) {
7853 max_insns = TCG_MAX_INSNS;
7858 tcg_gen_insn_start(pc_ptr, dc->cc_op);
7861 /* If RF is set, suppress an internally generated breakpoint. */
7862 if (unlikely(cpu_breakpoint_test(cs, pc_ptr,
7863 tb->flags & HF_RF_MASK
7864 ? BP_GDB : BP_ANY))) {
7865 gen_debug(dc, pc_ptr - dc->cs_base);
7866 /* The address covered by the breakpoint must be included in
7867 [tb->pc, tb->pc + tb->size) in order to for it to be
7868 properly cleared -- thus we increment the PC here so that
7869 the logic setting tb->size below does the right thing. */
7871 goto done_generating;
7873 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
7877 pc_ptr = disas_insn(env, dc, pc_ptr);
7878 /* stop translation if indicated */
7881 /* if single step mode, we generate only one instruction and
7882 generate an exception */
7883 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
7884 the flag and abort the translation to give the irqs a
7885 change to be happen */
7886 if (dc->tf || dc->singlestep_enabled ||
7887 (flags & HF_INHIBIT_IRQ_MASK)) {
7888 gen_jmp_im(pc_ptr - dc->cs_base);
7892 /* Do not cross the boundary of the pages in icount mode,
7893 it can cause an exception. Do it only when boundary is
7894 crossed by the first instruction in the block.
7895 If current instruction already crossed the bound - it's ok,
7896 because an exception hasn't stopped this code.
7898 if ((tb->cflags & CF_USE_ICOUNT)
7899 && ((pc_ptr & TARGET_PAGE_MASK)
7900 != ((pc_ptr + TARGET_MAX_INSN_SIZE - 1) & TARGET_PAGE_MASK)
7901 || (pc_ptr & ~TARGET_PAGE_MASK) == 0)) {
7902 gen_jmp_im(pc_ptr - dc->cs_base);
7906 /* if too long translation, stop generation too */
7907 if (tcg_op_buf_full() ||
7908 (pc_ptr - pc_start) >= (TARGET_PAGE_SIZE - 32) ||
7909 num_insns >= max_insns) {
7910 gen_jmp_im(pc_ptr - dc->cs_base);
7915 gen_jmp_im(pc_ptr - dc->cs_base);
7920 if (tb->cflags & CF_LAST_IO)
7923 gen_tb_end(tb, num_insns);
7926 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
7928 qemu_log("----------------\n");
7929 qemu_log("IN: %s\n", lookup_symbol(pc_start));
7930 #ifdef TARGET_X86_64
7935 disas_flags = !dc->code32;
7936 log_target_disas(cs, pc_start, pc_ptr - pc_start, disas_flags);
7941 tb->size = pc_ptr - pc_start;
7942 tb->icount = num_insns;
7945 void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb,
7948 int cc_op = data[1];
7949 env->eip = data[0] - tb->cs_base;
7950 if (cc_op != CC_OP_DYNAMIC) {