4 * Copyright (c) 2003 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 #include "qemu/osdep.h"
21 #include "qemu/host-utils.h"
23 #include "disas/disas.h"
24 #include "exec/exec-all.h"
26 #include "exec/cpu_ldst.h"
28 #include "exec/helper-proto.h"
29 #include "exec/helper-gen.h"
31 #include "trace-tcg.h"
35 #define PREFIX_REPZ 0x01
36 #define PREFIX_REPNZ 0x02
37 #define PREFIX_LOCK 0x04
38 #define PREFIX_DATA 0x08
39 #define PREFIX_ADR 0x10
40 #define PREFIX_VEX 0x20
43 #define CODE64(s) ((s)->code64)
44 #define REX_X(s) ((s)->rex_x)
45 #define REX_B(s) ((s)->rex_b)
60 /* For a switch indexed by MODRM, match all memory operands for a given OP. */
61 #define CASE_MODRM_MEM_OP(OP) \
62 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
63 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
64 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7
66 #define CASE_MODRM_OP(OP) \
67 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
68 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
69 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7: \
70 case (3 << 6) | (OP << 3) | 0 ... (3 << 6) | (OP << 3) | 7
72 //#define MACRO_TEST 1
74 /* global register indexes */
75 static TCGv_env cpu_env;
77 static TCGv cpu_cc_dst, cpu_cc_src, cpu_cc_src2, cpu_cc_srcT;
78 static TCGv_i32 cpu_cc_op;
79 static TCGv cpu_regs[CPU_NB_REGS];
80 static TCGv cpu_seg_base[6];
81 static TCGv_i64 cpu_bndl[4];
82 static TCGv_i64 cpu_bndu[4];
84 static TCGv cpu_T0, cpu_T1;
85 /* local register indexes (only used inside old micro ops) */
86 static TCGv cpu_tmp0, cpu_tmp4;
87 static TCGv_ptr cpu_ptr0, cpu_ptr1;
88 static TCGv_i32 cpu_tmp2_i32, cpu_tmp3_i32;
89 static TCGv_i64 cpu_tmp1_i64;
91 #include "exec/gen-icount.h"
94 static int x86_64_hregs;
97 typedef struct DisasContext {
98 /* current insn context */
99 int override; /* -1 if no override */
103 target_ulong pc_start;
104 target_ulong pc; /* pc = eip + cs_base */
105 int is_jmp; /* 1 = means jump (stop translation), 2 means CPU
106 static state change (stop translation) */
107 /* current block context */
108 target_ulong cs_base; /* base of CS segment */
109 int pe; /* protected mode */
110 int code32; /* 32 bit code segment */
112 int lma; /* long mode active */
113 int code64; /* 64 bit code segment */
116 int vex_l; /* vex vector length */
117 int vex_v; /* vex vvvv register, without 1's compliment. */
118 int ss32; /* 32 bit stack segment */
119 CCOp cc_op; /* current CC operation */
121 int addseg; /* non zero if either DS/ES/SS have a non zero base */
122 int f_st; /* currently unused */
123 int vm86; /* vm86 mode */
126 int tf; /* TF cpu flag */
127 int singlestep_enabled; /* "hardware" single step enabled */
128 int jmp_opt; /* use direct block chaining for direct jumps */
129 int repz_opt; /* optimize jumps within repz instructions */
130 int mem_index; /* select memory access functions */
131 uint64_t flags; /* all execution flags */
132 struct TranslationBlock *tb;
133 int popl_esp_hack; /* for correct popl with esp base handling */
134 int rip_offset; /* only used in x86_64, but left for simplicity */
136 int cpuid_ext_features;
137 int cpuid_ext2_features;
138 int cpuid_ext3_features;
139 int cpuid_7_0_ebx_features;
140 int cpuid_xsave_features;
143 static void gen_eob(DisasContext *s);
144 static void gen_jmp(DisasContext *s, target_ulong eip);
145 static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num);
146 static void gen_op(DisasContext *s1, int op, TCGMemOp ot, int d);
148 /* i386 arith/logic operations */
168 OP_SHL1, /* undocumented */
184 /* I386 int registers */
185 OR_EAX, /* MUST be even numbered */
194 OR_TMP0 = 16, /* temporary operand register */
196 OR_A0, /* temporary register used when doing address evaluation */
206 /* Bit set if the global variable is live after setting CC_OP to X. */
207 static const uint8_t cc_op_live[CC_OP_NB] = {
208 [CC_OP_DYNAMIC] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
209 [CC_OP_EFLAGS] = USES_CC_SRC,
210 [CC_OP_MULB ... CC_OP_MULQ] = USES_CC_DST | USES_CC_SRC,
211 [CC_OP_ADDB ... CC_OP_ADDQ] = USES_CC_DST | USES_CC_SRC,
212 [CC_OP_ADCB ... CC_OP_ADCQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
213 [CC_OP_SUBB ... CC_OP_SUBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRCT,
214 [CC_OP_SBBB ... CC_OP_SBBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
215 [CC_OP_LOGICB ... CC_OP_LOGICQ] = USES_CC_DST,
216 [CC_OP_INCB ... CC_OP_INCQ] = USES_CC_DST | USES_CC_SRC,
217 [CC_OP_DECB ... CC_OP_DECQ] = USES_CC_DST | USES_CC_SRC,
218 [CC_OP_SHLB ... CC_OP_SHLQ] = USES_CC_DST | USES_CC_SRC,
219 [CC_OP_SARB ... CC_OP_SARQ] = USES_CC_DST | USES_CC_SRC,
220 [CC_OP_BMILGB ... CC_OP_BMILGQ] = USES_CC_DST | USES_CC_SRC,
221 [CC_OP_ADCX] = USES_CC_DST | USES_CC_SRC,
222 [CC_OP_ADOX] = USES_CC_SRC | USES_CC_SRC2,
223 [CC_OP_ADCOX] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
225 [CC_OP_POPCNT] = USES_CC_SRC,
228 static void set_cc_op(DisasContext *s, CCOp op)
232 if (s->cc_op == op) {
236 /* Discard CC computation that will no longer be used. */
237 dead = cc_op_live[s->cc_op] & ~cc_op_live[op];
238 if (dead & USES_CC_DST) {
239 tcg_gen_discard_tl(cpu_cc_dst);
241 if (dead & USES_CC_SRC) {
242 tcg_gen_discard_tl(cpu_cc_src);
244 if (dead & USES_CC_SRC2) {
245 tcg_gen_discard_tl(cpu_cc_src2);
247 if (dead & USES_CC_SRCT) {
248 tcg_gen_discard_tl(cpu_cc_srcT);
251 if (op == CC_OP_DYNAMIC) {
252 /* The DYNAMIC setting is translator only, and should never be
253 stored. Thus we always consider it clean. */
254 s->cc_op_dirty = false;
256 /* Discard any computed CC_OP value (see shifts). */
257 if (s->cc_op == CC_OP_DYNAMIC) {
258 tcg_gen_discard_i32(cpu_cc_op);
260 s->cc_op_dirty = true;
265 static void gen_update_cc_op(DisasContext *s)
267 if (s->cc_op_dirty) {
268 tcg_gen_movi_i32(cpu_cc_op, s->cc_op);
269 s->cc_op_dirty = false;
275 #define NB_OP_SIZES 4
277 #else /* !TARGET_X86_64 */
279 #define NB_OP_SIZES 3
281 #endif /* !TARGET_X86_64 */
283 #if defined(HOST_WORDS_BIGENDIAN)
284 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
285 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
286 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
287 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
288 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
290 #define REG_B_OFFSET 0
291 #define REG_H_OFFSET 1
292 #define REG_W_OFFSET 0
293 #define REG_L_OFFSET 0
294 #define REG_LH_OFFSET 4
297 /* In instruction encodings for byte register accesses the
298 * register number usually indicates "low 8 bits of register N";
299 * however there are some special cases where N 4..7 indicates
300 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
301 * true for this special case, false otherwise.
303 static inline bool byte_reg_is_xH(int reg)
309 if (reg >= 8 || x86_64_hregs) {
316 /* Select the size of a push/pop operation. */
317 static inline TCGMemOp mo_pushpop(DisasContext *s, TCGMemOp ot)
320 return ot == MO_16 ? MO_16 : MO_64;
326 /* Select the size of the stack pointer. */
327 static inline TCGMemOp mo_stacksize(DisasContext *s)
329 return CODE64(s) ? MO_64 : s->ss32 ? MO_32 : MO_16;
332 /* Select only size 64 else 32. Used for SSE operand sizes. */
333 static inline TCGMemOp mo_64_32(TCGMemOp ot)
336 return ot == MO_64 ? MO_64 : MO_32;
342 /* Select size 8 if lsb of B is clear, else OT. Used for decoding
343 byte vs word opcodes. */
344 static inline TCGMemOp mo_b_d(int b, TCGMemOp ot)
346 return b & 1 ? ot : MO_8;
349 /* Select size 8 if lsb of B is clear, else OT capped at 32.
350 Used for decoding operand size of port opcodes. */
351 static inline TCGMemOp mo_b_d32(int b, TCGMemOp ot)
353 return b & 1 ? (ot == MO_16 ? MO_16 : MO_32) : MO_8;
356 static void gen_op_mov_reg_v(TCGMemOp ot, int reg, TCGv t0)
360 if (!byte_reg_is_xH(reg)) {
361 tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 8);
363 tcg_gen_deposit_tl(cpu_regs[reg - 4], cpu_regs[reg - 4], t0, 8, 8);
367 tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 16);
370 /* For x86_64, this sets the higher half of register to zero.
371 For i386, this is equivalent to a mov. */
372 tcg_gen_ext32u_tl(cpu_regs[reg], t0);
376 tcg_gen_mov_tl(cpu_regs[reg], t0);
384 static inline void gen_op_mov_v_reg(TCGMemOp ot, TCGv t0, int reg)
386 if (ot == MO_8 && byte_reg_is_xH(reg)) {
387 tcg_gen_extract_tl(t0, cpu_regs[reg - 4], 8, 8);
389 tcg_gen_mov_tl(t0, cpu_regs[reg]);
393 static void gen_add_A0_im(DisasContext *s, int val)
395 tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
397 tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
401 static inline void gen_op_jmp_v(TCGv dest)
403 tcg_gen_st_tl(dest, cpu_env, offsetof(CPUX86State, eip));
406 static inline void gen_op_add_reg_im(TCGMemOp size, int reg, int32_t val)
408 tcg_gen_addi_tl(cpu_tmp0, cpu_regs[reg], val);
409 gen_op_mov_reg_v(size, reg, cpu_tmp0);
412 static inline void gen_op_add_reg_T0(TCGMemOp size, int reg)
414 tcg_gen_add_tl(cpu_tmp0, cpu_regs[reg], cpu_T0);
415 gen_op_mov_reg_v(size, reg, cpu_tmp0);
418 static inline void gen_op_ld_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
420 tcg_gen_qemu_ld_tl(t0, a0, s->mem_index, idx | MO_LE);
423 static inline void gen_op_st_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
425 tcg_gen_qemu_st_tl(t0, a0, s->mem_index, idx | MO_LE);
428 static inline void gen_op_st_rm_T0_A0(DisasContext *s, int idx, int d)
431 gen_op_st_v(s, idx, cpu_T0, cpu_A0);
433 gen_op_mov_reg_v(idx, d, cpu_T0);
437 static inline void gen_jmp_im(target_ulong pc)
439 tcg_gen_movi_tl(cpu_tmp0, pc);
440 gen_op_jmp_v(cpu_tmp0);
443 /* Compute SEG:REG into A0. SEG is selected from the override segment
444 (OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to
445 indicate no override. */
446 static void gen_lea_v_seg(DisasContext *s, TCGMemOp aflag, TCGv a0,
447 int def_seg, int ovr_seg)
453 tcg_gen_mov_tl(cpu_A0, a0);
460 if (ovr_seg < 0 && s->addseg) {
464 tcg_gen_ext32u_tl(cpu_A0, a0);
470 tcg_gen_ext16u_tl(cpu_A0, a0);
485 TCGv seg = cpu_seg_base[ovr_seg];
487 if (aflag == MO_64) {
488 tcg_gen_add_tl(cpu_A0, a0, seg);
489 } else if (CODE64(s)) {
490 tcg_gen_ext32u_tl(cpu_A0, a0);
491 tcg_gen_add_tl(cpu_A0, cpu_A0, seg);
493 tcg_gen_add_tl(cpu_A0, a0, seg);
494 tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
499 static inline void gen_string_movl_A0_ESI(DisasContext *s)
501 gen_lea_v_seg(s, s->aflag, cpu_regs[R_ESI], R_DS, s->override);
504 static inline void gen_string_movl_A0_EDI(DisasContext *s)
506 gen_lea_v_seg(s, s->aflag, cpu_regs[R_EDI], R_ES, -1);
509 static inline void gen_op_movl_T0_Dshift(TCGMemOp ot)
511 tcg_gen_ld32s_tl(cpu_T0, cpu_env, offsetof(CPUX86State, df));
512 tcg_gen_shli_tl(cpu_T0, cpu_T0, ot);
515 static TCGv gen_ext_tl(TCGv dst, TCGv src, TCGMemOp size, bool sign)
520 tcg_gen_ext8s_tl(dst, src);
522 tcg_gen_ext8u_tl(dst, src);
527 tcg_gen_ext16s_tl(dst, src);
529 tcg_gen_ext16u_tl(dst, src);
535 tcg_gen_ext32s_tl(dst, src);
537 tcg_gen_ext32u_tl(dst, src);
546 static void gen_extu(TCGMemOp ot, TCGv reg)
548 gen_ext_tl(reg, reg, ot, false);
551 static void gen_exts(TCGMemOp ot, TCGv reg)
553 gen_ext_tl(reg, reg, ot, true);
556 static inline void gen_op_jnz_ecx(TCGMemOp size, TCGLabel *label1)
558 tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
559 gen_extu(size, cpu_tmp0);
560 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_tmp0, 0, label1);
563 static inline void gen_op_jz_ecx(TCGMemOp size, TCGLabel *label1)
565 tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
566 gen_extu(size, cpu_tmp0);
567 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
570 static void gen_helper_in_func(TCGMemOp ot, TCGv v, TCGv_i32 n)
574 gen_helper_inb(v, cpu_env, n);
577 gen_helper_inw(v, cpu_env, n);
580 gen_helper_inl(v, cpu_env, n);
587 static void gen_helper_out_func(TCGMemOp ot, TCGv_i32 v, TCGv_i32 n)
591 gen_helper_outb(cpu_env, v, n);
594 gen_helper_outw(cpu_env, v, n);
597 gen_helper_outl(cpu_env, v, n);
604 static void gen_check_io(DisasContext *s, TCGMemOp ot, target_ulong cur_eip,
607 target_ulong next_eip;
609 if (s->pe && (s->cpl > s->iopl || s->vm86)) {
610 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
613 gen_helper_check_iob(cpu_env, cpu_tmp2_i32);
616 gen_helper_check_iow(cpu_env, cpu_tmp2_i32);
619 gen_helper_check_iol(cpu_env, cpu_tmp2_i32);
625 if(s->flags & HF_SVMI_MASK) {
628 svm_flags |= (1 << (4 + ot));
629 next_eip = s->pc - s->cs_base;
630 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
631 gen_helper_svm_check_io(cpu_env, cpu_tmp2_i32,
632 tcg_const_i32(svm_flags),
633 tcg_const_i32(next_eip - cur_eip));
637 static inline void gen_movs(DisasContext *s, TCGMemOp ot)
639 gen_string_movl_A0_ESI(s);
640 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
641 gen_string_movl_A0_EDI(s);
642 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
643 gen_op_movl_T0_Dshift(ot);
644 gen_op_add_reg_T0(s->aflag, R_ESI);
645 gen_op_add_reg_T0(s->aflag, R_EDI);
648 static void gen_op_update1_cc(void)
650 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
653 static void gen_op_update2_cc(void)
655 tcg_gen_mov_tl(cpu_cc_src, cpu_T1);
656 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
659 static void gen_op_update3_cc(TCGv reg)
661 tcg_gen_mov_tl(cpu_cc_src2, reg);
662 tcg_gen_mov_tl(cpu_cc_src, cpu_T1);
663 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
666 static inline void gen_op_testl_T0_T1_cc(void)
668 tcg_gen_and_tl(cpu_cc_dst, cpu_T0, cpu_T1);
671 static void gen_op_update_neg_cc(void)
673 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
674 tcg_gen_neg_tl(cpu_cc_src, cpu_T0);
675 tcg_gen_movi_tl(cpu_cc_srcT, 0);
678 /* compute all eflags to cc_src */
679 static void gen_compute_eflags(DisasContext *s)
681 TCGv zero, dst, src1, src2;
684 if (s->cc_op == CC_OP_EFLAGS) {
687 if (s->cc_op == CC_OP_CLR) {
688 tcg_gen_movi_tl(cpu_cc_src, CC_Z | CC_P);
689 set_cc_op(s, CC_OP_EFLAGS);
698 /* Take care to not read values that are not live. */
699 live = cc_op_live[s->cc_op] & ~USES_CC_SRCT;
700 dead = live ^ (USES_CC_DST | USES_CC_SRC | USES_CC_SRC2);
702 zero = tcg_const_tl(0);
703 if (dead & USES_CC_DST) {
706 if (dead & USES_CC_SRC) {
709 if (dead & USES_CC_SRC2) {
715 gen_helper_cc_compute_all(cpu_cc_src, dst, src1, src2, cpu_cc_op);
716 set_cc_op(s, CC_OP_EFLAGS);
723 typedef struct CCPrepare {
733 /* compute eflags.C to reg */
734 static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg)
740 case CC_OP_SUBB ... CC_OP_SUBQ:
741 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
742 size = s->cc_op - CC_OP_SUBB;
743 t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
744 /* If no temporary was used, be careful not to alias t1 and t0. */
745 t0 = TCGV_EQUAL(t1, cpu_cc_src) ? cpu_tmp0 : reg;
746 tcg_gen_mov_tl(t0, cpu_cc_srcT);
750 case CC_OP_ADDB ... CC_OP_ADDQ:
751 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
752 size = s->cc_op - CC_OP_ADDB;
753 t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
754 t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
756 return (CCPrepare) { .cond = TCG_COND_LTU, .reg = t0,
757 .reg2 = t1, .mask = -1, .use_reg2 = true };
759 case CC_OP_LOGICB ... CC_OP_LOGICQ:
762 return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
764 case CC_OP_INCB ... CC_OP_INCQ:
765 case CC_OP_DECB ... CC_OP_DECQ:
766 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
767 .mask = -1, .no_setcond = true };
769 case CC_OP_SHLB ... CC_OP_SHLQ:
770 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
771 size = s->cc_op - CC_OP_SHLB;
772 shift = (8 << size) - 1;
773 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
774 .mask = (target_ulong)1 << shift };
776 case CC_OP_MULB ... CC_OP_MULQ:
777 return (CCPrepare) { .cond = TCG_COND_NE,
778 .reg = cpu_cc_src, .mask = -1 };
780 case CC_OP_BMILGB ... CC_OP_BMILGQ:
781 size = s->cc_op - CC_OP_BMILGB;
782 t0 = gen_ext_tl(reg, cpu_cc_src, size, false);
783 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 };
787 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_dst,
788 .mask = -1, .no_setcond = true };
791 case CC_OP_SARB ... CC_OP_SARQ:
793 return (CCPrepare) { .cond = TCG_COND_NE,
794 .reg = cpu_cc_src, .mask = CC_C };
797 /* The need to compute only C from CC_OP_DYNAMIC is important
798 in efficiently implementing e.g. INC at the start of a TB. */
800 gen_helper_cc_compute_c(reg, cpu_cc_dst, cpu_cc_src,
801 cpu_cc_src2, cpu_cc_op);
802 return (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
803 .mask = -1, .no_setcond = true };
807 /* compute eflags.P to reg */
808 static CCPrepare gen_prepare_eflags_p(DisasContext *s, TCGv reg)
810 gen_compute_eflags(s);
811 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
815 /* compute eflags.S to reg */
816 static CCPrepare gen_prepare_eflags_s(DisasContext *s, TCGv reg)
820 gen_compute_eflags(s);
826 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
830 return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
833 TCGMemOp size = (s->cc_op - CC_OP_ADDB) & 3;
834 TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, true);
835 return (CCPrepare) { .cond = TCG_COND_LT, .reg = t0, .mask = -1 };
840 /* compute eflags.O to reg */
841 static CCPrepare gen_prepare_eflags_o(DisasContext *s, TCGv reg)
846 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src2,
847 .mask = -1, .no_setcond = true };
850 return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
852 gen_compute_eflags(s);
853 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
858 /* compute eflags.Z to reg */
859 static CCPrepare gen_prepare_eflags_z(DisasContext *s, TCGv reg)
863 gen_compute_eflags(s);
869 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
872 return (CCPrepare) { .cond = TCG_COND_ALWAYS, .mask = -1 };
874 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = cpu_cc_src,
878 TCGMemOp size = (s->cc_op - CC_OP_ADDB) & 3;
879 TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
880 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 };
885 /* perform a conditional store into register 'reg' according to jump opcode
886 value 'b'. In the fast case, T0 is guaranted not to be used. */
887 static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg)
889 int inv, jcc_op, cond;
895 jcc_op = (b >> 1) & 7;
898 case CC_OP_SUBB ... CC_OP_SUBQ:
899 /* We optimize relational operators for the cmp/jcc case. */
900 size = s->cc_op - CC_OP_SUBB;
903 tcg_gen_mov_tl(cpu_tmp4, cpu_cc_srcT);
904 gen_extu(size, cpu_tmp4);
905 t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
906 cc = (CCPrepare) { .cond = TCG_COND_LEU, .reg = cpu_tmp4,
907 .reg2 = t0, .mask = -1, .use_reg2 = true };
916 tcg_gen_mov_tl(cpu_tmp4, cpu_cc_srcT);
917 gen_exts(size, cpu_tmp4);
918 t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, true);
919 cc = (CCPrepare) { .cond = cond, .reg = cpu_tmp4,
920 .reg2 = t0, .mask = -1, .use_reg2 = true };
930 /* This actually generates good code for JC, JZ and JS. */
933 cc = gen_prepare_eflags_o(s, reg);
936 cc = gen_prepare_eflags_c(s, reg);
939 cc = gen_prepare_eflags_z(s, reg);
942 gen_compute_eflags(s);
943 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
944 .mask = CC_Z | CC_C };
947 cc = gen_prepare_eflags_s(s, reg);
950 cc = gen_prepare_eflags_p(s, reg);
953 gen_compute_eflags(s);
954 if (TCGV_EQUAL(reg, cpu_cc_src)) {
957 tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */
958 tcg_gen_xor_tl(reg, reg, cpu_cc_src);
959 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
964 gen_compute_eflags(s);
965 if (TCGV_EQUAL(reg, cpu_cc_src)) {
968 tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */
969 tcg_gen_xor_tl(reg, reg, cpu_cc_src);
970 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
971 .mask = CC_S | CC_Z };
978 cc.cond = tcg_invert_cond(cc.cond);
983 static void gen_setcc1(DisasContext *s, int b, TCGv reg)
985 CCPrepare cc = gen_prepare_cc(s, b, reg);
988 if (cc.cond == TCG_COND_EQ) {
989 tcg_gen_xori_tl(reg, cc.reg, 1);
991 tcg_gen_mov_tl(reg, cc.reg);
996 if (cc.cond == TCG_COND_NE && !cc.use_reg2 && cc.imm == 0 &&
997 cc.mask != 0 && (cc.mask & (cc.mask - 1)) == 0) {
998 tcg_gen_shri_tl(reg, cc.reg, ctztl(cc.mask));
999 tcg_gen_andi_tl(reg, reg, 1);
1002 if (cc.mask != -1) {
1003 tcg_gen_andi_tl(reg, cc.reg, cc.mask);
1007 tcg_gen_setcond_tl(cc.cond, reg, cc.reg, cc.reg2);
1009 tcg_gen_setcondi_tl(cc.cond, reg, cc.reg, cc.imm);
1013 static inline void gen_compute_eflags_c(DisasContext *s, TCGv reg)
1015 gen_setcc1(s, JCC_B << 1, reg);
1018 /* generate a conditional jump to label 'l1' according to jump opcode
1019 value 'b'. In the fast case, T0 is guaranted not to be used. */
1020 static inline void gen_jcc1_noeob(DisasContext *s, int b, TCGLabel *l1)
1022 CCPrepare cc = gen_prepare_cc(s, b, cpu_T0);
1024 if (cc.mask != -1) {
1025 tcg_gen_andi_tl(cpu_T0, cc.reg, cc.mask);
1029 tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1031 tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1035 /* Generate a conditional jump to label 'l1' according to jump opcode
1036 value 'b'. In the fast case, T0 is guaranted not to be used.
1037 A translation block must end soon. */
1038 static inline void gen_jcc1(DisasContext *s, int b, TCGLabel *l1)
1040 CCPrepare cc = gen_prepare_cc(s, b, cpu_T0);
1042 gen_update_cc_op(s);
1043 if (cc.mask != -1) {
1044 tcg_gen_andi_tl(cpu_T0, cc.reg, cc.mask);
1047 set_cc_op(s, CC_OP_DYNAMIC);
1049 tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1051 tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1055 /* XXX: does not work with gdbstub "ice" single step - not a
1057 static TCGLabel *gen_jz_ecx_string(DisasContext *s, target_ulong next_eip)
1059 TCGLabel *l1 = gen_new_label();
1060 TCGLabel *l2 = gen_new_label();
1061 gen_op_jnz_ecx(s->aflag, l1);
1063 gen_jmp_tb(s, next_eip, 1);
1068 static inline void gen_stos(DisasContext *s, TCGMemOp ot)
1070 gen_op_mov_v_reg(MO_32, cpu_T0, R_EAX);
1071 gen_string_movl_A0_EDI(s);
1072 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
1073 gen_op_movl_T0_Dshift(ot);
1074 gen_op_add_reg_T0(s->aflag, R_EDI);
1077 static inline void gen_lods(DisasContext *s, TCGMemOp ot)
1079 gen_string_movl_A0_ESI(s);
1080 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1081 gen_op_mov_reg_v(ot, R_EAX, cpu_T0);
1082 gen_op_movl_T0_Dshift(ot);
1083 gen_op_add_reg_T0(s->aflag, R_ESI);
1086 static inline void gen_scas(DisasContext *s, TCGMemOp ot)
1088 gen_string_movl_A0_EDI(s);
1089 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
1090 gen_op(s, OP_CMPL, ot, R_EAX);
1091 gen_op_movl_T0_Dshift(ot);
1092 gen_op_add_reg_T0(s->aflag, R_EDI);
1095 static inline void gen_cmps(DisasContext *s, TCGMemOp ot)
1097 gen_string_movl_A0_EDI(s);
1098 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
1099 gen_string_movl_A0_ESI(s);
1100 gen_op(s, OP_CMPL, ot, OR_TMP0);
1101 gen_op_movl_T0_Dshift(ot);
1102 gen_op_add_reg_T0(s->aflag, R_ESI);
1103 gen_op_add_reg_T0(s->aflag, R_EDI);
1106 static void gen_bpt_io(DisasContext *s, TCGv_i32 t_port, int ot)
1108 if (s->flags & HF_IOBPT_MASK) {
1109 TCGv_i32 t_size = tcg_const_i32(1 << ot);
1110 TCGv t_next = tcg_const_tl(s->pc - s->cs_base);
1112 gen_helper_bpt_io(cpu_env, t_port, t_size, t_next);
1113 tcg_temp_free_i32(t_size);
1114 tcg_temp_free(t_next);
1119 static inline void gen_ins(DisasContext *s, TCGMemOp ot)
1121 if (s->tb->cflags & CF_USE_ICOUNT) {
1124 gen_string_movl_A0_EDI(s);
1125 /* Note: we must do this dummy write first to be restartable in
1126 case of page fault. */
1127 tcg_gen_movi_tl(cpu_T0, 0);
1128 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
1129 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_EDX]);
1130 tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1131 gen_helper_in_func(ot, cpu_T0, cpu_tmp2_i32);
1132 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
1133 gen_op_movl_T0_Dshift(ot);
1134 gen_op_add_reg_T0(s->aflag, R_EDI);
1135 gen_bpt_io(s, cpu_tmp2_i32, ot);
1136 if (s->tb->cflags & CF_USE_ICOUNT) {
1141 static inline void gen_outs(DisasContext *s, TCGMemOp ot)
1143 if (s->tb->cflags & CF_USE_ICOUNT) {
1146 gen_string_movl_A0_ESI(s);
1147 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1149 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_EDX]);
1150 tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1151 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T0);
1152 gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
1153 gen_op_movl_T0_Dshift(ot);
1154 gen_op_add_reg_T0(s->aflag, R_ESI);
1155 gen_bpt_io(s, cpu_tmp2_i32, ot);
1156 if (s->tb->cflags & CF_USE_ICOUNT) {
1161 /* same method as Valgrind : we generate jumps to current or next
1163 #define GEN_REPZ(op) \
1164 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1165 target_ulong cur_eip, target_ulong next_eip) \
1168 gen_update_cc_op(s); \
1169 l2 = gen_jz_ecx_string(s, next_eip); \
1170 gen_ ## op(s, ot); \
1171 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1172 /* a loop would cause two single step exceptions if ECX = 1 \
1173 before rep string_insn */ \
1175 gen_op_jz_ecx(s->aflag, l2); \
1176 gen_jmp(s, cur_eip); \
1179 #define GEN_REPZ2(op) \
1180 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1181 target_ulong cur_eip, \
1182 target_ulong next_eip, \
1186 gen_update_cc_op(s); \
1187 l2 = gen_jz_ecx_string(s, next_eip); \
1188 gen_ ## op(s, ot); \
1189 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1190 gen_update_cc_op(s); \
1191 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
1193 gen_op_jz_ecx(s->aflag, l2); \
1194 gen_jmp(s, cur_eip); \
1205 static void gen_helper_fp_arith_ST0_FT0(int op)
1209 gen_helper_fadd_ST0_FT0(cpu_env);
1212 gen_helper_fmul_ST0_FT0(cpu_env);
1215 gen_helper_fcom_ST0_FT0(cpu_env);
1218 gen_helper_fcom_ST0_FT0(cpu_env);
1221 gen_helper_fsub_ST0_FT0(cpu_env);
1224 gen_helper_fsubr_ST0_FT0(cpu_env);
1227 gen_helper_fdiv_ST0_FT0(cpu_env);
1230 gen_helper_fdivr_ST0_FT0(cpu_env);
1235 /* NOTE the exception in "r" op ordering */
1236 static void gen_helper_fp_arith_STN_ST0(int op, int opreg)
1238 TCGv_i32 tmp = tcg_const_i32(opreg);
1241 gen_helper_fadd_STN_ST0(cpu_env, tmp);
1244 gen_helper_fmul_STN_ST0(cpu_env, tmp);
1247 gen_helper_fsubr_STN_ST0(cpu_env, tmp);
1250 gen_helper_fsub_STN_ST0(cpu_env, tmp);
1253 gen_helper_fdivr_STN_ST0(cpu_env, tmp);
1256 gen_helper_fdiv_STN_ST0(cpu_env, tmp);
1261 /* if d == OR_TMP0, it means memory operand (address in A0) */
1262 static void gen_op(DisasContext *s1, int op, TCGMemOp ot, int d)
1265 gen_op_mov_v_reg(ot, cpu_T0, d);
1266 } else if (!(s1->prefix & PREFIX_LOCK)) {
1267 gen_op_ld_v(s1, ot, cpu_T0, cpu_A0);
1271 gen_compute_eflags_c(s1, cpu_tmp4);
1272 if (s1->prefix & PREFIX_LOCK) {
1273 tcg_gen_add_tl(cpu_T0, cpu_tmp4, cpu_T1);
1274 tcg_gen_atomic_add_fetch_tl(cpu_T0, cpu_A0, cpu_T0,
1275 s1->mem_index, ot | MO_LE);
1277 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
1278 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_tmp4);
1279 gen_op_st_rm_T0_A0(s1, ot, d);
1281 gen_op_update3_cc(cpu_tmp4);
1282 set_cc_op(s1, CC_OP_ADCB + ot);
1285 gen_compute_eflags_c(s1, cpu_tmp4);
1286 if (s1->prefix & PREFIX_LOCK) {
1287 tcg_gen_add_tl(cpu_T0, cpu_T1, cpu_tmp4);
1288 tcg_gen_neg_tl(cpu_T0, cpu_T0);
1289 tcg_gen_atomic_add_fetch_tl(cpu_T0, cpu_A0, cpu_T0,
1290 s1->mem_index, ot | MO_LE);
1292 tcg_gen_sub_tl(cpu_T0, cpu_T0, cpu_T1);
1293 tcg_gen_sub_tl(cpu_T0, cpu_T0, cpu_tmp4);
1294 gen_op_st_rm_T0_A0(s1, ot, d);
1296 gen_op_update3_cc(cpu_tmp4);
1297 set_cc_op(s1, CC_OP_SBBB + ot);
1300 if (s1->prefix & PREFIX_LOCK) {
1301 tcg_gen_atomic_add_fetch_tl(cpu_T0, cpu_A0, cpu_T1,
1302 s1->mem_index, ot | MO_LE);
1304 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
1305 gen_op_st_rm_T0_A0(s1, ot, d);
1307 gen_op_update2_cc();
1308 set_cc_op(s1, CC_OP_ADDB + ot);
1311 if (s1->prefix & PREFIX_LOCK) {
1312 tcg_gen_neg_tl(cpu_T0, cpu_T1);
1313 tcg_gen_atomic_fetch_add_tl(cpu_cc_srcT, cpu_A0, cpu_T0,
1314 s1->mem_index, ot | MO_LE);
1315 tcg_gen_sub_tl(cpu_T0, cpu_cc_srcT, cpu_T1);
1317 tcg_gen_mov_tl(cpu_cc_srcT, cpu_T0);
1318 tcg_gen_sub_tl(cpu_T0, cpu_T0, cpu_T1);
1319 gen_op_st_rm_T0_A0(s1, ot, d);
1321 gen_op_update2_cc();
1322 set_cc_op(s1, CC_OP_SUBB + ot);
1326 if (s1->prefix & PREFIX_LOCK) {
1327 tcg_gen_atomic_and_fetch_tl(cpu_T0, cpu_A0, cpu_T1,
1328 s1->mem_index, ot | MO_LE);
1330 tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1);
1331 gen_op_st_rm_T0_A0(s1, ot, d);
1333 gen_op_update1_cc();
1334 set_cc_op(s1, CC_OP_LOGICB + ot);
1337 if (s1->prefix & PREFIX_LOCK) {
1338 tcg_gen_atomic_or_fetch_tl(cpu_T0, cpu_A0, cpu_T1,
1339 s1->mem_index, ot | MO_LE);
1341 tcg_gen_or_tl(cpu_T0, cpu_T0, cpu_T1);
1342 gen_op_st_rm_T0_A0(s1, ot, d);
1344 gen_op_update1_cc();
1345 set_cc_op(s1, CC_OP_LOGICB + ot);
1348 if (s1->prefix & PREFIX_LOCK) {
1349 tcg_gen_atomic_xor_fetch_tl(cpu_T0, cpu_A0, cpu_T1,
1350 s1->mem_index, ot | MO_LE);
1352 tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_T1);
1353 gen_op_st_rm_T0_A0(s1, ot, d);
1355 gen_op_update1_cc();
1356 set_cc_op(s1, CC_OP_LOGICB + ot);
1359 tcg_gen_mov_tl(cpu_cc_src, cpu_T1);
1360 tcg_gen_mov_tl(cpu_cc_srcT, cpu_T0);
1361 tcg_gen_sub_tl(cpu_cc_dst, cpu_T0, cpu_T1);
1362 set_cc_op(s1, CC_OP_SUBB + ot);
1367 /* if d == OR_TMP0, it means memory operand (address in A0) */
1368 static void gen_inc(DisasContext *s1, TCGMemOp ot, int d, int c)
1370 if (s1->prefix & PREFIX_LOCK) {
1371 tcg_gen_movi_tl(cpu_T0, c > 0 ? 1 : -1);
1372 tcg_gen_atomic_add_fetch_tl(cpu_T0, cpu_A0, cpu_T0,
1373 s1->mem_index, ot | MO_LE);
1376 gen_op_mov_v_reg(ot, cpu_T0, d);
1378 gen_op_ld_v(s1, ot, cpu_T0, cpu_A0);
1380 tcg_gen_addi_tl(cpu_T0, cpu_T0, (c > 0 ? 1 : -1));
1381 gen_op_st_rm_T0_A0(s1, ot, d);
1384 gen_compute_eflags_c(s1, cpu_cc_src);
1385 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
1386 set_cc_op(s1, (c > 0 ? CC_OP_INCB : CC_OP_DECB) + ot);
1389 static void gen_shift_flags(DisasContext *s, TCGMemOp ot, TCGv result,
1390 TCGv shm1, TCGv count, bool is_right)
1392 TCGv_i32 z32, s32, oldop;
1395 /* Store the results into the CC variables. If we know that the
1396 variable must be dead, store unconditionally. Otherwise we'll
1397 need to not disrupt the current contents. */
1398 z_tl = tcg_const_tl(0);
1399 if (cc_op_live[s->cc_op] & USES_CC_DST) {
1400 tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_dst, count, z_tl,
1401 result, cpu_cc_dst);
1403 tcg_gen_mov_tl(cpu_cc_dst, result);
1405 if (cc_op_live[s->cc_op] & USES_CC_SRC) {
1406 tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_src, count, z_tl,
1409 tcg_gen_mov_tl(cpu_cc_src, shm1);
1411 tcg_temp_free(z_tl);
1413 /* Get the two potential CC_OP values into temporaries. */
1414 tcg_gen_movi_i32(cpu_tmp2_i32, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot);
1415 if (s->cc_op == CC_OP_DYNAMIC) {
1418 tcg_gen_movi_i32(cpu_tmp3_i32, s->cc_op);
1419 oldop = cpu_tmp3_i32;
1422 /* Conditionally store the CC_OP value. */
1423 z32 = tcg_const_i32(0);
1424 s32 = tcg_temp_new_i32();
1425 tcg_gen_trunc_tl_i32(s32, count);
1426 tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, s32, z32, cpu_tmp2_i32, oldop);
1427 tcg_temp_free_i32(z32);
1428 tcg_temp_free_i32(s32);
1430 /* The CC_OP value is no longer predictable. */
1431 set_cc_op(s, CC_OP_DYNAMIC);
1434 static void gen_shift_rm_T1(DisasContext *s, TCGMemOp ot, int op1,
1435 int is_right, int is_arith)
1437 target_ulong mask = (ot == MO_64 ? 0x3f : 0x1f);
1440 if (op1 == OR_TMP0) {
1441 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1443 gen_op_mov_v_reg(ot, cpu_T0, op1);
1446 tcg_gen_andi_tl(cpu_T1, cpu_T1, mask);
1447 tcg_gen_subi_tl(cpu_tmp0, cpu_T1, 1);
1451 gen_exts(ot, cpu_T0);
1452 tcg_gen_sar_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1453 tcg_gen_sar_tl(cpu_T0, cpu_T0, cpu_T1);
1455 gen_extu(ot, cpu_T0);
1456 tcg_gen_shr_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1457 tcg_gen_shr_tl(cpu_T0, cpu_T0, cpu_T1);
1460 tcg_gen_shl_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1461 tcg_gen_shl_tl(cpu_T0, cpu_T0, cpu_T1);
1465 gen_op_st_rm_T0_A0(s, ot, op1);
1467 gen_shift_flags(s, ot, cpu_T0, cpu_tmp0, cpu_T1, is_right);
1470 static void gen_shift_rm_im(DisasContext *s, TCGMemOp ot, int op1, int op2,
1471 int is_right, int is_arith)
1473 int mask = (ot == MO_64 ? 0x3f : 0x1f);
1477 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1479 gen_op_mov_v_reg(ot, cpu_T0, op1);
1485 gen_exts(ot, cpu_T0);
1486 tcg_gen_sari_tl(cpu_tmp4, cpu_T0, op2 - 1);
1487 tcg_gen_sari_tl(cpu_T0, cpu_T0, op2);
1489 gen_extu(ot, cpu_T0);
1490 tcg_gen_shri_tl(cpu_tmp4, cpu_T0, op2 - 1);
1491 tcg_gen_shri_tl(cpu_T0, cpu_T0, op2);
1494 tcg_gen_shli_tl(cpu_tmp4, cpu_T0, op2 - 1);
1495 tcg_gen_shli_tl(cpu_T0, cpu_T0, op2);
1500 gen_op_st_rm_T0_A0(s, ot, op1);
1502 /* update eflags if non zero shift */
1504 tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
1505 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
1506 set_cc_op(s, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot);
1510 static void gen_rot_rm_T1(DisasContext *s, TCGMemOp ot, int op1, int is_right)
1512 target_ulong mask = (ot == MO_64 ? 0x3f : 0x1f);
1516 if (op1 == OR_TMP0) {
1517 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1519 gen_op_mov_v_reg(ot, cpu_T0, op1);
1522 tcg_gen_andi_tl(cpu_T1, cpu_T1, mask);
1526 /* Replicate the 8-bit input so that a 32-bit rotate works. */
1527 tcg_gen_ext8u_tl(cpu_T0, cpu_T0);
1528 tcg_gen_muli_tl(cpu_T0, cpu_T0, 0x01010101);
1531 /* Replicate the 16-bit input so that a 32-bit rotate works. */
1532 tcg_gen_deposit_tl(cpu_T0, cpu_T0, cpu_T0, 16, 16);
1535 #ifdef TARGET_X86_64
1537 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
1538 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T1);
1540 tcg_gen_rotr_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
1542 tcg_gen_rotl_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
1544 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
1549 tcg_gen_rotr_tl(cpu_T0, cpu_T0, cpu_T1);
1551 tcg_gen_rotl_tl(cpu_T0, cpu_T0, cpu_T1);
1557 gen_op_st_rm_T0_A0(s, ot, op1);
1559 /* We'll need the flags computed into CC_SRC. */
1560 gen_compute_eflags(s);
1562 /* The value that was "rotated out" is now present at the other end
1563 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1564 since we've computed the flags into CC_SRC, these variables are
1567 tcg_gen_shri_tl(cpu_cc_src2, cpu_T0, mask - 1);
1568 tcg_gen_shri_tl(cpu_cc_dst, cpu_T0, mask);
1569 tcg_gen_andi_tl(cpu_cc_dst, cpu_cc_dst, 1);
1571 tcg_gen_shri_tl(cpu_cc_src2, cpu_T0, mask);
1572 tcg_gen_andi_tl(cpu_cc_dst, cpu_T0, 1);
1574 tcg_gen_andi_tl(cpu_cc_src2, cpu_cc_src2, 1);
1575 tcg_gen_xor_tl(cpu_cc_src2, cpu_cc_src2, cpu_cc_dst);
1577 /* Now conditionally store the new CC_OP value. If the shift count
1578 is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1579 Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1580 exactly as we computed above. */
1581 t0 = tcg_const_i32(0);
1582 t1 = tcg_temp_new_i32();
1583 tcg_gen_trunc_tl_i32(t1, cpu_T1);
1584 tcg_gen_movi_i32(cpu_tmp2_i32, CC_OP_ADCOX);
1585 tcg_gen_movi_i32(cpu_tmp3_i32, CC_OP_EFLAGS);
1586 tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, t1, t0,
1587 cpu_tmp2_i32, cpu_tmp3_i32);
1588 tcg_temp_free_i32(t0);
1589 tcg_temp_free_i32(t1);
1591 /* The CC_OP value is no longer predictable. */
1592 set_cc_op(s, CC_OP_DYNAMIC);
1595 static void gen_rot_rm_im(DisasContext *s, TCGMemOp ot, int op1, int op2,
1598 int mask = (ot == MO_64 ? 0x3f : 0x1f);
1602 if (op1 == OR_TMP0) {
1603 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1605 gen_op_mov_v_reg(ot, cpu_T0, op1);
1611 #ifdef TARGET_X86_64
1613 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
1615 tcg_gen_rotri_i32(cpu_tmp2_i32, cpu_tmp2_i32, op2);
1617 tcg_gen_rotli_i32(cpu_tmp2_i32, cpu_tmp2_i32, op2);
1619 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
1624 tcg_gen_rotri_tl(cpu_T0, cpu_T0, op2);
1626 tcg_gen_rotli_tl(cpu_T0, cpu_T0, op2);
1637 shift = mask + 1 - shift;
1639 gen_extu(ot, cpu_T0);
1640 tcg_gen_shli_tl(cpu_tmp0, cpu_T0, shift);
1641 tcg_gen_shri_tl(cpu_T0, cpu_T0, mask + 1 - shift);
1642 tcg_gen_or_tl(cpu_T0, cpu_T0, cpu_tmp0);
1648 gen_op_st_rm_T0_A0(s, ot, op1);
1651 /* Compute the flags into CC_SRC. */
1652 gen_compute_eflags(s);
1654 /* The value that was "rotated out" is now present at the other end
1655 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1656 since we've computed the flags into CC_SRC, these variables are
1659 tcg_gen_shri_tl(cpu_cc_src2, cpu_T0, mask - 1);
1660 tcg_gen_shri_tl(cpu_cc_dst, cpu_T0, mask);
1661 tcg_gen_andi_tl(cpu_cc_dst, cpu_cc_dst, 1);
1663 tcg_gen_shri_tl(cpu_cc_src2, cpu_T0, mask);
1664 tcg_gen_andi_tl(cpu_cc_dst, cpu_T0, 1);
1666 tcg_gen_andi_tl(cpu_cc_src2, cpu_cc_src2, 1);
1667 tcg_gen_xor_tl(cpu_cc_src2, cpu_cc_src2, cpu_cc_dst);
1668 set_cc_op(s, CC_OP_ADCOX);
1672 /* XXX: add faster immediate = 1 case */
1673 static void gen_rotc_rm_T1(DisasContext *s, TCGMemOp ot, int op1,
1676 gen_compute_eflags(s);
1677 assert(s->cc_op == CC_OP_EFLAGS);
1681 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1683 gen_op_mov_v_reg(ot, cpu_T0, op1);
1688 gen_helper_rcrb(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1691 gen_helper_rcrw(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1694 gen_helper_rcrl(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1696 #ifdef TARGET_X86_64
1698 gen_helper_rcrq(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1707 gen_helper_rclb(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1710 gen_helper_rclw(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1713 gen_helper_rcll(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1715 #ifdef TARGET_X86_64
1717 gen_helper_rclq(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1725 gen_op_st_rm_T0_A0(s, ot, op1);
1728 /* XXX: add faster immediate case */
1729 static void gen_shiftd_rm_T1(DisasContext *s, TCGMemOp ot, int op1,
1730 bool is_right, TCGv count_in)
1732 target_ulong mask = (ot == MO_64 ? 63 : 31);
1736 if (op1 == OR_TMP0) {
1737 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1739 gen_op_mov_v_reg(ot, cpu_T0, op1);
1742 count = tcg_temp_new();
1743 tcg_gen_andi_tl(count, count_in, mask);
1747 /* Note: we implement the Intel behaviour for shift count > 16.
1748 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A
1749 portion by constructing it as a 32-bit value. */
1751 tcg_gen_deposit_tl(cpu_tmp0, cpu_T0, cpu_T1, 16, 16);
1752 tcg_gen_mov_tl(cpu_T1, cpu_T0);
1753 tcg_gen_mov_tl(cpu_T0, cpu_tmp0);
1755 tcg_gen_deposit_tl(cpu_T1, cpu_T0, cpu_T1, 16, 16);
1758 #ifdef TARGET_X86_64
1760 /* Concatenate the two 32-bit values and use a 64-bit shift. */
1761 tcg_gen_subi_tl(cpu_tmp0, count, 1);
1763 tcg_gen_concat_tl_i64(cpu_T0, cpu_T0, cpu_T1);
1764 tcg_gen_shr_i64(cpu_tmp0, cpu_T0, cpu_tmp0);
1765 tcg_gen_shr_i64(cpu_T0, cpu_T0, count);
1767 tcg_gen_concat_tl_i64(cpu_T0, cpu_T1, cpu_T0);
1768 tcg_gen_shl_i64(cpu_tmp0, cpu_T0, cpu_tmp0);
1769 tcg_gen_shl_i64(cpu_T0, cpu_T0, count);
1770 tcg_gen_shri_i64(cpu_tmp0, cpu_tmp0, 32);
1771 tcg_gen_shri_i64(cpu_T0, cpu_T0, 32);
1776 tcg_gen_subi_tl(cpu_tmp0, count, 1);
1778 tcg_gen_shr_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1780 tcg_gen_subfi_tl(cpu_tmp4, mask + 1, count);
1781 tcg_gen_shr_tl(cpu_T0, cpu_T0, count);
1782 tcg_gen_shl_tl(cpu_T1, cpu_T1, cpu_tmp4);
1784 tcg_gen_shl_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1786 /* Only needed if count > 16, for Intel behaviour. */
1787 tcg_gen_subfi_tl(cpu_tmp4, 33, count);
1788 tcg_gen_shr_tl(cpu_tmp4, cpu_T1, cpu_tmp4);
1789 tcg_gen_or_tl(cpu_tmp0, cpu_tmp0, cpu_tmp4);
1792 tcg_gen_subfi_tl(cpu_tmp4, mask + 1, count);
1793 tcg_gen_shl_tl(cpu_T0, cpu_T0, count);
1794 tcg_gen_shr_tl(cpu_T1, cpu_T1, cpu_tmp4);
1796 tcg_gen_movi_tl(cpu_tmp4, 0);
1797 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_T1, count, cpu_tmp4,
1799 tcg_gen_or_tl(cpu_T0, cpu_T0, cpu_T1);
1804 gen_op_st_rm_T0_A0(s, ot, op1);
1806 gen_shift_flags(s, ot, cpu_T0, cpu_tmp0, count, is_right);
1807 tcg_temp_free(count);
1810 static void gen_shift(DisasContext *s1, int op, TCGMemOp ot, int d, int s)
1813 gen_op_mov_v_reg(ot, cpu_T1, s);
1816 gen_rot_rm_T1(s1, ot, d, 0);
1819 gen_rot_rm_T1(s1, ot, d, 1);
1823 gen_shift_rm_T1(s1, ot, d, 0, 0);
1826 gen_shift_rm_T1(s1, ot, d, 1, 0);
1829 gen_shift_rm_T1(s1, ot, d, 1, 1);
1832 gen_rotc_rm_T1(s1, ot, d, 0);
1835 gen_rotc_rm_T1(s1, ot, d, 1);
1840 static void gen_shifti(DisasContext *s1, int op, TCGMemOp ot, int d, int c)
1844 gen_rot_rm_im(s1, ot, d, c, 0);
1847 gen_rot_rm_im(s1, ot, d, c, 1);
1851 gen_shift_rm_im(s1, ot, d, c, 0, 0);
1854 gen_shift_rm_im(s1, ot, d, c, 1, 0);
1857 gen_shift_rm_im(s1, ot, d, c, 1, 1);
1860 /* currently not optimized */
1861 tcg_gen_movi_tl(cpu_T1, c);
1862 gen_shift(s1, op, ot, d, OR_TMP1);
1867 /* Decompose an address. */
1869 typedef struct AddressParts {
1877 static AddressParts gen_lea_modrm_0(CPUX86State *env, DisasContext *s,
1880 int def_seg, base, index, scale, mod, rm;
1889 mod = (modrm >> 6) & 3;
1891 base = rm | REX_B(s);
1894 /* Normally filtered out earlier, but including this path
1895 simplifies multi-byte nop, as well as bndcl, bndcu, bndcn. */
1904 int code = cpu_ldub_code(env, s->pc++);
1905 scale = (code >> 6) & 3;
1906 index = ((code >> 3) & 7) | REX_X(s);
1908 index = -1; /* no index */
1910 base = (code & 7) | REX_B(s);
1916 if ((base & 7) == 5) {
1918 disp = (int32_t)cpu_ldl_code(env, s->pc);
1920 if (CODE64(s) && !havesib) {
1922 disp += s->pc + s->rip_offset;
1927 disp = (int8_t)cpu_ldub_code(env, s->pc++);
1931 disp = (int32_t)cpu_ldl_code(env, s->pc);
1936 /* For correct popl handling with esp. */
1937 if (base == R_ESP && s->popl_esp_hack) {
1938 disp += s->popl_esp_hack;
1940 if (base == R_EBP || base == R_ESP) {
1949 disp = cpu_lduw_code(env, s->pc);
1953 } else if (mod == 1) {
1954 disp = (int8_t)cpu_ldub_code(env, s->pc++);
1956 disp = (int16_t)cpu_lduw_code(env, s->pc);
2001 return (AddressParts){ def_seg, base, index, scale, disp };
2004 /* Compute the address, with a minimum number of TCG ops. */
2005 static TCGv gen_lea_modrm_1(AddressParts a)
2012 ea = cpu_regs[a.index];
2014 tcg_gen_shli_tl(cpu_A0, cpu_regs[a.index], a.scale);
2018 tcg_gen_add_tl(cpu_A0, ea, cpu_regs[a.base]);
2021 } else if (a.base >= 0) {
2022 ea = cpu_regs[a.base];
2024 if (TCGV_IS_UNUSED(ea)) {
2025 tcg_gen_movi_tl(cpu_A0, a.disp);
2027 } else if (a.disp != 0) {
2028 tcg_gen_addi_tl(cpu_A0, ea, a.disp);
2035 static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm)
2037 AddressParts a = gen_lea_modrm_0(env, s, modrm);
2038 TCGv ea = gen_lea_modrm_1(a);
2039 gen_lea_v_seg(s, s->aflag, ea, a.def_seg, s->override);
2042 static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm)
2044 (void)gen_lea_modrm_0(env, s, modrm);
2047 /* Used for BNDCL, BNDCU, BNDCN. */
2048 static void gen_bndck(CPUX86State *env, DisasContext *s, int modrm,
2049 TCGCond cond, TCGv_i64 bndv)
2051 TCGv ea = gen_lea_modrm_1(gen_lea_modrm_0(env, s, modrm));
2053 tcg_gen_extu_tl_i64(cpu_tmp1_i64, ea);
2055 tcg_gen_ext32u_i64(cpu_tmp1_i64, cpu_tmp1_i64);
2057 tcg_gen_setcond_i64(cond, cpu_tmp1_i64, cpu_tmp1_i64, bndv);
2058 tcg_gen_extrl_i64_i32(cpu_tmp2_i32, cpu_tmp1_i64);
2059 gen_helper_bndck(cpu_env, cpu_tmp2_i32);
2062 /* used for LEA and MOV AX, mem */
2063 static void gen_add_A0_ds_seg(DisasContext *s)
2065 gen_lea_v_seg(s, s->aflag, cpu_A0, R_DS, s->override);
2068 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2070 static void gen_ldst_modrm(CPUX86State *env, DisasContext *s, int modrm,
2071 TCGMemOp ot, int reg, int is_store)
2075 mod = (modrm >> 6) & 3;
2076 rm = (modrm & 7) | REX_B(s);
2080 gen_op_mov_v_reg(ot, cpu_T0, reg);
2081 gen_op_mov_reg_v(ot, rm, cpu_T0);
2083 gen_op_mov_v_reg(ot, cpu_T0, rm);
2085 gen_op_mov_reg_v(ot, reg, cpu_T0);
2088 gen_lea_modrm(env, s, modrm);
2091 gen_op_mov_v_reg(ot, cpu_T0, reg);
2092 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
2094 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
2096 gen_op_mov_reg_v(ot, reg, cpu_T0);
2101 static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, TCGMemOp ot)
2107 ret = cpu_ldub_code(env, s->pc);
2111 ret = cpu_lduw_code(env, s->pc);
2115 #ifdef TARGET_X86_64
2118 ret = cpu_ldl_code(env, s->pc);
2127 static inline int insn_const_size(TCGMemOp ot)
2136 static inline bool use_goto_tb(DisasContext *s, target_ulong pc)
2138 #ifndef CONFIG_USER_ONLY
2139 return (pc & TARGET_PAGE_MASK) == (s->tb->pc & TARGET_PAGE_MASK) ||
2140 (pc & TARGET_PAGE_MASK) == (s->pc_start & TARGET_PAGE_MASK);
2146 static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
2148 target_ulong pc = s->cs_base + eip;
2150 if (use_goto_tb(s, pc)) {
2151 /* jump to same page: we can use a direct jump */
2152 tcg_gen_goto_tb(tb_num);
2154 tcg_gen_exit_tb((uintptr_t)s->tb + tb_num);
2156 /* jump to another page: currently not optimized */
2162 static inline void gen_jcc(DisasContext *s, int b,
2163 target_ulong val, target_ulong next_eip)
2168 l1 = gen_new_label();
2171 gen_goto_tb(s, 0, next_eip);
2174 gen_goto_tb(s, 1, val);
2175 s->is_jmp = DISAS_TB_JUMP;
2177 l1 = gen_new_label();
2178 l2 = gen_new_label();
2181 gen_jmp_im(next_eip);
2191 static void gen_cmovcc1(CPUX86State *env, DisasContext *s, TCGMemOp ot, int b,
2196 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
2198 cc = gen_prepare_cc(s, b, cpu_T1);
2199 if (cc.mask != -1) {
2200 TCGv t0 = tcg_temp_new();
2201 tcg_gen_andi_tl(t0, cc.reg, cc.mask);
2205 cc.reg2 = tcg_const_tl(cc.imm);
2208 tcg_gen_movcond_tl(cc.cond, cpu_T0, cc.reg, cc.reg2,
2209 cpu_T0, cpu_regs[reg]);
2210 gen_op_mov_reg_v(ot, reg, cpu_T0);
2212 if (cc.mask != -1) {
2213 tcg_temp_free(cc.reg);
2216 tcg_temp_free(cc.reg2);
2220 static inline void gen_op_movl_T0_seg(int seg_reg)
2222 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
2223 offsetof(CPUX86State,segs[seg_reg].selector));
2226 static inline void gen_op_movl_seg_T0_vm(int seg_reg)
2228 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
2229 tcg_gen_st32_tl(cpu_T0, cpu_env,
2230 offsetof(CPUX86State,segs[seg_reg].selector));
2231 tcg_gen_shli_tl(cpu_seg_base[seg_reg], cpu_T0, 4);
2234 /* move T0 to seg_reg and compute if the CPU state may change. Never
2235 call this function with seg_reg == R_CS */
2236 static void gen_movl_seg_T0(DisasContext *s, int seg_reg)
2238 if (s->pe && !s->vm86) {
2239 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
2240 gen_helper_load_seg(cpu_env, tcg_const_i32(seg_reg), cpu_tmp2_i32);
2241 /* abort translation because the addseg value may change or
2242 because ss32 may change. For R_SS, translation must always
2243 stop as a special handling must be done to disable hardware
2244 interrupts for the next instruction */
2245 if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS))
2246 s->is_jmp = DISAS_TB_JUMP;
2248 gen_op_movl_seg_T0_vm(seg_reg);
2249 if (seg_reg == R_SS)
2250 s->is_jmp = DISAS_TB_JUMP;
2254 static inline int svm_is_rep(int prefixes)
2256 return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0);
2260 gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
2261 uint32_t type, uint64_t param)
2263 /* no SVM activated; fast case */
2264 if (likely(!(s->flags & HF_SVMI_MASK)))
2266 gen_update_cc_op(s);
2267 gen_jmp_im(pc_start - s->cs_base);
2268 gen_helper_svm_check_intercept_param(cpu_env, tcg_const_i32(type),
2269 tcg_const_i64(param));
2273 gen_svm_check_intercept(DisasContext *s, target_ulong pc_start, uint64_t type)
2275 gen_svm_check_intercept_param(s, pc_start, type, 0);
2278 static inline void gen_stack_update(DisasContext *s, int addend)
2280 gen_op_add_reg_im(mo_stacksize(s), R_ESP, addend);
2283 /* Generate a push. It depends on ss32, addseg and dflag. */
2284 static void gen_push_v(DisasContext *s, TCGv val)
2286 TCGMemOp d_ot = mo_pushpop(s, s->dflag);
2287 TCGMemOp a_ot = mo_stacksize(s);
2288 int size = 1 << d_ot;
2289 TCGv new_esp = cpu_A0;
2291 tcg_gen_subi_tl(cpu_A0, cpu_regs[R_ESP], size);
2296 tcg_gen_mov_tl(new_esp, cpu_A0);
2298 gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1);
2301 gen_op_st_v(s, d_ot, val, cpu_A0);
2302 gen_op_mov_reg_v(a_ot, R_ESP, new_esp);
2305 /* two step pop is necessary for precise exceptions */
2306 static TCGMemOp gen_pop_T0(DisasContext *s)
2308 TCGMemOp d_ot = mo_pushpop(s, s->dflag);
2310 gen_lea_v_seg(s, mo_stacksize(s), cpu_regs[R_ESP], R_SS, -1);
2311 gen_op_ld_v(s, d_ot, cpu_T0, cpu_A0);
2316 static inline void gen_pop_update(DisasContext *s, TCGMemOp ot)
2318 gen_stack_update(s, 1 << ot);
2321 static inline void gen_stack_A0(DisasContext *s)
2323 gen_lea_v_seg(s, s->ss32 ? MO_32 : MO_16, cpu_regs[R_ESP], R_SS, -1);
2326 static void gen_pusha(DisasContext *s)
2328 TCGMemOp s_ot = s->ss32 ? MO_32 : MO_16;
2329 TCGMemOp d_ot = s->dflag;
2330 int size = 1 << d_ot;
2333 for (i = 0; i < 8; i++) {
2334 tcg_gen_addi_tl(cpu_A0, cpu_regs[R_ESP], (i - 8) * size);
2335 gen_lea_v_seg(s, s_ot, cpu_A0, R_SS, -1);
2336 gen_op_st_v(s, d_ot, cpu_regs[7 - i], cpu_A0);
2339 gen_stack_update(s, -8 * size);
2342 static void gen_popa(DisasContext *s)
2344 TCGMemOp s_ot = s->ss32 ? MO_32 : MO_16;
2345 TCGMemOp d_ot = s->dflag;
2346 int size = 1 << d_ot;
2349 for (i = 0; i < 8; i++) {
2350 /* ESP is not reloaded */
2351 if (7 - i == R_ESP) {
2354 tcg_gen_addi_tl(cpu_A0, cpu_regs[R_ESP], i * size);
2355 gen_lea_v_seg(s, s_ot, cpu_A0, R_SS, -1);
2356 gen_op_ld_v(s, d_ot, cpu_T0, cpu_A0);
2357 gen_op_mov_reg_v(d_ot, 7 - i, cpu_T0);
2360 gen_stack_update(s, 8 * size);
2363 static void gen_enter(DisasContext *s, int esp_addend, int level)
2365 TCGMemOp d_ot = mo_pushpop(s, s->dflag);
2366 TCGMemOp a_ot = CODE64(s) ? MO_64 : s->ss32 ? MO_32 : MO_16;
2367 int size = 1 << d_ot;
2369 /* Push BP; compute FrameTemp into T1. */
2370 tcg_gen_subi_tl(cpu_T1, cpu_regs[R_ESP], size);
2371 gen_lea_v_seg(s, a_ot, cpu_T1, R_SS, -1);
2372 gen_op_st_v(s, d_ot, cpu_regs[R_EBP], cpu_A0);
2378 /* Copy level-1 pointers from the previous frame. */
2379 for (i = 1; i < level; ++i) {
2380 tcg_gen_subi_tl(cpu_A0, cpu_regs[R_EBP], size * i);
2381 gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1);
2382 gen_op_ld_v(s, d_ot, cpu_tmp0, cpu_A0);
2384 tcg_gen_subi_tl(cpu_A0, cpu_T1, size * i);
2385 gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1);
2386 gen_op_st_v(s, d_ot, cpu_tmp0, cpu_A0);
2389 /* Push the current FrameTemp as the last level. */
2390 tcg_gen_subi_tl(cpu_A0, cpu_T1, size * level);
2391 gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1);
2392 gen_op_st_v(s, d_ot, cpu_T1, cpu_A0);
2395 /* Copy the FrameTemp value to EBP. */
2396 gen_op_mov_reg_v(a_ot, R_EBP, cpu_T1);
2398 /* Compute the final value of ESP. */
2399 tcg_gen_subi_tl(cpu_T1, cpu_T1, esp_addend + size * level);
2400 gen_op_mov_reg_v(a_ot, R_ESP, cpu_T1);
2403 static void gen_leave(DisasContext *s)
2405 TCGMemOp d_ot = mo_pushpop(s, s->dflag);
2406 TCGMemOp a_ot = mo_stacksize(s);
2408 gen_lea_v_seg(s, a_ot, cpu_regs[R_EBP], R_SS, -1);
2409 gen_op_ld_v(s, d_ot, cpu_T0, cpu_A0);
2411 tcg_gen_addi_tl(cpu_T1, cpu_regs[R_EBP], 1 << d_ot);
2413 gen_op_mov_reg_v(d_ot, R_EBP, cpu_T0);
2414 gen_op_mov_reg_v(a_ot, R_ESP, cpu_T1);
2417 static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
2419 gen_update_cc_op(s);
2420 gen_jmp_im(cur_eip);
2421 gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno));
2422 s->is_jmp = DISAS_TB_JUMP;
2425 /* Generate #UD for the current instruction. The assumption here is that
2426 the instruction is known, but it isn't allowed in the current cpu mode. */
2427 static void gen_illegal_opcode(DisasContext *s)
2429 gen_exception(s, EXCP06_ILLOP, s->pc_start - s->cs_base);
2432 /* Similarly, except that the assumption here is that we don't decode
2433 the instruction at all -- either a missing opcode, an unimplemented
2434 feature, or just a bogus instruction stream. */
2435 static void gen_unknown_opcode(CPUX86State *env, DisasContext *s)
2437 gen_illegal_opcode(s);
2439 if (qemu_loglevel_mask(LOG_UNIMP)) {
2440 target_ulong pc = s->pc_start, end = s->pc;
2442 qemu_log("ILLOPC: " TARGET_FMT_lx ":", pc);
2443 for (; pc < end; ++pc) {
2444 qemu_log(" %02x", cpu_ldub_code(env, pc));
2451 /* an interrupt is different from an exception because of the
2453 static void gen_interrupt(DisasContext *s, int intno,
2454 target_ulong cur_eip, target_ulong next_eip)
2456 gen_update_cc_op(s);
2457 gen_jmp_im(cur_eip);
2458 gen_helper_raise_interrupt(cpu_env, tcg_const_i32(intno),
2459 tcg_const_i32(next_eip - cur_eip));
2460 s->is_jmp = DISAS_TB_JUMP;
2463 static void gen_debug(DisasContext *s, target_ulong cur_eip)
2465 gen_update_cc_op(s);
2466 gen_jmp_im(cur_eip);
2467 gen_helper_debug(cpu_env);
2468 s->is_jmp = DISAS_TB_JUMP;
2471 static void gen_set_hflag(DisasContext *s, uint32_t mask)
2473 if ((s->flags & mask) == 0) {
2474 TCGv_i32 t = tcg_temp_new_i32();
2475 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2476 tcg_gen_ori_i32(t, t, mask);
2477 tcg_gen_st_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2478 tcg_temp_free_i32(t);
2483 static void gen_reset_hflag(DisasContext *s, uint32_t mask)
2485 if (s->flags & mask) {
2486 TCGv_i32 t = tcg_temp_new_i32();
2487 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2488 tcg_gen_andi_i32(t, t, ~mask);
2489 tcg_gen_st_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2490 tcg_temp_free_i32(t);
2495 /* Clear BND registers during legacy branches. */
2496 static void gen_bnd_jmp(DisasContext *s)
2498 /* Clear the registers only if BND prefix is missing, MPX is enabled,
2499 and if the BNDREGs are known to be in use (non-zero) already.
2500 The helper itself will check BNDPRESERVE at runtime. */
2501 if ((s->prefix & PREFIX_REPNZ) == 0
2502 && (s->flags & HF_MPX_EN_MASK) != 0
2503 && (s->flags & HF_MPX_IU_MASK) != 0) {
2504 gen_helper_bnd_jmp(cpu_env);
2508 /* Generate an end of block. Trace exception is also generated if needed.
2509 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set.
2510 If RECHECK_TF, emit a rechecking helper for #DB, ignoring the state of
2511 S->TF. This is used by the syscall/sysret insns. */
2512 static void gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf)
2514 gen_update_cc_op(s);
2516 /* If several instructions disable interrupts, only the first does it. */
2517 if (inhibit && !(s->flags & HF_INHIBIT_IRQ_MASK)) {
2518 gen_set_hflag(s, HF_INHIBIT_IRQ_MASK);
2520 gen_reset_hflag(s, HF_INHIBIT_IRQ_MASK);
2523 if (s->tb->flags & HF_RF_MASK) {
2524 gen_helper_reset_rf(cpu_env);
2526 if (s->singlestep_enabled) {
2527 gen_helper_debug(cpu_env);
2528 } else if (recheck_tf) {
2529 gen_helper_rechecking_single_step(cpu_env);
2532 gen_helper_single_step(cpu_env);
2536 s->is_jmp = DISAS_TB_JUMP;
2540 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set. */
2541 static void gen_eob_inhibit_irq(DisasContext *s, bool inhibit)
2543 gen_eob_worker(s, inhibit, false);
2546 /* End of block, resetting the inhibit irq flag. */
2547 static void gen_eob(DisasContext *s)
2549 gen_eob_worker(s, false, false);
2552 /* generate a jump to eip. No segment change must happen before as a
2553 direct call to the next block may occur */
2554 static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
2556 gen_update_cc_op(s);
2557 set_cc_op(s, CC_OP_DYNAMIC);
2559 gen_goto_tb(s, tb_num, eip);
2560 s->is_jmp = DISAS_TB_JUMP;
2567 static void gen_jmp(DisasContext *s, target_ulong eip)
2569 gen_jmp_tb(s, eip, 0);
2572 static inline void gen_ldq_env_A0(DisasContext *s, int offset)
2574 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
2575 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset);
2578 static inline void gen_stq_env_A0(DisasContext *s, int offset)
2580 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset);
2581 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
2584 static inline void gen_ldo_env_A0(DisasContext *s, int offset)
2586 int mem_index = s->mem_index;
2587 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, mem_index, MO_LEQ);
2588 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(0)));
2589 tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2590 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_tmp0, mem_index, MO_LEQ);
2591 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(1)));
2594 static inline void gen_sto_env_A0(DisasContext *s, int offset)
2596 int mem_index = s->mem_index;
2597 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(0)));
2598 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, mem_index, MO_LEQ);
2599 tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2600 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(1)));
2601 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_tmp0, mem_index, MO_LEQ);
2604 static inline void gen_op_movo(int d_offset, int s_offset)
2606 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + offsetof(ZMMReg, ZMM_Q(0)));
2607 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + offsetof(ZMMReg, ZMM_Q(0)));
2608 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + offsetof(ZMMReg, ZMM_Q(1)));
2609 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + offsetof(ZMMReg, ZMM_Q(1)));
2612 static inline void gen_op_movq(int d_offset, int s_offset)
2614 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
2615 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2618 static inline void gen_op_movl(int d_offset, int s_offset)
2620 tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env, s_offset);
2621 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, d_offset);
2624 static inline void gen_op_movq_env_0(int d_offset)
2626 tcg_gen_movi_i64(cpu_tmp1_i64, 0);
2627 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2630 typedef void (*SSEFunc_i_ep)(TCGv_i32 val, TCGv_ptr env, TCGv_ptr reg);
2631 typedef void (*SSEFunc_l_ep)(TCGv_i64 val, TCGv_ptr env, TCGv_ptr reg);
2632 typedef void (*SSEFunc_0_epi)(TCGv_ptr env, TCGv_ptr reg, TCGv_i32 val);
2633 typedef void (*SSEFunc_0_epl)(TCGv_ptr env, TCGv_ptr reg, TCGv_i64 val);
2634 typedef void (*SSEFunc_0_epp)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b);
2635 typedef void (*SSEFunc_0_eppi)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2637 typedef void (*SSEFunc_0_ppi)(TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv_i32 val);
2638 typedef void (*SSEFunc_0_eppt)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2641 #define SSE_SPECIAL ((void *)1)
2642 #define SSE_DUMMY ((void *)2)
2644 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2645 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2646 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2648 static const SSEFunc_0_epp sse_op_table1[256][4] = {
2649 /* 3DNow! extensions */
2650 [0x0e] = { SSE_DUMMY }, /* femms */
2651 [0x0f] = { SSE_DUMMY }, /* pf... */
2652 /* pure SSE operations */
2653 [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2654 [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2655 [0x12] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd, movsldup, movddup */
2656 [0x13] = { SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd */
2657 [0x14] = { gen_helper_punpckldq_xmm, gen_helper_punpcklqdq_xmm },
2658 [0x15] = { gen_helper_punpckhdq_xmm, gen_helper_punpckhqdq_xmm },
2659 [0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movhps, movhpd, movshdup */
2660 [0x17] = { SSE_SPECIAL, SSE_SPECIAL }, /* movhps, movhpd */
2662 [0x28] = { SSE_SPECIAL, SSE_SPECIAL }, /* movaps, movapd */
2663 [0x29] = { SSE_SPECIAL, SSE_SPECIAL }, /* movaps, movapd */
2664 [0x2a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2665 [0x2b] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movntps, movntpd, movntss, movntsd */
2666 [0x2c] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2667 [0x2d] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2668 [0x2e] = { gen_helper_ucomiss, gen_helper_ucomisd },
2669 [0x2f] = { gen_helper_comiss, gen_helper_comisd },
2670 [0x50] = { SSE_SPECIAL, SSE_SPECIAL }, /* movmskps, movmskpd */
2671 [0x51] = SSE_FOP(sqrt),
2672 [0x52] = { gen_helper_rsqrtps, NULL, gen_helper_rsqrtss, NULL },
2673 [0x53] = { gen_helper_rcpps, NULL, gen_helper_rcpss, NULL },
2674 [0x54] = { gen_helper_pand_xmm, gen_helper_pand_xmm }, /* andps, andpd */
2675 [0x55] = { gen_helper_pandn_xmm, gen_helper_pandn_xmm }, /* andnps, andnpd */
2676 [0x56] = { gen_helper_por_xmm, gen_helper_por_xmm }, /* orps, orpd */
2677 [0x57] = { gen_helper_pxor_xmm, gen_helper_pxor_xmm }, /* xorps, xorpd */
2678 [0x58] = SSE_FOP(add),
2679 [0x59] = SSE_FOP(mul),
2680 [0x5a] = { gen_helper_cvtps2pd, gen_helper_cvtpd2ps,
2681 gen_helper_cvtss2sd, gen_helper_cvtsd2ss },
2682 [0x5b] = { gen_helper_cvtdq2ps, gen_helper_cvtps2dq, gen_helper_cvttps2dq },
2683 [0x5c] = SSE_FOP(sub),
2684 [0x5d] = SSE_FOP(min),
2685 [0x5e] = SSE_FOP(div),
2686 [0x5f] = SSE_FOP(max),
2688 [0xc2] = SSE_FOP(cmpeq),
2689 [0xc6] = { (SSEFunc_0_epp)gen_helper_shufps,
2690 (SSEFunc_0_epp)gen_helper_shufpd }, /* XXX: casts */
2692 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */
2693 [0x38] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2694 [0x3a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2696 /* MMX ops and their SSE extensions */
2697 [0x60] = MMX_OP2(punpcklbw),
2698 [0x61] = MMX_OP2(punpcklwd),
2699 [0x62] = MMX_OP2(punpckldq),
2700 [0x63] = MMX_OP2(packsswb),
2701 [0x64] = MMX_OP2(pcmpgtb),
2702 [0x65] = MMX_OP2(pcmpgtw),
2703 [0x66] = MMX_OP2(pcmpgtl),
2704 [0x67] = MMX_OP2(packuswb),
2705 [0x68] = MMX_OP2(punpckhbw),
2706 [0x69] = MMX_OP2(punpckhwd),
2707 [0x6a] = MMX_OP2(punpckhdq),
2708 [0x6b] = MMX_OP2(packssdw),
2709 [0x6c] = { NULL, gen_helper_punpcklqdq_xmm },
2710 [0x6d] = { NULL, gen_helper_punpckhqdq_xmm },
2711 [0x6e] = { SSE_SPECIAL, SSE_SPECIAL }, /* movd mm, ea */
2712 [0x6f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, , movqdu */
2713 [0x70] = { (SSEFunc_0_epp)gen_helper_pshufw_mmx,
2714 (SSEFunc_0_epp)gen_helper_pshufd_xmm,
2715 (SSEFunc_0_epp)gen_helper_pshufhw_xmm,
2716 (SSEFunc_0_epp)gen_helper_pshuflw_xmm }, /* XXX: casts */
2717 [0x71] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftw */
2718 [0x72] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftd */
2719 [0x73] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftq */
2720 [0x74] = MMX_OP2(pcmpeqb),
2721 [0x75] = MMX_OP2(pcmpeqw),
2722 [0x76] = MMX_OP2(pcmpeql),
2723 [0x77] = { SSE_DUMMY }, /* emms */
2724 [0x78] = { NULL, SSE_SPECIAL, NULL, SSE_SPECIAL }, /* extrq_i, insertq_i */
2725 [0x79] = { NULL, gen_helper_extrq_r, NULL, gen_helper_insertq_r },
2726 [0x7c] = { NULL, gen_helper_haddpd, NULL, gen_helper_haddps },
2727 [0x7d] = { NULL, gen_helper_hsubpd, NULL, gen_helper_hsubps },
2728 [0x7e] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movd, movd, , movq */
2729 [0x7f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, movdqu */
2730 [0xc4] = { SSE_SPECIAL, SSE_SPECIAL }, /* pinsrw */
2731 [0xc5] = { SSE_SPECIAL, SSE_SPECIAL }, /* pextrw */
2732 [0xd0] = { NULL, gen_helper_addsubpd, NULL, gen_helper_addsubps },
2733 [0xd1] = MMX_OP2(psrlw),
2734 [0xd2] = MMX_OP2(psrld),
2735 [0xd3] = MMX_OP2(psrlq),
2736 [0xd4] = MMX_OP2(paddq),
2737 [0xd5] = MMX_OP2(pmullw),
2738 [0xd6] = { NULL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2739 [0xd7] = { SSE_SPECIAL, SSE_SPECIAL }, /* pmovmskb */
2740 [0xd8] = MMX_OP2(psubusb),
2741 [0xd9] = MMX_OP2(psubusw),
2742 [0xda] = MMX_OP2(pminub),
2743 [0xdb] = MMX_OP2(pand),
2744 [0xdc] = MMX_OP2(paddusb),
2745 [0xdd] = MMX_OP2(paddusw),
2746 [0xde] = MMX_OP2(pmaxub),
2747 [0xdf] = MMX_OP2(pandn),
2748 [0xe0] = MMX_OP2(pavgb),
2749 [0xe1] = MMX_OP2(psraw),
2750 [0xe2] = MMX_OP2(psrad),
2751 [0xe3] = MMX_OP2(pavgw),
2752 [0xe4] = MMX_OP2(pmulhuw),
2753 [0xe5] = MMX_OP2(pmulhw),
2754 [0xe6] = { NULL, gen_helper_cvttpd2dq, gen_helper_cvtdq2pd, gen_helper_cvtpd2dq },
2755 [0xe7] = { SSE_SPECIAL , SSE_SPECIAL }, /* movntq, movntq */
2756 [0xe8] = MMX_OP2(psubsb),
2757 [0xe9] = MMX_OP2(psubsw),
2758 [0xea] = MMX_OP2(pminsw),
2759 [0xeb] = MMX_OP2(por),
2760 [0xec] = MMX_OP2(paddsb),
2761 [0xed] = MMX_OP2(paddsw),
2762 [0xee] = MMX_OP2(pmaxsw),
2763 [0xef] = MMX_OP2(pxor),
2764 [0xf0] = { NULL, NULL, NULL, SSE_SPECIAL }, /* lddqu */
2765 [0xf1] = MMX_OP2(psllw),
2766 [0xf2] = MMX_OP2(pslld),
2767 [0xf3] = MMX_OP2(psllq),
2768 [0xf4] = MMX_OP2(pmuludq),
2769 [0xf5] = MMX_OP2(pmaddwd),
2770 [0xf6] = MMX_OP2(psadbw),
2771 [0xf7] = { (SSEFunc_0_epp)gen_helper_maskmov_mmx,
2772 (SSEFunc_0_epp)gen_helper_maskmov_xmm }, /* XXX: casts */
2773 [0xf8] = MMX_OP2(psubb),
2774 [0xf9] = MMX_OP2(psubw),
2775 [0xfa] = MMX_OP2(psubl),
2776 [0xfb] = MMX_OP2(psubq),
2777 [0xfc] = MMX_OP2(paddb),
2778 [0xfd] = MMX_OP2(paddw),
2779 [0xfe] = MMX_OP2(paddl),
2782 static const SSEFunc_0_epp sse_op_table2[3 * 8][2] = {
2783 [0 + 2] = MMX_OP2(psrlw),
2784 [0 + 4] = MMX_OP2(psraw),
2785 [0 + 6] = MMX_OP2(psllw),
2786 [8 + 2] = MMX_OP2(psrld),
2787 [8 + 4] = MMX_OP2(psrad),
2788 [8 + 6] = MMX_OP2(pslld),
2789 [16 + 2] = MMX_OP2(psrlq),
2790 [16 + 3] = { NULL, gen_helper_psrldq_xmm },
2791 [16 + 6] = MMX_OP2(psllq),
2792 [16 + 7] = { NULL, gen_helper_pslldq_xmm },
2795 static const SSEFunc_0_epi sse_op_table3ai[] = {
2796 gen_helper_cvtsi2ss,
2800 #ifdef TARGET_X86_64
2801 static const SSEFunc_0_epl sse_op_table3aq[] = {
2802 gen_helper_cvtsq2ss,
2807 static const SSEFunc_i_ep sse_op_table3bi[] = {
2808 gen_helper_cvttss2si,
2809 gen_helper_cvtss2si,
2810 gen_helper_cvttsd2si,
2814 #ifdef TARGET_X86_64
2815 static const SSEFunc_l_ep sse_op_table3bq[] = {
2816 gen_helper_cvttss2sq,
2817 gen_helper_cvtss2sq,
2818 gen_helper_cvttsd2sq,
2823 static const SSEFunc_0_epp sse_op_table4[8][4] = {
2834 static const SSEFunc_0_epp sse_op_table5[256] = {
2835 [0x0c] = gen_helper_pi2fw,
2836 [0x0d] = gen_helper_pi2fd,
2837 [0x1c] = gen_helper_pf2iw,
2838 [0x1d] = gen_helper_pf2id,
2839 [0x8a] = gen_helper_pfnacc,
2840 [0x8e] = gen_helper_pfpnacc,
2841 [0x90] = gen_helper_pfcmpge,
2842 [0x94] = gen_helper_pfmin,
2843 [0x96] = gen_helper_pfrcp,
2844 [0x97] = gen_helper_pfrsqrt,
2845 [0x9a] = gen_helper_pfsub,
2846 [0x9e] = gen_helper_pfadd,
2847 [0xa0] = gen_helper_pfcmpgt,
2848 [0xa4] = gen_helper_pfmax,
2849 [0xa6] = gen_helper_movq, /* pfrcpit1; no need to actually increase precision */
2850 [0xa7] = gen_helper_movq, /* pfrsqit1 */
2851 [0xaa] = gen_helper_pfsubr,
2852 [0xae] = gen_helper_pfacc,
2853 [0xb0] = gen_helper_pfcmpeq,
2854 [0xb4] = gen_helper_pfmul,
2855 [0xb6] = gen_helper_movq, /* pfrcpit2 */
2856 [0xb7] = gen_helper_pmulhrw_mmx,
2857 [0xbb] = gen_helper_pswapd,
2858 [0xbf] = gen_helper_pavgb_mmx /* pavgusb */
2861 struct SSEOpHelper_epp {
2862 SSEFunc_0_epp op[2];
2866 struct SSEOpHelper_eppi {
2867 SSEFunc_0_eppi op[2];
2871 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
2872 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
2873 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
2874 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
2875 #define PCLMULQDQ_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, \
2876 CPUID_EXT_PCLMULQDQ }
2877 #define AESNI_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_AES }
2879 static const struct SSEOpHelper_epp sse_op_table6[256] = {
2880 [0x00] = SSSE3_OP(pshufb),
2881 [0x01] = SSSE3_OP(phaddw),
2882 [0x02] = SSSE3_OP(phaddd),
2883 [0x03] = SSSE3_OP(phaddsw),
2884 [0x04] = SSSE3_OP(pmaddubsw),
2885 [0x05] = SSSE3_OP(phsubw),
2886 [0x06] = SSSE3_OP(phsubd),
2887 [0x07] = SSSE3_OP(phsubsw),
2888 [0x08] = SSSE3_OP(psignb),
2889 [0x09] = SSSE3_OP(psignw),
2890 [0x0a] = SSSE3_OP(psignd),
2891 [0x0b] = SSSE3_OP(pmulhrsw),
2892 [0x10] = SSE41_OP(pblendvb),
2893 [0x14] = SSE41_OP(blendvps),
2894 [0x15] = SSE41_OP(blendvpd),
2895 [0x17] = SSE41_OP(ptest),
2896 [0x1c] = SSSE3_OP(pabsb),
2897 [0x1d] = SSSE3_OP(pabsw),
2898 [0x1e] = SSSE3_OP(pabsd),
2899 [0x20] = SSE41_OP(pmovsxbw),
2900 [0x21] = SSE41_OP(pmovsxbd),
2901 [0x22] = SSE41_OP(pmovsxbq),
2902 [0x23] = SSE41_OP(pmovsxwd),
2903 [0x24] = SSE41_OP(pmovsxwq),
2904 [0x25] = SSE41_OP(pmovsxdq),
2905 [0x28] = SSE41_OP(pmuldq),
2906 [0x29] = SSE41_OP(pcmpeqq),
2907 [0x2a] = SSE41_SPECIAL, /* movntqda */
2908 [0x2b] = SSE41_OP(packusdw),
2909 [0x30] = SSE41_OP(pmovzxbw),
2910 [0x31] = SSE41_OP(pmovzxbd),
2911 [0x32] = SSE41_OP(pmovzxbq),
2912 [0x33] = SSE41_OP(pmovzxwd),
2913 [0x34] = SSE41_OP(pmovzxwq),
2914 [0x35] = SSE41_OP(pmovzxdq),
2915 [0x37] = SSE42_OP(pcmpgtq),
2916 [0x38] = SSE41_OP(pminsb),
2917 [0x39] = SSE41_OP(pminsd),
2918 [0x3a] = SSE41_OP(pminuw),
2919 [0x3b] = SSE41_OP(pminud),
2920 [0x3c] = SSE41_OP(pmaxsb),
2921 [0x3d] = SSE41_OP(pmaxsd),
2922 [0x3e] = SSE41_OP(pmaxuw),
2923 [0x3f] = SSE41_OP(pmaxud),
2924 [0x40] = SSE41_OP(pmulld),
2925 [0x41] = SSE41_OP(phminposuw),
2926 [0xdb] = AESNI_OP(aesimc),
2927 [0xdc] = AESNI_OP(aesenc),
2928 [0xdd] = AESNI_OP(aesenclast),
2929 [0xde] = AESNI_OP(aesdec),
2930 [0xdf] = AESNI_OP(aesdeclast),
2933 static const struct SSEOpHelper_eppi sse_op_table7[256] = {
2934 [0x08] = SSE41_OP(roundps),
2935 [0x09] = SSE41_OP(roundpd),
2936 [0x0a] = SSE41_OP(roundss),
2937 [0x0b] = SSE41_OP(roundsd),
2938 [0x0c] = SSE41_OP(blendps),
2939 [0x0d] = SSE41_OP(blendpd),
2940 [0x0e] = SSE41_OP(pblendw),
2941 [0x0f] = SSSE3_OP(palignr),
2942 [0x14] = SSE41_SPECIAL, /* pextrb */
2943 [0x15] = SSE41_SPECIAL, /* pextrw */
2944 [0x16] = SSE41_SPECIAL, /* pextrd/pextrq */
2945 [0x17] = SSE41_SPECIAL, /* extractps */
2946 [0x20] = SSE41_SPECIAL, /* pinsrb */
2947 [0x21] = SSE41_SPECIAL, /* insertps */
2948 [0x22] = SSE41_SPECIAL, /* pinsrd/pinsrq */
2949 [0x40] = SSE41_OP(dpps),
2950 [0x41] = SSE41_OP(dppd),
2951 [0x42] = SSE41_OP(mpsadbw),
2952 [0x44] = PCLMULQDQ_OP(pclmulqdq),
2953 [0x60] = SSE42_OP(pcmpestrm),
2954 [0x61] = SSE42_OP(pcmpestri),
2955 [0x62] = SSE42_OP(pcmpistrm),
2956 [0x63] = SSE42_OP(pcmpistri),
2957 [0xdf] = AESNI_OP(aeskeygenassist),
2960 static void gen_sse(CPUX86State *env, DisasContext *s, int b,
2961 target_ulong pc_start, int rex_r)
2963 int b1, op1_offset, op2_offset, is_xmm, val;
2964 int modrm, mod, rm, reg;
2965 SSEFunc_0_epp sse_fn_epp;
2966 SSEFunc_0_eppi sse_fn_eppi;
2967 SSEFunc_0_ppi sse_fn_ppi;
2968 SSEFunc_0_eppt sse_fn_eppt;
2972 if (s->prefix & PREFIX_DATA)
2974 else if (s->prefix & PREFIX_REPZ)
2976 else if (s->prefix & PREFIX_REPNZ)
2980 sse_fn_epp = sse_op_table1[b][b1];
2984 if ((b <= 0x5f && b >= 0x10) || b == 0xc6 || b == 0xc2) {
2994 /* simple MMX/SSE operation */
2995 if (s->flags & HF_TS_MASK) {
2996 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
2999 if (s->flags & HF_EM_MASK) {
3001 gen_illegal_opcode(s);
3005 && !(s->flags & HF_OSFXSR_MASK)
3006 && ((b != 0x38 && b != 0x3a) || (s->prefix & PREFIX_DATA))) {
3010 if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) {
3011 /* If we were fully decoding this we might use illegal_op. */
3015 gen_helper_emms(cpu_env);
3020 gen_helper_emms(cpu_env);
3023 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3024 the static cpu state) */
3026 gen_helper_enter_mmx(cpu_env);
3029 modrm = cpu_ldub_code(env, s->pc++);
3030 reg = ((modrm >> 3) & 7);
3033 mod = (modrm >> 6) & 3;
3034 if (sse_fn_epp == SSE_SPECIAL) {
3037 case 0x0e7: /* movntq */
3041 gen_lea_modrm(env, s, modrm);
3042 gen_stq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
3044 case 0x1e7: /* movntdq */
3045 case 0x02b: /* movntps */
3046 case 0x12b: /* movntps */
3049 gen_lea_modrm(env, s, modrm);
3050 gen_sto_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3052 case 0x3f0: /* lddqu */
3055 gen_lea_modrm(env, s, modrm);
3056 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3058 case 0x22b: /* movntss */
3059 case 0x32b: /* movntsd */
3062 gen_lea_modrm(env, s, modrm);
3064 gen_stq_env_A0(s, offsetof(CPUX86State,
3065 xmm_regs[reg].ZMM_Q(0)));
3067 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
3068 xmm_regs[reg].ZMM_L(0)));
3069 gen_op_st_v(s, MO_32, cpu_T0, cpu_A0);
3072 case 0x6e: /* movd mm, ea */
3073 #ifdef TARGET_X86_64
3074 if (s->dflag == MO_64) {
3075 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 0);
3076 tcg_gen_st_tl(cpu_T0, cpu_env, offsetof(CPUX86State,fpregs[reg].mmx));
3080 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 0);
3081 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3082 offsetof(CPUX86State,fpregs[reg].mmx));
3083 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
3084 gen_helper_movl_mm_T0_mmx(cpu_ptr0, cpu_tmp2_i32);
3087 case 0x16e: /* movd xmm, ea */
3088 #ifdef TARGET_X86_64
3089 if (s->dflag == MO_64) {
3090 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 0);
3091 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3092 offsetof(CPUX86State,xmm_regs[reg]));
3093 gen_helper_movq_mm_T0_xmm(cpu_ptr0, cpu_T0);
3097 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 0);
3098 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3099 offsetof(CPUX86State,xmm_regs[reg]));
3100 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
3101 gen_helper_movl_mm_T0_xmm(cpu_ptr0, cpu_tmp2_i32);
3104 case 0x6f: /* movq mm, ea */
3106 gen_lea_modrm(env, s, modrm);
3107 gen_ldq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
3110 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
3111 offsetof(CPUX86State,fpregs[rm].mmx));
3112 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
3113 offsetof(CPUX86State,fpregs[reg].mmx));
3116 case 0x010: /* movups */
3117 case 0x110: /* movupd */
3118 case 0x028: /* movaps */
3119 case 0x128: /* movapd */
3120 case 0x16f: /* movdqa xmm, ea */
3121 case 0x26f: /* movdqu xmm, ea */
3123 gen_lea_modrm(env, s, modrm);
3124 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3126 rm = (modrm & 7) | REX_B(s);
3127 gen_op_movo(offsetof(CPUX86State,xmm_regs[reg]),
3128 offsetof(CPUX86State,xmm_regs[rm]));
3131 case 0x210: /* movss xmm, ea */
3133 gen_lea_modrm(env, s, modrm);
3134 gen_op_ld_v(s, MO_32, cpu_T0, cpu_A0);
3135 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3136 tcg_gen_movi_tl(cpu_T0, 0);
3137 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)));
3138 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)));
3139 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)));
3141 rm = (modrm & 7) | REX_B(s);
3142 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)),
3143 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0)));
3146 case 0x310: /* movsd xmm, ea */
3148 gen_lea_modrm(env, s, modrm);
3149 gen_ldq_env_A0(s, offsetof(CPUX86State,
3150 xmm_regs[reg].ZMM_Q(0)));
3151 tcg_gen_movi_tl(cpu_T0, 0);
3152 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)));
3153 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)));
3155 rm = (modrm & 7) | REX_B(s);
3156 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3157 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3160 case 0x012: /* movlps */
3161 case 0x112: /* movlpd */
3163 gen_lea_modrm(env, s, modrm);
3164 gen_ldq_env_A0(s, offsetof(CPUX86State,
3165 xmm_regs[reg].ZMM_Q(0)));
3168 rm = (modrm & 7) | REX_B(s);
3169 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3170 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(1)));
3173 case 0x212: /* movsldup */
3175 gen_lea_modrm(env, s, modrm);
3176 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3178 rm = (modrm & 7) | REX_B(s);
3179 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)),
3180 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0)));
3181 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)),
3182 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(2)));
3184 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)),
3185 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3186 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)),
3187 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)));
3189 case 0x312: /* movddup */
3191 gen_lea_modrm(env, s, modrm);
3192 gen_ldq_env_A0(s, offsetof(CPUX86State,
3193 xmm_regs[reg].ZMM_Q(0)));
3195 rm = (modrm & 7) | REX_B(s);
3196 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3197 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3199 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)),
3200 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3202 case 0x016: /* movhps */
3203 case 0x116: /* movhpd */
3205 gen_lea_modrm(env, s, modrm);
3206 gen_ldq_env_A0(s, offsetof(CPUX86State,
3207 xmm_regs[reg].ZMM_Q(1)));
3210 rm = (modrm & 7) | REX_B(s);
3211 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)),
3212 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3215 case 0x216: /* movshdup */
3217 gen_lea_modrm(env, s, modrm);
3218 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3220 rm = (modrm & 7) | REX_B(s);
3221 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)),
3222 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(1)));
3223 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)),
3224 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(3)));
3226 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)),
3227 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)));
3228 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)),
3229 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)));
3234 int bit_index, field_length;
3236 if (b1 == 1 && reg != 0)
3238 field_length = cpu_ldub_code(env, s->pc++) & 0x3F;
3239 bit_index = cpu_ldub_code(env, s->pc++) & 0x3F;
3240 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3241 offsetof(CPUX86State,xmm_regs[reg]));
3243 gen_helper_extrq_i(cpu_env, cpu_ptr0,
3244 tcg_const_i32(bit_index),
3245 tcg_const_i32(field_length));
3247 gen_helper_insertq_i(cpu_env, cpu_ptr0,
3248 tcg_const_i32(bit_index),
3249 tcg_const_i32(field_length));
3252 case 0x7e: /* movd ea, mm */
3253 #ifdef TARGET_X86_64
3254 if (s->dflag == MO_64) {
3255 tcg_gen_ld_i64(cpu_T0, cpu_env,
3256 offsetof(CPUX86State,fpregs[reg].mmx));
3257 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 1);
3261 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
3262 offsetof(CPUX86State,fpregs[reg].mmx.MMX_L(0)));
3263 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 1);
3266 case 0x17e: /* movd ea, xmm */
3267 #ifdef TARGET_X86_64
3268 if (s->dflag == MO_64) {
3269 tcg_gen_ld_i64(cpu_T0, cpu_env,
3270 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3271 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 1);
3275 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
3276 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3277 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 1);
3280 case 0x27e: /* movq xmm, ea */
3282 gen_lea_modrm(env, s, modrm);
3283 gen_ldq_env_A0(s, offsetof(CPUX86State,
3284 xmm_regs[reg].ZMM_Q(0)));
3286 rm = (modrm & 7) | REX_B(s);
3287 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3288 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3290 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)));
3292 case 0x7f: /* movq ea, mm */
3294 gen_lea_modrm(env, s, modrm);
3295 gen_stq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
3298 gen_op_movq(offsetof(CPUX86State,fpregs[rm].mmx),
3299 offsetof(CPUX86State,fpregs[reg].mmx));
3302 case 0x011: /* movups */
3303 case 0x111: /* movupd */
3304 case 0x029: /* movaps */
3305 case 0x129: /* movapd */
3306 case 0x17f: /* movdqa ea, xmm */
3307 case 0x27f: /* movdqu ea, xmm */
3309 gen_lea_modrm(env, s, modrm);
3310 gen_sto_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3312 rm = (modrm & 7) | REX_B(s);
3313 gen_op_movo(offsetof(CPUX86State,xmm_regs[rm]),
3314 offsetof(CPUX86State,xmm_regs[reg]));
3317 case 0x211: /* movss ea, xmm */
3319 gen_lea_modrm(env, s, modrm);
3320 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3321 gen_op_st_v(s, MO_32, cpu_T0, cpu_A0);
3323 rm = (modrm & 7) | REX_B(s);
3324 gen_op_movl(offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0)),
3325 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3328 case 0x311: /* movsd ea, xmm */
3330 gen_lea_modrm(env, s, modrm);
3331 gen_stq_env_A0(s, offsetof(CPUX86State,
3332 xmm_regs[reg].ZMM_Q(0)));
3334 rm = (modrm & 7) | REX_B(s);
3335 gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)),
3336 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3339 case 0x013: /* movlps */
3340 case 0x113: /* movlpd */
3342 gen_lea_modrm(env, s, modrm);
3343 gen_stq_env_A0(s, offsetof(CPUX86State,
3344 xmm_regs[reg].ZMM_Q(0)));
3349 case 0x017: /* movhps */
3350 case 0x117: /* movhpd */
3352 gen_lea_modrm(env, s, modrm);
3353 gen_stq_env_A0(s, offsetof(CPUX86State,
3354 xmm_regs[reg].ZMM_Q(1)));
3359 case 0x71: /* shift mm, im */
3362 case 0x171: /* shift xmm, im */
3368 val = cpu_ldub_code(env, s->pc++);
3370 tcg_gen_movi_tl(cpu_T0, val);
3371 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(0)));
3372 tcg_gen_movi_tl(cpu_T0, 0);
3373 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(1)));
3374 op1_offset = offsetof(CPUX86State,xmm_t0);
3376 tcg_gen_movi_tl(cpu_T0, val);
3377 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(0)));
3378 tcg_gen_movi_tl(cpu_T0, 0);
3379 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(1)));
3380 op1_offset = offsetof(CPUX86State,mmx_t0);
3382 sse_fn_epp = sse_op_table2[((b - 1) & 3) * 8 +
3383 (((modrm >> 3)) & 7)][b1];
3388 rm = (modrm & 7) | REX_B(s);
3389 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3392 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3394 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
3395 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op1_offset);
3396 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
3398 case 0x050: /* movmskps */
3399 rm = (modrm & 7) | REX_B(s);
3400 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3401 offsetof(CPUX86State,xmm_regs[rm]));
3402 gen_helper_movmskps(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3403 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
3405 case 0x150: /* movmskpd */
3406 rm = (modrm & 7) | REX_B(s);
3407 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3408 offsetof(CPUX86State,xmm_regs[rm]));
3409 gen_helper_movmskpd(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3410 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
3412 case 0x02a: /* cvtpi2ps */
3413 case 0x12a: /* cvtpi2pd */
3414 gen_helper_enter_mmx(cpu_env);
3416 gen_lea_modrm(env, s, modrm);
3417 op2_offset = offsetof(CPUX86State,mmx_t0);
3418 gen_ldq_env_A0(s, op2_offset);
3421 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3423 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3424 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3425 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3428 gen_helper_cvtpi2ps(cpu_env, cpu_ptr0, cpu_ptr1);
3432 gen_helper_cvtpi2pd(cpu_env, cpu_ptr0, cpu_ptr1);
3436 case 0x22a: /* cvtsi2ss */
3437 case 0x32a: /* cvtsi2sd */
3438 ot = mo_64_32(s->dflag);
3439 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3440 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3441 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3443 SSEFunc_0_epi sse_fn_epi = sse_op_table3ai[(b >> 8) & 1];
3444 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
3445 sse_fn_epi(cpu_env, cpu_ptr0, cpu_tmp2_i32);
3447 #ifdef TARGET_X86_64
3448 SSEFunc_0_epl sse_fn_epl = sse_op_table3aq[(b >> 8) & 1];
3449 sse_fn_epl(cpu_env, cpu_ptr0, cpu_T0);
3455 case 0x02c: /* cvttps2pi */
3456 case 0x12c: /* cvttpd2pi */
3457 case 0x02d: /* cvtps2pi */
3458 case 0x12d: /* cvtpd2pi */
3459 gen_helper_enter_mmx(cpu_env);
3461 gen_lea_modrm(env, s, modrm);
3462 op2_offset = offsetof(CPUX86State,xmm_t0);
3463 gen_ldo_env_A0(s, op2_offset);
3465 rm = (modrm & 7) | REX_B(s);
3466 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3468 op1_offset = offsetof(CPUX86State,fpregs[reg & 7].mmx);
3469 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3470 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3473 gen_helper_cvttps2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3476 gen_helper_cvttpd2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3479 gen_helper_cvtps2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3482 gen_helper_cvtpd2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3486 case 0x22c: /* cvttss2si */
3487 case 0x32c: /* cvttsd2si */
3488 case 0x22d: /* cvtss2si */
3489 case 0x32d: /* cvtsd2si */
3490 ot = mo_64_32(s->dflag);
3492 gen_lea_modrm(env, s, modrm);
3494 gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_Q(0)));
3496 gen_op_ld_v(s, MO_32, cpu_T0, cpu_A0);
3497 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(0)));
3499 op2_offset = offsetof(CPUX86State,xmm_t0);
3501 rm = (modrm & 7) | REX_B(s);
3502 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3504 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
3506 SSEFunc_i_ep sse_fn_i_ep =
3507 sse_op_table3bi[((b >> 7) & 2) | (b & 1)];
3508 sse_fn_i_ep(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3509 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
3511 #ifdef TARGET_X86_64
3512 SSEFunc_l_ep sse_fn_l_ep =
3513 sse_op_table3bq[((b >> 7) & 2) | (b & 1)];
3514 sse_fn_l_ep(cpu_T0, cpu_env, cpu_ptr0);
3519 gen_op_mov_reg_v(ot, reg, cpu_T0);
3521 case 0xc4: /* pinsrw */
3524 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
3525 val = cpu_ldub_code(env, s->pc++);
3528 tcg_gen_st16_tl(cpu_T0, cpu_env,
3529 offsetof(CPUX86State,xmm_regs[reg].ZMM_W(val)));
3532 tcg_gen_st16_tl(cpu_T0, cpu_env,
3533 offsetof(CPUX86State,fpregs[reg].mmx.MMX_W(val)));
3536 case 0xc5: /* pextrw */
3540 ot = mo_64_32(s->dflag);
3541 val = cpu_ldub_code(env, s->pc++);
3544 rm = (modrm & 7) | REX_B(s);
3545 tcg_gen_ld16u_tl(cpu_T0, cpu_env,
3546 offsetof(CPUX86State,xmm_regs[rm].ZMM_W(val)));
3550 tcg_gen_ld16u_tl(cpu_T0, cpu_env,
3551 offsetof(CPUX86State,fpregs[rm].mmx.MMX_W(val)));
3553 reg = ((modrm >> 3) & 7) | rex_r;
3554 gen_op_mov_reg_v(ot, reg, cpu_T0);
3556 case 0x1d6: /* movq ea, xmm */
3558 gen_lea_modrm(env, s, modrm);
3559 gen_stq_env_A0(s, offsetof(CPUX86State,
3560 xmm_regs[reg].ZMM_Q(0)));
3562 rm = (modrm & 7) | REX_B(s);
3563 gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)),
3564 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3565 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(1)));
3568 case 0x2d6: /* movq2dq */
3569 gen_helper_enter_mmx(cpu_env);
3571 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3572 offsetof(CPUX86State,fpregs[rm].mmx));
3573 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)));
3575 case 0x3d6: /* movdq2q */
3576 gen_helper_enter_mmx(cpu_env);
3577 rm = (modrm & 7) | REX_B(s);
3578 gen_op_movq(offsetof(CPUX86State,fpregs[reg & 7].mmx),
3579 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3581 case 0xd7: /* pmovmskb */
3586 rm = (modrm & 7) | REX_B(s);
3587 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[rm]));
3588 gen_helper_pmovmskb_xmm(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3591 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,fpregs[rm].mmx));
3592 gen_helper_pmovmskb_mmx(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3594 reg = ((modrm >> 3) & 7) | rex_r;
3595 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
3601 if ((b & 0xf0) == 0xf0) {
3604 modrm = cpu_ldub_code(env, s->pc++);
3606 reg = ((modrm >> 3) & 7) | rex_r;
3607 mod = (modrm >> 6) & 3;
3612 sse_fn_epp = sse_op_table6[b].op[b1];
3616 if (!(s->cpuid_ext_features & sse_op_table6[b].ext_mask))
3620 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3622 op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
3624 op2_offset = offsetof(CPUX86State,xmm_t0);
3625 gen_lea_modrm(env, s, modrm);
3627 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3628 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3629 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3630 gen_ldq_env_A0(s, op2_offset +
3631 offsetof(ZMMReg, ZMM_Q(0)));
3633 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3634 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3635 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
3636 s->mem_index, MO_LEUL);
3637 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, op2_offset +
3638 offsetof(ZMMReg, ZMM_L(0)));
3640 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3641 tcg_gen_qemu_ld_tl(cpu_tmp0, cpu_A0,
3642 s->mem_index, MO_LEUW);
3643 tcg_gen_st16_tl(cpu_tmp0, cpu_env, op2_offset +
3644 offsetof(ZMMReg, ZMM_W(0)));
3646 case 0x2a: /* movntqda */
3647 gen_ldo_env_A0(s, op1_offset);
3650 gen_ldo_env_A0(s, op2_offset);
3654 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
3656 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3658 op2_offset = offsetof(CPUX86State,mmx_t0);
3659 gen_lea_modrm(env, s, modrm);
3660 gen_ldq_env_A0(s, op2_offset);
3663 if (sse_fn_epp == SSE_SPECIAL) {
3667 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3668 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3669 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
3672 set_cc_op(s, CC_OP_EFLAGS);
3679 /* Various integer extensions at 0f 38 f[0-f]. */
3680 b = modrm | (b1 << 8);
3681 modrm = cpu_ldub_code(env, s->pc++);
3682 reg = ((modrm >> 3) & 7) | rex_r;
3685 case 0x3f0: /* crc32 Gd,Eb */
3686 case 0x3f1: /* crc32 Gd,Ey */
3688 if (!(s->cpuid_ext_features & CPUID_EXT_SSE42)) {
3691 if ((b & 0xff) == 0xf0) {
3693 } else if (s->dflag != MO_64) {
3694 ot = (s->prefix & PREFIX_DATA ? MO_16 : MO_32);
3699 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[reg]);
3700 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3701 gen_helper_crc32(cpu_T0, cpu_tmp2_i32,
3702 cpu_T0, tcg_const_i32(8 << ot));
3704 ot = mo_64_32(s->dflag);
3705 gen_op_mov_reg_v(ot, reg, cpu_T0);
3708 case 0x1f0: /* crc32 or movbe */
3710 /* For these insns, the f3 prefix is supposed to have priority
3711 over the 66 prefix, but that's not what we implement above
3713 if (s->prefix & PREFIX_REPNZ) {
3717 case 0x0f0: /* movbe Gy,My */
3718 case 0x0f1: /* movbe My,Gy */
3719 if (!(s->cpuid_ext_features & CPUID_EXT_MOVBE)) {
3722 if (s->dflag != MO_64) {
3723 ot = (s->prefix & PREFIX_DATA ? MO_16 : MO_32);
3728 gen_lea_modrm(env, s, modrm);
3730 tcg_gen_qemu_ld_tl(cpu_T0, cpu_A0,
3731 s->mem_index, ot | MO_BE);
3732 gen_op_mov_reg_v(ot, reg, cpu_T0);
3734 tcg_gen_qemu_st_tl(cpu_regs[reg], cpu_A0,
3735 s->mem_index, ot | MO_BE);
3739 case 0x0f2: /* andn Gy, By, Ey */
3740 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
3741 || !(s->prefix & PREFIX_VEX)
3745 ot = mo_64_32(s->dflag);
3746 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3747 tcg_gen_andc_tl(cpu_T0, cpu_regs[s->vex_v], cpu_T0);
3748 gen_op_mov_reg_v(ot, reg, cpu_T0);
3749 gen_op_update1_cc();
3750 set_cc_op(s, CC_OP_LOGICB + ot);
3753 case 0x0f7: /* bextr Gy, Ey, By */
3754 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
3755 || !(s->prefix & PREFIX_VEX)
3759 ot = mo_64_32(s->dflag);
3763 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3764 /* Extract START, and shift the operand.
3765 Shifts larger than operand size get zeros. */
3766 tcg_gen_ext8u_tl(cpu_A0, cpu_regs[s->vex_v]);
3767 tcg_gen_shr_tl(cpu_T0, cpu_T0, cpu_A0);
3769 bound = tcg_const_tl(ot == MO_64 ? 63 : 31);
3770 zero = tcg_const_tl(0);
3771 tcg_gen_movcond_tl(TCG_COND_LEU, cpu_T0, cpu_A0, bound,
3773 tcg_temp_free(zero);
3775 /* Extract the LEN into a mask. Lengths larger than
3776 operand size get all ones. */
3777 tcg_gen_extract_tl(cpu_A0, cpu_regs[s->vex_v], 8, 8);
3778 tcg_gen_movcond_tl(TCG_COND_LEU, cpu_A0, cpu_A0, bound,
3780 tcg_temp_free(bound);
3781 tcg_gen_movi_tl(cpu_T1, 1);
3782 tcg_gen_shl_tl(cpu_T1, cpu_T1, cpu_A0);
3783 tcg_gen_subi_tl(cpu_T1, cpu_T1, 1);
3784 tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1);
3786 gen_op_mov_reg_v(ot, reg, cpu_T0);
3787 gen_op_update1_cc();
3788 set_cc_op(s, CC_OP_LOGICB + ot);
3792 case 0x0f5: /* bzhi Gy, Ey, By */
3793 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3794 || !(s->prefix & PREFIX_VEX)
3798 ot = mo_64_32(s->dflag);
3799 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3800 tcg_gen_ext8u_tl(cpu_T1, cpu_regs[s->vex_v]);
3802 TCGv bound = tcg_const_tl(ot == MO_64 ? 63 : 31);
3803 /* Note that since we're using BMILG (in order to get O
3804 cleared) we need to store the inverse into C. */
3805 tcg_gen_setcond_tl(TCG_COND_LT, cpu_cc_src,
3807 tcg_gen_movcond_tl(TCG_COND_GT, cpu_T1, cpu_T1,
3808 bound, bound, cpu_T1);
3809 tcg_temp_free(bound);
3811 tcg_gen_movi_tl(cpu_A0, -1);
3812 tcg_gen_shl_tl(cpu_A0, cpu_A0, cpu_T1);
3813 tcg_gen_andc_tl(cpu_T0, cpu_T0, cpu_A0);
3814 gen_op_mov_reg_v(ot, reg, cpu_T0);
3815 gen_op_update1_cc();
3816 set_cc_op(s, CC_OP_BMILGB + ot);
3819 case 0x3f6: /* mulx By, Gy, rdx, Ey */
3820 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3821 || !(s->prefix & PREFIX_VEX)
3825 ot = mo_64_32(s->dflag);
3826 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3829 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
3830 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_regs[R_EDX]);
3831 tcg_gen_mulu2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
3832 cpu_tmp2_i32, cpu_tmp3_i32);
3833 tcg_gen_extu_i32_tl(cpu_regs[s->vex_v], cpu_tmp2_i32);
3834 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp3_i32);
3836 #ifdef TARGET_X86_64
3838 tcg_gen_mulu2_i64(cpu_T0, cpu_T1,
3839 cpu_T0, cpu_regs[R_EDX]);
3840 tcg_gen_mov_i64(cpu_regs[s->vex_v], cpu_T0);
3841 tcg_gen_mov_i64(cpu_regs[reg], cpu_T1);
3847 case 0x3f5: /* pdep Gy, By, Ey */
3848 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3849 || !(s->prefix & PREFIX_VEX)
3853 ot = mo_64_32(s->dflag);
3854 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3855 /* Note that by zero-extending the mask operand, we
3856 automatically handle zero-extending the result. */
3858 tcg_gen_mov_tl(cpu_T1, cpu_regs[s->vex_v]);
3860 tcg_gen_ext32u_tl(cpu_T1, cpu_regs[s->vex_v]);
3862 gen_helper_pdep(cpu_regs[reg], cpu_T0, cpu_T1);
3865 case 0x2f5: /* pext Gy, By, Ey */
3866 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3867 || !(s->prefix & PREFIX_VEX)
3871 ot = mo_64_32(s->dflag);
3872 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3873 /* Note that by zero-extending the mask operand, we
3874 automatically handle zero-extending the result. */
3876 tcg_gen_mov_tl(cpu_T1, cpu_regs[s->vex_v]);
3878 tcg_gen_ext32u_tl(cpu_T1, cpu_regs[s->vex_v]);
3880 gen_helper_pext(cpu_regs[reg], cpu_T0, cpu_T1);
3883 case 0x1f6: /* adcx Gy, Ey */
3884 case 0x2f6: /* adox Gy, Ey */
3885 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_ADX)) {
3888 TCGv carry_in, carry_out, zero;
3891 ot = mo_64_32(s->dflag);
3892 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3894 /* Re-use the carry-out from a previous round. */
3895 TCGV_UNUSED(carry_in);
3896 carry_out = (b == 0x1f6 ? cpu_cc_dst : cpu_cc_src2);
3900 carry_in = cpu_cc_dst;
3901 end_op = CC_OP_ADCX;
3903 end_op = CC_OP_ADCOX;
3908 end_op = CC_OP_ADCOX;
3910 carry_in = cpu_cc_src2;
3911 end_op = CC_OP_ADOX;
3915 end_op = CC_OP_ADCOX;
3916 carry_in = carry_out;
3919 end_op = (b == 0x1f6 ? CC_OP_ADCX : CC_OP_ADOX);
3922 /* If we can't reuse carry-out, get it out of EFLAGS. */
3923 if (TCGV_IS_UNUSED(carry_in)) {
3924 if (s->cc_op != CC_OP_ADCX && s->cc_op != CC_OP_ADOX) {
3925 gen_compute_eflags(s);
3927 carry_in = cpu_tmp0;
3928 tcg_gen_extract_tl(carry_in, cpu_cc_src,
3929 ctz32(b == 0x1f6 ? CC_C : CC_O), 1);
3933 #ifdef TARGET_X86_64
3935 /* If we know TL is 64-bit, and we want a 32-bit
3936 result, just do everything in 64-bit arithmetic. */
3937 tcg_gen_ext32u_i64(cpu_regs[reg], cpu_regs[reg]);
3938 tcg_gen_ext32u_i64(cpu_T0, cpu_T0);
3939 tcg_gen_add_i64(cpu_T0, cpu_T0, cpu_regs[reg]);
3940 tcg_gen_add_i64(cpu_T0, cpu_T0, carry_in);
3941 tcg_gen_ext32u_i64(cpu_regs[reg], cpu_T0);
3942 tcg_gen_shri_i64(carry_out, cpu_T0, 32);
3946 /* Otherwise compute the carry-out in two steps. */
3947 zero = tcg_const_tl(0);
3948 tcg_gen_add2_tl(cpu_T0, carry_out,
3951 tcg_gen_add2_tl(cpu_regs[reg], carry_out,
3952 cpu_regs[reg], carry_out,
3954 tcg_temp_free(zero);
3957 set_cc_op(s, end_op);
3961 case 0x1f7: /* shlx Gy, Ey, By */
3962 case 0x2f7: /* sarx Gy, Ey, By */
3963 case 0x3f7: /* shrx Gy, Ey, By */
3964 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3965 || !(s->prefix & PREFIX_VEX)
3969 ot = mo_64_32(s->dflag);
3970 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3972 tcg_gen_andi_tl(cpu_T1, cpu_regs[s->vex_v], 63);
3974 tcg_gen_andi_tl(cpu_T1, cpu_regs[s->vex_v], 31);
3977 tcg_gen_shl_tl(cpu_T0, cpu_T0, cpu_T1);
3978 } else if (b == 0x2f7) {
3980 tcg_gen_ext32s_tl(cpu_T0, cpu_T0);
3982 tcg_gen_sar_tl(cpu_T0, cpu_T0, cpu_T1);
3985 tcg_gen_ext32u_tl(cpu_T0, cpu_T0);
3987 tcg_gen_shr_tl(cpu_T0, cpu_T0, cpu_T1);
3989 gen_op_mov_reg_v(ot, reg, cpu_T0);
3995 case 0x3f3: /* Group 17 */
3996 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
3997 || !(s->prefix & PREFIX_VEX)
4001 ot = mo_64_32(s->dflag);
4002 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4005 case 1: /* blsr By,Ey */
4006 tcg_gen_neg_tl(cpu_T1, cpu_T0);
4007 tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1);
4008 gen_op_mov_reg_v(ot, s->vex_v, cpu_T0);
4009 gen_op_update2_cc();
4010 set_cc_op(s, CC_OP_BMILGB + ot);
4013 case 2: /* blsmsk By,Ey */
4014 tcg_gen_mov_tl(cpu_cc_src, cpu_T0);
4015 tcg_gen_subi_tl(cpu_T0, cpu_T0, 1);
4016 tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_cc_src);
4017 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4018 set_cc_op(s, CC_OP_BMILGB + ot);
4021 case 3: /* blsi By, Ey */
4022 tcg_gen_mov_tl(cpu_cc_src, cpu_T0);
4023 tcg_gen_subi_tl(cpu_T0, cpu_T0, 1);
4024 tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_cc_src);
4025 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4026 set_cc_op(s, CC_OP_BMILGB + ot);
4042 modrm = cpu_ldub_code(env, s->pc++);
4044 reg = ((modrm >> 3) & 7) | rex_r;
4045 mod = (modrm >> 6) & 3;
4050 sse_fn_eppi = sse_op_table7[b].op[b1];
4054 if (!(s->cpuid_ext_features & sse_op_table7[b].ext_mask))
4057 if (sse_fn_eppi == SSE_SPECIAL) {
4058 ot = mo_64_32(s->dflag);
4059 rm = (modrm & 7) | REX_B(s);
4061 gen_lea_modrm(env, s, modrm);
4062 reg = ((modrm >> 3) & 7) | rex_r;
4063 val = cpu_ldub_code(env, s->pc++);
4065 case 0x14: /* pextrb */
4066 tcg_gen_ld8u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
4067 xmm_regs[reg].ZMM_B(val & 15)));
4069 gen_op_mov_reg_v(ot, rm, cpu_T0);
4071 tcg_gen_qemu_st_tl(cpu_T0, cpu_A0,
4072 s->mem_index, MO_UB);
4075 case 0x15: /* pextrw */
4076 tcg_gen_ld16u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
4077 xmm_regs[reg].ZMM_W(val & 7)));
4079 gen_op_mov_reg_v(ot, rm, cpu_T0);
4081 tcg_gen_qemu_st_tl(cpu_T0, cpu_A0,
4082 s->mem_index, MO_LEUW);
4086 if (ot == MO_32) { /* pextrd */
4087 tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
4088 offsetof(CPUX86State,
4089 xmm_regs[reg].ZMM_L(val & 3)));
4091 tcg_gen_extu_i32_tl(cpu_regs[rm], cpu_tmp2_i32);
4093 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
4094 s->mem_index, MO_LEUL);
4096 } else { /* pextrq */
4097 #ifdef TARGET_X86_64
4098 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
4099 offsetof(CPUX86State,
4100 xmm_regs[reg].ZMM_Q(val & 1)));
4102 tcg_gen_mov_i64(cpu_regs[rm], cpu_tmp1_i64);
4104 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0,
4105 s->mem_index, MO_LEQ);
4112 case 0x17: /* extractps */
4113 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
4114 xmm_regs[reg].ZMM_L(val & 3)));
4116 gen_op_mov_reg_v(ot, rm, cpu_T0);
4118 tcg_gen_qemu_st_tl(cpu_T0, cpu_A0,
4119 s->mem_index, MO_LEUL);
4122 case 0x20: /* pinsrb */
4124 gen_op_mov_v_reg(MO_32, cpu_T0, rm);
4126 tcg_gen_qemu_ld_tl(cpu_T0, cpu_A0,
4127 s->mem_index, MO_UB);
4129 tcg_gen_st8_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
4130 xmm_regs[reg].ZMM_B(val & 15)));
4132 case 0x21: /* insertps */
4134 tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
4135 offsetof(CPUX86State,xmm_regs[rm]
4136 .ZMM_L((val >> 6) & 3)));
4138 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
4139 s->mem_index, MO_LEUL);
4141 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
4142 offsetof(CPUX86State,xmm_regs[reg]
4143 .ZMM_L((val >> 4) & 3)));
4145 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4146 cpu_env, offsetof(CPUX86State,
4147 xmm_regs[reg].ZMM_L(0)));
4149 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4150 cpu_env, offsetof(CPUX86State,
4151 xmm_regs[reg].ZMM_L(1)));
4153 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4154 cpu_env, offsetof(CPUX86State,
4155 xmm_regs[reg].ZMM_L(2)));
4157 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4158 cpu_env, offsetof(CPUX86State,
4159 xmm_regs[reg].ZMM_L(3)));
4162 if (ot == MO_32) { /* pinsrd */
4164 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[rm]);
4166 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
4167 s->mem_index, MO_LEUL);
4169 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
4170 offsetof(CPUX86State,
4171 xmm_regs[reg].ZMM_L(val & 3)));
4172 } else { /* pinsrq */
4173 #ifdef TARGET_X86_64
4175 gen_op_mov_v_reg(ot, cpu_tmp1_i64, rm);
4177 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0,
4178 s->mem_index, MO_LEQ);
4180 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
4181 offsetof(CPUX86State,
4182 xmm_regs[reg].ZMM_Q(val & 1)));
4193 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
4195 op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
4197 op2_offset = offsetof(CPUX86State,xmm_t0);
4198 gen_lea_modrm(env, s, modrm);
4199 gen_ldo_env_A0(s, op2_offset);
4202 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
4204 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
4206 op2_offset = offsetof(CPUX86State,mmx_t0);
4207 gen_lea_modrm(env, s, modrm);
4208 gen_ldq_env_A0(s, op2_offset);
4211 val = cpu_ldub_code(env, s->pc++);
4213 if ((b & 0xfc) == 0x60) { /* pcmpXstrX */
4214 set_cc_op(s, CC_OP_EFLAGS);
4216 if (s->dflag == MO_64) {
4217 /* The helper must use entire 64-bit gp registers */
4222 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4223 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4224 sse_fn_eppi(cpu_env, cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
4228 /* Various integer extensions at 0f 3a f[0-f]. */
4229 b = modrm | (b1 << 8);
4230 modrm = cpu_ldub_code(env, s->pc++);
4231 reg = ((modrm >> 3) & 7) | rex_r;
4234 case 0x3f0: /* rorx Gy,Ey, Ib */
4235 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
4236 || !(s->prefix & PREFIX_VEX)
4240 ot = mo_64_32(s->dflag);
4241 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4242 b = cpu_ldub_code(env, s->pc++);
4244 tcg_gen_rotri_tl(cpu_T0, cpu_T0, b & 63);
4246 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
4247 tcg_gen_rotri_i32(cpu_tmp2_i32, cpu_tmp2_i32, b & 31);
4248 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
4250 gen_op_mov_reg_v(ot, reg, cpu_T0);
4260 gen_unknown_opcode(env, s);
4264 /* generic MMX or SSE operation */
4266 case 0x70: /* pshufx insn */
4267 case 0xc6: /* pshufx insn */
4268 case 0xc2: /* compare insns */
4275 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
4279 gen_lea_modrm(env, s, modrm);
4280 op2_offset = offsetof(CPUX86State,xmm_t0);
4286 /* Most sse scalar operations. */
4289 } else if (b1 == 3) {
4294 case 0x2e: /* ucomis[sd] */
4295 case 0x2f: /* comis[sd] */
4307 gen_op_ld_v(s, MO_32, cpu_T0, cpu_A0);
4308 tcg_gen_st32_tl(cpu_T0, cpu_env,
4309 offsetof(CPUX86State,xmm_t0.ZMM_L(0)));
4313 gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_D(0)));
4316 /* 128 bit access */
4317 gen_ldo_env_A0(s, op2_offset);
4321 rm = (modrm & 7) | REX_B(s);
4322 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
4325 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
4327 gen_lea_modrm(env, s, modrm);
4328 op2_offset = offsetof(CPUX86State,mmx_t0);
4329 gen_ldq_env_A0(s, op2_offset);
4332 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
4336 case 0x0f: /* 3DNow! data insns */
4337 val = cpu_ldub_code(env, s->pc++);
4338 sse_fn_epp = sse_op_table5[val];
4342 if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) {
4345 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4346 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4347 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4349 case 0x70: /* pshufx insn */
4350 case 0xc6: /* pshufx insn */
4351 val = cpu_ldub_code(env, s->pc++);
4352 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4353 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4354 /* XXX: introduce a new table? */
4355 sse_fn_ppi = (SSEFunc_0_ppi)sse_fn_epp;
4356 sse_fn_ppi(cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
4360 val = cpu_ldub_code(env, s->pc++);
4363 sse_fn_epp = sse_op_table4[val][b1];
4365 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4366 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4367 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4370 /* maskmov : we must prepare A0 */
4373 tcg_gen_mov_tl(cpu_A0, cpu_regs[R_EDI]);
4374 gen_extu(s->aflag, cpu_A0);
4375 gen_add_A0_ds_seg(s);
4377 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4378 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4379 /* XXX: introduce a new table? */
4380 sse_fn_eppt = (SSEFunc_0_eppt)sse_fn_epp;
4381 sse_fn_eppt(cpu_env, cpu_ptr0, cpu_ptr1, cpu_A0);
4384 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4385 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4386 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4389 if (b == 0x2e || b == 0x2f) {
4390 set_cc_op(s, CC_OP_EFLAGS);
4395 /* convert one instruction. s->is_jmp is set if the translation must
4396 be stopped. Return the next pc value */
4397 static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
4398 target_ulong pc_start)
4402 TCGMemOp ot, aflag, dflag;
4403 int modrm, reg, rm, mod, op, opreg, val;
4404 target_ulong next_eip, tval;
4407 s->pc_start = s->pc = pc_start;
4412 #ifdef TARGET_X86_64
4417 s->rip_offset = 0; /* for relative ip address */
4421 /* x86 has an upper limit of 15 bytes for an instruction. Since we
4422 * do not want to decode and generate IR for an illegal
4423 * instruction, the following check limits the instruction size to
4424 * 25 bytes: 14 prefix + 1 opc + 6 (modrm+sib+ofs) + 4 imm */
4425 if (s->pc - pc_start > 14) {
4428 b = cpu_ldub_code(env, s->pc);
4430 /* Collect prefixes. */
4433 prefixes |= PREFIX_REPZ;
4436 prefixes |= PREFIX_REPNZ;
4439 prefixes |= PREFIX_LOCK;
4460 prefixes |= PREFIX_DATA;
4463 prefixes |= PREFIX_ADR;
4465 #ifdef TARGET_X86_64
4469 rex_w = (b >> 3) & 1;
4470 rex_r = (b & 0x4) << 1;
4471 s->rex_x = (b & 0x2) << 2;
4472 REX_B(s) = (b & 0x1) << 3;
4473 x86_64_hregs = 1; /* select uniform byte register addressing */
4478 case 0xc5: /* 2-byte VEX */
4479 case 0xc4: /* 3-byte VEX */
4480 /* VEX prefixes cannot be used except in 32-bit mode.
4481 Otherwise the instruction is LES or LDS. */
4482 if (s->code32 && !s->vm86) {
4483 static const int pp_prefix[4] = {
4484 0, PREFIX_DATA, PREFIX_REPZ, PREFIX_REPNZ
4486 int vex3, vex2 = cpu_ldub_code(env, s->pc);
4488 if (!CODE64(s) && (vex2 & 0xc0) != 0xc0) {
4489 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4490 otherwise the instruction is LES or LDS. */
4495 /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
4496 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ
4497 | PREFIX_LOCK | PREFIX_DATA)) {
4500 #ifdef TARGET_X86_64
4505 rex_r = (~vex2 >> 4) & 8;
4508 b = cpu_ldub_code(env, s->pc++);
4510 #ifdef TARGET_X86_64
4511 s->rex_x = (~vex2 >> 3) & 8;
4512 s->rex_b = (~vex2 >> 2) & 8;
4514 vex3 = cpu_ldub_code(env, s->pc++);
4515 rex_w = (vex3 >> 7) & 1;
4516 switch (vex2 & 0x1f) {
4517 case 0x01: /* Implied 0f leading opcode bytes. */
4518 b = cpu_ldub_code(env, s->pc++) | 0x100;
4520 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4523 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4526 default: /* Reserved for future use. */
4530 s->vex_v = (~vex3 >> 3) & 0xf;
4531 s->vex_l = (vex3 >> 2) & 1;
4532 prefixes |= pp_prefix[vex3 & 3] | PREFIX_VEX;
4537 /* Post-process prefixes. */
4539 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit
4540 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4541 over 0x66 if both are present. */
4542 dflag = (rex_w > 0 ? MO_64 : prefixes & PREFIX_DATA ? MO_16 : MO_32);
4543 /* In 64-bit mode, 0x67 selects 32-bit addressing. */
4544 aflag = (prefixes & PREFIX_ADR ? MO_32 : MO_64);
4546 /* In 16/32-bit mode, 0x66 selects the opposite data size. */
4547 if (s->code32 ^ ((prefixes & PREFIX_DATA) != 0)) {
4552 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */
4553 if (s->code32 ^ ((prefixes & PREFIX_ADR) != 0)) {
4560 s->prefix = prefixes;
4564 /* now check op code */
4568 /**************************/
4569 /* extended op code */
4570 b = cpu_ldub_code(env, s->pc++) | 0x100;
4573 /**************************/
4588 ot = mo_b_d(b, dflag);
4591 case 0: /* OP Ev, Gv */
4592 modrm = cpu_ldub_code(env, s->pc++);
4593 reg = ((modrm >> 3) & 7) | rex_r;
4594 mod = (modrm >> 6) & 3;
4595 rm = (modrm & 7) | REX_B(s);
4597 gen_lea_modrm(env, s, modrm);
4599 } else if (op == OP_XORL && rm == reg) {
4601 /* xor reg, reg optimisation */
4602 set_cc_op(s, CC_OP_CLR);
4603 tcg_gen_movi_tl(cpu_T0, 0);
4604 gen_op_mov_reg_v(ot, reg, cpu_T0);
4609 gen_op_mov_v_reg(ot, cpu_T1, reg);
4610 gen_op(s, op, ot, opreg);
4612 case 1: /* OP Gv, Ev */
4613 modrm = cpu_ldub_code(env, s->pc++);
4614 mod = (modrm >> 6) & 3;
4615 reg = ((modrm >> 3) & 7) | rex_r;
4616 rm = (modrm & 7) | REX_B(s);
4618 gen_lea_modrm(env, s, modrm);
4619 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
4620 } else if (op == OP_XORL && rm == reg) {
4623 gen_op_mov_v_reg(ot, cpu_T1, rm);
4625 gen_op(s, op, ot, reg);
4627 case 2: /* OP A, Iv */
4628 val = insn_get(env, s, ot);
4629 tcg_gen_movi_tl(cpu_T1, val);
4630 gen_op(s, op, ot, OR_EAX);
4639 case 0x80: /* GRP1 */
4645 ot = mo_b_d(b, dflag);
4647 modrm = cpu_ldub_code(env, s->pc++);
4648 mod = (modrm >> 6) & 3;
4649 rm = (modrm & 7) | REX_B(s);
4650 op = (modrm >> 3) & 7;
4656 s->rip_offset = insn_const_size(ot);
4657 gen_lea_modrm(env, s, modrm);
4668 val = insn_get(env, s, ot);
4671 val = (int8_t)insn_get(env, s, MO_8);
4674 tcg_gen_movi_tl(cpu_T1, val);
4675 gen_op(s, op, ot, opreg);
4679 /**************************/
4680 /* inc, dec, and other misc arith */
4681 case 0x40 ... 0x47: /* inc Gv */
4683 gen_inc(s, ot, OR_EAX + (b & 7), 1);
4685 case 0x48 ... 0x4f: /* dec Gv */
4687 gen_inc(s, ot, OR_EAX + (b & 7), -1);
4689 case 0xf6: /* GRP3 */
4691 ot = mo_b_d(b, dflag);
4693 modrm = cpu_ldub_code(env, s->pc++);
4694 mod = (modrm >> 6) & 3;
4695 rm = (modrm & 7) | REX_B(s);
4696 op = (modrm >> 3) & 7;
4699 s->rip_offset = insn_const_size(ot);
4701 gen_lea_modrm(env, s, modrm);
4702 /* For those below that handle locked memory, don't load here. */
4703 if (!(s->prefix & PREFIX_LOCK)
4705 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
4708 gen_op_mov_v_reg(ot, cpu_T0, rm);
4713 val = insn_get(env, s, ot);
4714 tcg_gen_movi_tl(cpu_T1, val);
4715 gen_op_testl_T0_T1_cc();
4716 set_cc_op(s, CC_OP_LOGICB + ot);
4719 if (s->prefix & PREFIX_LOCK) {
4723 tcg_gen_movi_tl(cpu_T0, ~0);
4724 tcg_gen_atomic_xor_fetch_tl(cpu_T0, cpu_A0, cpu_T0,
4725 s->mem_index, ot | MO_LE);
4727 tcg_gen_not_tl(cpu_T0, cpu_T0);
4729 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
4731 gen_op_mov_reg_v(ot, rm, cpu_T0);
4736 if (s->prefix & PREFIX_LOCK) {
4738 TCGv a0, t0, t1, t2;
4743 a0 = tcg_temp_local_new();
4744 t0 = tcg_temp_local_new();
4745 label1 = gen_new_label();
4747 tcg_gen_mov_tl(a0, cpu_A0);
4748 tcg_gen_mov_tl(t0, cpu_T0);
4750 gen_set_label(label1);
4751 t1 = tcg_temp_new();
4752 t2 = tcg_temp_new();
4753 tcg_gen_mov_tl(t2, t0);
4754 tcg_gen_neg_tl(t1, t0);
4755 tcg_gen_atomic_cmpxchg_tl(t0, a0, t0, t1,
4756 s->mem_index, ot | MO_LE);
4758 tcg_gen_brcond_tl(TCG_COND_NE, t0, t2, label1);
4762 tcg_gen_mov_tl(cpu_T0, t0);
4765 tcg_gen_neg_tl(cpu_T0, cpu_T0);
4767 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
4769 gen_op_mov_reg_v(ot, rm, cpu_T0);
4772 gen_op_update_neg_cc();
4773 set_cc_op(s, CC_OP_SUBB + ot);
4778 gen_op_mov_v_reg(MO_8, cpu_T1, R_EAX);
4779 tcg_gen_ext8u_tl(cpu_T0, cpu_T0);
4780 tcg_gen_ext8u_tl(cpu_T1, cpu_T1);
4781 /* XXX: use 32 bit mul which could be faster */
4782 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
4783 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
4784 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4785 tcg_gen_andi_tl(cpu_cc_src, cpu_T0, 0xff00);
4786 set_cc_op(s, CC_OP_MULB);
4789 gen_op_mov_v_reg(MO_16, cpu_T1, R_EAX);
4790 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
4791 tcg_gen_ext16u_tl(cpu_T1, cpu_T1);
4792 /* XXX: use 32 bit mul which could be faster */
4793 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
4794 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
4795 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4796 tcg_gen_shri_tl(cpu_T0, cpu_T0, 16);
4797 gen_op_mov_reg_v(MO_16, R_EDX, cpu_T0);
4798 tcg_gen_mov_tl(cpu_cc_src, cpu_T0);
4799 set_cc_op(s, CC_OP_MULW);
4803 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
4804 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_regs[R_EAX]);
4805 tcg_gen_mulu2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
4806 cpu_tmp2_i32, cpu_tmp3_i32);
4807 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], cpu_tmp2_i32);
4808 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], cpu_tmp3_i32);
4809 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4810 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]);
4811 set_cc_op(s, CC_OP_MULL);
4813 #ifdef TARGET_X86_64
4815 tcg_gen_mulu2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX],
4816 cpu_T0, cpu_regs[R_EAX]);
4817 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4818 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]);
4819 set_cc_op(s, CC_OP_MULQ);
4827 gen_op_mov_v_reg(MO_8, cpu_T1, R_EAX);
4828 tcg_gen_ext8s_tl(cpu_T0, cpu_T0);
4829 tcg_gen_ext8s_tl(cpu_T1, cpu_T1);
4830 /* XXX: use 32 bit mul which could be faster */
4831 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
4832 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
4833 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4834 tcg_gen_ext8s_tl(cpu_tmp0, cpu_T0);
4835 tcg_gen_sub_tl(cpu_cc_src, cpu_T0, cpu_tmp0);
4836 set_cc_op(s, CC_OP_MULB);
4839 gen_op_mov_v_reg(MO_16, cpu_T1, R_EAX);
4840 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
4841 tcg_gen_ext16s_tl(cpu_T1, cpu_T1);
4842 /* XXX: use 32 bit mul which could be faster */
4843 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
4844 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
4845 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4846 tcg_gen_ext16s_tl(cpu_tmp0, cpu_T0);
4847 tcg_gen_sub_tl(cpu_cc_src, cpu_T0, cpu_tmp0);
4848 tcg_gen_shri_tl(cpu_T0, cpu_T0, 16);
4849 gen_op_mov_reg_v(MO_16, R_EDX, cpu_T0);
4850 set_cc_op(s, CC_OP_MULW);
4854 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
4855 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_regs[R_EAX]);
4856 tcg_gen_muls2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
4857 cpu_tmp2_i32, cpu_tmp3_i32);
4858 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], cpu_tmp2_i32);
4859 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], cpu_tmp3_i32);
4860 tcg_gen_sari_i32(cpu_tmp2_i32, cpu_tmp2_i32, 31);
4861 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4862 tcg_gen_sub_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
4863 tcg_gen_extu_i32_tl(cpu_cc_src, cpu_tmp2_i32);
4864 set_cc_op(s, CC_OP_MULL);
4866 #ifdef TARGET_X86_64
4868 tcg_gen_muls2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX],
4869 cpu_T0, cpu_regs[R_EAX]);
4870 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4871 tcg_gen_sari_tl(cpu_cc_src, cpu_regs[R_EAX], 63);
4872 tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, cpu_regs[R_EDX]);
4873 set_cc_op(s, CC_OP_MULQ);
4881 gen_helper_divb_AL(cpu_env, cpu_T0);
4884 gen_helper_divw_AX(cpu_env, cpu_T0);
4888 gen_helper_divl_EAX(cpu_env, cpu_T0);
4890 #ifdef TARGET_X86_64
4892 gen_helper_divq_EAX(cpu_env, cpu_T0);
4900 gen_helper_idivb_AL(cpu_env, cpu_T0);
4903 gen_helper_idivw_AX(cpu_env, cpu_T0);
4907 gen_helper_idivl_EAX(cpu_env, cpu_T0);
4909 #ifdef TARGET_X86_64
4911 gen_helper_idivq_EAX(cpu_env, cpu_T0);
4921 case 0xfe: /* GRP4 */
4922 case 0xff: /* GRP5 */
4923 ot = mo_b_d(b, dflag);
4925 modrm = cpu_ldub_code(env, s->pc++);
4926 mod = (modrm >> 6) & 3;
4927 rm = (modrm & 7) | REX_B(s);
4928 op = (modrm >> 3) & 7;
4929 if (op >= 2 && b == 0xfe) {
4933 if (op == 2 || op == 4) {
4934 /* operand size for jumps is 64 bit */
4936 } else if (op == 3 || op == 5) {
4937 ot = dflag != MO_16 ? MO_32 + (rex_w == 1) : MO_16;
4938 } else if (op == 6) {
4939 /* default push size is 64 bit */
4940 ot = mo_pushpop(s, dflag);
4944 gen_lea_modrm(env, s, modrm);
4945 if (op >= 2 && op != 3 && op != 5)
4946 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
4948 gen_op_mov_v_reg(ot, cpu_T0, rm);
4952 case 0: /* inc Ev */
4957 gen_inc(s, ot, opreg, 1);
4959 case 1: /* dec Ev */
4964 gen_inc(s, ot, opreg, -1);
4966 case 2: /* call Ev */
4967 /* XXX: optimize if memory (no 'and' is necessary) */
4968 if (dflag == MO_16) {
4969 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
4971 next_eip = s->pc - s->cs_base;
4972 tcg_gen_movi_tl(cpu_T1, next_eip);
4973 gen_push_v(s, cpu_T1);
4974 gen_op_jmp_v(cpu_T0);
4978 case 3: /* lcall Ev */
4979 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
4980 gen_add_A0_im(s, 1 << ot);
4981 gen_op_ld_v(s, MO_16, cpu_T0, cpu_A0);
4983 if (s->pe && !s->vm86) {
4984 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
4985 gen_helper_lcall_protected(cpu_env, cpu_tmp2_i32, cpu_T1,
4986 tcg_const_i32(dflag - 1),
4987 tcg_const_tl(s->pc - s->cs_base));
4989 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
4990 gen_helper_lcall_real(cpu_env, cpu_tmp2_i32, cpu_T1,
4991 tcg_const_i32(dflag - 1),
4992 tcg_const_i32(s->pc - s->cs_base));
4996 case 4: /* jmp Ev */
4997 if (dflag == MO_16) {
4998 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
5000 gen_op_jmp_v(cpu_T0);
5004 case 5: /* ljmp Ev */
5005 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
5006 gen_add_A0_im(s, 1 << ot);
5007 gen_op_ld_v(s, MO_16, cpu_T0, cpu_A0);
5009 if (s->pe && !s->vm86) {
5010 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
5011 gen_helper_ljmp_protected(cpu_env, cpu_tmp2_i32, cpu_T1,
5012 tcg_const_tl(s->pc - s->cs_base));
5014 gen_op_movl_seg_T0_vm(R_CS);
5015 gen_op_jmp_v(cpu_T1);
5019 case 6: /* push Ev */
5020 gen_push_v(s, cpu_T0);
5027 case 0x84: /* test Ev, Gv */
5029 ot = mo_b_d(b, dflag);
5031 modrm = cpu_ldub_code(env, s->pc++);
5032 reg = ((modrm >> 3) & 7) | rex_r;
5034 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5035 gen_op_mov_v_reg(ot, cpu_T1, reg);
5036 gen_op_testl_T0_T1_cc();
5037 set_cc_op(s, CC_OP_LOGICB + ot);
5040 case 0xa8: /* test eAX, Iv */
5042 ot = mo_b_d(b, dflag);
5043 val = insn_get(env, s, ot);
5045 gen_op_mov_v_reg(ot, cpu_T0, OR_EAX);
5046 tcg_gen_movi_tl(cpu_T1, val);
5047 gen_op_testl_T0_T1_cc();
5048 set_cc_op(s, CC_OP_LOGICB + ot);
5051 case 0x98: /* CWDE/CBW */
5053 #ifdef TARGET_X86_64
5055 gen_op_mov_v_reg(MO_32, cpu_T0, R_EAX);
5056 tcg_gen_ext32s_tl(cpu_T0, cpu_T0);
5057 gen_op_mov_reg_v(MO_64, R_EAX, cpu_T0);
5061 gen_op_mov_v_reg(MO_16, cpu_T0, R_EAX);
5062 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
5063 gen_op_mov_reg_v(MO_32, R_EAX, cpu_T0);
5066 gen_op_mov_v_reg(MO_8, cpu_T0, R_EAX);
5067 tcg_gen_ext8s_tl(cpu_T0, cpu_T0);
5068 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
5074 case 0x99: /* CDQ/CWD */
5076 #ifdef TARGET_X86_64
5078 gen_op_mov_v_reg(MO_64, cpu_T0, R_EAX);
5079 tcg_gen_sari_tl(cpu_T0, cpu_T0, 63);
5080 gen_op_mov_reg_v(MO_64, R_EDX, cpu_T0);
5084 gen_op_mov_v_reg(MO_32, cpu_T0, R_EAX);
5085 tcg_gen_ext32s_tl(cpu_T0, cpu_T0);
5086 tcg_gen_sari_tl(cpu_T0, cpu_T0, 31);
5087 gen_op_mov_reg_v(MO_32, R_EDX, cpu_T0);
5090 gen_op_mov_v_reg(MO_16, cpu_T0, R_EAX);
5091 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
5092 tcg_gen_sari_tl(cpu_T0, cpu_T0, 15);
5093 gen_op_mov_reg_v(MO_16, R_EDX, cpu_T0);
5099 case 0x1af: /* imul Gv, Ev */
5100 case 0x69: /* imul Gv, Ev, I */
5103 modrm = cpu_ldub_code(env, s->pc++);
5104 reg = ((modrm >> 3) & 7) | rex_r;
5106 s->rip_offset = insn_const_size(ot);
5109 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5111 val = insn_get(env, s, ot);
5112 tcg_gen_movi_tl(cpu_T1, val);
5113 } else if (b == 0x6b) {
5114 val = (int8_t)insn_get(env, s, MO_8);
5115 tcg_gen_movi_tl(cpu_T1, val);
5117 gen_op_mov_v_reg(ot, cpu_T1, reg);
5120 #ifdef TARGET_X86_64
5122 tcg_gen_muls2_i64(cpu_regs[reg], cpu_T1, cpu_T0, cpu_T1);
5123 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]);
5124 tcg_gen_sari_tl(cpu_cc_src, cpu_cc_dst, 63);
5125 tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, cpu_T1);
5129 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
5130 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T1);
5131 tcg_gen_muls2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
5132 cpu_tmp2_i32, cpu_tmp3_i32);
5133 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
5134 tcg_gen_sari_i32(cpu_tmp2_i32, cpu_tmp2_i32, 31);
5135 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]);
5136 tcg_gen_sub_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
5137 tcg_gen_extu_i32_tl(cpu_cc_src, cpu_tmp2_i32);
5140 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
5141 tcg_gen_ext16s_tl(cpu_T1, cpu_T1);
5142 /* XXX: use 32 bit mul which could be faster */
5143 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
5144 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
5145 tcg_gen_ext16s_tl(cpu_tmp0, cpu_T0);
5146 tcg_gen_sub_tl(cpu_cc_src, cpu_T0, cpu_tmp0);
5147 gen_op_mov_reg_v(ot, reg, cpu_T0);
5150 set_cc_op(s, CC_OP_MULB + ot);
5153 case 0x1c1: /* xadd Ev, Gv */
5154 ot = mo_b_d(b, dflag);
5155 modrm = cpu_ldub_code(env, s->pc++);
5156 reg = ((modrm >> 3) & 7) | rex_r;
5157 mod = (modrm >> 6) & 3;
5158 gen_op_mov_v_reg(ot, cpu_T0, reg);
5160 rm = (modrm & 7) | REX_B(s);
5161 gen_op_mov_v_reg(ot, cpu_T1, rm);
5162 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
5163 gen_op_mov_reg_v(ot, reg, cpu_T1);
5164 gen_op_mov_reg_v(ot, rm, cpu_T0);
5166 gen_lea_modrm(env, s, modrm);
5167 if (s->prefix & PREFIX_LOCK) {
5168 tcg_gen_atomic_fetch_add_tl(cpu_T1, cpu_A0, cpu_T0,
5169 s->mem_index, ot | MO_LE);
5170 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
5172 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
5173 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
5174 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
5176 gen_op_mov_reg_v(ot, reg, cpu_T1);
5178 gen_op_update2_cc();
5179 set_cc_op(s, CC_OP_ADDB + ot);
5182 case 0x1b1: /* cmpxchg Ev, Gv */
5184 TCGv oldv, newv, cmpv;
5186 ot = mo_b_d(b, dflag);
5187 modrm = cpu_ldub_code(env, s->pc++);
5188 reg = ((modrm >> 3) & 7) | rex_r;
5189 mod = (modrm >> 6) & 3;
5190 oldv = tcg_temp_new();
5191 newv = tcg_temp_new();
5192 cmpv = tcg_temp_new();
5193 gen_op_mov_v_reg(ot, newv, reg);
5194 tcg_gen_mov_tl(cmpv, cpu_regs[R_EAX]);
5196 if (s->prefix & PREFIX_LOCK) {
5200 gen_lea_modrm(env, s, modrm);
5201 tcg_gen_atomic_cmpxchg_tl(oldv, cpu_A0, cmpv, newv,
5202 s->mem_index, ot | MO_LE);
5203 gen_op_mov_reg_v(ot, R_EAX, oldv);
5206 rm = (modrm & 7) | REX_B(s);
5207 gen_op_mov_v_reg(ot, oldv, rm);
5209 gen_lea_modrm(env, s, modrm);
5210 gen_op_ld_v(s, ot, oldv, cpu_A0);
5211 rm = 0; /* avoid warning */
5215 /* store value = (old == cmp ? new : old); */
5216 tcg_gen_movcond_tl(TCG_COND_EQ, newv, oldv, cmpv, newv, oldv);
5218 gen_op_mov_reg_v(ot, R_EAX, oldv);
5219 gen_op_mov_reg_v(ot, rm, newv);
5221 /* Perform an unconditional store cycle like physical cpu;
5222 must be before changing accumulator to ensure
5223 idempotency if the store faults and the instruction
5225 gen_op_st_v(s, ot, newv, cpu_A0);
5226 gen_op_mov_reg_v(ot, R_EAX, oldv);
5229 tcg_gen_mov_tl(cpu_cc_src, oldv);
5230 tcg_gen_mov_tl(cpu_cc_srcT, cmpv);
5231 tcg_gen_sub_tl(cpu_cc_dst, cmpv, oldv);
5232 set_cc_op(s, CC_OP_SUBB + ot);
5233 tcg_temp_free(oldv);
5234 tcg_temp_free(newv);
5235 tcg_temp_free(cmpv);
5238 case 0x1c7: /* cmpxchg8b */
5239 modrm = cpu_ldub_code(env, s->pc++);
5240 mod = (modrm >> 6) & 3;
5241 if ((mod == 3) || ((modrm & 0x38) != 0x8))
5243 #ifdef TARGET_X86_64
5244 if (dflag == MO_64) {
5245 if (!(s->cpuid_ext_features & CPUID_EXT_CX16))
5247 gen_lea_modrm(env, s, modrm);
5248 if ((s->prefix & PREFIX_LOCK) && parallel_cpus) {
5249 gen_helper_cmpxchg16b(cpu_env, cpu_A0);
5251 gen_helper_cmpxchg16b_unlocked(cpu_env, cpu_A0);
5256 if (!(s->cpuid_features & CPUID_CX8))
5258 gen_lea_modrm(env, s, modrm);
5259 if ((s->prefix & PREFIX_LOCK) && parallel_cpus) {
5260 gen_helper_cmpxchg8b(cpu_env, cpu_A0);
5262 gen_helper_cmpxchg8b_unlocked(cpu_env, cpu_A0);
5265 set_cc_op(s, CC_OP_EFLAGS);
5268 /**************************/
5270 case 0x50 ... 0x57: /* push */
5271 gen_op_mov_v_reg(MO_32, cpu_T0, (b & 7) | REX_B(s));
5272 gen_push_v(s, cpu_T0);
5274 case 0x58 ... 0x5f: /* pop */
5276 /* NOTE: order is important for pop %sp */
5277 gen_pop_update(s, ot);
5278 gen_op_mov_reg_v(ot, (b & 7) | REX_B(s), cpu_T0);
5280 case 0x60: /* pusha */
5285 case 0x61: /* popa */
5290 case 0x68: /* push Iv */
5292 ot = mo_pushpop(s, dflag);
5294 val = insn_get(env, s, ot);
5296 val = (int8_t)insn_get(env, s, MO_8);
5297 tcg_gen_movi_tl(cpu_T0, val);
5298 gen_push_v(s, cpu_T0);
5300 case 0x8f: /* pop Ev */
5301 modrm = cpu_ldub_code(env, s->pc++);
5302 mod = (modrm >> 6) & 3;
5305 /* NOTE: order is important for pop %sp */
5306 gen_pop_update(s, ot);
5307 rm = (modrm & 7) | REX_B(s);
5308 gen_op_mov_reg_v(ot, rm, cpu_T0);
5310 /* NOTE: order is important too for MMU exceptions */
5311 s->popl_esp_hack = 1 << ot;
5312 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5313 s->popl_esp_hack = 0;
5314 gen_pop_update(s, ot);
5317 case 0xc8: /* enter */
5320 val = cpu_lduw_code(env, s->pc);
5322 level = cpu_ldub_code(env, s->pc++);
5323 gen_enter(s, val, level);
5326 case 0xc9: /* leave */
5329 case 0x06: /* push es */
5330 case 0x0e: /* push cs */
5331 case 0x16: /* push ss */
5332 case 0x1e: /* push ds */
5335 gen_op_movl_T0_seg(b >> 3);
5336 gen_push_v(s, cpu_T0);
5338 case 0x1a0: /* push fs */
5339 case 0x1a8: /* push gs */
5340 gen_op_movl_T0_seg((b >> 3) & 7);
5341 gen_push_v(s, cpu_T0);
5343 case 0x07: /* pop es */
5344 case 0x17: /* pop ss */
5345 case 0x1f: /* pop ds */
5350 gen_movl_seg_T0(s, reg);
5351 gen_pop_update(s, ot);
5352 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5354 gen_jmp_im(s->pc - s->cs_base);
5357 gen_eob_inhibit_irq(s, true);
5363 case 0x1a1: /* pop fs */
5364 case 0x1a9: /* pop gs */
5366 gen_movl_seg_T0(s, (b >> 3) & 7);
5367 gen_pop_update(s, ot);
5369 gen_jmp_im(s->pc - s->cs_base);
5374 /**************************/
5377 case 0x89: /* mov Gv, Ev */
5378 ot = mo_b_d(b, dflag);
5379 modrm = cpu_ldub_code(env, s->pc++);
5380 reg = ((modrm >> 3) & 7) | rex_r;
5382 /* generate a generic store */
5383 gen_ldst_modrm(env, s, modrm, ot, reg, 1);
5386 case 0xc7: /* mov Ev, Iv */
5387 ot = mo_b_d(b, dflag);
5388 modrm = cpu_ldub_code(env, s->pc++);
5389 mod = (modrm >> 6) & 3;
5391 s->rip_offset = insn_const_size(ot);
5392 gen_lea_modrm(env, s, modrm);
5394 val = insn_get(env, s, ot);
5395 tcg_gen_movi_tl(cpu_T0, val);
5397 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
5399 gen_op_mov_reg_v(ot, (modrm & 7) | REX_B(s), cpu_T0);
5403 case 0x8b: /* mov Ev, Gv */
5404 ot = mo_b_d(b, dflag);
5405 modrm = cpu_ldub_code(env, s->pc++);
5406 reg = ((modrm >> 3) & 7) | rex_r;
5408 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5409 gen_op_mov_reg_v(ot, reg, cpu_T0);
5411 case 0x8e: /* mov seg, Gv */
5412 modrm = cpu_ldub_code(env, s->pc++);
5413 reg = (modrm >> 3) & 7;
5414 if (reg >= 6 || reg == R_CS)
5416 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
5417 gen_movl_seg_T0(s, reg);
5418 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5420 gen_jmp_im(s->pc - s->cs_base);
5423 gen_eob_inhibit_irq(s, true);
5429 case 0x8c: /* mov Gv, seg */
5430 modrm = cpu_ldub_code(env, s->pc++);
5431 reg = (modrm >> 3) & 7;
5432 mod = (modrm >> 6) & 3;
5435 gen_op_movl_T0_seg(reg);
5436 ot = mod == 3 ? dflag : MO_16;
5437 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5440 case 0x1b6: /* movzbS Gv, Eb */
5441 case 0x1b7: /* movzwS Gv, Eb */
5442 case 0x1be: /* movsbS Gv, Eb */
5443 case 0x1bf: /* movswS Gv, Eb */
5448 /* d_ot is the size of destination */
5450 /* ot is the size of source */
5451 ot = (b & 1) + MO_8;
5452 /* s_ot is the sign+size of source */
5453 s_ot = b & 8 ? MO_SIGN | ot : ot;
5455 modrm = cpu_ldub_code(env, s->pc++);
5456 reg = ((modrm >> 3) & 7) | rex_r;
5457 mod = (modrm >> 6) & 3;
5458 rm = (modrm & 7) | REX_B(s);
5461 if (s_ot == MO_SB && byte_reg_is_xH(rm)) {
5462 tcg_gen_sextract_tl(cpu_T0, cpu_regs[rm - 4], 8, 8);
5464 gen_op_mov_v_reg(ot, cpu_T0, rm);
5467 tcg_gen_ext8u_tl(cpu_T0, cpu_T0);
5470 tcg_gen_ext8s_tl(cpu_T0, cpu_T0);
5473 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
5477 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
5481 gen_op_mov_reg_v(d_ot, reg, cpu_T0);
5483 gen_lea_modrm(env, s, modrm);
5484 gen_op_ld_v(s, s_ot, cpu_T0, cpu_A0);
5485 gen_op_mov_reg_v(d_ot, reg, cpu_T0);
5490 case 0x8d: /* lea */
5491 modrm = cpu_ldub_code(env, s->pc++);
5492 mod = (modrm >> 6) & 3;
5495 reg = ((modrm >> 3) & 7) | rex_r;
5497 AddressParts a = gen_lea_modrm_0(env, s, modrm);
5498 TCGv ea = gen_lea_modrm_1(a);
5499 gen_lea_v_seg(s, s->aflag, ea, -1, -1);
5500 gen_op_mov_reg_v(dflag, reg, cpu_A0);
5504 case 0xa0: /* mov EAX, Ov */
5506 case 0xa2: /* mov Ov, EAX */
5509 target_ulong offset_addr;
5511 ot = mo_b_d(b, dflag);
5513 #ifdef TARGET_X86_64
5515 offset_addr = cpu_ldq_code(env, s->pc);
5520 offset_addr = insn_get(env, s, s->aflag);
5523 tcg_gen_movi_tl(cpu_A0, offset_addr);
5524 gen_add_A0_ds_seg(s);
5526 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
5527 gen_op_mov_reg_v(ot, R_EAX, cpu_T0);
5529 gen_op_mov_v_reg(ot, cpu_T0, R_EAX);
5530 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
5534 case 0xd7: /* xlat */
5535 tcg_gen_mov_tl(cpu_A0, cpu_regs[R_EBX]);
5536 tcg_gen_ext8u_tl(cpu_T0, cpu_regs[R_EAX]);
5537 tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T0);
5538 gen_extu(s->aflag, cpu_A0);
5539 gen_add_A0_ds_seg(s);
5540 gen_op_ld_v(s, MO_8, cpu_T0, cpu_A0);
5541 gen_op_mov_reg_v(MO_8, R_EAX, cpu_T0);
5543 case 0xb0 ... 0xb7: /* mov R, Ib */
5544 val = insn_get(env, s, MO_8);
5545 tcg_gen_movi_tl(cpu_T0, val);
5546 gen_op_mov_reg_v(MO_8, (b & 7) | REX_B(s), cpu_T0);
5548 case 0xb8 ... 0xbf: /* mov R, Iv */
5549 #ifdef TARGET_X86_64
5550 if (dflag == MO_64) {
5553 tmp = cpu_ldq_code(env, s->pc);
5555 reg = (b & 7) | REX_B(s);
5556 tcg_gen_movi_tl(cpu_T0, tmp);
5557 gen_op_mov_reg_v(MO_64, reg, cpu_T0);
5562 val = insn_get(env, s, ot);
5563 reg = (b & 7) | REX_B(s);
5564 tcg_gen_movi_tl(cpu_T0, val);
5565 gen_op_mov_reg_v(ot, reg, cpu_T0);
5569 case 0x91 ... 0x97: /* xchg R, EAX */
5572 reg = (b & 7) | REX_B(s);
5576 case 0x87: /* xchg Ev, Gv */
5577 ot = mo_b_d(b, dflag);
5578 modrm = cpu_ldub_code(env, s->pc++);
5579 reg = ((modrm >> 3) & 7) | rex_r;
5580 mod = (modrm >> 6) & 3;
5582 rm = (modrm & 7) | REX_B(s);
5584 gen_op_mov_v_reg(ot, cpu_T0, reg);
5585 gen_op_mov_v_reg(ot, cpu_T1, rm);
5586 gen_op_mov_reg_v(ot, rm, cpu_T0);
5587 gen_op_mov_reg_v(ot, reg, cpu_T1);
5589 gen_lea_modrm(env, s, modrm);
5590 gen_op_mov_v_reg(ot, cpu_T0, reg);
5591 /* for xchg, lock is implicit */
5592 tcg_gen_atomic_xchg_tl(cpu_T1, cpu_A0, cpu_T0,
5593 s->mem_index, ot | MO_LE);
5594 gen_op_mov_reg_v(ot, reg, cpu_T1);
5597 case 0xc4: /* les Gv */
5598 /* In CODE64 this is VEX3; see above. */
5601 case 0xc5: /* lds Gv */
5602 /* In CODE64 this is VEX2; see above. */
5605 case 0x1b2: /* lss Gv */
5608 case 0x1b4: /* lfs Gv */
5611 case 0x1b5: /* lgs Gv */
5614 ot = dflag != MO_16 ? MO_32 : MO_16;
5615 modrm = cpu_ldub_code(env, s->pc++);
5616 reg = ((modrm >> 3) & 7) | rex_r;
5617 mod = (modrm >> 6) & 3;
5620 gen_lea_modrm(env, s, modrm);
5621 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
5622 gen_add_A0_im(s, 1 << ot);
5623 /* load the segment first to handle exceptions properly */
5624 gen_op_ld_v(s, MO_16, cpu_T0, cpu_A0);
5625 gen_movl_seg_T0(s, op);
5626 /* then put the data */
5627 gen_op_mov_reg_v(ot, reg, cpu_T1);
5629 gen_jmp_im(s->pc - s->cs_base);
5634 /************************/
5642 ot = mo_b_d(b, dflag);
5643 modrm = cpu_ldub_code(env, s->pc++);
5644 mod = (modrm >> 6) & 3;
5645 op = (modrm >> 3) & 7;
5651 gen_lea_modrm(env, s, modrm);
5654 opreg = (modrm & 7) | REX_B(s);
5659 gen_shift(s, op, ot, opreg, OR_ECX);
5662 shift = cpu_ldub_code(env, s->pc++);
5664 gen_shifti(s, op, ot, opreg, shift);
5679 case 0x1a4: /* shld imm */
5683 case 0x1a5: /* shld cl */
5687 case 0x1ac: /* shrd imm */
5691 case 0x1ad: /* shrd cl */
5696 modrm = cpu_ldub_code(env, s->pc++);
5697 mod = (modrm >> 6) & 3;
5698 rm = (modrm & 7) | REX_B(s);
5699 reg = ((modrm >> 3) & 7) | rex_r;
5701 gen_lea_modrm(env, s, modrm);
5706 gen_op_mov_v_reg(ot, cpu_T1, reg);
5709 TCGv imm = tcg_const_tl(cpu_ldub_code(env, s->pc++));
5710 gen_shiftd_rm_T1(s, ot, opreg, op, imm);
5713 gen_shiftd_rm_T1(s, ot, opreg, op, cpu_regs[R_ECX]);
5717 /************************/
5720 if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
5721 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5722 /* XXX: what to do if illegal op ? */
5723 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
5726 modrm = cpu_ldub_code(env, s->pc++);
5727 mod = (modrm >> 6) & 3;
5729 op = ((b & 7) << 3) | ((modrm >> 3) & 7);
5732 gen_lea_modrm(env, s, modrm);
5734 case 0x00 ... 0x07: /* fxxxs */
5735 case 0x10 ... 0x17: /* fixxxl */
5736 case 0x20 ... 0x27: /* fxxxl */
5737 case 0x30 ... 0x37: /* fixxx */
5744 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5745 s->mem_index, MO_LEUL);
5746 gen_helper_flds_FT0(cpu_env, cpu_tmp2_i32);
5749 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5750 s->mem_index, MO_LEUL);
5751 gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32);
5754 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0,
5755 s->mem_index, MO_LEQ);
5756 gen_helper_fldl_FT0(cpu_env, cpu_tmp1_i64);
5760 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5761 s->mem_index, MO_LESW);
5762 gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32);
5766 gen_helper_fp_arith_ST0_FT0(op1);
5768 /* fcomp needs pop */
5769 gen_helper_fpop(cpu_env);
5773 case 0x08: /* flds */
5774 case 0x0a: /* fsts */
5775 case 0x0b: /* fstps */
5776 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5777 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5778 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5783 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5784 s->mem_index, MO_LEUL);
5785 gen_helper_flds_ST0(cpu_env, cpu_tmp2_i32);
5788 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5789 s->mem_index, MO_LEUL);
5790 gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32);
5793 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0,
5794 s->mem_index, MO_LEQ);
5795 gen_helper_fldl_ST0(cpu_env, cpu_tmp1_i64);
5799 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5800 s->mem_index, MO_LESW);
5801 gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32);
5806 /* XXX: the corresponding CPUID bit must be tested ! */
5809 gen_helper_fisttl_ST0(cpu_tmp2_i32, cpu_env);
5810 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5811 s->mem_index, MO_LEUL);
5814 gen_helper_fisttll_ST0(cpu_tmp1_i64, cpu_env);
5815 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0,
5816 s->mem_index, MO_LEQ);
5820 gen_helper_fistt_ST0(cpu_tmp2_i32, cpu_env);
5821 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5822 s->mem_index, MO_LEUW);
5825 gen_helper_fpop(cpu_env);
5830 gen_helper_fsts_ST0(cpu_tmp2_i32, cpu_env);
5831 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5832 s->mem_index, MO_LEUL);
5835 gen_helper_fistl_ST0(cpu_tmp2_i32, cpu_env);
5836 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5837 s->mem_index, MO_LEUL);
5840 gen_helper_fstl_ST0(cpu_tmp1_i64, cpu_env);
5841 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0,
5842 s->mem_index, MO_LEQ);
5846 gen_helper_fist_ST0(cpu_tmp2_i32, cpu_env);
5847 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5848 s->mem_index, MO_LEUW);
5852 gen_helper_fpop(cpu_env);
5856 case 0x0c: /* fldenv mem */
5857 gen_helper_fldenv(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5859 case 0x0d: /* fldcw mem */
5860 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5861 s->mem_index, MO_LEUW);
5862 gen_helper_fldcw(cpu_env, cpu_tmp2_i32);
5864 case 0x0e: /* fnstenv mem */
5865 gen_helper_fstenv(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5867 case 0x0f: /* fnstcw mem */
5868 gen_helper_fnstcw(cpu_tmp2_i32, cpu_env);
5869 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5870 s->mem_index, MO_LEUW);
5872 case 0x1d: /* fldt mem */
5873 gen_helper_fldt_ST0(cpu_env, cpu_A0);
5875 case 0x1f: /* fstpt mem */
5876 gen_helper_fstt_ST0(cpu_env, cpu_A0);
5877 gen_helper_fpop(cpu_env);
5879 case 0x2c: /* frstor mem */
5880 gen_helper_frstor(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5882 case 0x2e: /* fnsave mem */
5883 gen_helper_fsave(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5885 case 0x2f: /* fnstsw mem */
5886 gen_helper_fnstsw(cpu_tmp2_i32, cpu_env);
5887 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5888 s->mem_index, MO_LEUW);
5890 case 0x3c: /* fbld */
5891 gen_helper_fbld_ST0(cpu_env, cpu_A0);
5893 case 0x3e: /* fbstp */
5894 gen_helper_fbst_ST0(cpu_env, cpu_A0);
5895 gen_helper_fpop(cpu_env);
5897 case 0x3d: /* fildll */
5898 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
5899 gen_helper_fildll_ST0(cpu_env, cpu_tmp1_i64);
5901 case 0x3f: /* fistpll */
5902 gen_helper_fistll_ST0(cpu_tmp1_i64, cpu_env);
5903 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
5904 gen_helper_fpop(cpu_env);
5910 /* register float ops */
5914 case 0x08: /* fld sti */
5915 gen_helper_fpush(cpu_env);
5916 gen_helper_fmov_ST0_STN(cpu_env,
5917 tcg_const_i32((opreg + 1) & 7));
5919 case 0x09: /* fxchg sti */
5920 case 0x29: /* fxchg4 sti, undocumented op */
5921 case 0x39: /* fxchg7 sti, undocumented op */
5922 gen_helper_fxchg_ST0_STN(cpu_env, tcg_const_i32(opreg));
5924 case 0x0a: /* grp d9/2 */
5927 /* check exceptions (FreeBSD FPU probe) */
5928 gen_helper_fwait(cpu_env);
5934 case 0x0c: /* grp d9/4 */
5937 gen_helper_fchs_ST0(cpu_env);
5940 gen_helper_fabs_ST0(cpu_env);
5943 gen_helper_fldz_FT0(cpu_env);
5944 gen_helper_fcom_ST0_FT0(cpu_env);
5947 gen_helper_fxam_ST0(cpu_env);
5953 case 0x0d: /* grp d9/5 */
5957 gen_helper_fpush(cpu_env);
5958 gen_helper_fld1_ST0(cpu_env);
5961 gen_helper_fpush(cpu_env);
5962 gen_helper_fldl2t_ST0(cpu_env);
5965 gen_helper_fpush(cpu_env);
5966 gen_helper_fldl2e_ST0(cpu_env);
5969 gen_helper_fpush(cpu_env);
5970 gen_helper_fldpi_ST0(cpu_env);
5973 gen_helper_fpush(cpu_env);
5974 gen_helper_fldlg2_ST0(cpu_env);
5977 gen_helper_fpush(cpu_env);
5978 gen_helper_fldln2_ST0(cpu_env);
5981 gen_helper_fpush(cpu_env);
5982 gen_helper_fldz_ST0(cpu_env);
5989 case 0x0e: /* grp d9/6 */
5992 gen_helper_f2xm1(cpu_env);
5995 gen_helper_fyl2x(cpu_env);
5998 gen_helper_fptan(cpu_env);
6000 case 3: /* fpatan */
6001 gen_helper_fpatan(cpu_env);
6003 case 4: /* fxtract */
6004 gen_helper_fxtract(cpu_env);
6006 case 5: /* fprem1 */
6007 gen_helper_fprem1(cpu_env);
6009 case 6: /* fdecstp */
6010 gen_helper_fdecstp(cpu_env);
6013 case 7: /* fincstp */
6014 gen_helper_fincstp(cpu_env);
6018 case 0x0f: /* grp d9/7 */
6021 gen_helper_fprem(cpu_env);
6023 case 1: /* fyl2xp1 */
6024 gen_helper_fyl2xp1(cpu_env);
6027 gen_helper_fsqrt(cpu_env);
6029 case 3: /* fsincos */
6030 gen_helper_fsincos(cpu_env);
6032 case 5: /* fscale */
6033 gen_helper_fscale(cpu_env);
6035 case 4: /* frndint */
6036 gen_helper_frndint(cpu_env);
6039 gen_helper_fsin(cpu_env);
6043 gen_helper_fcos(cpu_env);
6047 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6048 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6049 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6055 gen_helper_fp_arith_STN_ST0(op1, opreg);
6057 gen_helper_fpop(cpu_env);
6059 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6060 gen_helper_fp_arith_ST0_FT0(op1);
6064 case 0x02: /* fcom */
6065 case 0x22: /* fcom2, undocumented op */
6066 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6067 gen_helper_fcom_ST0_FT0(cpu_env);
6069 case 0x03: /* fcomp */
6070 case 0x23: /* fcomp3, undocumented op */
6071 case 0x32: /* fcomp5, undocumented op */
6072 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6073 gen_helper_fcom_ST0_FT0(cpu_env);
6074 gen_helper_fpop(cpu_env);
6076 case 0x15: /* da/5 */
6078 case 1: /* fucompp */
6079 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
6080 gen_helper_fucom_ST0_FT0(cpu_env);
6081 gen_helper_fpop(cpu_env);
6082 gen_helper_fpop(cpu_env);
6090 case 0: /* feni (287 only, just do nop here) */
6092 case 1: /* fdisi (287 only, just do nop here) */
6095 gen_helper_fclex(cpu_env);
6097 case 3: /* fninit */
6098 gen_helper_fninit(cpu_env);
6100 case 4: /* fsetpm (287 only, just do nop here) */
6106 case 0x1d: /* fucomi */
6107 if (!(s->cpuid_features & CPUID_CMOV)) {
6110 gen_update_cc_op(s);
6111 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6112 gen_helper_fucomi_ST0_FT0(cpu_env);
6113 set_cc_op(s, CC_OP_EFLAGS);
6115 case 0x1e: /* fcomi */
6116 if (!(s->cpuid_features & CPUID_CMOV)) {
6119 gen_update_cc_op(s);
6120 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6121 gen_helper_fcomi_ST0_FT0(cpu_env);
6122 set_cc_op(s, CC_OP_EFLAGS);
6124 case 0x28: /* ffree sti */
6125 gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
6127 case 0x2a: /* fst sti */
6128 gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
6130 case 0x2b: /* fstp sti */
6131 case 0x0b: /* fstp1 sti, undocumented op */
6132 case 0x3a: /* fstp8 sti, undocumented op */
6133 case 0x3b: /* fstp9 sti, undocumented op */
6134 gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
6135 gen_helper_fpop(cpu_env);
6137 case 0x2c: /* fucom st(i) */
6138 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6139 gen_helper_fucom_ST0_FT0(cpu_env);
6141 case 0x2d: /* fucomp st(i) */
6142 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6143 gen_helper_fucom_ST0_FT0(cpu_env);
6144 gen_helper_fpop(cpu_env);
6146 case 0x33: /* de/3 */
6148 case 1: /* fcompp */
6149 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
6150 gen_helper_fcom_ST0_FT0(cpu_env);
6151 gen_helper_fpop(cpu_env);
6152 gen_helper_fpop(cpu_env);
6158 case 0x38: /* ffreep sti, undocumented op */
6159 gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
6160 gen_helper_fpop(cpu_env);
6162 case 0x3c: /* df/4 */
6165 gen_helper_fnstsw(cpu_tmp2_i32, cpu_env);
6166 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
6167 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
6173 case 0x3d: /* fucomip */
6174 if (!(s->cpuid_features & CPUID_CMOV)) {
6177 gen_update_cc_op(s);
6178 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6179 gen_helper_fucomi_ST0_FT0(cpu_env);
6180 gen_helper_fpop(cpu_env);
6181 set_cc_op(s, CC_OP_EFLAGS);
6183 case 0x3e: /* fcomip */
6184 if (!(s->cpuid_features & CPUID_CMOV)) {
6187 gen_update_cc_op(s);
6188 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6189 gen_helper_fcomi_ST0_FT0(cpu_env);
6190 gen_helper_fpop(cpu_env);
6191 set_cc_op(s, CC_OP_EFLAGS);
6193 case 0x10 ... 0x13: /* fcmovxx */
6198 static const uint8_t fcmov_cc[8] = {
6205 if (!(s->cpuid_features & CPUID_CMOV)) {
6208 op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1);
6209 l1 = gen_new_label();
6210 gen_jcc1_noeob(s, op1, l1);
6211 gen_helper_fmov_ST0_STN(cpu_env, tcg_const_i32(opreg));
6220 /************************/
6223 case 0xa4: /* movsS */
6225 ot = mo_b_d(b, dflag);
6226 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6227 gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6233 case 0xaa: /* stosS */
6235 ot = mo_b_d(b, dflag);
6236 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6237 gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6242 case 0xac: /* lodsS */
6244 ot = mo_b_d(b, dflag);
6245 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6246 gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6251 case 0xae: /* scasS */
6253 ot = mo_b_d(b, dflag);
6254 if (prefixes & PREFIX_REPNZ) {
6255 gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
6256 } else if (prefixes & PREFIX_REPZ) {
6257 gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
6263 case 0xa6: /* cmpsS */
6265 ot = mo_b_d(b, dflag);
6266 if (prefixes & PREFIX_REPNZ) {
6267 gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
6268 } else if (prefixes & PREFIX_REPZ) {
6269 gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
6274 case 0x6c: /* insS */
6276 ot = mo_b_d32(b, dflag);
6277 tcg_gen_ext16u_tl(cpu_T0, cpu_regs[R_EDX]);
6278 gen_check_io(s, ot, pc_start - s->cs_base,
6279 SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) | 4);
6280 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6281 gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6284 if (s->tb->cflags & CF_USE_ICOUNT) {
6285 gen_jmp(s, s->pc - s->cs_base);
6289 case 0x6e: /* outsS */
6291 ot = mo_b_d32(b, dflag);
6292 tcg_gen_ext16u_tl(cpu_T0, cpu_regs[R_EDX]);
6293 gen_check_io(s, ot, pc_start - s->cs_base,
6294 svm_is_rep(prefixes) | 4);
6295 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6296 gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6299 if (s->tb->cflags & CF_USE_ICOUNT) {
6300 gen_jmp(s, s->pc - s->cs_base);
6305 /************************/
6310 ot = mo_b_d32(b, dflag);
6311 val = cpu_ldub_code(env, s->pc++);
6312 tcg_gen_movi_tl(cpu_T0, val);
6313 gen_check_io(s, ot, pc_start - s->cs_base,
6314 SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6315 if (s->tb->cflags & CF_USE_ICOUNT) {
6318 tcg_gen_movi_i32(cpu_tmp2_i32, val);
6319 gen_helper_in_func(ot, cpu_T1, cpu_tmp2_i32);
6320 gen_op_mov_reg_v(ot, R_EAX, cpu_T1);
6321 gen_bpt_io(s, cpu_tmp2_i32, ot);
6322 if (s->tb->cflags & CF_USE_ICOUNT) {
6324 gen_jmp(s, s->pc - s->cs_base);
6329 ot = mo_b_d32(b, dflag);
6330 val = cpu_ldub_code(env, s->pc++);
6331 tcg_gen_movi_tl(cpu_T0, val);
6332 gen_check_io(s, ot, pc_start - s->cs_base,
6333 svm_is_rep(prefixes));
6334 gen_op_mov_v_reg(ot, cpu_T1, R_EAX);
6336 if (s->tb->cflags & CF_USE_ICOUNT) {
6339 tcg_gen_movi_i32(cpu_tmp2_i32, val);
6340 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T1);
6341 gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6342 gen_bpt_io(s, cpu_tmp2_i32, ot);
6343 if (s->tb->cflags & CF_USE_ICOUNT) {
6345 gen_jmp(s, s->pc - s->cs_base);
6350 ot = mo_b_d32(b, dflag);
6351 tcg_gen_ext16u_tl(cpu_T0, cpu_regs[R_EDX]);
6352 gen_check_io(s, ot, pc_start - s->cs_base,
6353 SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6354 if (s->tb->cflags & CF_USE_ICOUNT) {
6357 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
6358 gen_helper_in_func(ot, cpu_T1, cpu_tmp2_i32);
6359 gen_op_mov_reg_v(ot, R_EAX, cpu_T1);
6360 gen_bpt_io(s, cpu_tmp2_i32, ot);
6361 if (s->tb->cflags & CF_USE_ICOUNT) {
6363 gen_jmp(s, s->pc - s->cs_base);
6368 ot = mo_b_d32(b, dflag);
6369 tcg_gen_ext16u_tl(cpu_T0, cpu_regs[R_EDX]);
6370 gen_check_io(s, ot, pc_start - s->cs_base,
6371 svm_is_rep(prefixes));
6372 gen_op_mov_v_reg(ot, cpu_T1, R_EAX);
6374 if (s->tb->cflags & CF_USE_ICOUNT) {
6377 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
6378 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T1);
6379 gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6380 gen_bpt_io(s, cpu_tmp2_i32, ot);
6381 if (s->tb->cflags & CF_USE_ICOUNT) {
6383 gen_jmp(s, s->pc - s->cs_base);
6387 /************************/
6389 case 0xc2: /* ret im */
6390 val = cpu_ldsw_code(env, s->pc);
6393 gen_stack_update(s, val + (1 << ot));
6394 /* Note that gen_pop_T0 uses a zero-extending load. */
6395 gen_op_jmp_v(cpu_T0);
6399 case 0xc3: /* ret */
6401 gen_pop_update(s, ot);
6402 /* Note that gen_pop_T0 uses a zero-extending load. */
6403 gen_op_jmp_v(cpu_T0);
6407 case 0xca: /* lret im */
6408 val = cpu_ldsw_code(env, s->pc);
6411 if (s->pe && !s->vm86) {
6412 gen_update_cc_op(s);
6413 gen_jmp_im(pc_start - s->cs_base);
6414 gen_helper_lret_protected(cpu_env, tcg_const_i32(dflag - 1),
6415 tcg_const_i32(val));
6419 gen_op_ld_v(s, dflag, cpu_T0, cpu_A0);
6420 /* NOTE: keeping EIP updated is not a problem in case of
6422 gen_op_jmp_v(cpu_T0);
6424 gen_add_A0_im(s, 1 << dflag);
6425 gen_op_ld_v(s, dflag, cpu_T0, cpu_A0);
6426 gen_op_movl_seg_T0_vm(R_CS);
6427 /* add stack offset */
6428 gen_stack_update(s, val + (2 << dflag));
6432 case 0xcb: /* lret */
6435 case 0xcf: /* iret */
6436 gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET);
6439 gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
6440 set_cc_op(s, CC_OP_EFLAGS);
6441 } else if (s->vm86) {
6443 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6445 gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
6446 set_cc_op(s, CC_OP_EFLAGS);
6449 gen_helper_iret_protected(cpu_env, tcg_const_i32(dflag - 1),
6450 tcg_const_i32(s->pc - s->cs_base));
6451 set_cc_op(s, CC_OP_EFLAGS);
6455 case 0xe8: /* call im */
6457 if (dflag != MO_16) {
6458 tval = (int32_t)insn_get(env, s, MO_32);
6460 tval = (int16_t)insn_get(env, s, MO_16);
6462 next_eip = s->pc - s->cs_base;
6464 if (dflag == MO_16) {
6466 } else if (!CODE64(s)) {
6469 tcg_gen_movi_tl(cpu_T0, next_eip);
6470 gen_push_v(s, cpu_T0);
6475 case 0x9a: /* lcall im */
6477 unsigned int selector, offset;
6482 offset = insn_get(env, s, ot);
6483 selector = insn_get(env, s, MO_16);
6485 tcg_gen_movi_tl(cpu_T0, selector);
6486 tcg_gen_movi_tl(cpu_T1, offset);
6489 case 0xe9: /* jmp im */
6490 if (dflag != MO_16) {
6491 tval = (int32_t)insn_get(env, s, MO_32);
6493 tval = (int16_t)insn_get(env, s, MO_16);
6495 tval += s->pc - s->cs_base;
6496 if (dflag == MO_16) {
6498 } else if (!CODE64(s)) {
6504 case 0xea: /* ljmp im */
6506 unsigned int selector, offset;
6511 offset = insn_get(env, s, ot);
6512 selector = insn_get(env, s, MO_16);
6514 tcg_gen_movi_tl(cpu_T0, selector);
6515 tcg_gen_movi_tl(cpu_T1, offset);
6518 case 0xeb: /* jmp Jb */
6519 tval = (int8_t)insn_get(env, s, MO_8);
6520 tval += s->pc - s->cs_base;
6521 if (dflag == MO_16) {
6526 case 0x70 ... 0x7f: /* jcc Jb */
6527 tval = (int8_t)insn_get(env, s, MO_8);
6529 case 0x180 ... 0x18f: /* jcc Jv */
6530 if (dflag != MO_16) {
6531 tval = (int32_t)insn_get(env, s, MO_32);
6533 tval = (int16_t)insn_get(env, s, MO_16);
6536 next_eip = s->pc - s->cs_base;
6538 if (dflag == MO_16) {
6542 gen_jcc(s, b, tval, next_eip);
6545 case 0x190 ... 0x19f: /* setcc Gv */
6546 modrm = cpu_ldub_code(env, s->pc++);
6547 gen_setcc1(s, b, cpu_T0);
6548 gen_ldst_modrm(env, s, modrm, MO_8, OR_TMP0, 1);
6550 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6551 if (!(s->cpuid_features & CPUID_CMOV)) {
6555 modrm = cpu_ldub_code(env, s->pc++);
6556 reg = ((modrm >> 3) & 7) | rex_r;
6557 gen_cmovcc1(env, s, ot, b, modrm, reg);
6560 /************************/
6562 case 0x9c: /* pushf */
6563 gen_svm_check_intercept(s, pc_start, SVM_EXIT_PUSHF);
6564 if (s->vm86 && s->iopl != 3) {
6565 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6567 gen_update_cc_op(s);
6568 gen_helper_read_eflags(cpu_T0, cpu_env);
6569 gen_push_v(s, cpu_T0);
6572 case 0x9d: /* popf */
6573 gen_svm_check_intercept(s, pc_start, SVM_EXIT_POPF);
6574 if (s->vm86 && s->iopl != 3) {
6575 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6579 if (dflag != MO_16) {
6580 gen_helper_write_eflags(cpu_env, cpu_T0,
6581 tcg_const_i32((TF_MASK | AC_MASK |
6586 gen_helper_write_eflags(cpu_env, cpu_T0,
6587 tcg_const_i32((TF_MASK | AC_MASK |
6589 IF_MASK | IOPL_MASK)
6593 if (s->cpl <= s->iopl) {
6594 if (dflag != MO_16) {
6595 gen_helper_write_eflags(cpu_env, cpu_T0,
6596 tcg_const_i32((TF_MASK |
6602 gen_helper_write_eflags(cpu_env, cpu_T0,
6603 tcg_const_i32((TF_MASK |
6611 if (dflag != MO_16) {
6612 gen_helper_write_eflags(cpu_env, cpu_T0,
6613 tcg_const_i32((TF_MASK | AC_MASK |
6614 ID_MASK | NT_MASK)));
6616 gen_helper_write_eflags(cpu_env, cpu_T0,
6617 tcg_const_i32((TF_MASK | AC_MASK |
6623 gen_pop_update(s, ot);
6624 set_cc_op(s, CC_OP_EFLAGS);
6625 /* abort translation because TF/AC flag may change */
6626 gen_jmp_im(s->pc - s->cs_base);
6630 case 0x9e: /* sahf */
6631 if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6633 gen_op_mov_v_reg(MO_8, cpu_T0, R_AH);
6634 gen_compute_eflags(s);
6635 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O);
6636 tcg_gen_andi_tl(cpu_T0, cpu_T0, CC_S | CC_Z | CC_A | CC_P | CC_C);
6637 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_T0);
6639 case 0x9f: /* lahf */
6640 if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6642 gen_compute_eflags(s);
6643 /* Note: gen_compute_eflags() only gives the condition codes */
6644 tcg_gen_ori_tl(cpu_T0, cpu_cc_src, 0x02);
6645 gen_op_mov_reg_v(MO_8, R_AH, cpu_T0);
6647 case 0xf5: /* cmc */
6648 gen_compute_eflags(s);
6649 tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6651 case 0xf8: /* clc */
6652 gen_compute_eflags(s);
6653 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C);
6655 case 0xf9: /* stc */
6656 gen_compute_eflags(s);
6657 tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6659 case 0xfc: /* cld */
6660 tcg_gen_movi_i32(cpu_tmp2_i32, 1);
6661 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, df));
6663 case 0xfd: /* std */
6664 tcg_gen_movi_i32(cpu_tmp2_i32, -1);
6665 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, df));
6668 /************************/
6669 /* bit operations */
6670 case 0x1ba: /* bt/bts/btr/btc Gv, im */
6672 modrm = cpu_ldub_code(env, s->pc++);
6673 op = (modrm >> 3) & 7;
6674 mod = (modrm >> 6) & 3;
6675 rm = (modrm & 7) | REX_B(s);
6678 gen_lea_modrm(env, s, modrm);
6679 if (!(s->prefix & PREFIX_LOCK)) {
6680 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
6683 gen_op_mov_v_reg(ot, cpu_T0, rm);
6686 val = cpu_ldub_code(env, s->pc++);
6687 tcg_gen_movi_tl(cpu_T1, val);
6692 case 0x1a3: /* bt Gv, Ev */
6695 case 0x1ab: /* bts */
6698 case 0x1b3: /* btr */
6701 case 0x1bb: /* btc */
6705 modrm = cpu_ldub_code(env, s->pc++);
6706 reg = ((modrm >> 3) & 7) | rex_r;
6707 mod = (modrm >> 6) & 3;
6708 rm = (modrm & 7) | REX_B(s);
6709 gen_op_mov_v_reg(MO_32, cpu_T1, reg);
6711 AddressParts a = gen_lea_modrm_0(env, s, modrm);
6712 /* specific case: we need to add a displacement */
6713 gen_exts(ot, cpu_T1);
6714 tcg_gen_sari_tl(cpu_tmp0, cpu_T1, 3 + ot);
6715 tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, ot);
6716 tcg_gen_add_tl(cpu_A0, gen_lea_modrm_1(a), cpu_tmp0);
6717 gen_lea_v_seg(s, s->aflag, cpu_A0, a.def_seg, s->override);
6718 if (!(s->prefix & PREFIX_LOCK)) {
6719 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
6722 gen_op_mov_v_reg(ot, cpu_T0, rm);
6725 tcg_gen_andi_tl(cpu_T1, cpu_T1, (1 << (3 + ot)) - 1);
6726 tcg_gen_movi_tl(cpu_tmp0, 1);
6727 tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T1);
6728 if (s->prefix & PREFIX_LOCK) {
6731 /* Needs no atomic ops; we surpressed the normal
6732 memory load for LOCK above so do it now. */
6733 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
6736 tcg_gen_atomic_fetch_or_tl(cpu_T0, cpu_A0, cpu_tmp0,
6737 s->mem_index, ot | MO_LE);
6740 tcg_gen_not_tl(cpu_tmp0, cpu_tmp0);
6741 tcg_gen_atomic_fetch_and_tl(cpu_T0, cpu_A0, cpu_tmp0,
6742 s->mem_index, ot | MO_LE);
6746 tcg_gen_atomic_fetch_xor_tl(cpu_T0, cpu_A0, cpu_tmp0,
6747 s->mem_index, ot | MO_LE);
6750 tcg_gen_shr_tl(cpu_tmp4, cpu_T0, cpu_T1);
6752 tcg_gen_shr_tl(cpu_tmp4, cpu_T0, cpu_T1);
6755 /* Data already loaded; nothing to do. */
6758 tcg_gen_or_tl(cpu_T0, cpu_T0, cpu_tmp0);
6761 tcg_gen_andc_tl(cpu_T0, cpu_T0, cpu_tmp0);
6765 tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_tmp0);
6770 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
6772 gen_op_mov_reg_v(ot, rm, cpu_T0);
6777 /* Delay all CC updates until after the store above. Note that
6778 C is the result of the test, Z is unchanged, and the others
6779 are all undefined. */
6781 case CC_OP_MULB ... CC_OP_MULQ:
6782 case CC_OP_ADDB ... CC_OP_ADDQ:
6783 case CC_OP_ADCB ... CC_OP_ADCQ:
6784 case CC_OP_SUBB ... CC_OP_SUBQ:
6785 case CC_OP_SBBB ... CC_OP_SBBQ:
6786 case CC_OP_LOGICB ... CC_OP_LOGICQ:
6787 case CC_OP_INCB ... CC_OP_INCQ:
6788 case CC_OP_DECB ... CC_OP_DECQ:
6789 case CC_OP_SHLB ... CC_OP_SHLQ:
6790 case CC_OP_SARB ... CC_OP_SARQ:
6791 case CC_OP_BMILGB ... CC_OP_BMILGQ:
6792 /* Z was going to be computed from the non-zero status of CC_DST.
6793 We can get that same Z value (and the new C value) by leaving
6794 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
6796 tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
6797 set_cc_op(s, ((s->cc_op - CC_OP_MULB) & 3) + CC_OP_SARB);
6800 /* Otherwise, generate EFLAGS and replace the C bit. */
6801 gen_compute_eflags(s);
6802 tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, cpu_tmp4,
6807 case 0x1bc: /* bsf / tzcnt */
6808 case 0x1bd: /* bsr / lzcnt */
6810 modrm = cpu_ldub_code(env, s->pc++);
6811 reg = ((modrm >> 3) & 7) | rex_r;
6812 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
6813 gen_extu(ot, cpu_T0);
6815 /* Note that lzcnt and tzcnt are in different extensions. */
6816 if ((prefixes & PREFIX_REPZ)
6818 ? s->cpuid_ext3_features & CPUID_EXT3_ABM
6819 : s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)) {
6821 /* For lzcnt/tzcnt, C bit is defined related to the input. */
6822 tcg_gen_mov_tl(cpu_cc_src, cpu_T0);
6824 /* For lzcnt, reduce the target_ulong result by the
6825 number of zeros that we expect to find at the top. */
6826 tcg_gen_clzi_tl(cpu_T0, cpu_T0, TARGET_LONG_BITS);
6827 tcg_gen_subi_tl(cpu_T0, cpu_T0, TARGET_LONG_BITS - size);
6829 /* For tzcnt, a zero input must return the operand size. */
6830 tcg_gen_ctzi_tl(cpu_T0, cpu_T0, size);
6832 /* For lzcnt/tzcnt, Z bit is defined related to the result. */
6833 gen_op_update1_cc();
6834 set_cc_op(s, CC_OP_BMILGB + ot);
6836 /* For bsr/bsf, only the Z bit is defined and it is related
6837 to the input and not the result. */
6838 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
6839 set_cc_op(s, CC_OP_LOGICB + ot);
6841 /* ??? The manual says that the output is undefined when the
6842 input is zero, but real hardware leaves it unchanged, and
6843 real programs appear to depend on that. Accomplish this
6844 by passing the output as the value to return upon zero. */
6846 /* For bsr, return the bit index of the first 1 bit,
6847 not the count of leading zeros. */
6848 tcg_gen_xori_tl(cpu_T1, cpu_regs[reg], TARGET_LONG_BITS - 1);
6849 tcg_gen_clz_tl(cpu_T0, cpu_T0, cpu_T1);
6850 tcg_gen_xori_tl(cpu_T0, cpu_T0, TARGET_LONG_BITS - 1);
6852 tcg_gen_ctz_tl(cpu_T0, cpu_T0, cpu_regs[reg]);
6855 gen_op_mov_reg_v(ot, reg, cpu_T0);
6857 /************************/
6859 case 0x27: /* daa */
6862 gen_update_cc_op(s);
6863 gen_helper_daa(cpu_env);
6864 set_cc_op(s, CC_OP_EFLAGS);
6866 case 0x2f: /* das */
6869 gen_update_cc_op(s);
6870 gen_helper_das(cpu_env);
6871 set_cc_op(s, CC_OP_EFLAGS);
6873 case 0x37: /* aaa */
6876 gen_update_cc_op(s);
6877 gen_helper_aaa(cpu_env);
6878 set_cc_op(s, CC_OP_EFLAGS);
6880 case 0x3f: /* aas */
6883 gen_update_cc_op(s);
6884 gen_helper_aas(cpu_env);
6885 set_cc_op(s, CC_OP_EFLAGS);
6887 case 0xd4: /* aam */
6890 val = cpu_ldub_code(env, s->pc++);
6892 gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base);
6894 gen_helper_aam(cpu_env, tcg_const_i32(val));
6895 set_cc_op(s, CC_OP_LOGICB);
6898 case 0xd5: /* aad */
6901 val = cpu_ldub_code(env, s->pc++);
6902 gen_helper_aad(cpu_env, tcg_const_i32(val));
6903 set_cc_op(s, CC_OP_LOGICB);
6905 /************************/
6907 case 0x90: /* nop */
6908 /* XXX: correct lock test for all insn */
6909 if (prefixes & PREFIX_LOCK) {
6912 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
6914 goto do_xchg_reg_eax;
6916 if (prefixes & PREFIX_REPZ) {
6917 gen_update_cc_op(s);
6918 gen_jmp_im(pc_start - s->cs_base);
6919 gen_helper_pause(cpu_env, tcg_const_i32(s->pc - pc_start));
6920 s->is_jmp = DISAS_TB_JUMP;
6923 case 0x9b: /* fwait */
6924 if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
6925 (HF_MP_MASK | HF_TS_MASK)) {
6926 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
6928 gen_helper_fwait(cpu_env);
6931 case 0xcc: /* int3 */
6932 gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
6934 case 0xcd: /* int N */
6935 val = cpu_ldub_code(env, s->pc++);
6936 if (s->vm86 && s->iopl != 3) {
6937 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6939 gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
6942 case 0xce: /* into */
6945 gen_update_cc_op(s);
6946 gen_jmp_im(pc_start - s->cs_base);
6947 gen_helper_into(cpu_env, tcg_const_i32(s->pc - pc_start));
6950 case 0xf1: /* icebp (undocumented, exits to external debugger) */
6951 gen_svm_check_intercept(s, pc_start, SVM_EXIT_ICEBP);
6953 gen_debug(s, pc_start - s->cs_base);
6956 tb_flush(CPU(x86_env_get_cpu(env)));
6957 qemu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM);
6961 case 0xfa: /* cli */
6963 if (s->cpl <= s->iopl) {
6964 gen_helper_cli(cpu_env);
6966 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6970 gen_helper_cli(cpu_env);
6972 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6976 case 0xfb: /* sti */
6977 if (s->vm86 ? s->iopl == 3 : s->cpl <= s->iopl) {
6978 gen_helper_sti(cpu_env);
6979 /* interruptions are enabled only the first insn after sti */
6980 gen_jmp_im(s->pc - s->cs_base);
6981 gen_eob_inhibit_irq(s, true);
6983 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6986 case 0x62: /* bound */
6990 modrm = cpu_ldub_code(env, s->pc++);
6991 reg = (modrm >> 3) & 7;
6992 mod = (modrm >> 6) & 3;
6995 gen_op_mov_v_reg(ot, cpu_T0, reg);
6996 gen_lea_modrm(env, s, modrm);
6997 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
6999 gen_helper_boundw(cpu_env, cpu_A0, cpu_tmp2_i32);
7001 gen_helper_boundl(cpu_env, cpu_A0, cpu_tmp2_i32);
7004 case 0x1c8 ... 0x1cf: /* bswap reg */
7005 reg = (b & 7) | REX_B(s);
7006 #ifdef TARGET_X86_64
7007 if (dflag == MO_64) {
7008 gen_op_mov_v_reg(MO_64, cpu_T0, reg);
7009 tcg_gen_bswap64_i64(cpu_T0, cpu_T0);
7010 gen_op_mov_reg_v(MO_64, reg, cpu_T0);
7014 gen_op_mov_v_reg(MO_32, cpu_T0, reg);
7015 tcg_gen_ext32u_tl(cpu_T0, cpu_T0);
7016 tcg_gen_bswap32_tl(cpu_T0, cpu_T0);
7017 gen_op_mov_reg_v(MO_32, reg, cpu_T0);
7020 case 0xd6: /* salc */
7023 gen_compute_eflags_c(s, cpu_T0);
7024 tcg_gen_neg_tl(cpu_T0, cpu_T0);
7025 gen_op_mov_reg_v(MO_8, R_EAX, cpu_T0);
7027 case 0xe0: /* loopnz */
7028 case 0xe1: /* loopz */
7029 case 0xe2: /* loop */
7030 case 0xe3: /* jecxz */
7032 TCGLabel *l1, *l2, *l3;
7034 tval = (int8_t)insn_get(env, s, MO_8);
7035 next_eip = s->pc - s->cs_base;
7037 if (dflag == MO_16) {
7041 l1 = gen_new_label();
7042 l2 = gen_new_label();
7043 l3 = gen_new_label();
7046 case 0: /* loopnz */
7048 gen_op_add_reg_im(s->aflag, R_ECX, -1);
7049 gen_op_jz_ecx(s->aflag, l3);
7050 gen_jcc1(s, (JCC_Z << 1) | (b ^ 1), l1);
7053 gen_op_add_reg_im(s->aflag, R_ECX, -1);
7054 gen_op_jnz_ecx(s->aflag, l1);
7058 gen_op_jz_ecx(s->aflag, l1);
7063 gen_jmp_im(next_eip);
7072 case 0x130: /* wrmsr */
7073 case 0x132: /* rdmsr */
7075 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7077 gen_update_cc_op(s);
7078 gen_jmp_im(pc_start - s->cs_base);
7080 gen_helper_rdmsr(cpu_env);
7082 gen_helper_wrmsr(cpu_env);
7086 case 0x131: /* rdtsc */
7087 gen_update_cc_op(s);
7088 gen_jmp_im(pc_start - s->cs_base);
7089 if (s->tb->cflags & CF_USE_ICOUNT) {
7092 gen_helper_rdtsc(cpu_env);
7093 if (s->tb->cflags & CF_USE_ICOUNT) {
7095 gen_jmp(s, s->pc - s->cs_base);
7098 case 0x133: /* rdpmc */
7099 gen_update_cc_op(s);
7100 gen_jmp_im(pc_start - s->cs_base);
7101 gen_helper_rdpmc(cpu_env);
7103 case 0x134: /* sysenter */
7104 /* For Intel SYSENTER is valid on 64-bit */
7105 if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
7108 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7110 gen_helper_sysenter(cpu_env);
7114 case 0x135: /* sysexit */
7115 /* For Intel SYSEXIT is valid on 64-bit */
7116 if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
7119 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7121 gen_helper_sysexit(cpu_env, tcg_const_i32(dflag - 1));
7125 #ifdef TARGET_X86_64
7126 case 0x105: /* syscall */
7127 /* XXX: is it usable in real mode ? */
7128 gen_update_cc_op(s);
7129 gen_jmp_im(pc_start - s->cs_base);
7130 gen_helper_syscall(cpu_env, tcg_const_i32(s->pc - pc_start));
7131 /* TF handling for the syscall insn is different. The TF bit is checked
7132 after the syscall insn completes. This allows #DB to not be
7133 generated after one has entered CPL0 if TF is set in FMASK. */
7134 gen_eob_worker(s, false, true);
7136 case 0x107: /* sysret */
7138 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7140 gen_helper_sysret(cpu_env, tcg_const_i32(dflag - 1));
7141 /* condition codes are modified only in long mode */
7143 set_cc_op(s, CC_OP_EFLAGS);
7145 /* TF handling for the sysret insn is different. The TF bit is
7146 checked after the sysret insn completes. This allows #DB to be
7147 generated "as if" the syscall insn in userspace has just
7149 gen_eob_worker(s, false, true);
7153 case 0x1a2: /* cpuid */
7154 gen_update_cc_op(s);
7155 gen_jmp_im(pc_start - s->cs_base);
7156 gen_helper_cpuid(cpu_env);
7158 case 0xf4: /* hlt */
7160 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7162 gen_update_cc_op(s);
7163 gen_jmp_im(pc_start - s->cs_base);
7164 gen_helper_hlt(cpu_env, tcg_const_i32(s->pc - pc_start));
7165 s->is_jmp = DISAS_TB_JUMP;
7169 modrm = cpu_ldub_code(env, s->pc++);
7170 mod = (modrm >> 6) & 3;
7171 op = (modrm >> 3) & 7;
7174 if (!s->pe || s->vm86)
7176 gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_READ);
7177 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
7178 offsetof(CPUX86State, ldt.selector));
7179 ot = mod == 3 ? dflag : MO_16;
7180 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7183 if (!s->pe || s->vm86)
7186 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7188 gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_WRITE);
7189 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7190 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
7191 gen_helper_lldt(cpu_env, cpu_tmp2_i32);
7195 if (!s->pe || s->vm86)
7197 gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_READ);
7198 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
7199 offsetof(CPUX86State, tr.selector));
7200 ot = mod == 3 ? dflag : MO_16;
7201 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7204 if (!s->pe || s->vm86)
7207 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7209 gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_WRITE);
7210 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7211 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
7212 gen_helper_ltr(cpu_env, cpu_tmp2_i32);
7217 if (!s->pe || s->vm86)
7219 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7220 gen_update_cc_op(s);
7222 gen_helper_verr(cpu_env, cpu_T0);
7224 gen_helper_verw(cpu_env, cpu_T0);
7226 set_cc_op(s, CC_OP_EFLAGS);
7234 modrm = cpu_ldub_code(env, s->pc++);
7236 CASE_MODRM_MEM_OP(0): /* sgdt */
7237 gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_READ);
7238 gen_lea_modrm(env, s, modrm);
7239 tcg_gen_ld32u_tl(cpu_T0,
7240 cpu_env, offsetof(CPUX86State, gdt.limit));
7241 gen_op_st_v(s, MO_16, cpu_T0, cpu_A0);
7242 gen_add_A0_im(s, 2);
7243 tcg_gen_ld_tl(cpu_T0, cpu_env, offsetof(CPUX86State, gdt.base));
7244 if (dflag == MO_16) {
7245 tcg_gen_andi_tl(cpu_T0, cpu_T0, 0xffffff);
7247 gen_op_st_v(s, CODE64(s) + MO_32, cpu_T0, cpu_A0);
7250 case 0xc8: /* monitor */
7251 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || s->cpl != 0) {
7254 gen_update_cc_op(s);
7255 gen_jmp_im(pc_start - s->cs_base);
7256 tcg_gen_mov_tl(cpu_A0, cpu_regs[R_EAX]);
7257 gen_extu(s->aflag, cpu_A0);
7258 gen_add_A0_ds_seg(s);
7259 gen_helper_monitor(cpu_env, cpu_A0);
7262 case 0xc9: /* mwait */
7263 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || s->cpl != 0) {
7266 gen_update_cc_op(s);
7267 gen_jmp_im(pc_start - s->cs_base);
7268 gen_helper_mwait(cpu_env, tcg_const_i32(s->pc - pc_start));
7272 case 0xca: /* clac */
7273 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)
7277 gen_helper_clac(cpu_env);
7278 gen_jmp_im(s->pc - s->cs_base);
7282 case 0xcb: /* stac */
7283 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)
7287 gen_helper_stac(cpu_env);
7288 gen_jmp_im(s->pc - s->cs_base);
7292 CASE_MODRM_MEM_OP(1): /* sidt */
7293 gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_READ);
7294 gen_lea_modrm(env, s, modrm);
7295 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State, idt.limit));
7296 gen_op_st_v(s, MO_16, cpu_T0, cpu_A0);
7297 gen_add_A0_im(s, 2);
7298 tcg_gen_ld_tl(cpu_T0, cpu_env, offsetof(CPUX86State, idt.base));
7299 if (dflag == MO_16) {
7300 tcg_gen_andi_tl(cpu_T0, cpu_T0, 0xffffff);
7302 gen_op_st_v(s, CODE64(s) + MO_32, cpu_T0, cpu_A0);
7305 case 0xd0: /* xgetbv */
7306 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
7307 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA
7308 | PREFIX_REPZ | PREFIX_REPNZ))) {
7311 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_ECX]);
7312 gen_helper_xgetbv(cpu_tmp1_i64, cpu_env, cpu_tmp2_i32);
7313 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], cpu_tmp1_i64);
7316 case 0xd1: /* xsetbv */
7317 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
7318 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA
7319 | PREFIX_REPZ | PREFIX_REPNZ))) {
7323 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7326 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
7328 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_ECX]);
7329 gen_helper_xsetbv(cpu_env, cpu_tmp2_i32, cpu_tmp1_i64);
7330 /* End TB because translation flags may change. */
7331 gen_jmp_im(s->pc - s->cs_base);
7335 case 0xd8: /* VMRUN */
7336 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7340 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7343 gen_update_cc_op(s);
7344 gen_jmp_im(pc_start - s->cs_base);
7345 gen_helper_vmrun(cpu_env, tcg_const_i32(s->aflag - 1),
7346 tcg_const_i32(s->pc - pc_start));
7348 s->is_jmp = DISAS_TB_JUMP;
7351 case 0xd9: /* VMMCALL */
7352 if (!(s->flags & HF_SVME_MASK)) {
7355 gen_update_cc_op(s);
7356 gen_jmp_im(pc_start - s->cs_base);
7357 gen_helper_vmmcall(cpu_env);
7360 case 0xda: /* VMLOAD */
7361 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7365 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7368 gen_update_cc_op(s);
7369 gen_jmp_im(pc_start - s->cs_base);
7370 gen_helper_vmload(cpu_env, tcg_const_i32(s->aflag - 1));
7373 case 0xdb: /* VMSAVE */
7374 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7378 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7381 gen_update_cc_op(s);
7382 gen_jmp_im(pc_start - s->cs_base);
7383 gen_helper_vmsave(cpu_env, tcg_const_i32(s->aflag - 1));
7386 case 0xdc: /* STGI */
7387 if ((!(s->flags & HF_SVME_MASK)
7388 && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
7393 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7396 gen_update_cc_op(s);
7397 gen_jmp_im(pc_start - s->cs_base);
7398 gen_helper_stgi(cpu_env);
7401 case 0xdd: /* CLGI */
7402 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7406 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7409 gen_update_cc_op(s);
7410 gen_jmp_im(pc_start - s->cs_base);
7411 gen_helper_clgi(cpu_env);
7414 case 0xde: /* SKINIT */
7415 if ((!(s->flags & HF_SVME_MASK)
7416 && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
7420 gen_update_cc_op(s);
7421 gen_jmp_im(pc_start - s->cs_base);
7422 gen_helper_skinit(cpu_env);
7425 case 0xdf: /* INVLPGA */
7426 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7430 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7433 gen_update_cc_op(s);
7434 gen_jmp_im(pc_start - s->cs_base);
7435 gen_helper_invlpga(cpu_env, tcg_const_i32(s->aflag - 1));
7438 CASE_MODRM_MEM_OP(2): /* lgdt */
7440 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7443 gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_WRITE);
7444 gen_lea_modrm(env, s, modrm);
7445 gen_op_ld_v(s, MO_16, cpu_T1, cpu_A0);
7446 gen_add_A0_im(s, 2);
7447 gen_op_ld_v(s, CODE64(s) + MO_32, cpu_T0, cpu_A0);
7448 if (dflag == MO_16) {
7449 tcg_gen_andi_tl(cpu_T0, cpu_T0, 0xffffff);
7451 tcg_gen_st_tl(cpu_T0, cpu_env, offsetof(CPUX86State, gdt.base));
7452 tcg_gen_st32_tl(cpu_T1, cpu_env, offsetof(CPUX86State, gdt.limit));
7455 CASE_MODRM_MEM_OP(3): /* lidt */
7457 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7460 gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_WRITE);
7461 gen_lea_modrm(env, s, modrm);
7462 gen_op_ld_v(s, MO_16, cpu_T1, cpu_A0);
7463 gen_add_A0_im(s, 2);
7464 gen_op_ld_v(s, CODE64(s) + MO_32, cpu_T0, cpu_A0);
7465 if (dflag == MO_16) {
7466 tcg_gen_andi_tl(cpu_T0, cpu_T0, 0xffffff);
7468 tcg_gen_st_tl(cpu_T0, cpu_env, offsetof(CPUX86State, idt.base));
7469 tcg_gen_st32_tl(cpu_T1, cpu_env, offsetof(CPUX86State, idt.limit));
7472 CASE_MODRM_OP(4): /* smsw */
7473 gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0);
7474 tcg_gen_ld_tl(cpu_T0, cpu_env, offsetof(CPUX86State, cr[0]));
7476 mod = (modrm >> 6) & 3;
7477 ot = (mod != 3 ? MO_16 : s->dflag);
7481 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7483 case 0xee: /* rdpkru */
7484 if (prefixes & PREFIX_LOCK) {
7487 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_ECX]);
7488 gen_helper_rdpkru(cpu_tmp1_i64, cpu_env, cpu_tmp2_i32);
7489 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], cpu_tmp1_i64);
7491 case 0xef: /* wrpkru */
7492 if (prefixes & PREFIX_LOCK) {
7495 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
7497 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_ECX]);
7498 gen_helper_wrpkru(cpu_env, cpu_tmp2_i32, cpu_tmp1_i64);
7500 CASE_MODRM_OP(6): /* lmsw */
7502 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7505 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
7506 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7507 gen_helper_lmsw(cpu_env, cpu_T0);
7508 gen_jmp_im(s->pc - s->cs_base);
7512 CASE_MODRM_MEM_OP(7): /* invlpg */
7514 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7517 gen_update_cc_op(s);
7518 gen_jmp_im(pc_start - s->cs_base);
7519 gen_lea_modrm(env, s, modrm);
7520 gen_helper_invlpg(cpu_env, cpu_A0);
7521 gen_jmp_im(s->pc - s->cs_base);
7525 case 0xf8: /* swapgs */
7526 #ifdef TARGET_X86_64
7529 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7531 tcg_gen_mov_tl(cpu_T0, cpu_seg_base[R_GS]);
7532 tcg_gen_ld_tl(cpu_seg_base[R_GS], cpu_env,
7533 offsetof(CPUX86State, kernelgsbase));
7534 tcg_gen_st_tl(cpu_T0, cpu_env,
7535 offsetof(CPUX86State, kernelgsbase));
7542 case 0xf9: /* rdtscp */
7543 if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP)) {
7546 gen_update_cc_op(s);
7547 gen_jmp_im(pc_start - s->cs_base);
7548 if (s->tb->cflags & CF_USE_ICOUNT) {
7551 gen_helper_rdtscp(cpu_env);
7552 if (s->tb->cflags & CF_USE_ICOUNT) {
7554 gen_jmp(s, s->pc - s->cs_base);
7563 case 0x108: /* invd */
7564 case 0x109: /* wbinvd */
7566 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7568 gen_svm_check_intercept(s, pc_start, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD);
7572 case 0x63: /* arpl or movslS (x86_64) */
7573 #ifdef TARGET_X86_64
7576 /* d_ot is the size of destination */
7579 modrm = cpu_ldub_code(env, s->pc++);
7580 reg = ((modrm >> 3) & 7) | rex_r;
7581 mod = (modrm >> 6) & 3;
7582 rm = (modrm & 7) | REX_B(s);
7585 gen_op_mov_v_reg(MO_32, cpu_T0, rm);
7587 if (d_ot == MO_64) {
7588 tcg_gen_ext32s_tl(cpu_T0, cpu_T0);
7590 gen_op_mov_reg_v(d_ot, reg, cpu_T0);
7592 gen_lea_modrm(env, s, modrm);
7593 gen_op_ld_v(s, MO_32 | MO_SIGN, cpu_T0, cpu_A0);
7594 gen_op_mov_reg_v(d_ot, reg, cpu_T0);
7600 TCGv t0, t1, t2, a0;
7602 if (!s->pe || s->vm86)
7604 t0 = tcg_temp_local_new();
7605 t1 = tcg_temp_local_new();
7606 t2 = tcg_temp_local_new();
7608 modrm = cpu_ldub_code(env, s->pc++);
7609 reg = (modrm >> 3) & 7;
7610 mod = (modrm >> 6) & 3;
7613 gen_lea_modrm(env, s, modrm);
7614 gen_op_ld_v(s, ot, t0, cpu_A0);
7615 a0 = tcg_temp_local_new();
7616 tcg_gen_mov_tl(a0, cpu_A0);
7618 gen_op_mov_v_reg(ot, t0, rm);
7621 gen_op_mov_v_reg(ot, t1, reg);
7622 tcg_gen_andi_tl(cpu_tmp0, t0, 3);
7623 tcg_gen_andi_tl(t1, t1, 3);
7624 tcg_gen_movi_tl(t2, 0);
7625 label1 = gen_new_label();
7626 tcg_gen_brcond_tl(TCG_COND_GE, cpu_tmp0, t1, label1);
7627 tcg_gen_andi_tl(t0, t0, ~3);
7628 tcg_gen_or_tl(t0, t0, t1);
7629 tcg_gen_movi_tl(t2, CC_Z);
7630 gen_set_label(label1);
7632 gen_op_st_v(s, ot, t0, a0);
7635 gen_op_mov_reg_v(ot, rm, t0);
7637 gen_compute_eflags(s);
7638 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z);
7639 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t2);
7645 case 0x102: /* lar */
7646 case 0x103: /* lsl */
7650 if (!s->pe || s->vm86)
7652 ot = dflag != MO_16 ? MO_32 : MO_16;
7653 modrm = cpu_ldub_code(env, s->pc++);
7654 reg = ((modrm >> 3) & 7) | rex_r;
7655 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7656 t0 = tcg_temp_local_new();
7657 gen_update_cc_op(s);
7659 gen_helper_lar(t0, cpu_env, cpu_T0);
7661 gen_helper_lsl(t0, cpu_env, cpu_T0);
7663 tcg_gen_andi_tl(cpu_tmp0, cpu_cc_src, CC_Z);
7664 label1 = gen_new_label();
7665 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
7666 gen_op_mov_reg_v(ot, reg, t0);
7667 gen_set_label(label1);
7668 set_cc_op(s, CC_OP_EFLAGS);
7673 modrm = cpu_ldub_code(env, s->pc++);
7674 mod = (modrm >> 6) & 3;
7675 op = (modrm >> 3) & 7;
7677 case 0: /* prefetchnta */
7678 case 1: /* prefetchnt0 */
7679 case 2: /* prefetchnt0 */
7680 case 3: /* prefetchnt0 */
7683 gen_nop_modrm(env, s, modrm);
7684 /* nothing more to do */
7686 default: /* nop (multi byte) */
7687 gen_nop_modrm(env, s, modrm);
7692 modrm = cpu_ldub_code(env, s->pc++);
7693 if (s->flags & HF_MPX_EN_MASK) {
7694 mod = (modrm >> 6) & 3;
7695 reg = ((modrm >> 3) & 7) | rex_r;
7696 if (prefixes & PREFIX_REPZ) {
7699 || (prefixes & PREFIX_LOCK)
7700 || s->aflag == MO_16) {
7703 gen_bndck(env, s, modrm, TCG_COND_LTU, cpu_bndl[reg]);
7704 } else if (prefixes & PREFIX_REPNZ) {
7707 || (prefixes & PREFIX_LOCK)
7708 || s->aflag == MO_16) {
7711 TCGv_i64 notu = tcg_temp_new_i64();
7712 tcg_gen_not_i64(notu, cpu_bndu[reg]);
7713 gen_bndck(env, s, modrm, TCG_COND_GTU, notu);
7714 tcg_temp_free_i64(notu);
7715 } else if (prefixes & PREFIX_DATA) {
7716 /* bndmov -- from reg/mem */
7717 if (reg >= 4 || s->aflag == MO_16) {
7721 int reg2 = (modrm & 7) | REX_B(s);
7722 if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) {
7725 if (s->flags & HF_MPX_IU_MASK) {
7726 tcg_gen_mov_i64(cpu_bndl[reg], cpu_bndl[reg2]);
7727 tcg_gen_mov_i64(cpu_bndu[reg], cpu_bndu[reg2]);
7730 gen_lea_modrm(env, s, modrm);
7732 tcg_gen_qemu_ld_i64(cpu_bndl[reg], cpu_A0,
7733 s->mem_index, MO_LEQ);
7734 tcg_gen_addi_tl(cpu_A0, cpu_A0, 8);
7735 tcg_gen_qemu_ld_i64(cpu_bndu[reg], cpu_A0,
7736 s->mem_index, MO_LEQ);
7738 tcg_gen_qemu_ld_i64(cpu_bndl[reg], cpu_A0,
7739 s->mem_index, MO_LEUL);
7740 tcg_gen_addi_tl(cpu_A0, cpu_A0, 4);
7741 tcg_gen_qemu_ld_i64(cpu_bndu[reg], cpu_A0,
7742 s->mem_index, MO_LEUL);
7744 /* bnd registers are now in-use */
7745 gen_set_hflag(s, HF_MPX_IU_MASK);
7747 } else if (mod != 3) {
7749 AddressParts a = gen_lea_modrm_0(env, s, modrm);
7751 || (prefixes & PREFIX_LOCK)
7752 || s->aflag == MO_16
7757 tcg_gen_addi_tl(cpu_A0, cpu_regs[a.base], a.disp);
7759 tcg_gen_movi_tl(cpu_A0, 0);
7761 gen_lea_v_seg(s, s->aflag, cpu_A0, a.def_seg, s->override);
7763 tcg_gen_mov_tl(cpu_T0, cpu_regs[a.index]);
7765 tcg_gen_movi_tl(cpu_T0, 0);
7768 gen_helper_bndldx64(cpu_bndl[reg], cpu_env, cpu_A0, cpu_T0);
7769 tcg_gen_ld_i64(cpu_bndu[reg], cpu_env,
7770 offsetof(CPUX86State, mmx_t0.MMX_Q(0)));
7772 gen_helper_bndldx32(cpu_bndu[reg], cpu_env, cpu_A0, cpu_T0);
7773 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndu[reg]);
7774 tcg_gen_shri_i64(cpu_bndu[reg], cpu_bndu[reg], 32);
7776 gen_set_hflag(s, HF_MPX_IU_MASK);
7779 gen_nop_modrm(env, s, modrm);
7782 modrm = cpu_ldub_code(env, s->pc++);
7783 if (s->flags & HF_MPX_EN_MASK) {
7784 mod = (modrm >> 6) & 3;
7785 reg = ((modrm >> 3) & 7) | rex_r;
7786 if (mod != 3 && (prefixes & PREFIX_REPZ)) {
7789 || (prefixes & PREFIX_LOCK)
7790 || s->aflag == MO_16) {
7793 AddressParts a = gen_lea_modrm_0(env, s, modrm);
7795 tcg_gen_extu_tl_i64(cpu_bndl[reg], cpu_regs[a.base]);
7797 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndl[reg]);
7799 } else if (a.base == -1) {
7800 /* no base register has lower bound of 0 */
7801 tcg_gen_movi_i64(cpu_bndl[reg], 0);
7803 /* rip-relative generates #ud */
7806 tcg_gen_not_tl(cpu_A0, gen_lea_modrm_1(a));
7808 tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
7810 tcg_gen_extu_tl_i64(cpu_bndu[reg], cpu_A0);
7811 /* bnd registers are now in-use */
7812 gen_set_hflag(s, HF_MPX_IU_MASK);
7814 } else if (prefixes & PREFIX_REPNZ) {
7817 || (prefixes & PREFIX_LOCK)
7818 || s->aflag == MO_16) {
7821 gen_bndck(env, s, modrm, TCG_COND_GTU, cpu_bndu[reg]);
7822 } else if (prefixes & PREFIX_DATA) {
7823 /* bndmov -- to reg/mem */
7824 if (reg >= 4 || s->aflag == MO_16) {
7828 int reg2 = (modrm & 7) | REX_B(s);
7829 if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) {
7832 if (s->flags & HF_MPX_IU_MASK) {
7833 tcg_gen_mov_i64(cpu_bndl[reg2], cpu_bndl[reg]);
7834 tcg_gen_mov_i64(cpu_bndu[reg2], cpu_bndu[reg]);
7837 gen_lea_modrm(env, s, modrm);
7839 tcg_gen_qemu_st_i64(cpu_bndl[reg], cpu_A0,
7840 s->mem_index, MO_LEQ);
7841 tcg_gen_addi_tl(cpu_A0, cpu_A0, 8);
7842 tcg_gen_qemu_st_i64(cpu_bndu[reg], cpu_A0,
7843 s->mem_index, MO_LEQ);
7845 tcg_gen_qemu_st_i64(cpu_bndl[reg], cpu_A0,
7846 s->mem_index, MO_LEUL);
7847 tcg_gen_addi_tl(cpu_A0, cpu_A0, 4);
7848 tcg_gen_qemu_st_i64(cpu_bndu[reg], cpu_A0,
7849 s->mem_index, MO_LEUL);
7852 } else if (mod != 3) {
7854 AddressParts a = gen_lea_modrm_0(env, s, modrm);
7856 || (prefixes & PREFIX_LOCK)
7857 || s->aflag == MO_16
7862 tcg_gen_addi_tl(cpu_A0, cpu_regs[a.base], a.disp);
7864 tcg_gen_movi_tl(cpu_A0, 0);
7866 gen_lea_v_seg(s, s->aflag, cpu_A0, a.def_seg, s->override);
7868 tcg_gen_mov_tl(cpu_T0, cpu_regs[a.index]);
7870 tcg_gen_movi_tl(cpu_T0, 0);
7873 gen_helper_bndstx64(cpu_env, cpu_A0, cpu_T0,
7874 cpu_bndl[reg], cpu_bndu[reg]);
7876 gen_helper_bndstx32(cpu_env, cpu_A0, cpu_T0,
7877 cpu_bndl[reg], cpu_bndu[reg]);
7881 gen_nop_modrm(env, s, modrm);
7883 case 0x119: case 0x11c ... 0x11f: /* nop (multi byte) */
7884 modrm = cpu_ldub_code(env, s->pc++);
7885 gen_nop_modrm(env, s, modrm);
7887 case 0x120: /* mov reg, crN */
7888 case 0x122: /* mov crN, reg */
7890 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7892 modrm = cpu_ldub_code(env, s->pc++);
7893 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7894 * AMD documentation (24594.pdf) and testing of
7895 * intel 386 and 486 processors all show that the mod bits
7896 * are assumed to be 1's, regardless of actual values.
7898 rm = (modrm & 7) | REX_B(s);
7899 reg = ((modrm >> 3) & 7) | rex_r;
7904 if ((prefixes & PREFIX_LOCK) && (reg == 0) &&
7905 (s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) {
7914 gen_update_cc_op(s);
7915 gen_jmp_im(pc_start - s->cs_base);
7917 gen_op_mov_v_reg(ot, cpu_T0, rm);
7918 gen_helper_write_crN(cpu_env, tcg_const_i32(reg),
7920 gen_jmp_im(s->pc - s->cs_base);
7923 gen_helper_read_crN(cpu_T0, cpu_env, tcg_const_i32(reg));
7924 gen_op_mov_reg_v(ot, rm, cpu_T0);
7932 case 0x121: /* mov reg, drN */
7933 case 0x123: /* mov drN, reg */
7935 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7937 modrm = cpu_ldub_code(env, s->pc++);
7938 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7939 * AMD documentation (24594.pdf) and testing of
7940 * intel 386 and 486 processors all show that the mod bits
7941 * are assumed to be 1's, regardless of actual values.
7943 rm = (modrm & 7) | REX_B(s);
7944 reg = ((modrm >> 3) & 7) | rex_r;
7953 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
7954 gen_op_mov_v_reg(ot, cpu_T0, rm);
7955 tcg_gen_movi_i32(cpu_tmp2_i32, reg);
7956 gen_helper_set_dr(cpu_env, cpu_tmp2_i32, cpu_T0);
7957 gen_jmp_im(s->pc - s->cs_base);
7960 gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_DR0 + reg);
7961 tcg_gen_movi_i32(cpu_tmp2_i32, reg);
7962 gen_helper_get_dr(cpu_T0, cpu_env, cpu_tmp2_i32);
7963 gen_op_mov_reg_v(ot, rm, cpu_T0);
7967 case 0x106: /* clts */
7969 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7971 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
7972 gen_helper_clts(cpu_env);
7973 /* abort block because static cpu state changed */
7974 gen_jmp_im(s->pc - s->cs_base);
7978 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
7979 case 0x1c3: /* MOVNTI reg, mem */
7980 if (!(s->cpuid_features & CPUID_SSE2))
7982 ot = mo_64_32(dflag);
7983 modrm = cpu_ldub_code(env, s->pc++);
7984 mod = (modrm >> 6) & 3;
7987 reg = ((modrm >> 3) & 7) | rex_r;
7988 /* generate a generic store */
7989 gen_ldst_modrm(env, s, modrm, ot, reg, 1);
7992 modrm = cpu_ldub_code(env, s->pc++);
7994 CASE_MODRM_MEM_OP(0): /* fxsave */
7995 if (!(s->cpuid_features & CPUID_FXSR)
7996 || (prefixes & PREFIX_LOCK)) {
7999 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
8000 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
8003 gen_lea_modrm(env, s, modrm);
8004 gen_helper_fxsave(cpu_env, cpu_A0);
8007 CASE_MODRM_MEM_OP(1): /* fxrstor */
8008 if (!(s->cpuid_features & CPUID_FXSR)
8009 || (prefixes & PREFIX_LOCK)) {
8012 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
8013 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
8016 gen_lea_modrm(env, s, modrm);
8017 gen_helper_fxrstor(cpu_env, cpu_A0);
8020 CASE_MODRM_MEM_OP(2): /* ldmxcsr */
8021 if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) {
8024 if (s->flags & HF_TS_MASK) {
8025 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
8028 gen_lea_modrm(env, s, modrm);
8029 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0, s->mem_index, MO_LEUL);
8030 gen_helper_ldmxcsr(cpu_env, cpu_tmp2_i32);
8033 CASE_MODRM_MEM_OP(3): /* stmxcsr */
8034 if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) {
8037 if (s->flags & HF_TS_MASK) {
8038 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
8041 gen_lea_modrm(env, s, modrm);
8042 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State, mxcsr));
8043 gen_op_st_v(s, MO_32, cpu_T0, cpu_A0);
8046 CASE_MODRM_MEM_OP(4): /* xsave */
8047 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
8048 || (prefixes & (PREFIX_LOCK | PREFIX_DATA
8049 | PREFIX_REPZ | PREFIX_REPNZ))) {
8052 gen_lea_modrm(env, s, modrm);
8053 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
8055 gen_helper_xsave(cpu_env, cpu_A0, cpu_tmp1_i64);
8058 CASE_MODRM_MEM_OP(5): /* xrstor */
8059 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
8060 || (prefixes & (PREFIX_LOCK | PREFIX_DATA
8061 | PREFIX_REPZ | PREFIX_REPNZ))) {
8064 gen_lea_modrm(env, s, modrm);
8065 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
8067 gen_helper_xrstor(cpu_env, cpu_A0, cpu_tmp1_i64);
8068 /* XRSTOR is how MPX is enabled, which changes how
8069 we translate. Thus we need to end the TB. */
8070 gen_update_cc_op(s);
8071 gen_jmp_im(s->pc - s->cs_base);
8075 CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */
8076 if (prefixes & PREFIX_LOCK) {
8079 if (prefixes & PREFIX_DATA) {
8081 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLWB)) {
8084 gen_nop_modrm(env, s, modrm);
8087 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
8088 || (s->cpuid_xsave_features & CPUID_XSAVE_XSAVEOPT) == 0
8089 || (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))) {
8092 gen_lea_modrm(env, s, modrm);
8093 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
8095 gen_helper_xsaveopt(cpu_env, cpu_A0, cpu_tmp1_i64);
8099 CASE_MODRM_MEM_OP(7): /* clflush / clflushopt */
8100 if (prefixes & PREFIX_LOCK) {
8103 if (prefixes & PREFIX_DATA) {
8105 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLFLUSHOPT)) {
8110 if ((s->prefix & (PREFIX_REPZ | PREFIX_REPNZ))
8111 || !(s->cpuid_features & CPUID_CLFLUSH)) {
8115 gen_nop_modrm(env, s, modrm);
8118 case 0xc0 ... 0xc7: /* rdfsbase (f3 0f ae /0) */
8119 case 0xc8 ... 0xc8: /* rdgsbase (f3 0f ae /1) */
8120 case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */
8121 case 0xd8 ... 0xd8: /* wrgsbase (f3 0f ae /3) */
8123 && (prefixes & PREFIX_REPZ)
8124 && !(prefixes & PREFIX_LOCK)
8125 && (s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_FSGSBASE)) {
8126 TCGv base, treg, src, dst;
8128 /* Preserve hflags bits by testing CR4 at runtime. */
8129 tcg_gen_movi_i32(cpu_tmp2_i32, CR4_FSGSBASE_MASK);
8130 gen_helper_cr4_testbit(cpu_env, cpu_tmp2_i32);
8132 base = cpu_seg_base[modrm & 8 ? R_GS : R_FS];
8133 treg = cpu_regs[(modrm & 7) | REX_B(s)];
8137 dst = base, src = treg;
8140 dst = treg, src = base;
8143 if (s->dflag == MO_32) {
8144 tcg_gen_ext32u_tl(dst, src);
8146 tcg_gen_mov_tl(dst, src);
8152 case 0xf8: /* sfence / pcommit */
8153 if (prefixes & PREFIX_DATA) {
8155 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_PCOMMIT)
8156 || (prefixes & PREFIX_LOCK)) {
8162 case 0xf9 ... 0xff: /* sfence */
8163 if (!(s->cpuid_features & CPUID_SSE)
8164 || (prefixes & PREFIX_LOCK)) {
8167 tcg_gen_mb(TCG_MO_ST_ST | TCG_BAR_SC);
8169 case 0xe8 ... 0xef: /* lfence */
8170 if (!(s->cpuid_features & CPUID_SSE)
8171 || (prefixes & PREFIX_LOCK)) {
8174 tcg_gen_mb(TCG_MO_LD_LD | TCG_BAR_SC);
8176 case 0xf0 ... 0xf7: /* mfence */
8177 if (!(s->cpuid_features & CPUID_SSE2)
8178 || (prefixes & PREFIX_LOCK)) {
8181 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8189 case 0x10d: /* 3DNow! prefetch(w) */
8190 modrm = cpu_ldub_code(env, s->pc++);
8191 mod = (modrm >> 6) & 3;
8194 gen_nop_modrm(env, s, modrm);
8196 case 0x1aa: /* rsm */
8197 gen_svm_check_intercept(s, pc_start, SVM_EXIT_RSM);
8198 if (!(s->flags & HF_SMM_MASK))
8200 gen_update_cc_op(s);
8201 gen_jmp_im(s->pc - s->cs_base);
8202 gen_helper_rsm(cpu_env);
8205 case 0x1b8: /* SSE4.2 popcnt */
8206 if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) !=
8209 if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT))
8212 modrm = cpu_ldub_code(env, s->pc++);
8213 reg = ((modrm >> 3) & 7) | rex_r;
8215 if (s->prefix & PREFIX_DATA) {
8218 ot = mo_64_32(dflag);
8221 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
8222 gen_extu(ot, cpu_T0);
8223 tcg_gen_mov_tl(cpu_cc_src, cpu_T0);
8224 tcg_gen_ctpop_tl(cpu_T0, cpu_T0);
8225 gen_op_mov_reg_v(ot, reg, cpu_T0);
8227 set_cc_op(s, CC_OP_POPCNT);
8229 case 0x10e ... 0x10f:
8230 /* 3DNow! instructions, ignore prefixes */
8231 s->prefix &= ~(PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA);
8232 case 0x110 ... 0x117:
8233 case 0x128 ... 0x12f:
8234 case 0x138 ... 0x13a:
8235 case 0x150 ... 0x179:
8236 case 0x17c ... 0x17f:
8238 case 0x1c4 ... 0x1c6:
8239 case 0x1d0 ... 0x1fe:
8240 gen_sse(env, s, b, pc_start, rex_r);
8247 gen_illegal_opcode(s);
8250 gen_unknown_opcode(env, s);
8254 void tcg_x86_init(void)
8256 static const char reg_names[CPU_NB_REGS][4] = {
8257 #ifdef TARGET_X86_64
8285 static const char seg_base_names[6][8] = {
8293 static const char bnd_regl_names[4][8] = {
8294 "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb"
8296 static const char bnd_regu_names[4][8] = {
8297 "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub"
8300 static bool initialized;
8307 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
8308 tcg_ctx.tcg_env = cpu_env;
8309 cpu_cc_op = tcg_global_mem_new_i32(cpu_env,
8310 offsetof(CPUX86State, cc_op), "cc_op");
8311 cpu_cc_dst = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_dst),
8313 cpu_cc_src = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src),
8315 cpu_cc_src2 = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src2),
8318 for (i = 0; i < CPU_NB_REGS; ++i) {
8319 cpu_regs[i] = tcg_global_mem_new(cpu_env,
8320 offsetof(CPUX86State, regs[i]),
8324 for (i = 0; i < 6; ++i) {
8326 = tcg_global_mem_new(cpu_env,
8327 offsetof(CPUX86State, segs[i].base),
8331 for (i = 0; i < 4; ++i) {
8333 = tcg_global_mem_new_i64(cpu_env,
8334 offsetof(CPUX86State, bnd_regs[i].lb),
8337 = tcg_global_mem_new_i64(cpu_env,
8338 offsetof(CPUX86State, bnd_regs[i].ub),
8343 /* generate intermediate code for basic block 'tb'. */
8344 void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb)
8346 X86CPU *cpu = x86_env_get_cpu(env);
8347 CPUState *cs = CPU(cpu);
8348 DisasContext dc1, *dc = &dc1;
8349 target_ulong pc_ptr;
8351 target_ulong pc_start;
8352 target_ulong cs_base;
8356 /* generate intermediate code */
8358 cs_base = tb->cs_base;
8361 dc->pe = (flags >> HF_PE_SHIFT) & 1;
8362 dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
8363 dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
8364 dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
8366 dc->vm86 = (flags >> VM_SHIFT) & 1;
8367 dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
8368 dc->iopl = (flags >> IOPL_SHIFT) & 3;
8369 dc->tf = (flags >> TF_SHIFT) & 1;
8370 dc->singlestep_enabled = cs->singlestep_enabled;
8371 dc->cc_op = CC_OP_DYNAMIC;
8372 dc->cc_op_dirty = false;
8373 dc->cs_base = cs_base;
8375 dc->popl_esp_hack = 0;
8376 /* select memory access functions */
8378 #ifdef CONFIG_SOFTMMU
8379 dc->mem_index = cpu_mmu_index(env, false);
8381 dc->cpuid_features = env->features[FEAT_1_EDX];
8382 dc->cpuid_ext_features = env->features[FEAT_1_ECX];
8383 dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX];
8384 dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX];
8385 dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX];
8386 dc->cpuid_xsave_features = env->features[FEAT_XSAVE];
8387 #ifdef TARGET_X86_64
8388 dc->lma = (flags >> HF_LMA_SHIFT) & 1;
8389 dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
8392 dc->jmp_opt = !(dc->tf || cs->singlestep_enabled ||
8393 (flags & HF_INHIBIT_IRQ_MASK));
8394 /* Do not optimize repz jumps at all in icount mode, because
8395 rep movsS instructions are execured with different paths
8396 in !repz_opt and repz_opt modes. The first one was used
8397 always except single step mode. And this setting
8398 disables jumps optimization and control paths become
8399 equivalent in run and single step modes.
8400 Now there will be no jump optimization for repz in
8401 record/replay modes and there will always be an
8402 additional step for ecx=0 when icount is enabled.
8404 dc->repz_opt = !dc->jmp_opt && !(tb->cflags & CF_USE_ICOUNT);
8406 /* check addseg logic */
8407 if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
8408 printf("ERROR addseg\n");
8411 cpu_T0 = tcg_temp_new();
8412 cpu_T1 = tcg_temp_new();
8413 cpu_A0 = tcg_temp_new();
8415 cpu_tmp0 = tcg_temp_new();
8416 cpu_tmp1_i64 = tcg_temp_new_i64();
8417 cpu_tmp2_i32 = tcg_temp_new_i32();
8418 cpu_tmp3_i32 = tcg_temp_new_i32();
8419 cpu_tmp4 = tcg_temp_new();
8420 cpu_ptr0 = tcg_temp_new_ptr();
8421 cpu_ptr1 = tcg_temp_new_ptr();
8422 cpu_cc_srcT = tcg_temp_local_new();
8424 dc->is_jmp = DISAS_NEXT;
8427 max_insns = tb->cflags & CF_COUNT_MASK;
8428 if (max_insns == 0) {
8429 max_insns = CF_COUNT_MASK;
8431 if (max_insns > TCG_MAX_INSNS) {
8432 max_insns = TCG_MAX_INSNS;
8437 tcg_gen_insn_start(pc_ptr, dc->cc_op);
8440 /* If RF is set, suppress an internally generated breakpoint. */
8441 if (unlikely(cpu_breakpoint_test(cs, pc_ptr,
8442 tb->flags & HF_RF_MASK
8443 ? BP_GDB : BP_ANY))) {
8444 gen_debug(dc, pc_ptr - dc->cs_base);
8445 /* The address covered by the breakpoint must be included in
8446 [tb->pc, tb->pc + tb->size) in order to for it to be
8447 properly cleared -- thus we increment the PC here so that
8448 the logic setting tb->size below does the right thing. */
8450 goto done_generating;
8452 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
8456 pc_ptr = disas_insn(env, dc, pc_ptr);
8457 /* stop translation if indicated */
8460 /* if single step mode, we generate only one instruction and
8461 generate an exception */
8462 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
8463 the flag and abort the translation to give the irqs a
8464 change to be happen */
8465 if (dc->tf || dc->singlestep_enabled ||
8466 (flags & HF_INHIBIT_IRQ_MASK)) {
8467 gen_jmp_im(pc_ptr - dc->cs_base);
8471 /* Do not cross the boundary of the pages in icount mode,
8472 it can cause an exception. Do it only when boundary is
8473 crossed by the first instruction in the block.
8474 If current instruction already crossed the bound - it's ok,
8475 because an exception hasn't stopped this code.
8477 if ((tb->cflags & CF_USE_ICOUNT)
8478 && ((pc_ptr & TARGET_PAGE_MASK)
8479 != ((pc_ptr + TARGET_MAX_INSN_SIZE - 1) & TARGET_PAGE_MASK)
8480 || (pc_ptr & ~TARGET_PAGE_MASK) == 0)) {
8481 gen_jmp_im(pc_ptr - dc->cs_base);
8485 /* if too long translation, stop generation too */
8486 if (tcg_op_buf_full() ||
8487 (pc_ptr - pc_start) >= (TARGET_PAGE_SIZE - 32) ||
8488 num_insns >= max_insns) {
8489 gen_jmp_im(pc_ptr - dc->cs_base);
8494 gen_jmp_im(pc_ptr - dc->cs_base);
8499 if (tb->cflags & CF_LAST_IO)
8502 gen_tb_end(tb, num_insns);
8505 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
8506 && qemu_log_in_addr_range(pc_start)) {
8509 qemu_log("----------------\n");
8510 qemu_log("IN: %s\n", lookup_symbol(pc_start));
8511 #ifdef TARGET_X86_64
8516 disas_flags = !dc->code32;
8517 log_target_disas(cs, pc_start, pc_ptr - pc_start, disas_flags);
8523 tb->size = pc_ptr - pc_start;
8524 tb->icount = num_insns;
8527 void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb,
8530 int cc_op = data[1];
8531 env->eip = data[0] - tb->cs_base;
8532 if (cc_op != CC_OP_DYNAMIC) {