4 * Copyright (c) 2003 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 #include "qemu/osdep.h"
21 #include "qemu/host-utils.h"
23 #include "disas/disas.h"
24 #include "exec/exec-all.h"
26 #include "exec/cpu_ldst.h"
27 #include "exec/translator.h"
29 #include "exec/helper-proto.h"
30 #include "exec/helper-gen.h"
32 #include "trace-tcg.h"
35 #define PREFIX_REPZ 0x01
36 #define PREFIX_REPNZ 0x02
37 #define PREFIX_LOCK 0x04
38 #define PREFIX_DATA 0x08
39 #define PREFIX_ADR 0x10
40 #define PREFIX_VEX 0x20
43 #define CODE64(s) ((s)->code64)
44 #define REX_X(s) ((s)->rex_x)
45 #define REX_B(s) ((s)->rex_b)
60 /* For a switch indexed by MODRM, match all memory operands for a given OP. */
61 #define CASE_MODRM_MEM_OP(OP) \
62 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
63 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
64 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7
66 #define CASE_MODRM_OP(OP) \
67 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
68 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
69 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7: \
70 case (3 << 6) | (OP << 3) | 0 ... (3 << 6) | (OP << 3) | 7
72 //#define MACRO_TEST 1
74 /* global register indexes */
76 static TCGv cpu_cc_dst, cpu_cc_src, cpu_cc_src2, cpu_cc_srcT;
77 static TCGv_i32 cpu_cc_op;
78 static TCGv cpu_regs[CPU_NB_REGS];
79 static TCGv cpu_seg_base[6];
80 static TCGv_i64 cpu_bndl[4];
81 static TCGv_i64 cpu_bndu[4];
83 static TCGv cpu_T0, cpu_T1;
84 /* local register indexes (only used inside old micro ops) */
85 static TCGv cpu_tmp0, cpu_tmp4;
86 static TCGv_ptr cpu_ptr0, cpu_ptr1;
87 static TCGv_i32 cpu_tmp2_i32, cpu_tmp3_i32;
88 static TCGv_i64 cpu_tmp1_i64;
90 #include "exec/gen-icount.h"
93 static int x86_64_hregs;
96 typedef struct DisasContext {
97 DisasContextBase base;
99 /* current insn context */
100 int override; /* -1 if no override */
104 target_ulong pc_start;
105 target_ulong pc; /* pc = eip + cs_base */
106 /* current block context */
107 target_ulong cs_base; /* base of CS segment */
108 int pe; /* protected mode */
109 int code32; /* 32 bit code segment */
111 int lma; /* long mode active */
112 int code64; /* 64 bit code segment */
115 int vex_l; /* vex vector length */
116 int vex_v; /* vex vvvv register, without 1's complement. */
117 int ss32; /* 32 bit stack segment */
118 CCOp cc_op; /* current CC operation */
120 int addseg; /* non zero if either DS/ES/SS have a non zero base */
121 int f_st; /* currently unused */
122 int vm86; /* vm86 mode */
125 int tf; /* TF cpu flag */
126 int jmp_opt; /* use direct block chaining for direct jumps */
127 int repz_opt; /* optimize jumps within repz instructions */
128 int mem_index; /* select memory access functions */
129 uint64_t flags; /* all execution flags */
130 int popl_esp_hack; /* for correct popl with esp base handling */
131 int rip_offset; /* only used in x86_64, but left for simplicity */
133 int cpuid_ext_features;
134 int cpuid_ext2_features;
135 int cpuid_ext3_features;
136 int cpuid_7_0_ebx_features;
137 int cpuid_xsave_features;
141 static void gen_eob(DisasContext *s);
142 static void gen_jr(DisasContext *s, TCGv dest);
143 static void gen_jmp(DisasContext *s, target_ulong eip);
144 static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num);
145 static void gen_op(DisasContext *s1, int op, TCGMemOp ot, int d);
147 /* i386 arith/logic operations */
167 OP_SHL1, /* undocumented */
183 /* I386 int registers */
184 OR_EAX, /* MUST be even numbered */
193 OR_TMP0 = 16, /* temporary operand register */
195 OR_A0, /* temporary register used when doing address evaluation */
205 /* Bit set if the global variable is live after setting CC_OP to X. */
206 static const uint8_t cc_op_live[CC_OP_NB] = {
207 [CC_OP_DYNAMIC] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
208 [CC_OP_EFLAGS] = USES_CC_SRC,
209 [CC_OP_MULB ... CC_OP_MULQ] = USES_CC_DST | USES_CC_SRC,
210 [CC_OP_ADDB ... CC_OP_ADDQ] = USES_CC_DST | USES_CC_SRC,
211 [CC_OP_ADCB ... CC_OP_ADCQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
212 [CC_OP_SUBB ... CC_OP_SUBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRCT,
213 [CC_OP_SBBB ... CC_OP_SBBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
214 [CC_OP_LOGICB ... CC_OP_LOGICQ] = USES_CC_DST,
215 [CC_OP_INCB ... CC_OP_INCQ] = USES_CC_DST | USES_CC_SRC,
216 [CC_OP_DECB ... CC_OP_DECQ] = USES_CC_DST | USES_CC_SRC,
217 [CC_OP_SHLB ... CC_OP_SHLQ] = USES_CC_DST | USES_CC_SRC,
218 [CC_OP_SARB ... CC_OP_SARQ] = USES_CC_DST | USES_CC_SRC,
219 [CC_OP_BMILGB ... CC_OP_BMILGQ] = USES_CC_DST | USES_CC_SRC,
220 [CC_OP_ADCX] = USES_CC_DST | USES_CC_SRC,
221 [CC_OP_ADOX] = USES_CC_SRC | USES_CC_SRC2,
222 [CC_OP_ADCOX] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
224 [CC_OP_POPCNT] = USES_CC_SRC,
227 static void set_cc_op(DisasContext *s, CCOp op)
231 if (s->cc_op == op) {
235 /* Discard CC computation that will no longer be used. */
236 dead = cc_op_live[s->cc_op] & ~cc_op_live[op];
237 if (dead & USES_CC_DST) {
238 tcg_gen_discard_tl(cpu_cc_dst);
240 if (dead & USES_CC_SRC) {
241 tcg_gen_discard_tl(cpu_cc_src);
243 if (dead & USES_CC_SRC2) {
244 tcg_gen_discard_tl(cpu_cc_src2);
246 if (dead & USES_CC_SRCT) {
247 tcg_gen_discard_tl(cpu_cc_srcT);
250 if (op == CC_OP_DYNAMIC) {
251 /* The DYNAMIC setting is translator only, and should never be
252 stored. Thus we always consider it clean. */
253 s->cc_op_dirty = false;
255 /* Discard any computed CC_OP value (see shifts). */
256 if (s->cc_op == CC_OP_DYNAMIC) {
257 tcg_gen_discard_i32(cpu_cc_op);
259 s->cc_op_dirty = true;
264 static void gen_update_cc_op(DisasContext *s)
266 if (s->cc_op_dirty) {
267 tcg_gen_movi_i32(cpu_cc_op, s->cc_op);
268 s->cc_op_dirty = false;
274 #define NB_OP_SIZES 4
276 #else /* !TARGET_X86_64 */
278 #define NB_OP_SIZES 3
280 #endif /* !TARGET_X86_64 */
282 #if defined(HOST_WORDS_BIGENDIAN)
283 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
284 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
285 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
286 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
287 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
289 #define REG_B_OFFSET 0
290 #define REG_H_OFFSET 1
291 #define REG_W_OFFSET 0
292 #define REG_L_OFFSET 0
293 #define REG_LH_OFFSET 4
296 /* In instruction encodings for byte register accesses the
297 * register number usually indicates "low 8 bits of register N";
298 * however there are some special cases where N 4..7 indicates
299 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
300 * true for this special case, false otherwise.
302 static inline bool byte_reg_is_xH(int reg)
308 if (reg >= 8 || x86_64_hregs) {
315 /* Select the size of a push/pop operation. */
316 static inline TCGMemOp mo_pushpop(DisasContext *s, TCGMemOp ot)
319 return ot == MO_16 ? MO_16 : MO_64;
325 /* Select the size of the stack pointer. */
326 static inline TCGMemOp mo_stacksize(DisasContext *s)
328 return CODE64(s) ? MO_64 : s->ss32 ? MO_32 : MO_16;
331 /* Select only size 64 else 32. Used for SSE operand sizes. */
332 static inline TCGMemOp mo_64_32(TCGMemOp ot)
335 return ot == MO_64 ? MO_64 : MO_32;
341 /* Select size 8 if lsb of B is clear, else OT. Used for decoding
342 byte vs word opcodes. */
343 static inline TCGMemOp mo_b_d(int b, TCGMemOp ot)
345 return b & 1 ? ot : MO_8;
348 /* Select size 8 if lsb of B is clear, else OT capped at 32.
349 Used for decoding operand size of port opcodes. */
350 static inline TCGMemOp mo_b_d32(int b, TCGMemOp ot)
352 return b & 1 ? (ot == MO_16 ? MO_16 : MO_32) : MO_8;
355 static void gen_op_mov_reg_v(TCGMemOp ot, int reg, TCGv t0)
359 if (!byte_reg_is_xH(reg)) {
360 tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 8);
362 tcg_gen_deposit_tl(cpu_regs[reg - 4], cpu_regs[reg - 4], t0, 8, 8);
366 tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 16);
369 /* For x86_64, this sets the higher half of register to zero.
370 For i386, this is equivalent to a mov. */
371 tcg_gen_ext32u_tl(cpu_regs[reg], t0);
375 tcg_gen_mov_tl(cpu_regs[reg], t0);
383 static inline void gen_op_mov_v_reg(TCGMemOp ot, TCGv t0, int reg)
385 if (ot == MO_8 && byte_reg_is_xH(reg)) {
386 tcg_gen_extract_tl(t0, cpu_regs[reg - 4], 8, 8);
388 tcg_gen_mov_tl(t0, cpu_regs[reg]);
392 static void gen_add_A0_im(DisasContext *s, int val)
394 tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
396 tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
400 static inline void gen_op_jmp_v(TCGv dest)
402 tcg_gen_st_tl(dest, cpu_env, offsetof(CPUX86State, eip));
405 static inline void gen_op_add_reg_im(TCGMemOp size, int reg, int32_t val)
407 tcg_gen_addi_tl(cpu_tmp0, cpu_regs[reg], val);
408 gen_op_mov_reg_v(size, reg, cpu_tmp0);
411 static inline void gen_op_add_reg_T0(TCGMemOp size, int reg)
413 tcg_gen_add_tl(cpu_tmp0, cpu_regs[reg], cpu_T0);
414 gen_op_mov_reg_v(size, reg, cpu_tmp0);
417 static inline void gen_op_ld_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
419 tcg_gen_qemu_ld_tl(t0, a0, s->mem_index, idx | MO_LE);
422 static inline void gen_op_st_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
424 tcg_gen_qemu_st_tl(t0, a0, s->mem_index, idx | MO_LE);
427 static inline void gen_op_st_rm_T0_A0(DisasContext *s, int idx, int d)
430 gen_op_st_v(s, idx, cpu_T0, cpu_A0);
432 gen_op_mov_reg_v(idx, d, cpu_T0);
436 static inline void gen_jmp_im(target_ulong pc)
438 tcg_gen_movi_tl(cpu_tmp0, pc);
439 gen_op_jmp_v(cpu_tmp0);
442 /* Compute SEG:REG into A0. SEG is selected from the override segment
443 (OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to
444 indicate no override. */
445 static void gen_lea_v_seg(DisasContext *s, TCGMemOp aflag, TCGv a0,
446 int def_seg, int ovr_seg)
452 tcg_gen_mov_tl(cpu_A0, a0);
459 if (ovr_seg < 0 && s->addseg) {
463 tcg_gen_ext32u_tl(cpu_A0, a0);
469 tcg_gen_ext16u_tl(cpu_A0, a0);
484 TCGv seg = cpu_seg_base[ovr_seg];
486 if (aflag == MO_64) {
487 tcg_gen_add_tl(cpu_A0, a0, seg);
488 } else if (CODE64(s)) {
489 tcg_gen_ext32u_tl(cpu_A0, a0);
490 tcg_gen_add_tl(cpu_A0, cpu_A0, seg);
492 tcg_gen_add_tl(cpu_A0, a0, seg);
493 tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
498 static inline void gen_string_movl_A0_ESI(DisasContext *s)
500 gen_lea_v_seg(s, s->aflag, cpu_regs[R_ESI], R_DS, s->override);
503 static inline void gen_string_movl_A0_EDI(DisasContext *s)
505 gen_lea_v_seg(s, s->aflag, cpu_regs[R_EDI], R_ES, -1);
508 static inline void gen_op_movl_T0_Dshift(TCGMemOp ot)
510 tcg_gen_ld32s_tl(cpu_T0, cpu_env, offsetof(CPUX86State, df));
511 tcg_gen_shli_tl(cpu_T0, cpu_T0, ot);
514 static TCGv gen_ext_tl(TCGv dst, TCGv src, TCGMemOp size, bool sign)
519 tcg_gen_ext8s_tl(dst, src);
521 tcg_gen_ext8u_tl(dst, src);
526 tcg_gen_ext16s_tl(dst, src);
528 tcg_gen_ext16u_tl(dst, src);
534 tcg_gen_ext32s_tl(dst, src);
536 tcg_gen_ext32u_tl(dst, src);
545 static void gen_extu(TCGMemOp ot, TCGv reg)
547 gen_ext_tl(reg, reg, ot, false);
550 static void gen_exts(TCGMemOp ot, TCGv reg)
552 gen_ext_tl(reg, reg, ot, true);
555 static inline void gen_op_jnz_ecx(TCGMemOp size, TCGLabel *label1)
557 tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
558 gen_extu(size, cpu_tmp0);
559 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_tmp0, 0, label1);
562 static inline void gen_op_jz_ecx(TCGMemOp size, TCGLabel *label1)
564 tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
565 gen_extu(size, cpu_tmp0);
566 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
569 static void gen_helper_in_func(TCGMemOp ot, TCGv v, TCGv_i32 n)
573 gen_helper_inb(v, cpu_env, n);
576 gen_helper_inw(v, cpu_env, n);
579 gen_helper_inl(v, cpu_env, n);
586 static void gen_helper_out_func(TCGMemOp ot, TCGv_i32 v, TCGv_i32 n)
590 gen_helper_outb(cpu_env, v, n);
593 gen_helper_outw(cpu_env, v, n);
596 gen_helper_outl(cpu_env, v, n);
603 static void gen_check_io(DisasContext *s, TCGMemOp ot, target_ulong cur_eip,
606 target_ulong next_eip;
608 if (s->pe && (s->cpl > s->iopl || s->vm86)) {
609 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
612 gen_helper_check_iob(cpu_env, cpu_tmp2_i32);
615 gen_helper_check_iow(cpu_env, cpu_tmp2_i32);
618 gen_helper_check_iol(cpu_env, cpu_tmp2_i32);
624 if(s->flags & HF_SVMI_MASK) {
627 svm_flags |= (1 << (4 + ot));
628 next_eip = s->pc - s->cs_base;
629 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
630 gen_helper_svm_check_io(cpu_env, cpu_tmp2_i32,
631 tcg_const_i32(svm_flags),
632 tcg_const_i32(next_eip - cur_eip));
636 static inline void gen_movs(DisasContext *s, TCGMemOp ot)
638 gen_string_movl_A0_ESI(s);
639 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
640 gen_string_movl_A0_EDI(s);
641 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
642 gen_op_movl_T0_Dshift(ot);
643 gen_op_add_reg_T0(s->aflag, R_ESI);
644 gen_op_add_reg_T0(s->aflag, R_EDI);
647 static void gen_op_update1_cc(void)
649 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
652 static void gen_op_update2_cc(void)
654 tcg_gen_mov_tl(cpu_cc_src, cpu_T1);
655 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
658 static void gen_op_update3_cc(TCGv reg)
660 tcg_gen_mov_tl(cpu_cc_src2, reg);
661 tcg_gen_mov_tl(cpu_cc_src, cpu_T1);
662 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
665 static inline void gen_op_testl_T0_T1_cc(void)
667 tcg_gen_and_tl(cpu_cc_dst, cpu_T0, cpu_T1);
670 static void gen_op_update_neg_cc(void)
672 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
673 tcg_gen_neg_tl(cpu_cc_src, cpu_T0);
674 tcg_gen_movi_tl(cpu_cc_srcT, 0);
677 /* compute all eflags to cc_src */
678 static void gen_compute_eflags(DisasContext *s)
680 TCGv zero, dst, src1, src2;
683 if (s->cc_op == CC_OP_EFLAGS) {
686 if (s->cc_op == CC_OP_CLR) {
687 tcg_gen_movi_tl(cpu_cc_src, CC_Z | CC_P);
688 set_cc_op(s, CC_OP_EFLAGS);
697 /* Take care to not read values that are not live. */
698 live = cc_op_live[s->cc_op] & ~USES_CC_SRCT;
699 dead = live ^ (USES_CC_DST | USES_CC_SRC | USES_CC_SRC2);
701 zero = tcg_const_tl(0);
702 if (dead & USES_CC_DST) {
705 if (dead & USES_CC_SRC) {
708 if (dead & USES_CC_SRC2) {
714 gen_helper_cc_compute_all(cpu_cc_src, dst, src1, src2, cpu_cc_op);
715 set_cc_op(s, CC_OP_EFLAGS);
722 typedef struct CCPrepare {
732 /* compute eflags.C to reg */
733 static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg)
739 case CC_OP_SUBB ... CC_OP_SUBQ:
740 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
741 size = s->cc_op - CC_OP_SUBB;
742 t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
743 /* If no temporary was used, be careful not to alias t1 and t0. */
744 t0 = t1 == cpu_cc_src ? cpu_tmp0 : reg;
745 tcg_gen_mov_tl(t0, cpu_cc_srcT);
749 case CC_OP_ADDB ... CC_OP_ADDQ:
750 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
751 size = s->cc_op - CC_OP_ADDB;
752 t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
753 t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
755 return (CCPrepare) { .cond = TCG_COND_LTU, .reg = t0,
756 .reg2 = t1, .mask = -1, .use_reg2 = true };
758 case CC_OP_LOGICB ... CC_OP_LOGICQ:
761 return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
763 case CC_OP_INCB ... CC_OP_INCQ:
764 case CC_OP_DECB ... CC_OP_DECQ:
765 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
766 .mask = -1, .no_setcond = true };
768 case CC_OP_SHLB ... CC_OP_SHLQ:
769 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
770 size = s->cc_op - CC_OP_SHLB;
771 shift = (8 << size) - 1;
772 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
773 .mask = (target_ulong)1 << shift };
775 case CC_OP_MULB ... CC_OP_MULQ:
776 return (CCPrepare) { .cond = TCG_COND_NE,
777 .reg = cpu_cc_src, .mask = -1 };
779 case CC_OP_BMILGB ... CC_OP_BMILGQ:
780 size = s->cc_op - CC_OP_BMILGB;
781 t0 = gen_ext_tl(reg, cpu_cc_src, size, false);
782 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 };
786 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_dst,
787 .mask = -1, .no_setcond = true };
790 case CC_OP_SARB ... CC_OP_SARQ:
792 return (CCPrepare) { .cond = TCG_COND_NE,
793 .reg = cpu_cc_src, .mask = CC_C };
796 /* The need to compute only C from CC_OP_DYNAMIC is important
797 in efficiently implementing e.g. INC at the start of a TB. */
799 gen_helper_cc_compute_c(reg, cpu_cc_dst, cpu_cc_src,
800 cpu_cc_src2, cpu_cc_op);
801 return (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
802 .mask = -1, .no_setcond = true };
806 /* compute eflags.P to reg */
807 static CCPrepare gen_prepare_eflags_p(DisasContext *s, TCGv reg)
809 gen_compute_eflags(s);
810 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
814 /* compute eflags.S to reg */
815 static CCPrepare gen_prepare_eflags_s(DisasContext *s, TCGv reg)
819 gen_compute_eflags(s);
825 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
829 return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
832 TCGMemOp size = (s->cc_op - CC_OP_ADDB) & 3;
833 TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, true);
834 return (CCPrepare) { .cond = TCG_COND_LT, .reg = t0, .mask = -1 };
839 /* compute eflags.O to reg */
840 static CCPrepare gen_prepare_eflags_o(DisasContext *s, TCGv reg)
845 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src2,
846 .mask = -1, .no_setcond = true };
849 return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
851 gen_compute_eflags(s);
852 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
857 /* compute eflags.Z to reg */
858 static CCPrepare gen_prepare_eflags_z(DisasContext *s, TCGv reg)
862 gen_compute_eflags(s);
868 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
871 return (CCPrepare) { .cond = TCG_COND_ALWAYS, .mask = -1 };
873 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = cpu_cc_src,
877 TCGMemOp size = (s->cc_op - CC_OP_ADDB) & 3;
878 TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
879 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 };
884 /* perform a conditional store into register 'reg' according to jump opcode
885 value 'b'. In the fast case, T0 is guaranted not to be used. */
886 static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg)
888 int inv, jcc_op, cond;
894 jcc_op = (b >> 1) & 7;
897 case CC_OP_SUBB ... CC_OP_SUBQ:
898 /* We optimize relational operators for the cmp/jcc case. */
899 size = s->cc_op - CC_OP_SUBB;
902 tcg_gen_mov_tl(cpu_tmp4, cpu_cc_srcT);
903 gen_extu(size, cpu_tmp4);
904 t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
905 cc = (CCPrepare) { .cond = TCG_COND_LEU, .reg = cpu_tmp4,
906 .reg2 = t0, .mask = -1, .use_reg2 = true };
915 tcg_gen_mov_tl(cpu_tmp4, cpu_cc_srcT);
916 gen_exts(size, cpu_tmp4);
917 t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, true);
918 cc = (CCPrepare) { .cond = cond, .reg = cpu_tmp4,
919 .reg2 = t0, .mask = -1, .use_reg2 = true };
929 /* This actually generates good code for JC, JZ and JS. */
932 cc = gen_prepare_eflags_o(s, reg);
935 cc = gen_prepare_eflags_c(s, reg);
938 cc = gen_prepare_eflags_z(s, reg);
941 gen_compute_eflags(s);
942 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
943 .mask = CC_Z | CC_C };
946 cc = gen_prepare_eflags_s(s, reg);
949 cc = gen_prepare_eflags_p(s, reg);
952 gen_compute_eflags(s);
953 if (reg == cpu_cc_src) {
956 tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */
957 tcg_gen_xor_tl(reg, reg, cpu_cc_src);
958 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
963 gen_compute_eflags(s);
964 if (reg == cpu_cc_src) {
967 tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */
968 tcg_gen_xor_tl(reg, reg, cpu_cc_src);
969 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
970 .mask = CC_S | CC_Z };
977 cc.cond = tcg_invert_cond(cc.cond);
982 static void gen_setcc1(DisasContext *s, int b, TCGv reg)
984 CCPrepare cc = gen_prepare_cc(s, b, reg);
987 if (cc.cond == TCG_COND_EQ) {
988 tcg_gen_xori_tl(reg, cc.reg, 1);
990 tcg_gen_mov_tl(reg, cc.reg);
995 if (cc.cond == TCG_COND_NE && !cc.use_reg2 && cc.imm == 0 &&
996 cc.mask != 0 && (cc.mask & (cc.mask - 1)) == 0) {
997 tcg_gen_shri_tl(reg, cc.reg, ctztl(cc.mask));
998 tcg_gen_andi_tl(reg, reg, 1);
1001 if (cc.mask != -1) {
1002 tcg_gen_andi_tl(reg, cc.reg, cc.mask);
1006 tcg_gen_setcond_tl(cc.cond, reg, cc.reg, cc.reg2);
1008 tcg_gen_setcondi_tl(cc.cond, reg, cc.reg, cc.imm);
1012 static inline void gen_compute_eflags_c(DisasContext *s, TCGv reg)
1014 gen_setcc1(s, JCC_B << 1, reg);
1017 /* generate a conditional jump to label 'l1' according to jump opcode
1018 value 'b'. In the fast case, T0 is guaranted not to be used. */
1019 static inline void gen_jcc1_noeob(DisasContext *s, int b, TCGLabel *l1)
1021 CCPrepare cc = gen_prepare_cc(s, b, cpu_T0);
1023 if (cc.mask != -1) {
1024 tcg_gen_andi_tl(cpu_T0, cc.reg, cc.mask);
1028 tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1030 tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1034 /* Generate a conditional jump to label 'l1' according to jump opcode
1035 value 'b'. In the fast case, T0 is guaranted not to be used.
1036 A translation block must end soon. */
1037 static inline void gen_jcc1(DisasContext *s, int b, TCGLabel *l1)
1039 CCPrepare cc = gen_prepare_cc(s, b, cpu_T0);
1041 gen_update_cc_op(s);
1042 if (cc.mask != -1) {
1043 tcg_gen_andi_tl(cpu_T0, cc.reg, cc.mask);
1046 set_cc_op(s, CC_OP_DYNAMIC);
1048 tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1050 tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1054 /* XXX: does not work with gdbstub "ice" single step - not a
1056 static TCGLabel *gen_jz_ecx_string(DisasContext *s, target_ulong next_eip)
1058 TCGLabel *l1 = gen_new_label();
1059 TCGLabel *l2 = gen_new_label();
1060 gen_op_jnz_ecx(s->aflag, l1);
1062 gen_jmp_tb(s, next_eip, 1);
1067 static inline void gen_stos(DisasContext *s, TCGMemOp ot)
1069 gen_op_mov_v_reg(MO_32, cpu_T0, R_EAX);
1070 gen_string_movl_A0_EDI(s);
1071 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
1072 gen_op_movl_T0_Dshift(ot);
1073 gen_op_add_reg_T0(s->aflag, R_EDI);
1076 static inline void gen_lods(DisasContext *s, TCGMemOp ot)
1078 gen_string_movl_A0_ESI(s);
1079 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1080 gen_op_mov_reg_v(ot, R_EAX, cpu_T0);
1081 gen_op_movl_T0_Dshift(ot);
1082 gen_op_add_reg_T0(s->aflag, R_ESI);
1085 static inline void gen_scas(DisasContext *s, TCGMemOp ot)
1087 gen_string_movl_A0_EDI(s);
1088 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
1089 gen_op(s, OP_CMPL, ot, R_EAX);
1090 gen_op_movl_T0_Dshift(ot);
1091 gen_op_add_reg_T0(s->aflag, R_EDI);
1094 static inline void gen_cmps(DisasContext *s, TCGMemOp ot)
1096 gen_string_movl_A0_EDI(s);
1097 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
1098 gen_string_movl_A0_ESI(s);
1099 gen_op(s, OP_CMPL, ot, OR_TMP0);
1100 gen_op_movl_T0_Dshift(ot);
1101 gen_op_add_reg_T0(s->aflag, R_ESI);
1102 gen_op_add_reg_T0(s->aflag, R_EDI);
1105 static void gen_bpt_io(DisasContext *s, TCGv_i32 t_port, int ot)
1107 if (s->flags & HF_IOBPT_MASK) {
1108 TCGv_i32 t_size = tcg_const_i32(1 << ot);
1109 TCGv t_next = tcg_const_tl(s->pc - s->cs_base);
1111 gen_helper_bpt_io(cpu_env, t_port, t_size, t_next);
1112 tcg_temp_free_i32(t_size);
1113 tcg_temp_free(t_next);
1118 static inline void gen_ins(DisasContext *s, TCGMemOp ot)
1120 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
1123 gen_string_movl_A0_EDI(s);
1124 /* Note: we must do this dummy write first to be restartable in
1125 case of page fault. */
1126 tcg_gen_movi_tl(cpu_T0, 0);
1127 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
1128 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_EDX]);
1129 tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1130 gen_helper_in_func(ot, cpu_T0, cpu_tmp2_i32);
1131 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
1132 gen_op_movl_T0_Dshift(ot);
1133 gen_op_add_reg_T0(s->aflag, R_EDI);
1134 gen_bpt_io(s, cpu_tmp2_i32, ot);
1135 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
1140 static inline void gen_outs(DisasContext *s, TCGMemOp ot)
1142 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
1145 gen_string_movl_A0_ESI(s);
1146 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1148 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_EDX]);
1149 tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1150 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T0);
1151 gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
1152 gen_op_movl_T0_Dshift(ot);
1153 gen_op_add_reg_T0(s->aflag, R_ESI);
1154 gen_bpt_io(s, cpu_tmp2_i32, ot);
1155 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
1160 /* same method as Valgrind : we generate jumps to current or next
1162 #define GEN_REPZ(op) \
1163 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1164 target_ulong cur_eip, target_ulong next_eip) \
1167 gen_update_cc_op(s); \
1168 l2 = gen_jz_ecx_string(s, next_eip); \
1169 gen_ ## op(s, ot); \
1170 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1171 /* a loop would cause two single step exceptions if ECX = 1 \
1172 before rep string_insn */ \
1174 gen_op_jz_ecx(s->aflag, l2); \
1175 gen_jmp(s, cur_eip); \
1178 #define GEN_REPZ2(op) \
1179 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1180 target_ulong cur_eip, \
1181 target_ulong next_eip, \
1185 gen_update_cc_op(s); \
1186 l2 = gen_jz_ecx_string(s, next_eip); \
1187 gen_ ## op(s, ot); \
1188 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1189 gen_update_cc_op(s); \
1190 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
1192 gen_op_jz_ecx(s->aflag, l2); \
1193 gen_jmp(s, cur_eip); \
1204 static void gen_helper_fp_arith_ST0_FT0(int op)
1208 gen_helper_fadd_ST0_FT0(cpu_env);
1211 gen_helper_fmul_ST0_FT0(cpu_env);
1214 gen_helper_fcom_ST0_FT0(cpu_env);
1217 gen_helper_fcom_ST0_FT0(cpu_env);
1220 gen_helper_fsub_ST0_FT0(cpu_env);
1223 gen_helper_fsubr_ST0_FT0(cpu_env);
1226 gen_helper_fdiv_ST0_FT0(cpu_env);
1229 gen_helper_fdivr_ST0_FT0(cpu_env);
1234 /* NOTE the exception in "r" op ordering */
1235 static void gen_helper_fp_arith_STN_ST0(int op, int opreg)
1237 TCGv_i32 tmp = tcg_const_i32(opreg);
1240 gen_helper_fadd_STN_ST0(cpu_env, tmp);
1243 gen_helper_fmul_STN_ST0(cpu_env, tmp);
1246 gen_helper_fsubr_STN_ST0(cpu_env, tmp);
1249 gen_helper_fsub_STN_ST0(cpu_env, tmp);
1252 gen_helper_fdivr_STN_ST0(cpu_env, tmp);
1255 gen_helper_fdiv_STN_ST0(cpu_env, tmp);
1260 /* if d == OR_TMP0, it means memory operand (address in A0) */
1261 static void gen_op(DisasContext *s1, int op, TCGMemOp ot, int d)
1264 gen_op_mov_v_reg(ot, cpu_T0, d);
1265 } else if (!(s1->prefix & PREFIX_LOCK)) {
1266 gen_op_ld_v(s1, ot, cpu_T0, cpu_A0);
1270 gen_compute_eflags_c(s1, cpu_tmp4);
1271 if (s1->prefix & PREFIX_LOCK) {
1272 tcg_gen_add_tl(cpu_T0, cpu_tmp4, cpu_T1);
1273 tcg_gen_atomic_add_fetch_tl(cpu_T0, cpu_A0, cpu_T0,
1274 s1->mem_index, ot | MO_LE);
1276 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
1277 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_tmp4);
1278 gen_op_st_rm_T0_A0(s1, ot, d);
1280 gen_op_update3_cc(cpu_tmp4);
1281 set_cc_op(s1, CC_OP_ADCB + ot);
1284 gen_compute_eflags_c(s1, cpu_tmp4);
1285 if (s1->prefix & PREFIX_LOCK) {
1286 tcg_gen_add_tl(cpu_T0, cpu_T1, cpu_tmp4);
1287 tcg_gen_neg_tl(cpu_T0, cpu_T0);
1288 tcg_gen_atomic_add_fetch_tl(cpu_T0, cpu_A0, cpu_T0,
1289 s1->mem_index, ot | MO_LE);
1291 tcg_gen_sub_tl(cpu_T0, cpu_T0, cpu_T1);
1292 tcg_gen_sub_tl(cpu_T0, cpu_T0, cpu_tmp4);
1293 gen_op_st_rm_T0_A0(s1, ot, d);
1295 gen_op_update3_cc(cpu_tmp4);
1296 set_cc_op(s1, CC_OP_SBBB + ot);
1299 if (s1->prefix & PREFIX_LOCK) {
1300 tcg_gen_atomic_add_fetch_tl(cpu_T0, cpu_A0, cpu_T1,
1301 s1->mem_index, ot | MO_LE);
1303 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
1304 gen_op_st_rm_T0_A0(s1, ot, d);
1306 gen_op_update2_cc();
1307 set_cc_op(s1, CC_OP_ADDB + ot);
1310 if (s1->prefix & PREFIX_LOCK) {
1311 tcg_gen_neg_tl(cpu_T0, cpu_T1);
1312 tcg_gen_atomic_fetch_add_tl(cpu_cc_srcT, cpu_A0, cpu_T0,
1313 s1->mem_index, ot | MO_LE);
1314 tcg_gen_sub_tl(cpu_T0, cpu_cc_srcT, cpu_T1);
1316 tcg_gen_mov_tl(cpu_cc_srcT, cpu_T0);
1317 tcg_gen_sub_tl(cpu_T0, cpu_T0, cpu_T1);
1318 gen_op_st_rm_T0_A0(s1, ot, d);
1320 gen_op_update2_cc();
1321 set_cc_op(s1, CC_OP_SUBB + ot);
1325 if (s1->prefix & PREFIX_LOCK) {
1326 tcg_gen_atomic_and_fetch_tl(cpu_T0, cpu_A0, cpu_T1,
1327 s1->mem_index, ot | MO_LE);
1329 tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1);
1330 gen_op_st_rm_T0_A0(s1, ot, d);
1332 gen_op_update1_cc();
1333 set_cc_op(s1, CC_OP_LOGICB + ot);
1336 if (s1->prefix & PREFIX_LOCK) {
1337 tcg_gen_atomic_or_fetch_tl(cpu_T0, cpu_A0, cpu_T1,
1338 s1->mem_index, ot | MO_LE);
1340 tcg_gen_or_tl(cpu_T0, cpu_T0, cpu_T1);
1341 gen_op_st_rm_T0_A0(s1, ot, d);
1343 gen_op_update1_cc();
1344 set_cc_op(s1, CC_OP_LOGICB + ot);
1347 if (s1->prefix & PREFIX_LOCK) {
1348 tcg_gen_atomic_xor_fetch_tl(cpu_T0, cpu_A0, cpu_T1,
1349 s1->mem_index, ot | MO_LE);
1351 tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_T1);
1352 gen_op_st_rm_T0_A0(s1, ot, d);
1354 gen_op_update1_cc();
1355 set_cc_op(s1, CC_OP_LOGICB + ot);
1358 tcg_gen_mov_tl(cpu_cc_src, cpu_T1);
1359 tcg_gen_mov_tl(cpu_cc_srcT, cpu_T0);
1360 tcg_gen_sub_tl(cpu_cc_dst, cpu_T0, cpu_T1);
1361 set_cc_op(s1, CC_OP_SUBB + ot);
1366 /* if d == OR_TMP0, it means memory operand (address in A0) */
1367 static void gen_inc(DisasContext *s1, TCGMemOp ot, int d, int c)
1369 if (s1->prefix & PREFIX_LOCK) {
1370 tcg_gen_movi_tl(cpu_T0, c > 0 ? 1 : -1);
1371 tcg_gen_atomic_add_fetch_tl(cpu_T0, cpu_A0, cpu_T0,
1372 s1->mem_index, ot | MO_LE);
1375 gen_op_mov_v_reg(ot, cpu_T0, d);
1377 gen_op_ld_v(s1, ot, cpu_T0, cpu_A0);
1379 tcg_gen_addi_tl(cpu_T0, cpu_T0, (c > 0 ? 1 : -1));
1380 gen_op_st_rm_T0_A0(s1, ot, d);
1383 gen_compute_eflags_c(s1, cpu_cc_src);
1384 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
1385 set_cc_op(s1, (c > 0 ? CC_OP_INCB : CC_OP_DECB) + ot);
1388 static void gen_shift_flags(DisasContext *s, TCGMemOp ot, TCGv result,
1389 TCGv shm1, TCGv count, bool is_right)
1391 TCGv_i32 z32, s32, oldop;
1394 /* Store the results into the CC variables. If we know that the
1395 variable must be dead, store unconditionally. Otherwise we'll
1396 need to not disrupt the current contents. */
1397 z_tl = tcg_const_tl(0);
1398 if (cc_op_live[s->cc_op] & USES_CC_DST) {
1399 tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_dst, count, z_tl,
1400 result, cpu_cc_dst);
1402 tcg_gen_mov_tl(cpu_cc_dst, result);
1404 if (cc_op_live[s->cc_op] & USES_CC_SRC) {
1405 tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_src, count, z_tl,
1408 tcg_gen_mov_tl(cpu_cc_src, shm1);
1410 tcg_temp_free(z_tl);
1412 /* Get the two potential CC_OP values into temporaries. */
1413 tcg_gen_movi_i32(cpu_tmp2_i32, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot);
1414 if (s->cc_op == CC_OP_DYNAMIC) {
1417 tcg_gen_movi_i32(cpu_tmp3_i32, s->cc_op);
1418 oldop = cpu_tmp3_i32;
1421 /* Conditionally store the CC_OP value. */
1422 z32 = tcg_const_i32(0);
1423 s32 = tcg_temp_new_i32();
1424 tcg_gen_trunc_tl_i32(s32, count);
1425 tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, s32, z32, cpu_tmp2_i32, oldop);
1426 tcg_temp_free_i32(z32);
1427 tcg_temp_free_i32(s32);
1429 /* The CC_OP value is no longer predictable. */
1430 set_cc_op(s, CC_OP_DYNAMIC);
1433 static void gen_shift_rm_T1(DisasContext *s, TCGMemOp ot, int op1,
1434 int is_right, int is_arith)
1436 target_ulong mask = (ot == MO_64 ? 0x3f : 0x1f);
1439 if (op1 == OR_TMP0) {
1440 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1442 gen_op_mov_v_reg(ot, cpu_T0, op1);
1445 tcg_gen_andi_tl(cpu_T1, cpu_T1, mask);
1446 tcg_gen_subi_tl(cpu_tmp0, cpu_T1, 1);
1450 gen_exts(ot, cpu_T0);
1451 tcg_gen_sar_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1452 tcg_gen_sar_tl(cpu_T0, cpu_T0, cpu_T1);
1454 gen_extu(ot, cpu_T0);
1455 tcg_gen_shr_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1456 tcg_gen_shr_tl(cpu_T0, cpu_T0, cpu_T1);
1459 tcg_gen_shl_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1460 tcg_gen_shl_tl(cpu_T0, cpu_T0, cpu_T1);
1464 gen_op_st_rm_T0_A0(s, ot, op1);
1466 gen_shift_flags(s, ot, cpu_T0, cpu_tmp0, cpu_T1, is_right);
1469 static void gen_shift_rm_im(DisasContext *s, TCGMemOp ot, int op1, int op2,
1470 int is_right, int is_arith)
1472 int mask = (ot == MO_64 ? 0x3f : 0x1f);
1476 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1478 gen_op_mov_v_reg(ot, cpu_T0, op1);
1484 gen_exts(ot, cpu_T0);
1485 tcg_gen_sari_tl(cpu_tmp4, cpu_T0, op2 - 1);
1486 tcg_gen_sari_tl(cpu_T0, cpu_T0, op2);
1488 gen_extu(ot, cpu_T0);
1489 tcg_gen_shri_tl(cpu_tmp4, cpu_T0, op2 - 1);
1490 tcg_gen_shri_tl(cpu_T0, cpu_T0, op2);
1493 tcg_gen_shli_tl(cpu_tmp4, cpu_T0, op2 - 1);
1494 tcg_gen_shli_tl(cpu_T0, cpu_T0, op2);
1499 gen_op_st_rm_T0_A0(s, ot, op1);
1501 /* update eflags if non zero shift */
1503 tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
1504 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
1505 set_cc_op(s, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot);
1509 static void gen_rot_rm_T1(DisasContext *s, TCGMemOp ot, int op1, int is_right)
1511 target_ulong mask = (ot == MO_64 ? 0x3f : 0x1f);
1515 if (op1 == OR_TMP0) {
1516 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1518 gen_op_mov_v_reg(ot, cpu_T0, op1);
1521 tcg_gen_andi_tl(cpu_T1, cpu_T1, mask);
1525 /* Replicate the 8-bit input so that a 32-bit rotate works. */
1526 tcg_gen_ext8u_tl(cpu_T0, cpu_T0);
1527 tcg_gen_muli_tl(cpu_T0, cpu_T0, 0x01010101);
1530 /* Replicate the 16-bit input so that a 32-bit rotate works. */
1531 tcg_gen_deposit_tl(cpu_T0, cpu_T0, cpu_T0, 16, 16);
1534 #ifdef TARGET_X86_64
1536 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
1537 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T1);
1539 tcg_gen_rotr_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
1541 tcg_gen_rotl_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
1543 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
1548 tcg_gen_rotr_tl(cpu_T0, cpu_T0, cpu_T1);
1550 tcg_gen_rotl_tl(cpu_T0, cpu_T0, cpu_T1);
1556 gen_op_st_rm_T0_A0(s, ot, op1);
1558 /* We'll need the flags computed into CC_SRC. */
1559 gen_compute_eflags(s);
1561 /* The value that was "rotated out" is now present at the other end
1562 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1563 since we've computed the flags into CC_SRC, these variables are
1566 tcg_gen_shri_tl(cpu_cc_src2, cpu_T0, mask - 1);
1567 tcg_gen_shri_tl(cpu_cc_dst, cpu_T0, mask);
1568 tcg_gen_andi_tl(cpu_cc_dst, cpu_cc_dst, 1);
1570 tcg_gen_shri_tl(cpu_cc_src2, cpu_T0, mask);
1571 tcg_gen_andi_tl(cpu_cc_dst, cpu_T0, 1);
1573 tcg_gen_andi_tl(cpu_cc_src2, cpu_cc_src2, 1);
1574 tcg_gen_xor_tl(cpu_cc_src2, cpu_cc_src2, cpu_cc_dst);
1576 /* Now conditionally store the new CC_OP value. If the shift count
1577 is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1578 Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1579 exactly as we computed above. */
1580 t0 = tcg_const_i32(0);
1581 t1 = tcg_temp_new_i32();
1582 tcg_gen_trunc_tl_i32(t1, cpu_T1);
1583 tcg_gen_movi_i32(cpu_tmp2_i32, CC_OP_ADCOX);
1584 tcg_gen_movi_i32(cpu_tmp3_i32, CC_OP_EFLAGS);
1585 tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, t1, t0,
1586 cpu_tmp2_i32, cpu_tmp3_i32);
1587 tcg_temp_free_i32(t0);
1588 tcg_temp_free_i32(t1);
1590 /* The CC_OP value is no longer predictable. */
1591 set_cc_op(s, CC_OP_DYNAMIC);
1594 static void gen_rot_rm_im(DisasContext *s, TCGMemOp ot, int op1, int op2,
1597 int mask = (ot == MO_64 ? 0x3f : 0x1f);
1601 if (op1 == OR_TMP0) {
1602 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1604 gen_op_mov_v_reg(ot, cpu_T0, op1);
1610 #ifdef TARGET_X86_64
1612 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
1614 tcg_gen_rotri_i32(cpu_tmp2_i32, cpu_tmp2_i32, op2);
1616 tcg_gen_rotli_i32(cpu_tmp2_i32, cpu_tmp2_i32, op2);
1618 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
1623 tcg_gen_rotri_tl(cpu_T0, cpu_T0, op2);
1625 tcg_gen_rotli_tl(cpu_T0, cpu_T0, op2);
1636 shift = mask + 1 - shift;
1638 gen_extu(ot, cpu_T0);
1639 tcg_gen_shli_tl(cpu_tmp0, cpu_T0, shift);
1640 tcg_gen_shri_tl(cpu_T0, cpu_T0, mask + 1 - shift);
1641 tcg_gen_or_tl(cpu_T0, cpu_T0, cpu_tmp0);
1647 gen_op_st_rm_T0_A0(s, ot, op1);
1650 /* Compute the flags into CC_SRC. */
1651 gen_compute_eflags(s);
1653 /* The value that was "rotated out" is now present at the other end
1654 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1655 since we've computed the flags into CC_SRC, these variables are
1658 tcg_gen_shri_tl(cpu_cc_src2, cpu_T0, mask - 1);
1659 tcg_gen_shri_tl(cpu_cc_dst, cpu_T0, mask);
1660 tcg_gen_andi_tl(cpu_cc_dst, cpu_cc_dst, 1);
1662 tcg_gen_shri_tl(cpu_cc_src2, cpu_T0, mask);
1663 tcg_gen_andi_tl(cpu_cc_dst, cpu_T0, 1);
1665 tcg_gen_andi_tl(cpu_cc_src2, cpu_cc_src2, 1);
1666 tcg_gen_xor_tl(cpu_cc_src2, cpu_cc_src2, cpu_cc_dst);
1667 set_cc_op(s, CC_OP_ADCOX);
1671 /* XXX: add faster immediate = 1 case */
1672 static void gen_rotc_rm_T1(DisasContext *s, TCGMemOp ot, int op1,
1675 gen_compute_eflags(s);
1676 assert(s->cc_op == CC_OP_EFLAGS);
1680 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1682 gen_op_mov_v_reg(ot, cpu_T0, op1);
1687 gen_helper_rcrb(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1690 gen_helper_rcrw(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1693 gen_helper_rcrl(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1695 #ifdef TARGET_X86_64
1697 gen_helper_rcrq(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1706 gen_helper_rclb(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1709 gen_helper_rclw(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1712 gen_helper_rcll(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1714 #ifdef TARGET_X86_64
1716 gen_helper_rclq(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1724 gen_op_st_rm_T0_A0(s, ot, op1);
1727 /* XXX: add faster immediate case */
1728 static void gen_shiftd_rm_T1(DisasContext *s, TCGMemOp ot, int op1,
1729 bool is_right, TCGv count_in)
1731 target_ulong mask = (ot == MO_64 ? 63 : 31);
1735 if (op1 == OR_TMP0) {
1736 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1738 gen_op_mov_v_reg(ot, cpu_T0, op1);
1741 count = tcg_temp_new();
1742 tcg_gen_andi_tl(count, count_in, mask);
1746 /* Note: we implement the Intel behaviour for shift count > 16.
1747 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A
1748 portion by constructing it as a 32-bit value. */
1750 tcg_gen_deposit_tl(cpu_tmp0, cpu_T0, cpu_T1, 16, 16);
1751 tcg_gen_mov_tl(cpu_T1, cpu_T0);
1752 tcg_gen_mov_tl(cpu_T0, cpu_tmp0);
1754 tcg_gen_deposit_tl(cpu_T1, cpu_T0, cpu_T1, 16, 16);
1757 #ifdef TARGET_X86_64
1759 /* Concatenate the two 32-bit values and use a 64-bit shift. */
1760 tcg_gen_subi_tl(cpu_tmp0, count, 1);
1762 tcg_gen_concat_tl_i64(cpu_T0, cpu_T0, cpu_T1);
1763 tcg_gen_shr_i64(cpu_tmp0, cpu_T0, cpu_tmp0);
1764 tcg_gen_shr_i64(cpu_T0, cpu_T0, count);
1766 tcg_gen_concat_tl_i64(cpu_T0, cpu_T1, cpu_T0);
1767 tcg_gen_shl_i64(cpu_tmp0, cpu_T0, cpu_tmp0);
1768 tcg_gen_shl_i64(cpu_T0, cpu_T0, count);
1769 tcg_gen_shri_i64(cpu_tmp0, cpu_tmp0, 32);
1770 tcg_gen_shri_i64(cpu_T0, cpu_T0, 32);
1775 tcg_gen_subi_tl(cpu_tmp0, count, 1);
1777 tcg_gen_shr_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1779 tcg_gen_subfi_tl(cpu_tmp4, mask + 1, count);
1780 tcg_gen_shr_tl(cpu_T0, cpu_T0, count);
1781 tcg_gen_shl_tl(cpu_T1, cpu_T1, cpu_tmp4);
1783 tcg_gen_shl_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1785 /* Only needed if count > 16, for Intel behaviour. */
1786 tcg_gen_subfi_tl(cpu_tmp4, 33, count);
1787 tcg_gen_shr_tl(cpu_tmp4, cpu_T1, cpu_tmp4);
1788 tcg_gen_or_tl(cpu_tmp0, cpu_tmp0, cpu_tmp4);
1791 tcg_gen_subfi_tl(cpu_tmp4, mask + 1, count);
1792 tcg_gen_shl_tl(cpu_T0, cpu_T0, count);
1793 tcg_gen_shr_tl(cpu_T1, cpu_T1, cpu_tmp4);
1795 tcg_gen_movi_tl(cpu_tmp4, 0);
1796 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_T1, count, cpu_tmp4,
1798 tcg_gen_or_tl(cpu_T0, cpu_T0, cpu_T1);
1803 gen_op_st_rm_T0_A0(s, ot, op1);
1805 gen_shift_flags(s, ot, cpu_T0, cpu_tmp0, count, is_right);
1806 tcg_temp_free(count);
1809 static void gen_shift(DisasContext *s1, int op, TCGMemOp ot, int d, int s)
1812 gen_op_mov_v_reg(ot, cpu_T1, s);
1815 gen_rot_rm_T1(s1, ot, d, 0);
1818 gen_rot_rm_T1(s1, ot, d, 1);
1822 gen_shift_rm_T1(s1, ot, d, 0, 0);
1825 gen_shift_rm_T1(s1, ot, d, 1, 0);
1828 gen_shift_rm_T1(s1, ot, d, 1, 1);
1831 gen_rotc_rm_T1(s1, ot, d, 0);
1834 gen_rotc_rm_T1(s1, ot, d, 1);
1839 static void gen_shifti(DisasContext *s1, int op, TCGMemOp ot, int d, int c)
1843 gen_rot_rm_im(s1, ot, d, c, 0);
1846 gen_rot_rm_im(s1, ot, d, c, 1);
1850 gen_shift_rm_im(s1, ot, d, c, 0, 0);
1853 gen_shift_rm_im(s1, ot, d, c, 1, 0);
1856 gen_shift_rm_im(s1, ot, d, c, 1, 1);
1859 /* currently not optimized */
1860 tcg_gen_movi_tl(cpu_T1, c);
1861 gen_shift(s1, op, ot, d, OR_TMP1);
1866 #define X86_MAX_INSN_LENGTH 15
1868 static uint64_t advance_pc(CPUX86State *env, DisasContext *s, int num_bytes)
1870 uint64_t pc = s->pc;
1873 if (unlikely(s->pc - s->pc_start > X86_MAX_INSN_LENGTH)) {
1874 /* If the instruction's 16th byte is on a different page than the 1st, a
1875 * page fault on the second page wins over the general protection fault
1876 * caused by the instruction being too long.
1877 * This can happen even if the operand is only one byte long!
1879 if (((s->pc - 1) ^ (pc - 1)) & TARGET_PAGE_MASK) {
1880 volatile uint8_t unused =
1881 cpu_ldub_code(env, (s->pc - 1) & TARGET_PAGE_MASK);
1884 siglongjmp(s->jmpbuf, 1);
1890 static inline uint8_t x86_ldub_code(CPUX86State *env, DisasContext *s)
1892 return cpu_ldub_code(env, advance_pc(env, s, 1));
1895 static inline int16_t x86_ldsw_code(CPUX86State *env, DisasContext *s)
1897 return cpu_ldsw_code(env, advance_pc(env, s, 2));
1900 static inline uint16_t x86_lduw_code(CPUX86State *env, DisasContext *s)
1902 return cpu_lduw_code(env, advance_pc(env, s, 2));
1905 static inline uint32_t x86_ldl_code(CPUX86State *env, DisasContext *s)
1907 return cpu_ldl_code(env, advance_pc(env, s, 4));
1910 #ifdef TARGET_X86_64
1911 static inline uint64_t x86_ldq_code(CPUX86State *env, DisasContext *s)
1913 return cpu_ldq_code(env, advance_pc(env, s, 8));
1917 /* Decompose an address. */
1919 typedef struct AddressParts {
1927 static AddressParts gen_lea_modrm_0(CPUX86State *env, DisasContext *s,
1930 int def_seg, base, index, scale, mod, rm;
1939 mod = (modrm >> 6) & 3;
1941 base = rm | REX_B(s);
1944 /* Normally filtered out earlier, but including this path
1945 simplifies multi-byte nop, as well as bndcl, bndcu, bndcn. */
1954 int code = x86_ldub_code(env, s);
1955 scale = (code >> 6) & 3;
1956 index = ((code >> 3) & 7) | REX_X(s);
1958 index = -1; /* no index */
1960 base = (code & 7) | REX_B(s);
1966 if ((base & 7) == 5) {
1968 disp = (int32_t)x86_ldl_code(env, s);
1969 if (CODE64(s) && !havesib) {
1971 disp += s->pc + s->rip_offset;
1976 disp = (int8_t)x86_ldub_code(env, s);
1980 disp = (int32_t)x86_ldl_code(env, s);
1984 /* For correct popl handling with esp. */
1985 if (base == R_ESP && s->popl_esp_hack) {
1986 disp += s->popl_esp_hack;
1988 if (base == R_EBP || base == R_ESP) {
1997 disp = x86_lduw_code(env, s);
2000 } else if (mod == 1) {
2001 disp = (int8_t)x86_ldub_code(env, s);
2003 disp = (int16_t)x86_lduw_code(env, s);
2047 return (AddressParts){ def_seg, base, index, scale, disp };
2050 /* Compute the address, with a minimum number of TCG ops. */
2051 static TCGv gen_lea_modrm_1(AddressParts a)
2057 ea = cpu_regs[a.index];
2059 tcg_gen_shli_tl(cpu_A0, cpu_regs[a.index], a.scale);
2063 tcg_gen_add_tl(cpu_A0, ea, cpu_regs[a.base]);
2066 } else if (a.base >= 0) {
2067 ea = cpu_regs[a.base];
2070 tcg_gen_movi_tl(cpu_A0, a.disp);
2072 } else if (a.disp != 0) {
2073 tcg_gen_addi_tl(cpu_A0, ea, a.disp);
2080 static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm)
2082 AddressParts a = gen_lea_modrm_0(env, s, modrm);
2083 TCGv ea = gen_lea_modrm_1(a);
2084 gen_lea_v_seg(s, s->aflag, ea, a.def_seg, s->override);
2087 static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm)
2089 (void)gen_lea_modrm_0(env, s, modrm);
2092 /* Used for BNDCL, BNDCU, BNDCN. */
2093 static void gen_bndck(CPUX86State *env, DisasContext *s, int modrm,
2094 TCGCond cond, TCGv_i64 bndv)
2096 TCGv ea = gen_lea_modrm_1(gen_lea_modrm_0(env, s, modrm));
2098 tcg_gen_extu_tl_i64(cpu_tmp1_i64, ea);
2100 tcg_gen_ext32u_i64(cpu_tmp1_i64, cpu_tmp1_i64);
2102 tcg_gen_setcond_i64(cond, cpu_tmp1_i64, cpu_tmp1_i64, bndv);
2103 tcg_gen_extrl_i64_i32(cpu_tmp2_i32, cpu_tmp1_i64);
2104 gen_helper_bndck(cpu_env, cpu_tmp2_i32);
2107 /* used for LEA and MOV AX, mem */
2108 static void gen_add_A0_ds_seg(DisasContext *s)
2110 gen_lea_v_seg(s, s->aflag, cpu_A0, R_DS, s->override);
2113 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2115 static void gen_ldst_modrm(CPUX86State *env, DisasContext *s, int modrm,
2116 TCGMemOp ot, int reg, int is_store)
2120 mod = (modrm >> 6) & 3;
2121 rm = (modrm & 7) | REX_B(s);
2125 gen_op_mov_v_reg(ot, cpu_T0, reg);
2126 gen_op_mov_reg_v(ot, rm, cpu_T0);
2128 gen_op_mov_v_reg(ot, cpu_T0, rm);
2130 gen_op_mov_reg_v(ot, reg, cpu_T0);
2133 gen_lea_modrm(env, s, modrm);
2136 gen_op_mov_v_reg(ot, cpu_T0, reg);
2137 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
2139 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
2141 gen_op_mov_reg_v(ot, reg, cpu_T0);
2146 static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, TCGMemOp ot)
2152 ret = x86_ldub_code(env, s);
2155 ret = x86_lduw_code(env, s);
2158 #ifdef TARGET_X86_64
2161 ret = x86_ldl_code(env, s);
2169 static inline int insn_const_size(TCGMemOp ot)
2178 static inline bool use_goto_tb(DisasContext *s, target_ulong pc)
2180 #ifndef CONFIG_USER_ONLY
2181 return (pc & TARGET_PAGE_MASK) == (s->base.tb->pc & TARGET_PAGE_MASK) ||
2182 (pc & TARGET_PAGE_MASK) == (s->pc_start & TARGET_PAGE_MASK);
2188 static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
2190 target_ulong pc = s->cs_base + eip;
2192 if (use_goto_tb(s, pc)) {
2193 /* jump to same page: we can use a direct jump */
2194 tcg_gen_goto_tb(tb_num);
2196 tcg_gen_exit_tb(s->base.tb, tb_num);
2197 s->base.is_jmp = DISAS_NORETURN;
2199 /* jump to another page */
2201 gen_jr(s, cpu_tmp0);
2205 static inline void gen_jcc(DisasContext *s, int b,
2206 target_ulong val, target_ulong next_eip)
2211 l1 = gen_new_label();
2214 gen_goto_tb(s, 0, next_eip);
2217 gen_goto_tb(s, 1, val);
2219 l1 = gen_new_label();
2220 l2 = gen_new_label();
2223 gen_jmp_im(next_eip);
2233 static void gen_cmovcc1(CPUX86State *env, DisasContext *s, TCGMemOp ot, int b,
2238 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
2240 cc = gen_prepare_cc(s, b, cpu_T1);
2241 if (cc.mask != -1) {
2242 TCGv t0 = tcg_temp_new();
2243 tcg_gen_andi_tl(t0, cc.reg, cc.mask);
2247 cc.reg2 = tcg_const_tl(cc.imm);
2250 tcg_gen_movcond_tl(cc.cond, cpu_T0, cc.reg, cc.reg2,
2251 cpu_T0, cpu_regs[reg]);
2252 gen_op_mov_reg_v(ot, reg, cpu_T0);
2254 if (cc.mask != -1) {
2255 tcg_temp_free(cc.reg);
2258 tcg_temp_free(cc.reg2);
2262 static inline void gen_op_movl_T0_seg(int seg_reg)
2264 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
2265 offsetof(CPUX86State,segs[seg_reg].selector));
2268 static inline void gen_op_movl_seg_T0_vm(int seg_reg)
2270 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
2271 tcg_gen_st32_tl(cpu_T0, cpu_env,
2272 offsetof(CPUX86State,segs[seg_reg].selector));
2273 tcg_gen_shli_tl(cpu_seg_base[seg_reg], cpu_T0, 4);
2276 /* move T0 to seg_reg and compute if the CPU state may change. Never
2277 call this function with seg_reg == R_CS */
2278 static void gen_movl_seg_T0(DisasContext *s, int seg_reg)
2280 if (s->pe && !s->vm86) {
2281 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
2282 gen_helper_load_seg(cpu_env, tcg_const_i32(seg_reg), cpu_tmp2_i32);
2283 /* abort translation because the addseg value may change or
2284 because ss32 may change. For R_SS, translation must always
2285 stop as a special handling must be done to disable hardware
2286 interrupts for the next instruction */
2287 if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS)) {
2288 s->base.is_jmp = DISAS_TOO_MANY;
2291 gen_op_movl_seg_T0_vm(seg_reg);
2292 if (seg_reg == R_SS) {
2293 s->base.is_jmp = DISAS_TOO_MANY;
2298 static inline int svm_is_rep(int prefixes)
2300 return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0);
2304 gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
2305 uint32_t type, uint64_t param)
2307 /* no SVM activated; fast case */
2308 if (likely(!(s->flags & HF_SVMI_MASK)))
2310 gen_update_cc_op(s);
2311 gen_jmp_im(pc_start - s->cs_base);
2312 gen_helper_svm_check_intercept_param(cpu_env, tcg_const_i32(type),
2313 tcg_const_i64(param));
2317 gen_svm_check_intercept(DisasContext *s, target_ulong pc_start, uint64_t type)
2319 gen_svm_check_intercept_param(s, pc_start, type, 0);
2322 static inline void gen_stack_update(DisasContext *s, int addend)
2324 gen_op_add_reg_im(mo_stacksize(s), R_ESP, addend);
2327 /* Generate a push. It depends on ss32, addseg and dflag. */
2328 static void gen_push_v(DisasContext *s, TCGv val)
2330 TCGMemOp d_ot = mo_pushpop(s, s->dflag);
2331 TCGMemOp a_ot = mo_stacksize(s);
2332 int size = 1 << d_ot;
2333 TCGv new_esp = cpu_A0;
2335 tcg_gen_subi_tl(cpu_A0, cpu_regs[R_ESP], size);
2340 tcg_gen_mov_tl(new_esp, cpu_A0);
2342 gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1);
2345 gen_op_st_v(s, d_ot, val, cpu_A0);
2346 gen_op_mov_reg_v(a_ot, R_ESP, new_esp);
2349 /* two step pop is necessary for precise exceptions */
2350 static TCGMemOp gen_pop_T0(DisasContext *s)
2352 TCGMemOp d_ot = mo_pushpop(s, s->dflag);
2354 gen_lea_v_seg(s, mo_stacksize(s), cpu_regs[R_ESP], R_SS, -1);
2355 gen_op_ld_v(s, d_ot, cpu_T0, cpu_A0);
2360 static inline void gen_pop_update(DisasContext *s, TCGMemOp ot)
2362 gen_stack_update(s, 1 << ot);
2365 static inline void gen_stack_A0(DisasContext *s)
2367 gen_lea_v_seg(s, s->ss32 ? MO_32 : MO_16, cpu_regs[R_ESP], R_SS, -1);
2370 static void gen_pusha(DisasContext *s)
2372 TCGMemOp s_ot = s->ss32 ? MO_32 : MO_16;
2373 TCGMemOp d_ot = s->dflag;
2374 int size = 1 << d_ot;
2377 for (i = 0; i < 8; i++) {
2378 tcg_gen_addi_tl(cpu_A0, cpu_regs[R_ESP], (i - 8) * size);
2379 gen_lea_v_seg(s, s_ot, cpu_A0, R_SS, -1);
2380 gen_op_st_v(s, d_ot, cpu_regs[7 - i], cpu_A0);
2383 gen_stack_update(s, -8 * size);
2386 static void gen_popa(DisasContext *s)
2388 TCGMemOp s_ot = s->ss32 ? MO_32 : MO_16;
2389 TCGMemOp d_ot = s->dflag;
2390 int size = 1 << d_ot;
2393 for (i = 0; i < 8; i++) {
2394 /* ESP is not reloaded */
2395 if (7 - i == R_ESP) {
2398 tcg_gen_addi_tl(cpu_A0, cpu_regs[R_ESP], i * size);
2399 gen_lea_v_seg(s, s_ot, cpu_A0, R_SS, -1);
2400 gen_op_ld_v(s, d_ot, cpu_T0, cpu_A0);
2401 gen_op_mov_reg_v(d_ot, 7 - i, cpu_T0);
2404 gen_stack_update(s, 8 * size);
2407 static void gen_enter(DisasContext *s, int esp_addend, int level)
2409 TCGMemOp d_ot = mo_pushpop(s, s->dflag);
2410 TCGMemOp a_ot = CODE64(s) ? MO_64 : s->ss32 ? MO_32 : MO_16;
2411 int size = 1 << d_ot;
2413 /* Push BP; compute FrameTemp into T1. */
2414 tcg_gen_subi_tl(cpu_T1, cpu_regs[R_ESP], size);
2415 gen_lea_v_seg(s, a_ot, cpu_T1, R_SS, -1);
2416 gen_op_st_v(s, d_ot, cpu_regs[R_EBP], cpu_A0);
2422 /* Copy level-1 pointers from the previous frame. */
2423 for (i = 1; i < level; ++i) {
2424 tcg_gen_subi_tl(cpu_A0, cpu_regs[R_EBP], size * i);
2425 gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1);
2426 gen_op_ld_v(s, d_ot, cpu_tmp0, cpu_A0);
2428 tcg_gen_subi_tl(cpu_A0, cpu_T1, size * i);
2429 gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1);
2430 gen_op_st_v(s, d_ot, cpu_tmp0, cpu_A0);
2433 /* Push the current FrameTemp as the last level. */
2434 tcg_gen_subi_tl(cpu_A0, cpu_T1, size * level);
2435 gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1);
2436 gen_op_st_v(s, d_ot, cpu_T1, cpu_A0);
2439 /* Copy the FrameTemp value to EBP. */
2440 gen_op_mov_reg_v(a_ot, R_EBP, cpu_T1);
2442 /* Compute the final value of ESP. */
2443 tcg_gen_subi_tl(cpu_T1, cpu_T1, esp_addend + size * level);
2444 gen_op_mov_reg_v(a_ot, R_ESP, cpu_T1);
2447 static void gen_leave(DisasContext *s)
2449 TCGMemOp d_ot = mo_pushpop(s, s->dflag);
2450 TCGMemOp a_ot = mo_stacksize(s);
2452 gen_lea_v_seg(s, a_ot, cpu_regs[R_EBP], R_SS, -1);
2453 gen_op_ld_v(s, d_ot, cpu_T0, cpu_A0);
2455 tcg_gen_addi_tl(cpu_T1, cpu_regs[R_EBP], 1 << d_ot);
2457 gen_op_mov_reg_v(d_ot, R_EBP, cpu_T0);
2458 gen_op_mov_reg_v(a_ot, R_ESP, cpu_T1);
2461 static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
2463 gen_update_cc_op(s);
2464 gen_jmp_im(cur_eip);
2465 gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno));
2466 s->base.is_jmp = DISAS_NORETURN;
2469 /* Generate #UD for the current instruction. The assumption here is that
2470 the instruction is known, but it isn't allowed in the current cpu mode. */
2471 static void gen_illegal_opcode(DisasContext *s)
2473 gen_exception(s, EXCP06_ILLOP, s->pc_start - s->cs_base);
2476 /* Similarly, except that the assumption here is that we don't decode
2477 the instruction at all -- either a missing opcode, an unimplemented
2478 feature, or just a bogus instruction stream. */
2479 static void gen_unknown_opcode(CPUX86State *env, DisasContext *s)
2481 gen_illegal_opcode(s);
2483 if (qemu_loglevel_mask(LOG_UNIMP)) {
2484 target_ulong pc = s->pc_start, end = s->pc;
2486 qemu_log("ILLOPC: " TARGET_FMT_lx ":", pc);
2487 for (; pc < end; ++pc) {
2488 qemu_log(" %02x", cpu_ldub_code(env, pc));
2495 /* an interrupt is different from an exception because of the
2497 static void gen_interrupt(DisasContext *s, int intno,
2498 target_ulong cur_eip, target_ulong next_eip)
2500 gen_update_cc_op(s);
2501 gen_jmp_im(cur_eip);
2502 gen_helper_raise_interrupt(cpu_env, tcg_const_i32(intno),
2503 tcg_const_i32(next_eip - cur_eip));
2504 s->base.is_jmp = DISAS_NORETURN;
2507 static void gen_debug(DisasContext *s, target_ulong cur_eip)
2509 gen_update_cc_op(s);
2510 gen_jmp_im(cur_eip);
2511 gen_helper_debug(cpu_env);
2512 s->base.is_jmp = DISAS_NORETURN;
2515 static void gen_set_hflag(DisasContext *s, uint32_t mask)
2517 if ((s->flags & mask) == 0) {
2518 TCGv_i32 t = tcg_temp_new_i32();
2519 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2520 tcg_gen_ori_i32(t, t, mask);
2521 tcg_gen_st_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2522 tcg_temp_free_i32(t);
2527 static void gen_reset_hflag(DisasContext *s, uint32_t mask)
2529 if (s->flags & mask) {
2530 TCGv_i32 t = tcg_temp_new_i32();
2531 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2532 tcg_gen_andi_i32(t, t, ~mask);
2533 tcg_gen_st_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2534 tcg_temp_free_i32(t);
2539 /* Clear BND registers during legacy branches. */
2540 static void gen_bnd_jmp(DisasContext *s)
2542 /* Clear the registers only if BND prefix is missing, MPX is enabled,
2543 and if the BNDREGs are known to be in use (non-zero) already.
2544 The helper itself will check BNDPRESERVE at runtime. */
2545 if ((s->prefix & PREFIX_REPNZ) == 0
2546 && (s->flags & HF_MPX_EN_MASK) != 0
2547 && (s->flags & HF_MPX_IU_MASK) != 0) {
2548 gen_helper_bnd_jmp(cpu_env);
2552 /* Generate an end of block. Trace exception is also generated if needed.
2553 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set.
2554 If RECHECK_TF, emit a rechecking helper for #DB, ignoring the state of
2555 S->TF. This is used by the syscall/sysret insns. */
2557 do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, bool jr)
2559 gen_update_cc_op(s);
2561 /* If several instructions disable interrupts, only the first does it. */
2562 if (inhibit && !(s->flags & HF_INHIBIT_IRQ_MASK)) {
2563 gen_set_hflag(s, HF_INHIBIT_IRQ_MASK);
2565 gen_reset_hflag(s, HF_INHIBIT_IRQ_MASK);
2568 if (s->base.tb->flags & HF_RF_MASK) {
2569 gen_helper_reset_rf(cpu_env);
2571 if (s->base.singlestep_enabled) {
2572 gen_helper_debug(cpu_env);
2573 } else if (recheck_tf) {
2574 gen_helper_rechecking_single_step(cpu_env);
2575 tcg_gen_exit_tb(NULL, 0);
2577 gen_helper_single_step(cpu_env);
2579 tcg_gen_lookup_and_goto_ptr();
2581 tcg_gen_exit_tb(NULL, 0);
2583 s->base.is_jmp = DISAS_NORETURN;
2587 gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf)
2589 do_gen_eob_worker(s, inhibit, recheck_tf, false);
2593 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set. */
2594 static void gen_eob_inhibit_irq(DisasContext *s, bool inhibit)
2596 gen_eob_worker(s, inhibit, false);
2599 /* End of block, resetting the inhibit irq flag. */
2600 static void gen_eob(DisasContext *s)
2602 gen_eob_worker(s, false, false);
2605 /* Jump to register */
2606 static void gen_jr(DisasContext *s, TCGv dest)
2608 do_gen_eob_worker(s, false, false, true);
2611 /* generate a jump to eip. No segment change must happen before as a
2612 direct call to the next block may occur */
2613 static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
2615 gen_update_cc_op(s);
2616 set_cc_op(s, CC_OP_DYNAMIC);
2618 gen_goto_tb(s, tb_num, eip);
2625 static void gen_jmp(DisasContext *s, target_ulong eip)
2627 gen_jmp_tb(s, eip, 0);
2630 static inline void gen_ldq_env_A0(DisasContext *s, int offset)
2632 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
2633 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset);
2636 static inline void gen_stq_env_A0(DisasContext *s, int offset)
2638 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset);
2639 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
2642 static inline void gen_ldo_env_A0(DisasContext *s, int offset)
2644 int mem_index = s->mem_index;
2645 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, mem_index, MO_LEQ);
2646 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(0)));
2647 tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2648 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_tmp0, mem_index, MO_LEQ);
2649 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(1)));
2652 static inline void gen_sto_env_A0(DisasContext *s, int offset)
2654 int mem_index = s->mem_index;
2655 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(0)));
2656 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, mem_index, MO_LEQ);
2657 tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2658 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(1)));
2659 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_tmp0, mem_index, MO_LEQ);
2662 static inline void gen_op_movo(int d_offset, int s_offset)
2664 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + offsetof(ZMMReg, ZMM_Q(0)));
2665 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + offsetof(ZMMReg, ZMM_Q(0)));
2666 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + offsetof(ZMMReg, ZMM_Q(1)));
2667 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + offsetof(ZMMReg, ZMM_Q(1)));
2670 static inline void gen_op_movq(int d_offset, int s_offset)
2672 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
2673 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2676 static inline void gen_op_movl(int d_offset, int s_offset)
2678 tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env, s_offset);
2679 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, d_offset);
2682 static inline void gen_op_movq_env_0(int d_offset)
2684 tcg_gen_movi_i64(cpu_tmp1_i64, 0);
2685 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2688 typedef void (*SSEFunc_i_ep)(TCGv_i32 val, TCGv_ptr env, TCGv_ptr reg);
2689 typedef void (*SSEFunc_l_ep)(TCGv_i64 val, TCGv_ptr env, TCGv_ptr reg);
2690 typedef void (*SSEFunc_0_epi)(TCGv_ptr env, TCGv_ptr reg, TCGv_i32 val);
2691 typedef void (*SSEFunc_0_epl)(TCGv_ptr env, TCGv_ptr reg, TCGv_i64 val);
2692 typedef void (*SSEFunc_0_epp)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b);
2693 typedef void (*SSEFunc_0_eppi)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2695 typedef void (*SSEFunc_0_ppi)(TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv_i32 val);
2696 typedef void (*SSEFunc_0_eppt)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2699 #define SSE_SPECIAL ((void *)1)
2700 #define SSE_DUMMY ((void *)2)
2702 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2703 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2704 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2706 static const SSEFunc_0_epp sse_op_table1[256][4] = {
2707 /* 3DNow! extensions */
2708 [0x0e] = { SSE_DUMMY }, /* femms */
2709 [0x0f] = { SSE_DUMMY }, /* pf... */
2710 /* pure SSE operations */
2711 [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2712 [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2713 [0x12] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd, movsldup, movddup */
2714 [0x13] = { SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd */
2715 [0x14] = { gen_helper_punpckldq_xmm, gen_helper_punpcklqdq_xmm },
2716 [0x15] = { gen_helper_punpckhdq_xmm, gen_helper_punpckhqdq_xmm },
2717 [0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movhps, movhpd, movshdup */
2718 [0x17] = { SSE_SPECIAL, SSE_SPECIAL }, /* movhps, movhpd */
2720 [0x28] = { SSE_SPECIAL, SSE_SPECIAL }, /* movaps, movapd */
2721 [0x29] = { SSE_SPECIAL, SSE_SPECIAL }, /* movaps, movapd */
2722 [0x2a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2723 [0x2b] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movntps, movntpd, movntss, movntsd */
2724 [0x2c] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2725 [0x2d] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2726 [0x2e] = { gen_helper_ucomiss, gen_helper_ucomisd },
2727 [0x2f] = { gen_helper_comiss, gen_helper_comisd },
2728 [0x50] = { SSE_SPECIAL, SSE_SPECIAL }, /* movmskps, movmskpd */
2729 [0x51] = SSE_FOP(sqrt),
2730 [0x52] = { gen_helper_rsqrtps, NULL, gen_helper_rsqrtss, NULL },
2731 [0x53] = { gen_helper_rcpps, NULL, gen_helper_rcpss, NULL },
2732 [0x54] = { gen_helper_pand_xmm, gen_helper_pand_xmm }, /* andps, andpd */
2733 [0x55] = { gen_helper_pandn_xmm, gen_helper_pandn_xmm }, /* andnps, andnpd */
2734 [0x56] = { gen_helper_por_xmm, gen_helper_por_xmm }, /* orps, orpd */
2735 [0x57] = { gen_helper_pxor_xmm, gen_helper_pxor_xmm }, /* xorps, xorpd */
2736 [0x58] = SSE_FOP(add),
2737 [0x59] = SSE_FOP(mul),
2738 [0x5a] = { gen_helper_cvtps2pd, gen_helper_cvtpd2ps,
2739 gen_helper_cvtss2sd, gen_helper_cvtsd2ss },
2740 [0x5b] = { gen_helper_cvtdq2ps, gen_helper_cvtps2dq, gen_helper_cvttps2dq },
2741 [0x5c] = SSE_FOP(sub),
2742 [0x5d] = SSE_FOP(min),
2743 [0x5e] = SSE_FOP(div),
2744 [0x5f] = SSE_FOP(max),
2746 [0xc2] = SSE_FOP(cmpeq),
2747 [0xc6] = { (SSEFunc_0_epp)gen_helper_shufps,
2748 (SSEFunc_0_epp)gen_helper_shufpd }, /* XXX: casts */
2750 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */
2751 [0x38] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2752 [0x3a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2754 /* MMX ops and their SSE extensions */
2755 [0x60] = MMX_OP2(punpcklbw),
2756 [0x61] = MMX_OP2(punpcklwd),
2757 [0x62] = MMX_OP2(punpckldq),
2758 [0x63] = MMX_OP2(packsswb),
2759 [0x64] = MMX_OP2(pcmpgtb),
2760 [0x65] = MMX_OP2(pcmpgtw),
2761 [0x66] = MMX_OP2(pcmpgtl),
2762 [0x67] = MMX_OP2(packuswb),
2763 [0x68] = MMX_OP2(punpckhbw),
2764 [0x69] = MMX_OP2(punpckhwd),
2765 [0x6a] = MMX_OP2(punpckhdq),
2766 [0x6b] = MMX_OP2(packssdw),
2767 [0x6c] = { NULL, gen_helper_punpcklqdq_xmm },
2768 [0x6d] = { NULL, gen_helper_punpckhqdq_xmm },
2769 [0x6e] = { SSE_SPECIAL, SSE_SPECIAL }, /* movd mm, ea */
2770 [0x6f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, , movqdu */
2771 [0x70] = { (SSEFunc_0_epp)gen_helper_pshufw_mmx,
2772 (SSEFunc_0_epp)gen_helper_pshufd_xmm,
2773 (SSEFunc_0_epp)gen_helper_pshufhw_xmm,
2774 (SSEFunc_0_epp)gen_helper_pshuflw_xmm }, /* XXX: casts */
2775 [0x71] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftw */
2776 [0x72] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftd */
2777 [0x73] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftq */
2778 [0x74] = MMX_OP2(pcmpeqb),
2779 [0x75] = MMX_OP2(pcmpeqw),
2780 [0x76] = MMX_OP2(pcmpeql),
2781 [0x77] = { SSE_DUMMY }, /* emms */
2782 [0x78] = { NULL, SSE_SPECIAL, NULL, SSE_SPECIAL }, /* extrq_i, insertq_i */
2783 [0x79] = { NULL, gen_helper_extrq_r, NULL, gen_helper_insertq_r },
2784 [0x7c] = { NULL, gen_helper_haddpd, NULL, gen_helper_haddps },
2785 [0x7d] = { NULL, gen_helper_hsubpd, NULL, gen_helper_hsubps },
2786 [0x7e] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movd, movd, , movq */
2787 [0x7f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, movdqu */
2788 [0xc4] = { SSE_SPECIAL, SSE_SPECIAL }, /* pinsrw */
2789 [0xc5] = { SSE_SPECIAL, SSE_SPECIAL }, /* pextrw */
2790 [0xd0] = { NULL, gen_helper_addsubpd, NULL, gen_helper_addsubps },
2791 [0xd1] = MMX_OP2(psrlw),
2792 [0xd2] = MMX_OP2(psrld),
2793 [0xd3] = MMX_OP2(psrlq),
2794 [0xd4] = MMX_OP2(paddq),
2795 [0xd5] = MMX_OP2(pmullw),
2796 [0xd6] = { NULL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2797 [0xd7] = { SSE_SPECIAL, SSE_SPECIAL }, /* pmovmskb */
2798 [0xd8] = MMX_OP2(psubusb),
2799 [0xd9] = MMX_OP2(psubusw),
2800 [0xda] = MMX_OP2(pminub),
2801 [0xdb] = MMX_OP2(pand),
2802 [0xdc] = MMX_OP2(paddusb),
2803 [0xdd] = MMX_OP2(paddusw),
2804 [0xde] = MMX_OP2(pmaxub),
2805 [0xdf] = MMX_OP2(pandn),
2806 [0xe0] = MMX_OP2(pavgb),
2807 [0xe1] = MMX_OP2(psraw),
2808 [0xe2] = MMX_OP2(psrad),
2809 [0xe3] = MMX_OP2(pavgw),
2810 [0xe4] = MMX_OP2(pmulhuw),
2811 [0xe5] = MMX_OP2(pmulhw),
2812 [0xe6] = { NULL, gen_helper_cvttpd2dq, gen_helper_cvtdq2pd, gen_helper_cvtpd2dq },
2813 [0xe7] = { SSE_SPECIAL , SSE_SPECIAL }, /* movntq, movntq */
2814 [0xe8] = MMX_OP2(psubsb),
2815 [0xe9] = MMX_OP2(psubsw),
2816 [0xea] = MMX_OP2(pminsw),
2817 [0xeb] = MMX_OP2(por),
2818 [0xec] = MMX_OP2(paddsb),
2819 [0xed] = MMX_OP2(paddsw),
2820 [0xee] = MMX_OP2(pmaxsw),
2821 [0xef] = MMX_OP2(pxor),
2822 [0xf0] = { NULL, NULL, NULL, SSE_SPECIAL }, /* lddqu */
2823 [0xf1] = MMX_OP2(psllw),
2824 [0xf2] = MMX_OP2(pslld),
2825 [0xf3] = MMX_OP2(psllq),
2826 [0xf4] = MMX_OP2(pmuludq),
2827 [0xf5] = MMX_OP2(pmaddwd),
2828 [0xf6] = MMX_OP2(psadbw),
2829 [0xf7] = { (SSEFunc_0_epp)gen_helper_maskmov_mmx,
2830 (SSEFunc_0_epp)gen_helper_maskmov_xmm }, /* XXX: casts */
2831 [0xf8] = MMX_OP2(psubb),
2832 [0xf9] = MMX_OP2(psubw),
2833 [0xfa] = MMX_OP2(psubl),
2834 [0xfb] = MMX_OP2(psubq),
2835 [0xfc] = MMX_OP2(paddb),
2836 [0xfd] = MMX_OP2(paddw),
2837 [0xfe] = MMX_OP2(paddl),
2840 static const SSEFunc_0_epp sse_op_table2[3 * 8][2] = {
2841 [0 + 2] = MMX_OP2(psrlw),
2842 [0 + 4] = MMX_OP2(psraw),
2843 [0 + 6] = MMX_OP2(psllw),
2844 [8 + 2] = MMX_OP2(psrld),
2845 [8 + 4] = MMX_OP2(psrad),
2846 [8 + 6] = MMX_OP2(pslld),
2847 [16 + 2] = MMX_OP2(psrlq),
2848 [16 + 3] = { NULL, gen_helper_psrldq_xmm },
2849 [16 + 6] = MMX_OP2(psllq),
2850 [16 + 7] = { NULL, gen_helper_pslldq_xmm },
2853 static const SSEFunc_0_epi sse_op_table3ai[] = {
2854 gen_helper_cvtsi2ss,
2858 #ifdef TARGET_X86_64
2859 static const SSEFunc_0_epl sse_op_table3aq[] = {
2860 gen_helper_cvtsq2ss,
2865 static const SSEFunc_i_ep sse_op_table3bi[] = {
2866 gen_helper_cvttss2si,
2867 gen_helper_cvtss2si,
2868 gen_helper_cvttsd2si,
2872 #ifdef TARGET_X86_64
2873 static const SSEFunc_l_ep sse_op_table3bq[] = {
2874 gen_helper_cvttss2sq,
2875 gen_helper_cvtss2sq,
2876 gen_helper_cvttsd2sq,
2881 static const SSEFunc_0_epp sse_op_table4[8][4] = {
2892 static const SSEFunc_0_epp sse_op_table5[256] = {
2893 [0x0c] = gen_helper_pi2fw,
2894 [0x0d] = gen_helper_pi2fd,
2895 [0x1c] = gen_helper_pf2iw,
2896 [0x1d] = gen_helper_pf2id,
2897 [0x8a] = gen_helper_pfnacc,
2898 [0x8e] = gen_helper_pfpnacc,
2899 [0x90] = gen_helper_pfcmpge,
2900 [0x94] = gen_helper_pfmin,
2901 [0x96] = gen_helper_pfrcp,
2902 [0x97] = gen_helper_pfrsqrt,
2903 [0x9a] = gen_helper_pfsub,
2904 [0x9e] = gen_helper_pfadd,
2905 [0xa0] = gen_helper_pfcmpgt,
2906 [0xa4] = gen_helper_pfmax,
2907 [0xa6] = gen_helper_movq, /* pfrcpit1; no need to actually increase precision */
2908 [0xa7] = gen_helper_movq, /* pfrsqit1 */
2909 [0xaa] = gen_helper_pfsubr,
2910 [0xae] = gen_helper_pfacc,
2911 [0xb0] = gen_helper_pfcmpeq,
2912 [0xb4] = gen_helper_pfmul,
2913 [0xb6] = gen_helper_movq, /* pfrcpit2 */
2914 [0xb7] = gen_helper_pmulhrw_mmx,
2915 [0xbb] = gen_helper_pswapd,
2916 [0xbf] = gen_helper_pavgb_mmx /* pavgusb */
2919 struct SSEOpHelper_epp {
2920 SSEFunc_0_epp op[2];
2924 struct SSEOpHelper_eppi {
2925 SSEFunc_0_eppi op[2];
2929 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
2930 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
2931 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
2932 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
2933 #define PCLMULQDQ_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, \
2934 CPUID_EXT_PCLMULQDQ }
2935 #define AESNI_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_AES }
2937 static const struct SSEOpHelper_epp sse_op_table6[256] = {
2938 [0x00] = SSSE3_OP(pshufb),
2939 [0x01] = SSSE3_OP(phaddw),
2940 [0x02] = SSSE3_OP(phaddd),
2941 [0x03] = SSSE3_OP(phaddsw),
2942 [0x04] = SSSE3_OP(pmaddubsw),
2943 [0x05] = SSSE3_OP(phsubw),
2944 [0x06] = SSSE3_OP(phsubd),
2945 [0x07] = SSSE3_OP(phsubsw),
2946 [0x08] = SSSE3_OP(psignb),
2947 [0x09] = SSSE3_OP(psignw),
2948 [0x0a] = SSSE3_OP(psignd),
2949 [0x0b] = SSSE3_OP(pmulhrsw),
2950 [0x10] = SSE41_OP(pblendvb),
2951 [0x14] = SSE41_OP(blendvps),
2952 [0x15] = SSE41_OP(blendvpd),
2953 [0x17] = SSE41_OP(ptest),
2954 [0x1c] = SSSE3_OP(pabsb),
2955 [0x1d] = SSSE3_OP(pabsw),
2956 [0x1e] = SSSE3_OP(pabsd),
2957 [0x20] = SSE41_OP(pmovsxbw),
2958 [0x21] = SSE41_OP(pmovsxbd),
2959 [0x22] = SSE41_OP(pmovsxbq),
2960 [0x23] = SSE41_OP(pmovsxwd),
2961 [0x24] = SSE41_OP(pmovsxwq),
2962 [0x25] = SSE41_OP(pmovsxdq),
2963 [0x28] = SSE41_OP(pmuldq),
2964 [0x29] = SSE41_OP(pcmpeqq),
2965 [0x2a] = SSE41_SPECIAL, /* movntqda */
2966 [0x2b] = SSE41_OP(packusdw),
2967 [0x30] = SSE41_OP(pmovzxbw),
2968 [0x31] = SSE41_OP(pmovzxbd),
2969 [0x32] = SSE41_OP(pmovzxbq),
2970 [0x33] = SSE41_OP(pmovzxwd),
2971 [0x34] = SSE41_OP(pmovzxwq),
2972 [0x35] = SSE41_OP(pmovzxdq),
2973 [0x37] = SSE42_OP(pcmpgtq),
2974 [0x38] = SSE41_OP(pminsb),
2975 [0x39] = SSE41_OP(pminsd),
2976 [0x3a] = SSE41_OP(pminuw),
2977 [0x3b] = SSE41_OP(pminud),
2978 [0x3c] = SSE41_OP(pmaxsb),
2979 [0x3d] = SSE41_OP(pmaxsd),
2980 [0x3e] = SSE41_OP(pmaxuw),
2981 [0x3f] = SSE41_OP(pmaxud),
2982 [0x40] = SSE41_OP(pmulld),
2983 [0x41] = SSE41_OP(phminposuw),
2984 [0xdb] = AESNI_OP(aesimc),
2985 [0xdc] = AESNI_OP(aesenc),
2986 [0xdd] = AESNI_OP(aesenclast),
2987 [0xde] = AESNI_OP(aesdec),
2988 [0xdf] = AESNI_OP(aesdeclast),
2991 static const struct SSEOpHelper_eppi sse_op_table7[256] = {
2992 [0x08] = SSE41_OP(roundps),
2993 [0x09] = SSE41_OP(roundpd),
2994 [0x0a] = SSE41_OP(roundss),
2995 [0x0b] = SSE41_OP(roundsd),
2996 [0x0c] = SSE41_OP(blendps),
2997 [0x0d] = SSE41_OP(blendpd),
2998 [0x0e] = SSE41_OP(pblendw),
2999 [0x0f] = SSSE3_OP(palignr),
3000 [0x14] = SSE41_SPECIAL, /* pextrb */
3001 [0x15] = SSE41_SPECIAL, /* pextrw */
3002 [0x16] = SSE41_SPECIAL, /* pextrd/pextrq */
3003 [0x17] = SSE41_SPECIAL, /* extractps */
3004 [0x20] = SSE41_SPECIAL, /* pinsrb */
3005 [0x21] = SSE41_SPECIAL, /* insertps */
3006 [0x22] = SSE41_SPECIAL, /* pinsrd/pinsrq */
3007 [0x40] = SSE41_OP(dpps),
3008 [0x41] = SSE41_OP(dppd),
3009 [0x42] = SSE41_OP(mpsadbw),
3010 [0x44] = PCLMULQDQ_OP(pclmulqdq),
3011 [0x60] = SSE42_OP(pcmpestrm),
3012 [0x61] = SSE42_OP(pcmpestri),
3013 [0x62] = SSE42_OP(pcmpistrm),
3014 [0x63] = SSE42_OP(pcmpistri),
3015 [0xdf] = AESNI_OP(aeskeygenassist),
3018 static void gen_sse(CPUX86State *env, DisasContext *s, int b,
3019 target_ulong pc_start, int rex_r)
3021 int b1, op1_offset, op2_offset, is_xmm, val;
3022 int modrm, mod, rm, reg;
3023 SSEFunc_0_epp sse_fn_epp;
3024 SSEFunc_0_eppi sse_fn_eppi;
3025 SSEFunc_0_ppi sse_fn_ppi;
3026 SSEFunc_0_eppt sse_fn_eppt;
3030 if (s->prefix & PREFIX_DATA)
3032 else if (s->prefix & PREFIX_REPZ)
3034 else if (s->prefix & PREFIX_REPNZ)
3038 sse_fn_epp = sse_op_table1[b][b1];
3042 if ((b <= 0x5f && b >= 0x10) || b == 0xc6 || b == 0xc2) {
3052 /* simple MMX/SSE operation */
3053 if (s->flags & HF_TS_MASK) {
3054 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
3057 if (s->flags & HF_EM_MASK) {
3059 gen_illegal_opcode(s);
3063 && !(s->flags & HF_OSFXSR_MASK)
3064 && ((b != 0x38 && b != 0x3a) || (s->prefix & PREFIX_DATA))) {
3068 if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) {
3069 /* If we were fully decoding this we might use illegal_op. */
3073 gen_helper_emms(cpu_env);
3078 gen_helper_emms(cpu_env);
3081 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3082 the static cpu state) */
3084 gen_helper_enter_mmx(cpu_env);
3087 modrm = x86_ldub_code(env, s);
3088 reg = ((modrm >> 3) & 7);
3091 mod = (modrm >> 6) & 3;
3092 if (sse_fn_epp == SSE_SPECIAL) {
3095 case 0x0e7: /* movntq */
3099 gen_lea_modrm(env, s, modrm);
3100 gen_stq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
3102 case 0x1e7: /* movntdq */
3103 case 0x02b: /* movntps */
3104 case 0x12b: /* movntps */
3107 gen_lea_modrm(env, s, modrm);
3108 gen_sto_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3110 case 0x3f0: /* lddqu */
3113 gen_lea_modrm(env, s, modrm);
3114 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3116 case 0x22b: /* movntss */
3117 case 0x32b: /* movntsd */
3120 gen_lea_modrm(env, s, modrm);
3122 gen_stq_env_A0(s, offsetof(CPUX86State,
3123 xmm_regs[reg].ZMM_Q(0)));
3125 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
3126 xmm_regs[reg].ZMM_L(0)));
3127 gen_op_st_v(s, MO_32, cpu_T0, cpu_A0);
3130 case 0x6e: /* movd mm, ea */
3131 #ifdef TARGET_X86_64
3132 if (s->dflag == MO_64) {
3133 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 0);
3134 tcg_gen_st_tl(cpu_T0, cpu_env, offsetof(CPUX86State,fpregs[reg].mmx));
3138 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 0);
3139 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3140 offsetof(CPUX86State,fpregs[reg].mmx));
3141 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
3142 gen_helper_movl_mm_T0_mmx(cpu_ptr0, cpu_tmp2_i32);
3145 case 0x16e: /* movd xmm, ea */
3146 #ifdef TARGET_X86_64
3147 if (s->dflag == MO_64) {
3148 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 0);
3149 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3150 offsetof(CPUX86State,xmm_regs[reg]));
3151 gen_helper_movq_mm_T0_xmm(cpu_ptr0, cpu_T0);
3155 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 0);
3156 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3157 offsetof(CPUX86State,xmm_regs[reg]));
3158 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
3159 gen_helper_movl_mm_T0_xmm(cpu_ptr0, cpu_tmp2_i32);
3162 case 0x6f: /* movq mm, ea */
3164 gen_lea_modrm(env, s, modrm);
3165 gen_ldq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
3168 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
3169 offsetof(CPUX86State,fpregs[rm].mmx));
3170 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
3171 offsetof(CPUX86State,fpregs[reg].mmx));
3174 case 0x010: /* movups */
3175 case 0x110: /* movupd */
3176 case 0x028: /* movaps */
3177 case 0x128: /* movapd */
3178 case 0x16f: /* movdqa xmm, ea */
3179 case 0x26f: /* movdqu xmm, ea */
3181 gen_lea_modrm(env, s, modrm);
3182 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3184 rm = (modrm & 7) | REX_B(s);
3185 gen_op_movo(offsetof(CPUX86State,xmm_regs[reg]),
3186 offsetof(CPUX86State,xmm_regs[rm]));
3189 case 0x210: /* movss xmm, ea */
3191 gen_lea_modrm(env, s, modrm);
3192 gen_op_ld_v(s, MO_32, cpu_T0, cpu_A0);
3193 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3194 tcg_gen_movi_tl(cpu_T0, 0);
3195 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)));
3196 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)));
3197 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)));
3199 rm = (modrm & 7) | REX_B(s);
3200 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)),
3201 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0)));
3204 case 0x310: /* movsd xmm, ea */
3206 gen_lea_modrm(env, s, modrm);
3207 gen_ldq_env_A0(s, offsetof(CPUX86State,
3208 xmm_regs[reg].ZMM_Q(0)));
3209 tcg_gen_movi_tl(cpu_T0, 0);
3210 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)));
3211 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)));
3213 rm = (modrm & 7) | REX_B(s);
3214 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3215 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3218 case 0x012: /* movlps */
3219 case 0x112: /* movlpd */
3221 gen_lea_modrm(env, s, modrm);
3222 gen_ldq_env_A0(s, offsetof(CPUX86State,
3223 xmm_regs[reg].ZMM_Q(0)));
3226 rm = (modrm & 7) | REX_B(s);
3227 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3228 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(1)));
3231 case 0x212: /* movsldup */
3233 gen_lea_modrm(env, s, modrm);
3234 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3236 rm = (modrm & 7) | REX_B(s);
3237 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)),
3238 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0)));
3239 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)),
3240 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(2)));
3242 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)),
3243 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3244 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)),
3245 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)));
3247 case 0x312: /* movddup */
3249 gen_lea_modrm(env, s, modrm);
3250 gen_ldq_env_A0(s, offsetof(CPUX86State,
3251 xmm_regs[reg].ZMM_Q(0)));
3253 rm = (modrm & 7) | REX_B(s);
3254 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3255 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3257 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)),
3258 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3260 case 0x016: /* movhps */
3261 case 0x116: /* movhpd */
3263 gen_lea_modrm(env, s, modrm);
3264 gen_ldq_env_A0(s, offsetof(CPUX86State,
3265 xmm_regs[reg].ZMM_Q(1)));
3268 rm = (modrm & 7) | REX_B(s);
3269 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)),
3270 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3273 case 0x216: /* movshdup */
3275 gen_lea_modrm(env, s, modrm);
3276 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3278 rm = (modrm & 7) | REX_B(s);
3279 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)),
3280 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(1)));
3281 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)),
3282 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(3)));
3284 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)),
3285 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)));
3286 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)),
3287 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)));
3292 int bit_index, field_length;
3294 if (b1 == 1 && reg != 0)
3296 field_length = x86_ldub_code(env, s) & 0x3F;
3297 bit_index = x86_ldub_code(env, s) & 0x3F;
3298 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3299 offsetof(CPUX86State,xmm_regs[reg]));
3301 gen_helper_extrq_i(cpu_env, cpu_ptr0,
3302 tcg_const_i32(bit_index),
3303 tcg_const_i32(field_length));
3305 gen_helper_insertq_i(cpu_env, cpu_ptr0,
3306 tcg_const_i32(bit_index),
3307 tcg_const_i32(field_length));
3310 case 0x7e: /* movd ea, mm */
3311 #ifdef TARGET_X86_64
3312 if (s->dflag == MO_64) {
3313 tcg_gen_ld_i64(cpu_T0, cpu_env,
3314 offsetof(CPUX86State,fpregs[reg].mmx));
3315 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 1);
3319 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
3320 offsetof(CPUX86State,fpregs[reg].mmx.MMX_L(0)));
3321 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 1);
3324 case 0x17e: /* movd ea, xmm */
3325 #ifdef TARGET_X86_64
3326 if (s->dflag == MO_64) {
3327 tcg_gen_ld_i64(cpu_T0, cpu_env,
3328 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3329 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 1);
3333 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
3334 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3335 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 1);
3338 case 0x27e: /* movq xmm, ea */
3340 gen_lea_modrm(env, s, modrm);
3341 gen_ldq_env_A0(s, offsetof(CPUX86State,
3342 xmm_regs[reg].ZMM_Q(0)));
3344 rm = (modrm & 7) | REX_B(s);
3345 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3346 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3348 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)));
3350 case 0x7f: /* movq ea, mm */
3352 gen_lea_modrm(env, s, modrm);
3353 gen_stq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
3356 gen_op_movq(offsetof(CPUX86State,fpregs[rm].mmx),
3357 offsetof(CPUX86State,fpregs[reg].mmx));
3360 case 0x011: /* movups */
3361 case 0x111: /* movupd */
3362 case 0x029: /* movaps */
3363 case 0x129: /* movapd */
3364 case 0x17f: /* movdqa ea, xmm */
3365 case 0x27f: /* movdqu ea, xmm */
3367 gen_lea_modrm(env, s, modrm);
3368 gen_sto_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3370 rm = (modrm & 7) | REX_B(s);
3371 gen_op_movo(offsetof(CPUX86State,xmm_regs[rm]),
3372 offsetof(CPUX86State,xmm_regs[reg]));
3375 case 0x211: /* movss ea, xmm */
3377 gen_lea_modrm(env, s, modrm);
3378 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3379 gen_op_st_v(s, MO_32, cpu_T0, cpu_A0);
3381 rm = (modrm & 7) | REX_B(s);
3382 gen_op_movl(offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0)),
3383 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3386 case 0x311: /* movsd ea, xmm */
3388 gen_lea_modrm(env, s, modrm);
3389 gen_stq_env_A0(s, offsetof(CPUX86State,
3390 xmm_regs[reg].ZMM_Q(0)));
3392 rm = (modrm & 7) | REX_B(s);
3393 gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)),
3394 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3397 case 0x013: /* movlps */
3398 case 0x113: /* movlpd */
3400 gen_lea_modrm(env, s, modrm);
3401 gen_stq_env_A0(s, offsetof(CPUX86State,
3402 xmm_regs[reg].ZMM_Q(0)));
3407 case 0x017: /* movhps */
3408 case 0x117: /* movhpd */
3410 gen_lea_modrm(env, s, modrm);
3411 gen_stq_env_A0(s, offsetof(CPUX86State,
3412 xmm_regs[reg].ZMM_Q(1)));
3417 case 0x71: /* shift mm, im */
3420 case 0x171: /* shift xmm, im */
3426 val = x86_ldub_code(env, s);
3428 tcg_gen_movi_tl(cpu_T0, val);
3429 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(0)));
3430 tcg_gen_movi_tl(cpu_T0, 0);
3431 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(1)));
3432 op1_offset = offsetof(CPUX86State,xmm_t0);
3434 tcg_gen_movi_tl(cpu_T0, val);
3435 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(0)));
3436 tcg_gen_movi_tl(cpu_T0, 0);
3437 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(1)));
3438 op1_offset = offsetof(CPUX86State,mmx_t0);
3440 sse_fn_epp = sse_op_table2[((b - 1) & 3) * 8 +
3441 (((modrm >> 3)) & 7)][b1];
3446 rm = (modrm & 7) | REX_B(s);
3447 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3450 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3452 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
3453 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op1_offset);
3454 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
3456 case 0x050: /* movmskps */
3457 rm = (modrm & 7) | REX_B(s);
3458 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3459 offsetof(CPUX86State,xmm_regs[rm]));
3460 gen_helper_movmskps(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3461 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
3463 case 0x150: /* movmskpd */
3464 rm = (modrm & 7) | REX_B(s);
3465 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3466 offsetof(CPUX86State,xmm_regs[rm]));
3467 gen_helper_movmskpd(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3468 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
3470 case 0x02a: /* cvtpi2ps */
3471 case 0x12a: /* cvtpi2pd */
3472 gen_helper_enter_mmx(cpu_env);
3474 gen_lea_modrm(env, s, modrm);
3475 op2_offset = offsetof(CPUX86State,mmx_t0);
3476 gen_ldq_env_A0(s, op2_offset);
3479 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3481 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3482 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3483 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3486 gen_helper_cvtpi2ps(cpu_env, cpu_ptr0, cpu_ptr1);
3490 gen_helper_cvtpi2pd(cpu_env, cpu_ptr0, cpu_ptr1);
3494 case 0x22a: /* cvtsi2ss */
3495 case 0x32a: /* cvtsi2sd */
3496 ot = mo_64_32(s->dflag);
3497 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3498 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3499 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3501 SSEFunc_0_epi sse_fn_epi = sse_op_table3ai[(b >> 8) & 1];
3502 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
3503 sse_fn_epi(cpu_env, cpu_ptr0, cpu_tmp2_i32);
3505 #ifdef TARGET_X86_64
3506 SSEFunc_0_epl sse_fn_epl = sse_op_table3aq[(b >> 8) & 1];
3507 sse_fn_epl(cpu_env, cpu_ptr0, cpu_T0);
3513 case 0x02c: /* cvttps2pi */
3514 case 0x12c: /* cvttpd2pi */
3515 case 0x02d: /* cvtps2pi */
3516 case 0x12d: /* cvtpd2pi */
3517 gen_helper_enter_mmx(cpu_env);
3519 gen_lea_modrm(env, s, modrm);
3520 op2_offset = offsetof(CPUX86State,xmm_t0);
3521 gen_ldo_env_A0(s, op2_offset);
3523 rm = (modrm & 7) | REX_B(s);
3524 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3526 op1_offset = offsetof(CPUX86State,fpregs[reg & 7].mmx);
3527 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3528 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3531 gen_helper_cvttps2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3534 gen_helper_cvttpd2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3537 gen_helper_cvtps2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3540 gen_helper_cvtpd2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3544 case 0x22c: /* cvttss2si */
3545 case 0x32c: /* cvttsd2si */
3546 case 0x22d: /* cvtss2si */
3547 case 0x32d: /* cvtsd2si */
3548 ot = mo_64_32(s->dflag);
3550 gen_lea_modrm(env, s, modrm);
3552 gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_Q(0)));
3554 gen_op_ld_v(s, MO_32, cpu_T0, cpu_A0);
3555 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(0)));
3557 op2_offset = offsetof(CPUX86State,xmm_t0);
3559 rm = (modrm & 7) | REX_B(s);
3560 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3562 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
3564 SSEFunc_i_ep sse_fn_i_ep =
3565 sse_op_table3bi[((b >> 7) & 2) | (b & 1)];
3566 sse_fn_i_ep(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3567 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
3569 #ifdef TARGET_X86_64
3570 SSEFunc_l_ep sse_fn_l_ep =
3571 sse_op_table3bq[((b >> 7) & 2) | (b & 1)];
3572 sse_fn_l_ep(cpu_T0, cpu_env, cpu_ptr0);
3577 gen_op_mov_reg_v(ot, reg, cpu_T0);
3579 case 0xc4: /* pinsrw */
3582 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
3583 val = x86_ldub_code(env, s);
3586 tcg_gen_st16_tl(cpu_T0, cpu_env,
3587 offsetof(CPUX86State,xmm_regs[reg].ZMM_W(val)));
3590 tcg_gen_st16_tl(cpu_T0, cpu_env,
3591 offsetof(CPUX86State,fpregs[reg].mmx.MMX_W(val)));
3594 case 0xc5: /* pextrw */
3598 ot = mo_64_32(s->dflag);
3599 val = x86_ldub_code(env, s);
3602 rm = (modrm & 7) | REX_B(s);
3603 tcg_gen_ld16u_tl(cpu_T0, cpu_env,
3604 offsetof(CPUX86State,xmm_regs[rm].ZMM_W(val)));
3608 tcg_gen_ld16u_tl(cpu_T0, cpu_env,
3609 offsetof(CPUX86State,fpregs[rm].mmx.MMX_W(val)));
3611 reg = ((modrm >> 3) & 7) | rex_r;
3612 gen_op_mov_reg_v(ot, reg, cpu_T0);
3614 case 0x1d6: /* movq ea, xmm */
3616 gen_lea_modrm(env, s, modrm);
3617 gen_stq_env_A0(s, offsetof(CPUX86State,
3618 xmm_regs[reg].ZMM_Q(0)));
3620 rm = (modrm & 7) | REX_B(s);
3621 gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)),
3622 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3623 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(1)));
3626 case 0x2d6: /* movq2dq */
3627 gen_helper_enter_mmx(cpu_env);
3629 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3630 offsetof(CPUX86State,fpregs[rm].mmx));
3631 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)));
3633 case 0x3d6: /* movdq2q */
3634 gen_helper_enter_mmx(cpu_env);
3635 rm = (modrm & 7) | REX_B(s);
3636 gen_op_movq(offsetof(CPUX86State,fpregs[reg & 7].mmx),
3637 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3639 case 0xd7: /* pmovmskb */
3644 rm = (modrm & 7) | REX_B(s);
3645 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[rm]));
3646 gen_helper_pmovmskb_xmm(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3649 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,fpregs[rm].mmx));
3650 gen_helper_pmovmskb_mmx(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3652 reg = ((modrm >> 3) & 7) | rex_r;
3653 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
3659 if ((b & 0xf0) == 0xf0) {
3662 modrm = x86_ldub_code(env, s);
3664 reg = ((modrm >> 3) & 7) | rex_r;
3665 mod = (modrm >> 6) & 3;
3670 sse_fn_epp = sse_op_table6[b].op[b1];
3674 if (!(s->cpuid_ext_features & sse_op_table6[b].ext_mask))
3678 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3680 op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
3682 op2_offset = offsetof(CPUX86State,xmm_t0);
3683 gen_lea_modrm(env, s, modrm);
3685 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3686 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3687 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3688 gen_ldq_env_A0(s, op2_offset +
3689 offsetof(ZMMReg, ZMM_Q(0)));
3691 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3692 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3693 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
3694 s->mem_index, MO_LEUL);
3695 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, op2_offset +
3696 offsetof(ZMMReg, ZMM_L(0)));
3698 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3699 tcg_gen_qemu_ld_tl(cpu_tmp0, cpu_A0,
3700 s->mem_index, MO_LEUW);
3701 tcg_gen_st16_tl(cpu_tmp0, cpu_env, op2_offset +
3702 offsetof(ZMMReg, ZMM_W(0)));
3704 case 0x2a: /* movntqda */
3705 gen_ldo_env_A0(s, op1_offset);
3708 gen_ldo_env_A0(s, op2_offset);
3712 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
3714 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3716 op2_offset = offsetof(CPUX86State,mmx_t0);
3717 gen_lea_modrm(env, s, modrm);
3718 gen_ldq_env_A0(s, op2_offset);
3721 if (sse_fn_epp == SSE_SPECIAL) {
3725 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3726 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3727 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
3730 set_cc_op(s, CC_OP_EFLAGS);
3737 /* Various integer extensions at 0f 38 f[0-f]. */
3738 b = modrm | (b1 << 8);
3739 modrm = x86_ldub_code(env, s);
3740 reg = ((modrm >> 3) & 7) | rex_r;
3743 case 0x3f0: /* crc32 Gd,Eb */
3744 case 0x3f1: /* crc32 Gd,Ey */
3746 if (!(s->cpuid_ext_features & CPUID_EXT_SSE42)) {
3749 if ((b & 0xff) == 0xf0) {
3751 } else if (s->dflag != MO_64) {
3752 ot = (s->prefix & PREFIX_DATA ? MO_16 : MO_32);
3757 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[reg]);
3758 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3759 gen_helper_crc32(cpu_T0, cpu_tmp2_i32,
3760 cpu_T0, tcg_const_i32(8 << ot));
3762 ot = mo_64_32(s->dflag);
3763 gen_op_mov_reg_v(ot, reg, cpu_T0);
3766 case 0x1f0: /* crc32 or movbe */
3768 /* For these insns, the f3 prefix is supposed to have priority
3769 over the 66 prefix, but that's not what we implement above
3771 if (s->prefix & PREFIX_REPNZ) {
3775 case 0x0f0: /* movbe Gy,My */
3776 case 0x0f1: /* movbe My,Gy */
3777 if (!(s->cpuid_ext_features & CPUID_EXT_MOVBE)) {
3780 if (s->dflag != MO_64) {
3781 ot = (s->prefix & PREFIX_DATA ? MO_16 : MO_32);
3786 gen_lea_modrm(env, s, modrm);
3788 tcg_gen_qemu_ld_tl(cpu_T0, cpu_A0,
3789 s->mem_index, ot | MO_BE);
3790 gen_op_mov_reg_v(ot, reg, cpu_T0);
3792 tcg_gen_qemu_st_tl(cpu_regs[reg], cpu_A0,
3793 s->mem_index, ot | MO_BE);
3797 case 0x0f2: /* andn Gy, By, Ey */
3798 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
3799 || !(s->prefix & PREFIX_VEX)
3803 ot = mo_64_32(s->dflag);
3804 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3805 tcg_gen_andc_tl(cpu_T0, cpu_T0, cpu_regs[s->vex_v]);
3806 gen_op_mov_reg_v(ot, reg, cpu_T0);
3807 gen_op_update1_cc();
3808 set_cc_op(s, CC_OP_LOGICB + ot);
3811 case 0x0f7: /* bextr Gy, Ey, By */
3812 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
3813 || !(s->prefix & PREFIX_VEX)
3817 ot = mo_64_32(s->dflag);
3821 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3822 /* Extract START, and shift the operand.
3823 Shifts larger than operand size get zeros. */
3824 tcg_gen_ext8u_tl(cpu_A0, cpu_regs[s->vex_v]);
3825 tcg_gen_shr_tl(cpu_T0, cpu_T0, cpu_A0);
3827 bound = tcg_const_tl(ot == MO_64 ? 63 : 31);
3828 zero = tcg_const_tl(0);
3829 tcg_gen_movcond_tl(TCG_COND_LEU, cpu_T0, cpu_A0, bound,
3831 tcg_temp_free(zero);
3833 /* Extract the LEN into a mask. Lengths larger than
3834 operand size get all ones. */
3835 tcg_gen_extract_tl(cpu_A0, cpu_regs[s->vex_v], 8, 8);
3836 tcg_gen_movcond_tl(TCG_COND_LEU, cpu_A0, cpu_A0, bound,
3838 tcg_temp_free(bound);
3839 tcg_gen_movi_tl(cpu_T1, 1);
3840 tcg_gen_shl_tl(cpu_T1, cpu_T1, cpu_A0);
3841 tcg_gen_subi_tl(cpu_T1, cpu_T1, 1);
3842 tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1);
3844 gen_op_mov_reg_v(ot, reg, cpu_T0);
3845 gen_op_update1_cc();
3846 set_cc_op(s, CC_OP_LOGICB + ot);
3850 case 0x0f5: /* bzhi Gy, Ey, By */
3851 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3852 || !(s->prefix & PREFIX_VEX)
3856 ot = mo_64_32(s->dflag);
3857 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3858 tcg_gen_ext8u_tl(cpu_T1, cpu_regs[s->vex_v]);
3860 TCGv bound = tcg_const_tl(ot == MO_64 ? 63 : 31);
3861 /* Note that since we're using BMILG (in order to get O
3862 cleared) we need to store the inverse into C. */
3863 tcg_gen_setcond_tl(TCG_COND_LT, cpu_cc_src,
3865 tcg_gen_movcond_tl(TCG_COND_GT, cpu_T1, cpu_T1,
3866 bound, bound, cpu_T1);
3867 tcg_temp_free(bound);
3869 tcg_gen_movi_tl(cpu_A0, -1);
3870 tcg_gen_shl_tl(cpu_A0, cpu_A0, cpu_T1);
3871 tcg_gen_andc_tl(cpu_T0, cpu_T0, cpu_A0);
3872 gen_op_mov_reg_v(ot, reg, cpu_T0);
3873 gen_op_update1_cc();
3874 set_cc_op(s, CC_OP_BMILGB + ot);
3877 case 0x3f6: /* mulx By, Gy, rdx, Ey */
3878 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3879 || !(s->prefix & PREFIX_VEX)
3883 ot = mo_64_32(s->dflag);
3884 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3887 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
3888 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_regs[R_EDX]);
3889 tcg_gen_mulu2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
3890 cpu_tmp2_i32, cpu_tmp3_i32);
3891 tcg_gen_extu_i32_tl(cpu_regs[s->vex_v], cpu_tmp2_i32);
3892 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp3_i32);
3894 #ifdef TARGET_X86_64
3896 tcg_gen_mulu2_i64(cpu_T0, cpu_T1,
3897 cpu_T0, cpu_regs[R_EDX]);
3898 tcg_gen_mov_i64(cpu_regs[s->vex_v], cpu_T0);
3899 tcg_gen_mov_i64(cpu_regs[reg], cpu_T1);
3905 case 0x3f5: /* pdep Gy, By, Ey */
3906 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3907 || !(s->prefix & PREFIX_VEX)
3911 ot = mo_64_32(s->dflag);
3912 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3913 /* Note that by zero-extending the mask operand, we
3914 automatically handle zero-extending the result. */
3916 tcg_gen_mov_tl(cpu_T1, cpu_regs[s->vex_v]);
3918 tcg_gen_ext32u_tl(cpu_T1, cpu_regs[s->vex_v]);
3920 gen_helper_pdep(cpu_regs[reg], cpu_T0, cpu_T1);
3923 case 0x2f5: /* pext Gy, By, Ey */
3924 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3925 || !(s->prefix & PREFIX_VEX)
3929 ot = mo_64_32(s->dflag);
3930 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3931 /* Note that by zero-extending the mask operand, we
3932 automatically handle zero-extending the result. */
3934 tcg_gen_mov_tl(cpu_T1, cpu_regs[s->vex_v]);
3936 tcg_gen_ext32u_tl(cpu_T1, cpu_regs[s->vex_v]);
3938 gen_helper_pext(cpu_regs[reg], cpu_T0, cpu_T1);
3941 case 0x1f6: /* adcx Gy, Ey */
3942 case 0x2f6: /* adox Gy, Ey */
3943 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_ADX)) {
3946 TCGv carry_in, carry_out, zero;
3949 ot = mo_64_32(s->dflag);
3950 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3952 /* Re-use the carry-out from a previous round. */
3954 carry_out = (b == 0x1f6 ? cpu_cc_dst : cpu_cc_src2);
3958 carry_in = cpu_cc_dst;
3959 end_op = CC_OP_ADCX;
3961 end_op = CC_OP_ADCOX;
3966 end_op = CC_OP_ADCOX;
3968 carry_in = cpu_cc_src2;
3969 end_op = CC_OP_ADOX;
3973 end_op = CC_OP_ADCOX;
3974 carry_in = carry_out;
3977 end_op = (b == 0x1f6 ? CC_OP_ADCX : CC_OP_ADOX);
3980 /* If we can't reuse carry-out, get it out of EFLAGS. */
3982 if (s->cc_op != CC_OP_ADCX && s->cc_op != CC_OP_ADOX) {
3983 gen_compute_eflags(s);
3985 carry_in = cpu_tmp0;
3986 tcg_gen_extract_tl(carry_in, cpu_cc_src,
3987 ctz32(b == 0x1f6 ? CC_C : CC_O), 1);
3991 #ifdef TARGET_X86_64
3993 /* If we know TL is 64-bit, and we want a 32-bit
3994 result, just do everything in 64-bit arithmetic. */
3995 tcg_gen_ext32u_i64(cpu_regs[reg], cpu_regs[reg]);
3996 tcg_gen_ext32u_i64(cpu_T0, cpu_T0);
3997 tcg_gen_add_i64(cpu_T0, cpu_T0, cpu_regs[reg]);
3998 tcg_gen_add_i64(cpu_T0, cpu_T0, carry_in);
3999 tcg_gen_ext32u_i64(cpu_regs[reg], cpu_T0);
4000 tcg_gen_shri_i64(carry_out, cpu_T0, 32);
4004 /* Otherwise compute the carry-out in two steps. */
4005 zero = tcg_const_tl(0);
4006 tcg_gen_add2_tl(cpu_T0, carry_out,
4009 tcg_gen_add2_tl(cpu_regs[reg], carry_out,
4010 cpu_regs[reg], carry_out,
4012 tcg_temp_free(zero);
4015 set_cc_op(s, end_op);
4019 case 0x1f7: /* shlx Gy, Ey, By */
4020 case 0x2f7: /* sarx Gy, Ey, By */
4021 case 0x3f7: /* shrx Gy, Ey, By */
4022 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
4023 || !(s->prefix & PREFIX_VEX)
4027 ot = mo_64_32(s->dflag);
4028 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4030 tcg_gen_andi_tl(cpu_T1, cpu_regs[s->vex_v], 63);
4032 tcg_gen_andi_tl(cpu_T1, cpu_regs[s->vex_v], 31);
4035 tcg_gen_shl_tl(cpu_T0, cpu_T0, cpu_T1);
4036 } else if (b == 0x2f7) {
4038 tcg_gen_ext32s_tl(cpu_T0, cpu_T0);
4040 tcg_gen_sar_tl(cpu_T0, cpu_T0, cpu_T1);
4043 tcg_gen_ext32u_tl(cpu_T0, cpu_T0);
4045 tcg_gen_shr_tl(cpu_T0, cpu_T0, cpu_T1);
4047 gen_op_mov_reg_v(ot, reg, cpu_T0);
4053 case 0x3f3: /* Group 17 */
4054 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
4055 || !(s->prefix & PREFIX_VEX)
4059 ot = mo_64_32(s->dflag);
4060 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4062 tcg_gen_mov_tl(cpu_cc_src, cpu_T0);
4064 case 1: /* blsr By,Ey */
4065 tcg_gen_subi_tl(cpu_T1, cpu_T0, 1);
4066 tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1);
4068 case 2: /* blsmsk By,Ey */
4069 tcg_gen_subi_tl(cpu_T1, cpu_T0, 1);
4070 tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_T1);
4072 case 3: /* blsi By, Ey */
4073 tcg_gen_neg_tl(cpu_T1, cpu_T0);
4074 tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1);
4079 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4080 gen_op_mov_reg_v(ot, s->vex_v, cpu_T0);
4081 set_cc_op(s, CC_OP_BMILGB + ot);
4092 modrm = x86_ldub_code(env, s);
4094 reg = ((modrm >> 3) & 7) | rex_r;
4095 mod = (modrm >> 6) & 3;
4100 sse_fn_eppi = sse_op_table7[b].op[b1];
4104 if (!(s->cpuid_ext_features & sse_op_table7[b].ext_mask))
4109 if (sse_fn_eppi == SSE_SPECIAL) {
4110 ot = mo_64_32(s->dflag);
4111 rm = (modrm & 7) | REX_B(s);
4113 gen_lea_modrm(env, s, modrm);
4114 reg = ((modrm >> 3) & 7) | rex_r;
4115 val = x86_ldub_code(env, s);
4117 case 0x14: /* pextrb */
4118 tcg_gen_ld8u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
4119 xmm_regs[reg].ZMM_B(val & 15)));
4121 gen_op_mov_reg_v(ot, rm, cpu_T0);
4123 tcg_gen_qemu_st_tl(cpu_T0, cpu_A0,
4124 s->mem_index, MO_UB);
4127 case 0x15: /* pextrw */
4128 tcg_gen_ld16u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
4129 xmm_regs[reg].ZMM_W(val & 7)));
4131 gen_op_mov_reg_v(ot, rm, cpu_T0);
4133 tcg_gen_qemu_st_tl(cpu_T0, cpu_A0,
4134 s->mem_index, MO_LEUW);
4138 if (ot == MO_32) { /* pextrd */
4139 tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
4140 offsetof(CPUX86State,
4141 xmm_regs[reg].ZMM_L(val & 3)));
4143 tcg_gen_extu_i32_tl(cpu_regs[rm], cpu_tmp2_i32);
4145 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
4146 s->mem_index, MO_LEUL);
4148 } else { /* pextrq */
4149 #ifdef TARGET_X86_64
4150 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
4151 offsetof(CPUX86State,
4152 xmm_regs[reg].ZMM_Q(val & 1)));
4154 tcg_gen_mov_i64(cpu_regs[rm], cpu_tmp1_i64);
4156 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0,
4157 s->mem_index, MO_LEQ);
4164 case 0x17: /* extractps */
4165 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
4166 xmm_regs[reg].ZMM_L(val & 3)));
4168 gen_op_mov_reg_v(ot, rm, cpu_T0);
4170 tcg_gen_qemu_st_tl(cpu_T0, cpu_A0,
4171 s->mem_index, MO_LEUL);
4174 case 0x20: /* pinsrb */
4176 gen_op_mov_v_reg(MO_32, cpu_T0, rm);
4178 tcg_gen_qemu_ld_tl(cpu_T0, cpu_A0,
4179 s->mem_index, MO_UB);
4181 tcg_gen_st8_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
4182 xmm_regs[reg].ZMM_B(val & 15)));
4184 case 0x21: /* insertps */
4186 tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
4187 offsetof(CPUX86State,xmm_regs[rm]
4188 .ZMM_L((val >> 6) & 3)));
4190 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
4191 s->mem_index, MO_LEUL);
4193 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
4194 offsetof(CPUX86State,xmm_regs[reg]
4195 .ZMM_L((val >> 4) & 3)));
4197 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4198 cpu_env, offsetof(CPUX86State,
4199 xmm_regs[reg].ZMM_L(0)));
4201 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4202 cpu_env, offsetof(CPUX86State,
4203 xmm_regs[reg].ZMM_L(1)));
4205 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4206 cpu_env, offsetof(CPUX86State,
4207 xmm_regs[reg].ZMM_L(2)));
4209 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4210 cpu_env, offsetof(CPUX86State,
4211 xmm_regs[reg].ZMM_L(3)));
4214 if (ot == MO_32) { /* pinsrd */
4216 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[rm]);
4218 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
4219 s->mem_index, MO_LEUL);
4221 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
4222 offsetof(CPUX86State,
4223 xmm_regs[reg].ZMM_L(val & 3)));
4224 } else { /* pinsrq */
4225 #ifdef TARGET_X86_64
4227 gen_op_mov_v_reg(ot, cpu_tmp1_i64, rm);
4229 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0,
4230 s->mem_index, MO_LEQ);
4232 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
4233 offsetof(CPUX86State,
4234 xmm_regs[reg].ZMM_Q(val & 1)));
4245 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
4247 op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
4249 op2_offset = offsetof(CPUX86State,xmm_t0);
4250 gen_lea_modrm(env, s, modrm);
4251 gen_ldo_env_A0(s, op2_offset);
4254 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
4256 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
4258 op2_offset = offsetof(CPUX86State,mmx_t0);
4259 gen_lea_modrm(env, s, modrm);
4260 gen_ldq_env_A0(s, op2_offset);
4263 val = x86_ldub_code(env, s);
4265 if ((b & 0xfc) == 0x60) { /* pcmpXstrX */
4266 set_cc_op(s, CC_OP_EFLAGS);
4268 if (s->dflag == MO_64) {
4269 /* The helper must use entire 64-bit gp registers */
4274 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4275 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4276 sse_fn_eppi(cpu_env, cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
4280 /* Various integer extensions at 0f 3a f[0-f]. */
4281 b = modrm | (b1 << 8);
4282 modrm = x86_ldub_code(env, s);
4283 reg = ((modrm >> 3) & 7) | rex_r;
4286 case 0x3f0: /* rorx Gy,Ey, Ib */
4287 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
4288 || !(s->prefix & PREFIX_VEX)
4292 ot = mo_64_32(s->dflag);
4293 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4294 b = x86_ldub_code(env, s);
4296 tcg_gen_rotri_tl(cpu_T0, cpu_T0, b & 63);
4298 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
4299 tcg_gen_rotri_i32(cpu_tmp2_i32, cpu_tmp2_i32, b & 31);
4300 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
4302 gen_op_mov_reg_v(ot, reg, cpu_T0);
4312 gen_unknown_opcode(env, s);
4316 /* generic MMX or SSE operation */
4318 case 0x70: /* pshufx insn */
4319 case 0xc6: /* pshufx insn */
4320 case 0xc2: /* compare insns */
4327 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
4331 gen_lea_modrm(env, s, modrm);
4332 op2_offset = offsetof(CPUX86State,xmm_t0);
4338 /* Most sse scalar operations. */
4341 } else if (b1 == 3) {
4346 case 0x2e: /* ucomis[sd] */
4347 case 0x2f: /* comis[sd] */
4359 gen_op_ld_v(s, MO_32, cpu_T0, cpu_A0);
4360 tcg_gen_st32_tl(cpu_T0, cpu_env,
4361 offsetof(CPUX86State,xmm_t0.ZMM_L(0)));
4365 gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_D(0)));
4368 /* 128 bit access */
4369 gen_ldo_env_A0(s, op2_offset);
4373 rm = (modrm & 7) | REX_B(s);
4374 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
4377 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
4379 gen_lea_modrm(env, s, modrm);
4380 op2_offset = offsetof(CPUX86State,mmx_t0);
4381 gen_ldq_env_A0(s, op2_offset);
4384 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
4388 case 0x0f: /* 3DNow! data insns */
4389 val = x86_ldub_code(env, s);
4390 sse_fn_epp = sse_op_table5[val];
4394 if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) {
4397 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4398 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4399 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4401 case 0x70: /* pshufx insn */
4402 case 0xc6: /* pshufx insn */
4403 val = x86_ldub_code(env, s);
4404 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4405 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4406 /* XXX: introduce a new table? */
4407 sse_fn_ppi = (SSEFunc_0_ppi)sse_fn_epp;
4408 sse_fn_ppi(cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
4412 val = x86_ldub_code(env, s);
4415 sse_fn_epp = sse_op_table4[val][b1];
4417 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4418 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4419 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4422 /* maskmov : we must prepare A0 */
4425 tcg_gen_mov_tl(cpu_A0, cpu_regs[R_EDI]);
4426 gen_extu(s->aflag, cpu_A0);
4427 gen_add_A0_ds_seg(s);
4429 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4430 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4431 /* XXX: introduce a new table? */
4432 sse_fn_eppt = (SSEFunc_0_eppt)sse_fn_epp;
4433 sse_fn_eppt(cpu_env, cpu_ptr0, cpu_ptr1, cpu_A0);
4436 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4437 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4438 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4441 if (b == 0x2e || b == 0x2f) {
4442 set_cc_op(s, CC_OP_EFLAGS);
4447 /* convert one instruction. s->base.is_jmp is set if the translation must
4448 be stopped. Return the next pc value */
4449 static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
4451 CPUX86State *env = cpu->env_ptr;
4454 TCGMemOp ot, aflag, dflag;
4455 int modrm, reg, rm, mod, op, opreg, val;
4456 target_ulong next_eip, tval;
4458 target_ulong pc_start = s->base.pc_next;
4460 s->pc_start = s->pc = pc_start;
4462 #ifdef TARGET_X86_64
4467 s->rip_offset = 0; /* for relative ip address */
4470 if (sigsetjmp(s->jmpbuf, 0) != 0) {
4471 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
4480 b = x86_ldub_code(env, s);
4481 /* Collect prefixes. */
4484 prefixes |= PREFIX_REPZ;
4487 prefixes |= PREFIX_REPNZ;
4490 prefixes |= PREFIX_LOCK;
4511 prefixes |= PREFIX_DATA;
4514 prefixes |= PREFIX_ADR;
4516 #ifdef TARGET_X86_64
4520 rex_w = (b >> 3) & 1;
4521 rex_r = (b & 0x4) << 1;
4522 s->rex_x = (b & 0x2) << 2;
4523 REX_B(s) = (b & 0x1) << 3;
4524 x86_64_hregs = 1; /* select uniform byte register addressing */
4529 case 0xc5: /* 2-byte VEX */
4530 case 0xc4: /* 3-byte VEX */
4531 /* VEX prefixes cannot be used except in 32-bit mode.
4532 Otherwise the instruction is LES or LDS. */
4533 if (s->code32 && !s->vm86) {
4534 static const int pp_prefix[4] = {
4535 0, PREFIX_DATA, PREFIX_REPZ, PREFIX_REPNZ
4537 int vex3, vex2 = x86_ldub_code(env, s);
4539 if (!CODE64(s) && (vex2 & 0xc0) != 0xc0) {
4540 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4541 otherwise the instruction is LES or LDS. */
4542 s->pc--; /* rewind the advance_pc() x86_ldub_code() did */
4546 /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
4547 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ
4548 | PREFIX_LOCK | PREFIX_DATA)) {
4551 #ifdef TARGET_X86_64
4556 rex_r = (~vex2 >> 4) & 8;
4558 /* 2-byte VEX prefix: RVVVVlpp, implied 0f leading opcode byte */
4560 b = x86_ldub_code(env, s) | 0x100;
4562 /* 3-byte VEX prefix: RXBmmmmm wVVVVlpp */
4563 #ifdef TARGET_X86_64
4564 s->rex_x = (~vex2 >> 3) & 8;
4565 s->rex_b = (~vex2 >> 2) & 8;
4567 vex3 = x86_ldub_code(env, s);
4568 rex_w = (vex3 >> 7) & 1;
4569 switch (vex2 & 0x1f) {
4570 case 0x01: /* Implied 0f leading opcode bytes. */
4571 b = x86_ldub_code(env, s) | 0x100;
4573 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4576 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4579 default: /* Reserved for future use. */
4583 s->vex_v = (~vex3 >> 3) & 0xf;
4584 s->vex_l = (vex3 >> 2) & 1;
4585 prefixes |= pp_prefix[vex3 & 3] | PREFIX_VEX;
4590 /* Post-process prefixes. */
4592 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit
4593 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4594 over 0x66 if both are present. */
4595 dflag = (rex_w > 0 ? MO_64 : prefixes & PREFIX_DATA ? MO_16 : MO_32);
4596 /* In 64-bit mode, 0x67 selects 32-bit addressing. */
4597 aflag = (prefixes & PREFIX_ADR ? MO_32 : MO_64);
4599 /* In 16/32-bit mode, 0x66 selects the opposite data size. */
4600 if (s->code32 ^ ((prefixes & PREFIX_DATA) != 0)) {
4605 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */
4606 if (s->code32 ^ ((prefixes & PREFIX_ADR) != 0)) {
4613 s->prefix = prefixes;
4617 /* now check op code */
4621 /**************************/
4622 /* extended op code */
4623 b = x86_ldub_code(env, s) | 0x100;
4626 /**************************/
4641 ot = mo_b_d(b, dflag);
4644 case 0: /* OP Ev, Gv */
4645 modrm = x86_ldub_code(env, s);
4646 reg = ((modrm >> 3) & 7) | rex_r;
4647 mod = (modrm >> 6) & 3;
4648 rm = (modrm & 7) | REX_B(s);
4650 gen_lea_modrm(env, s, modrm);
4652 } else if (op == OP_XORL && rm == reg) {
4654 /* xor reg, reg optimisation */
4655 set_cc_op(s, CC_OP_CLR);
4656 tcg_gen_movi_tl(cpu_T0, 0);
4657 gen_op_mov_reg_v(ot, reg, cpu_T0);
4662 gen_op_mov_v_reg(ot, cpu_T1, reg);
4663 gen_op(s, op, ot, opreg);
4665 case 1: /* OP Gv, Ev */
4666 modrm = x86_ldub_code(env, s);
4667 mod = (modrm >> 6) & 3;
4668 reg = ((modrm >> 3) & 7) | rex_r;
4669 rm = (modrm & 7) | REX_B(s);
4671 gen_lea_modrm(env, s, modrm);
4672 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
4673 } else if (op == OP_XORL && rm == reg) {
4676 gen_op_mov_v_reg(ot, cpu_T1, rm);
4678 gen_op(s, op, ot, reg);
4680 case 2: /* OP A, Iv */
4681 val = insn_get(env, s, ot);
4682 tcg_gen_movi_tl(cpu_T1, val);
4683 gen_op(s, op, ot, OR_EAX);
4693 case 0x80: /* GRP1 */
4699 ot = mo_b_d(b, dflag);
4701 modrm = x86_ldub_code(env, s);
4702 mod = (modrm >> 6) & 3;
4703 rm = (modrm & 7) | REX_B(s);
4704 op = (modrm >> 3) & 7;
4710 s->rip_offset = insn_const_size(ot);
4711 gen_lea_modrm(env, s, modrm);
4722 val = insn_get(env, s, ot);
4725 val = (int8_t)insn_get(env, s, MO_8);
4728 tcg_gen_movi_tl(cpu_T1, val);
4729 gen_op(s, op, ot, opreg);
4733 /**************************/
4734 /* inc, dec, and other misc arith */
4735 case 0x40 ... 0x47: /* inc Gv */
4737 gen_inc(s, ot, OR_EAX + (b & 7), 1);
4739 case 0x48 ... 0x4f: /* dec Gv */
4741 gen_inc(s, ot, OR_EAX + (b & 7), -1);
4743 case 0xf6: /* GRP3 */
4745 ot = mo_b_d(b, dflag);
4747 modrm = x86_ldub_code(env, s);
4748 mod = (modrm >> 6) & 3;
4749 rm = (modrm & 7) | REX_B(s);
4750 op = (modrm >> 3) & 7;
4753 s->rip_offset = insn_const_size(ot);
4755 gen_lea_modrm(env, s, modrm);
4756 /* For those below that handle locked memory, don't load here. */
4757 if (!(s->prefix & PREFIX_LOCK)
4759 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
4762 gen_op_mov_v_reg(ot, cpu_T0, rm);
4767 val = insn_get(env, s, ot);
4768 tcg_gen_movi_tl(cpu_T1, val);
4769 gen_op_testl_T0_T1_cc();
4770 set_cc_op(s, CC_OP_LOGICB + ot);
4773 if (s->prefix & PREFIX_LOCK) {
4777 tcg_gen_movi_tl(cpu_T0, ~0);
4778 tcg_gen_atomic_xor_fetch_tl(cpu_T0, cpu_A0, cpu_T0,
4779 s->mem_index, ot | MO_LE);
4781 tcg_gen_not_tl(cpu_T0, cpu_T0);
4783 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
4785 gen_op_mov_reg_v(ot, rm, cpu_T0);
4790 if (s->prefix & PREFIX_LOCK) {
4792 TCGv a0, t0, t1, t2;
4797 a0 = tcg_temp_local_new();
4798 t0 = tcg_temp_local_new();
4799 label1 = gen_new_label();
4801 tcg_gen_mov_tl(a0, cpu_A0);
4802 tcg_gen_mov_tl(t0, cpu_T0);
4804 gen_set_label(label1);
4805 t1 = tcg_temp_new();
4806 t2 = tcg_temp_new();
4807 tcg_gen_mov_tl(t2, t0);
4808 tcg_gen_neg_tl(t1, t0);
4809 tcg_gen_atomic_cmpxchg_tl(t0, a0, t0, t1,
4810 s->mem_index, ot | MO_LE);
4812 tcg_gen_brcond_tl(TCG_COND_NE, t0, t2, label1);
4816 tcg_gen_mov_tl(cpu_T0, t0);
4819 tcg_gen_neg_tl(cpu_T0, cpu_T0);
4821 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
4823 gen_op_mov_reg_v(ot, rm, cpu_T0);
4826 gen_op_update_neg_cc();
4827 set_cc_op(s, CC_OP_SUBB + ot);
4832 gen_op_mov_v_reg(MO_8, cpu_T1, R_EAX);
4833 tcg_gen_ext8u_tl(cpu_T0, cpu_T0);
4834 tcg_gen_ext8u_tl(cpu_T1, cpu_T1);
4835 /* XXX: use 32 bit mul which could be faster */
4836 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
4837 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
4838 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4839 tcg_gen_andi_tl(cpu_cc_src, cpu_T0, 0xff00);
4840 set_cc_op(s, CC_OP_MULB);
4843 gen_op_mov_v_reg(MO_16, cpu_T1, R_EAX);
4844 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
4845 tcg_gen_ext16u_tl(cpu_T1, cpu_T1);
4846 /* XXX: use 32 bit mul which could be faster */
4847 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
4848 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
4849 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4850 tcg_gen_shri_tl(cpu_T0, cpu_T0, 16);
4851 gen_op_mov_reg_v(MO_16, R_EDX, cpu_T0);
4852 tcg_gen_mov_tl(cpu_cc_src, cpu_T0);
4853 set_cc_op(s, CC_OP_MULW);
4857 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
4858 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_regs[R_EAX]);
4859 tcg_gen_mulu2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
4860 cpu_tmp2_i32, cpu_tmp3_i32);
4861 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], cpu_tmp2_i32);
4862 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], cpu_tmp3_i32);
4863 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4864 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]);
4865 set_cc_op(s, CC_OP_MULL);
4867 #ifdef TARGET_X86_64
4869 tcg_gen_mulu2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX],
4870 cpu_T0, cpu_regs[R_EAX]);
4871 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4872 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]);
4873 set_cc_op(s, CC_OP_MULQ);
4881 gen_op_mov_v_reg(MO_8, cpu_T1, R_EAX);
4882 tcg_gen_ext8s_tl(cpu_T0, cpu_T0);
4883 tcg_gen_ext8s_tl(cpu_T1, cpu_T1);
4884 /* XXX: use 32 bit mul which could be faster */
4885 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
4886 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
4887 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4888 tcg_gen_ext8s_tl(cpu_tmp0, cpu_T0);
4889 tcg_gen_sub_tl(cpu_cc_src, cpu_T0, cpu_tmp0);
4890 set_cc_op(s, CC_OP_MULB);
4893 gen_op_mov_v_reg(MO_16, cpu_T1, R_EAX);
4894 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
4895 tcg_gen_ext16s_tl(cpu_T1, cpu_T1);
4896 /* XXX: use 32 bit mul which could be faster */
4897 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
4898 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
4899 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4900 tcg_gen_ext16s_tl(cpu_tmp0, cpu_T0);
4901 tcg_gen_sub_tl(cpu_cc_src, cpu_T0, cpu_tmp0);
4902 tcg_gen_shri_tl(cpu_T0, cpu_T0, 16);
4903 gen_op_mov_reg_v(MO_16, R_EDX, cpu_T0);
4904 set_cc_op(s, CC_OP_MULW);
4908 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
4909 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_regs[R_EAX]);
4910 tcg_gen_muls2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
4911 cpu_tmp2_i32, cpu_tmp3_i32);
4912 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], cpu_tmp2_i32);
4913 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], cpu_tmp3_i32);
4914 tcg_gen_sari_i32(cpu_tmp2_i32, cpu_tmp2_i32, 31);
4915 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4916 tcg_gen_sub_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
4917 tcg_gen_extu_i32_tl(cpu_cc_src, cpu_tmp2_i32);
4918 set_cc_op(s, CC_OP_MULL);
4920 #ifdef TARGET_X86_64
4922 tcg_gen_muls2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX],
4923 cpu_T0, cpu_regs[R_EAX]);
4924 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4925 tcg_gen_sari_tl(cpu_cc_src, cpu_regs[R_EAX], 63);
4926 tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, cpu_regs[R_EDX]);
4927 set_cc_op(s, CC_OP_MULQ);
4935 gen_helper_divb_AL(cpu_env, cpu_T0);
4938 gen_helper_divw_AX(cpu_env, cpu_T0);
4942 gen_helper_divl_EAX(cpu_env, cpu_T0);
4944 #ifdef TARGET_X86_64
4946 gen_helper_divq_EAX(cpu_env, cpu_T0);
4954 gen_helper_idivb_AL(cpu_env, cpu_T0);
4957 gen_helper_idivw_AX(cpu_env, cpu_T0);
4961 gen_helper_idivl_EAX(cpu_env, cpu_T0);
4963 #ifdef TARGET_X86_64
4965 gen_helper_idivq_EAX(cpu_env, cpu_T0);
4975 case 0xfe: /* GRP4 */
4976 case 0xff: /* GRP5 */
4977 ot = mo_b_d(b, dflag);
4979 modrm = x86_ldub_code(env, s);
4980 mod = (modrm >> 6) & 3;
4981 rm = (modrm & 7) | REX_B(s);
4982 op = (modrm >> 3) & 7;
4983 if (op >= 2 && b == 0xfe) {
4987 if (op == 2 || op == 4) {
4988 /* operand size for jumps is 64 bit */
4990 } else if (op == 3 || op == 5) {
4991 ot = dflag != MO_16 ? MO_32 + (rex_w == 1) : MO_16;
4992 } else if (op == 6) {
4993 /* default push size is 64 bit */
4994 ot = mo_pushpop(s, dflag);
4998 gen_lea_modrm(env, s, modrm);
4999 if (op >= 2 && op != 3 && op != 5)
5000 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
5002 gen_op_mov_v_reg(ot, cpu_T0, rm);
5006 case 0: /* inc Ev */
5011 gen_inc(s, ot, opreg, 1);
5013 case 1: /* dec Ev */
5018 gen_inc(s, ot, opreg, -1);
5020 case 2: /* call Ev */
5021 /* XXX: optimize if memory (no 'and' is necessary) */
5022 if (dflag == MO_16) {
5023 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
5025 next_eip = s->pc - s->cs_base;
5026 tcg_gen_movi_tl(cpu_T1, next_eip);
5027 gen_push_v(s, cpu_T1);
5028 gen_op_jmp_v(cpu_T0);
5032 case 3: /* lcall Ev */
5033 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
5034 gen_add_A0_im(s, 1 << ot);
5035 gen_op_ld_v(s, MO_16, cpu_T0, cpu_A0);
5037 if (s->pe && !s->vm86) {
5038 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
5039 gen_helper_lcall_protected(cpu_env, cpu_tmp2_i32, cpu_T1,
5040 tcg_const_i32(dflag - 1),
5041 tcg_const_tl(s->pc - s->cs_base));
5043 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
5044 gen_helper_lcall_real(cpu_env, cpu_tmp2_i32, cpu_T1,
5045 tcg_const_i32(dflag - 1),
5046 tcg_const_i32(s->pc - s->cs_base));
5048 tcg_gen_ld_tl(cpu_tmp4, cpu_env, offsetof(CPUX86State, eip));
5049 gen_jr(s, cpu_tmp4);
5051 case 4: /* jmp Ev */
5052 if (dflag == MO_16) {
5053 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
5055 gen_op_jmp_v(cpu_T0);
5059 case 5: /* ljmp Ev */
5060 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
5061 gen_add_A0_im(s, 1 << ot);
5062 gen_op_ld_v(s, MO_16, cpu_T0, cpu_A0);
5064 if (s->pe && !s->vm86) {
5065 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
5066 gen_helper_ljmp_protected(cpu_env, cpu_tmp2_i32, cpu_T1,
5067 tcg_const_tl(s->pc - s->cs_base));
5069 gen_op_movl_seg_T0_vm(R_CS);
5070 gen_op_jmp_v(cpu_T1);
5072 tcg_gen_ld_tl(cpu_tmp4, cpu_env, offsetof(CPUX86State, eip));
5073 gen_jr(s, cpu_tmp4);
5075 case 6: /* push Ev */
5076 gen_push_v(s, cpu_T0);
5083 case 0x84: /* test Ev, Gv */
5085 ot = mo_b_d(b, dflag);
5087 modrm = x86_ldub_code(env, s);
5088 reg = ((modrm >> 3) & 7) | rex_r;
5090 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5091 gen_op_mov_v_reg(ot, cpu_T1, reg);
5092 gen_op_testl_T0_T1_cc();
5093 set_cc_op(s, CC_OP_LOGICB + ot);
5096 case 0xa8: /* test eAX, Iv */
5098 ot = mo_b_d(b, dflag);
5099 val = insn_get(env, s, ot);
5101 gen_op_mov_v_reg(ot, cpu_T0, OR_EAX);
5102 tcg_gen_movi_tl(cpu_T1, val);
5103 gen_op_testl_T0_T1_cc();
5104 set_cc_op(s, CC_OP_LOGICB + ot);
5107 case 0x98: /* CWDE/CBW */
5109 #ifdef TARGET_X86_64
5111 gen_op_mov_v_reg(MO_32, cpu_T0, R_EAX);
5112 tcg_gen_ext32s_tl(cpu_T0, cpu_T0);
5113 gen_op_mov_reg_v(MO_64, R_EAX, cpu_T0);
5117 gen_op_mov_v_reg(MO_16, cpu_T0, R_EAX);
5118 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
5119 gen_op_mov_reg_v(MO_32, R_EAX, cpu_T0);
5122 gen_op_mov_v_reg(MO_8, cpu_T0, R_EAX);
5123 tcg_gen_ext8s_tl(cpu_T0, cpu_T0);
5124 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
5130 case 0x99: /* CDQ/CWD */
5132 #ifdef TARGET_X86_64
5134 gen_op_mov_v_reg(MO_64, cpu_T0, R_EAX);
5135 tcg_gen_sari_tl(cpu_T0, cpu_T0, 63);
5136 gen_op_mov_reg_v(MO_64, R_EDX, cpu_T0);
5140 gen_op_mov_v_reg(MO_32, cpu_T0, R_EAX);
5141 tcg_gen_ext32s_tl(cpu_T0, cpu_T0);
5142 tcg_gen_sari_tl(cpu_T0, cpu_T0, 31);
5143 gen_op_mov_reg_v(MO_32, R_EDX, cpu_T0);
5146 gen_op_mov_v_reg(MO_16, cpu_T0, R_EAX);
5147 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
5148 tcg_gen_sari_tl(cpu_T0, cpu_T0, 15);
5149 gen_op_mov_reg_v(MO_16, R_EDX, cpu_T0);
5155 case 0x1af: /* imul Gv, Ev */
5156 case 0x69: /* imul Gv, Ev, I */
5159 modrm = x86_ldub_code(env, s);
5160 reg = ((modrm >> 3) & 7) | rex_r;
5162 s->rip_offset = insn_const_size(ot);
5165 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5167 val = insn_get(env, s, ot);
5168 tcg_gen_movi_tl(cpu_T1, val);
5169 } else if (b == 0x6b) {
5170 val = (int8_t)insn_get(env, s, MO_8);
5171 tcg_gen_movi_tl(cpu_T1, val);
5173 gen_op_mov_v_reg(ot, cpu_T1, reg);
5176 #ifdef TARGET_X86_64
5178 tcg_gen_muls2_i64(cpu_regs[reg], cpu_T1, cpu_T0, cpu_T1);
5179 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]);
5180 tcg_gen_sari_tl(cpu_cc_src, cpu_cc_dst, 63);
5181 tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, cpu_T1);
5185 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
5186 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T1);
5187 tcg_gen_muls2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
5188 cpu_tmp2_i32, cpu_tmp3_i32);
5189 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
5190 tcg_gen_sari_i32(cpu_tmp2_i32, cpu_tmp2_i32, 31);
5191 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]);
5192 tcg_gen_sub_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
5193 tcg_gen_extu_i32_tl(cpu_cc_src, cpu_tmp2_i32);
5196 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
5197 tcg_gen_ext16s_tl(cpu_T1, cpu_T1);
5198 /* XXX: use 32 bit mul which could be faster */
5199 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
5200 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
5201 tcg_gen_ext16s_tl(cpu_tmp0, cpu_T0);
5202 tcg_gen_sub_tl(cpu_cc_src, cpu_T0, cpu_tmp0);
5203 gen_op_mov_reg_v(ot, reg, cpu_T0);
5206 set_cc_op(s, CC_OP_MULB + ot);
5209 case 0x1c1: /* xadd Ev, Gv */
5210 ot = mo_b_d(b, dflag);
5211 modrm = x86_ldub_code(env, s);
5212 reg = ((modrm >> 3) & 7) | rex_r;
5213 mod = (modrm >> 6) & 3;
5214 gen_op_mov_v_reg(ot, cpu_T0, reg);
5216 rm = (modrm & 7) | REX_B(s);
5217 gen_op_mov_v_reg(ot, cpu_T1, rm);
5218 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
5219 gen_op_mov_reg_v(ot, reg, cpu_T1);
5220 gen_op_mov_reg_v(ot, rm, cpu_T0);
5222 gen_lea_modrm(env, s, modrm);
5223 if (s->prefix & PREFIX_LOCK) {
5224 tcg_gen_atomic_fetch_add_tl(cpu_T1, cpu_A0, cpu_T0,
5225 s->mem_index, ot | MO_LE);
5226 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
5228 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
5229 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
5230 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
5232 gen_op_mov_reg_v(ot, reg, cpu_T1);
5234 gen_op_update2_cc();
5235 set_cc_op(s, CC_OP_ADDB + ot);
5238 case 0x1b1: /* cmpxchg Ev, Gv */
5240 TCGv oldv, newv, cmpv;
5242 ot = mo_b_d(b, dflag);
5243 modrm = x86_ldub_code(env, s);
5244 reg = ((modrm >> 3) & 7) | rex_r;
5245 mod = (modrm >> 6) & 3;
5246 oldv = tcg_temp_new();
5247 newv = tcg_temp_new();
5248 cmpv = tcg_temp_new();
5249 gen_op_mov_v_reg(ot, newv, reg);
5250 tcg_gen_mov_tl(cmpv, cpu_regs[R_EAX]);
5252 if (s->prefix & PREFIX_LOCK) {
5256 gen_lea_modrm(env, s, modrm);
5257 tcg_gen_atomic_cmpxchg_tl(oldv, cpu_A0, cmpv, newv,
5258 s->mem_index, ot | MO_LE);
5259 gen_op_mov_reg_v(ot, R_EAX, oldv);
5262 rm = (modrm & 7) | REX_B(s);
5263 gen_op_mov_v_reg(ot, oldv, rm);
5265 gen_lea_modrm(env, s, modrm);
5266 gen_op_ld_v(s, ot, oldv, cpu_A0);
5267 rm = 0; /* avoid warning */
5271 /* store value = (old == cmp ? new : old); */
5272 tcg_gen_movcond_tl(TCG_COND_EQ, newv, oldv, cmpv, newv, oldv);
5274 gen_op_mov_reg_v(ot, R_EAX, oldv);
5275 gen_op_mov_reg_v(ot, rm, newv);
5277 /* Perform an unconditional store cycle like physical cpu;
5278 must be before changing accumulator to ensure
5279 idempotency if the store faults and the instruction
5281 gen_op_st_v(s, ot, newv, cpu_A0);
5282 gen_op_mov_reg_v(ot, R_EAX, oldv);
5285 tcg_gen_mov_tl(cpu_cc_src, oldv);
5286 tcg_gen_mov_tl(cpu_cc_srcT, cmpv);
5287 tcg_gen_sub_tl(cpu_cc_dst, cmpv, oldv);
5288 set_cc_op(s, CC_OP_SUBB + ot);
5289 tcg_temp_free(oldv);
5290 tcg_temp_free(newv);
5291 tcg_temp_free(cmpv);
5294 case 0x1c7: /* cmpxchg8b */
5295 modrm = x86_ldub_code(env, s);
5296 mod = (modrm >> 6) & 3;
5297 if ((mod == 3) || ((modrm & 0x38) != 0x8))
5299 #ifdef TARGET_X86_64
5300 if (dflag == MO_64) {
5301 if (!(s->cpuid_ext_features & CPUID_EXT_CX16))
5303 gen_lea_modrm(env, s, modrm);
5304 if ((s->prefix & PREFIX_LOCK) && (tb_cflags(s->base.tb) & CF_PARALLEL)) {
5305 gen_helper_cmpxchg16b(cpu_env, cpu_A0);
5307 gen_helper_cmpxchg16b_unlocked(cpu_env, cpu_A0);
5312 if (!(s->cpuid_features & CPUID_CX8))
5314 gen_lea_modrm(env, s, modrm);
5315 if ((s->prefix & PREFIX_LOCK) && (tb_cflags(s->base.tb) & CF_PARALLEL)) {
5316 gen_helper_cmpxchg8b(cpu_env, cpu_A0);
5318 gen_helper_cmpxchg8b_unlocked(cpu_env, cpu_A0);
5321 set_cc_op(s, CC_OP_EFLAGS);
5324 /**************************/
5326 case 0x50 ... 0x57: /* push */
5327 gen_op_mov_v_reg(MO_32, cpu_T0, (b & 7) | REX_B(s));
5328 gen_push_v(s, cpu_T0);
5330 case 0x58 ... 0x5f: /* pop */
5332 /* NOTE: order is important for pop %sp */
5333 gen_pop_update(s, ot);
5334 gen_op_mov_reg_v(ot, (b & 7) | REX_B(s), cpu_T0);
5336 case 0x60: /* pusha */
5341 case 0x61: /* popa */
5346 case 0x68: /* push Iv */
5348 ot = mo_pushpop(s, dflag);
5350 val = insn_get(env, s, ot);
5352 val = (int8_t)insn_get(env, s, MO_8);
5353 tcg_gen_movi_tl(cpu_T0, val);
5354 gen_push_v(s, cpu_T0);
5356 case 0x8f: /* pop Ev */
5357 modrm = x86_ldub_code(env, s);
5358 mod = (modrm >> 6) & 3;
5361 /* NOTE: order is important for pop %sp */
5362 gen_pop_update(s, ot);
5363 rm = (modrm & 7) | REX_B(s);
5364 gen_op_mov_reg_v(ot, rm, cpu_T0);
5366 /* NOTE: order is important too for MMU exceptions */
5367 s->popl_esp_hack = 1 << ot;
5368 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5369 s->popl_esp_hack = 0;
5370 gen_pop_update(s, ot);
5373 case 0xc8: /* enter */
5376 val = x86_lduw_code(env, s);
5377 level = x86_ldub_code(env, s);
5378 gen_enter(s, val, level);
5381 case 0xc9: /* leave */
5384 case 0x06: /* push es */
5385 case 0x0e: /* push cs */
5386 case 0x16: /* push ss */
5387 case 0x1e: /* push ds */
5390 gen_op_movl_T0_seg(b >> 3);
5391 gen_push_v(s, cpu_T0);
5393 case 0x1a0: /* push fs */
5394 case 0x1a8: /* push gs */
5395 gen_op_movl_T0_seg((b >> 3) & 7);
5396 gen_push_v(s, cpu_T0);
5398 case 0x07: /* pop es */
5399 case 0x17: /* pop ss */
5400 case 0x1f: /* pop ds */
5405 gen_movl_seg_T0(s, reg);
5406 gen_pop_update(s, ot);
5407 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5408 if (s->base.is_jmp) {
5409 gen_jmp_im(s->pc - s->cs_base);
5412 gen_eob_inhibit_irq(s, true);
5418 case 0x1a1: /* pop fs */
5419 case 0x1a9: /* pop gs */
5421 gen_movl_seg_T0(s, (b >> 3) & 7);
5422 gen_pop_update(s, ot);
5423 if (s->base.is_jmp) {
5424 gen_jmp_im(s->pc - s->cs_base);
5429 /**************************/
5432 case 0x89: /* mov Gv, Ev */
5433 ot = mo_b_d(b, dflag);
5434 modrm = x86_ldub_code(env, s);
5435 reg = ((modrm >> 3) & 7) | rex_r;
5437 /* generate a generic store */
5438 gen_ldst_modrm(env, s, modrm, ot, reg, 1);
5441 case 0xc7: /* mov Ev, Iv */
5442 ot = mo_b_d(b, dflag);
5443 modrm = x86_ldub_code(env, s);
5444 mod = (modrm >> 6) & 3;
5446 s->rip_offset = insn_const_size(ot);
5447 gen_lea_modrm(env, s, modrm);
5449 val = insn_get(env, s, ot);
5450 tcg_gen_movi_tl(cpu_T0, val);
5452 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
5454 gen_op_mov_reg_v(ot, (modrm & 7) | REX_B(s), cpu_T0);
5458 case 0x8b: /* mov Ev, Gv */
5459 ot = mo_b_d(b, dflag);
5460 modrm = x86_ldub_code(env, s);
5461 reg = ((modrm >> 3) & 7) | rex_r;
5463 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5464 gen_op_mov_reg_v(ot, reg, cpu_T0);
5466 case 0x8e: /* mov seg, Gv */
5467 modrm = x86_ldub_code(env, s);
5468 reg = (modrm >> 3) & 7;
5469 if (reg >= 6 || reg == R_CS)
5471 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
5472 gen_movl_seg_T0(s, reg);
5473 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5474 if (s->base.is_jmp) {
5475 gen_jmp_im(s->pc - s->cs_base);
5478 gen_eob_inhibit_irq(s, true);
5484 case 0x8c: /* mov Gv, seg */
5485 modrm = x86_ldub_code(env, s);
5486 reg = (modrm >> 3) & 7;
5487 mod = (modrm >> 6) & 3;
5490 gen_op_movl_T0_seg(reg);
5491 ot = mod == 3 ? dflag : MO_16;
5492 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5495 case 0x1b6: /* movzbS Gv, Eb */
5496 case 0x1b7: /* movzwS Gv, Eb */
5497 case 0x1be: /* movsbS Gv, Eb */
5498 case 0x1bf: /* movswS Gv, Eb */
5503 /* d_ot is the size of destination */
5505 /* ot is the size of source */
5506 ot = (b & 1) + MO_8;
5507 /* s_ot is the sign+size of source */
5508 s_ot = b & 8 ? MO_SIGN | ot : ot;
5510 modrm = x86_ldub_code(env, s);
5511 reg = ((modrm >> 3) & 7) | rex_r;
5512 mod = (modrm >> 6) & 3;
5513 rm = (modrm & 7) | REX_B(s);
5516 if (s_ot == MO_SB && byte_reg_is_xH(rm)) {
5517 tcg_gen_sextract_tl(cpu_T0, cpu_regs[rm - 4], 8, 8);
5519 gen_op_mov_v_reg(ot, cpu_T0, rm);
5522 tcg_gen_ext8u_tl(cpu_T0, cpu_T0);
5525 tcg_gen_ext8s_tl(cpu_T0, cpu_T0);
5528 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
5532 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
5536 gen_op_mov_reg_v(d_ot, reg, cpu_T0);
5538 gen_lea_modrm(env, s, modrm);
5539 gen_op_ld_v(s, s_ot, cpu_T0, cpu_A0);
5540 gen_op_mov_reg_v(d_ot, reg, cpu_T0);
5545 case 0x8d: /* lea */
5546 modrm = x86_ldub_code(env, s);
5547 mod = (modrm >> 6) & 3;
5550 reg = ((modrm >> 3) & 7) | rex_r;
5552 AddressParts a = gen_lea_modrm_0(env, s, modrm);
5553 TCGv ea = gen_lea_modrm_1(a);
5554 gen_lea_v_seg(s, s->aflag, ea, -1, -1);
5555 gen_op_mov_reg_v(dflag, reg, cpu_A0);
5559 case 0xa0: /* mov EAX, Ov */
5561 case 0xa2: /* mov Ov, EAX */
5564 target_ulong offset_addr;
5566 ot = mo_b_d(b, dflag);
5568 #ifdef TARGET_X86_64
5570 offset_addr = x86_ldq_code(env, s);
5574 offset_addr = insn_get(env, s, s->aflag);
5577 tcg_gen_movi_tl(cpu_A0, offset_addr);
5578 gen_add_A0_ds_seg(s);
5580 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
5581 gen_op_mov_reg_v(ot, R_EAX, cpu_T0);
5583 gen_op_mov_v_reg(ot, cpu_T0, R_EAX);
5584 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
5588 case 0xd7: /* xlat */
5589 tcg_gen_mov_tl(cpu_A0, cpu_regs[R_EBX]);
5590 tcg_gen_ext8u_tl(cpu_T0, cpu_regs[R_EAX]);
5591 tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T0);
5592 gen_extu(s->aflag, cpu_A0);
5593 gen_add_A0_ds_seg(s);
5594 gen_op_ld_v(s, MO_8, cpu_T0, cpu_A0);
5595 gen_op_mov_reg_v(MO_8, R_EAX, cpu_T0);
5597 case 0xb0 ... 0xb7: /* mov R, Ib */
5598 val = insn_get(env, s, MO_8);
5599 tcg_gen_movi_tl(cpu_T0, val);
5600 gen_op_mov_reg_v(MO_8, (b & 7) | REX_B(s), cpu_T0);
5602 case 0xb8 ... 0xbf: /* mov R, Iv */
5603 #ifdef TARGET_X86_64
5604 if (dflag == MO_64) {
5607 tmp = x86_ldq_code(env, s);
5608 reg = (b & 7) | REX_B(s);
5609 tcg_gen_movi_tl(cpu_T0, tmp);
5610 gen_op_mov_reg_v(MO_64, reg, cpu_T0);
5615 val = insn_get(env, s, ot);
5616 reg = (b & 7) | REX_B(s);
5617 tcg_gen_movi_tl(cpu_T0, val);
5618 gen_op_mov_reg_v(ot, reg, cpu_T0);
5622 case 0x91 ... 0x97: /* xchg R, EAX */
5625 reg = (b & 7) | REX_B(s);
5629 case 0x87: /* xchg Ev, Gv */
5630 ot = mo_b_d(b, dflag);
5631 modrm = x86_ldub_code(env, s);
5632 reg = ((modrm >> 3) & 7) | rex_r;
5633 mod = (modrm >> 6) & 3;
5635 rm = (modrm & 7) | REX_B(s);
5637 gen_op_mov_v_reg(ot, cpu_T0, reg);
5638 gen_op_mov_v_reg(ot, cpu_T1, rm);
5639 gen_op_mov_reg_v(ot, rm, cpu_T0);
5640 gen_op_mov_reg_v(ot, reg, cpu_T1);
5642 gen_lea_modrm(env, s, modrm);
5643 gen_op_mov_v_reg(ot, cpu_T0, reg);
5644 /* for xchg, lock is implicit */
5645 tcg_gen_atomic_xchg_tl(cpu_T1, cpu_A0, cpu_T0,
5646 s->mem_index, ot | MO_LE);
5647 gen_op_mov_reg_v(ot, reg, cpu_T1);
5650 case 0xc4: /* les Gv */
5651 /* In CODE64 this is VEX3; see above. */
5654 case 0xc5: /* lds Gv */
5655 /* In CODE64 this is VEX2; see above. */
5658 case 0x1b2: /* lss Gv */
5661 case 0x1b4: /* lfs Gv */
5664 case 0x1b5: /* lgs Gv */
5667 ot = dflag != MO_16 ? MO_32 : MO_16;
5668 modrm = x86_ldub_code(env, s);
5669 reg = ((modrm >> 3) & 7) | rex_r;
5670 mod = (modrm >> 6) & 3;
5673 gen_lea_modrm(env, s, modrm);
5674 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
5675 gen_add_A0_im(s, 1 << ot);
5676 /* load the segment first to handle exceptions properly */
5677 gen_op_ld_v(s, MO_16, cpu_T0, cpu_A0);
5678 gen_movl_seg_T0(s, op);
5679 /* then put the data */
5680 gen_op_mov_reg_v(ot, reg, cpu_T1);
5681 if (s->base.is_jmp) {
5682 gen_jmp_im(s->pc - s->cs_base);
5687 /************************/
5695 ot = mo_b_d(b, dflag);
5696 modrm = x86_ldub_code(env, s);
5697 mod = (modrm >> 6) & 3;
5698 op = (modrm >> 3) & 7;
5704 gen_lea_modrm(env, s, modrm);
5707 opreg = (modrm & 7) | REX_B(s);
5712 gen_shift(s, op, ot, opreg, OR_ECX);
5715 shift = x86_ldub_code(env, s);
5717 gen_shifti(s, op, ot, opreg, shift);
5732 case 0x1a4: /* shld imm */
5736 case 0x1a5: /* shld cl */
5740 case 0x1ac: /* shrd imm */
5744 case 0x1ad: /* shrd cl */
5749 modrm = x86_ldub_code(env, s);
5750 mod = (modrm >> 6) & 3;
5751 rm = (modrm & 7) | REX_B(s);
5752 reg = ((modrm >> 3) & 7) | rex_r;
5754 gen_lea_modrm(env, s, modrm);
5759 gen_op_mov_v_reg(ot, cpu_T1, reg);
5762 TCGv imm = tcg_const_tl(x86_ldub_code(env, s));
5763 gen_shiftd_rm_T1(s, ot, opreg, op, imm);
5766 gen_shiftd_rm_T1(s, ot, opreg, op, cpu_regs[R_ECX]);
5770 /************************/
5773 if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
5774 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5775 /* XXX: what to do if illegal op ? */
5776 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
5779 modrm = x86_ldub_code(env, s);
5780 mod = (modrm >> 6) & 3;
5782 op = ((b & 7) << 3) | ((modrm >> 3) & 7);
5785 gen_lea_modrm(env, s, modrm);
5787 case 0x00 ... 0x07: /* fxxxs */
5788 case 0x10 ... 0x17: /* fixxxl */
5789 case 0x20 ... 0x27: /* fxxxl */
5790 case 0x30 ... 0x37: /* fixxx */
5797 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5798 s->mem_index, MO_LEUL);
5799 gen_helper_flds_FT0(cpu_env, cpu_tmp2_i32);
5802 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5803 s->mem_index, MO_LEUL);
5804 gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32);
5807 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0,
5808 s->mem_index, MO_LEQ);
5809 gen_helper_fldl_FT0(cpu_env, cpu_tmp1_i64);
5813 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5814 s->mem_index, MO_LESW);
5815 gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32);
5819 gen_helper_fp_arith_ST0_FT0(op1);
5821 /* fcomp needs pop */
5822 gen_helper_fpop(cpu_env);
5826 case 0x08: /* flds */
5827 case 0x0a: /* fsts */
5828 case 0x0b: /* fstps */
5829 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5830 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5831 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5836 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5837 s->mem_index, MO_LEUL);
5838 gen_helper_flds_ST0(cpu_env, cpu_tmp2_i32);
5841 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5842 s->mem_index, MO_LEUL);
5843 gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32);
5846 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0,
5847 s->mem_index, MO_LEQ);
5848 gen_helper_fldl_ST0(cpu_env, cpu_tmp1_i64);
5852 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5853 s->mem_index, MO_LESW);
5854 gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32);
5859 /* XXX: the corresponding CPUID bit must be tested ! */
5862 gen_helper_fisttl_ST0(cpu_tmp2_i32, cpu_env);
5863 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5864 s->mem_index, MO_LEUL);
5867 gen_helper_fisttll_ST0(cpu_tmp1_i64, cpu_env);
5868 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0,
5869 s->mem_index, MO_LEQ);
5873 gen_helper_fistt_ST0(cpu_tmp2_i32, cpu_env);
5874 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5875 s->mem_index, MO_LEUW);
5878 gen_helper_fpop(cpu_env);
5883 gen_helper_fsts_ST0(cpu_tmp2_i32, cpu_env);
5884 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5885 s->mem_index, MO_LEUL);
5888 gen_helper_fistl_ST0(cpu_tmp2_i32, cpu_env);
5889 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5890 s->mem_index, MO_LEUL);
5893 gen_helper_fstl_ST0(cpu_tmp1_i64, cpu_env);
5894 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0,
5895 s->mem_index, MO_LEQ);
5899 gen_helper_fist_ST0(cpu_tmp2_i32, cpu_env);
5900 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5901 s->mem_index, MO_LEUW);
5905 gen_helper_fpop(cpu_env);
5909 case 0x0c: /* fldenv mem */
5910 gen_helper_fldenv(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5912 case 0x0d: /* fldcw mem */
5913 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5914 s->mem_index, MO_LEUW);
5915 gen_helper_fldcw(cpu_env, cpu_tmp2_i32);
5917 case 0x0e: /* fnstenv mem */
5918 gen_helper_fstenv(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5920 case 0x0f: /* fnstcw mem */
5921 gen_helper_fnstcw(cpu_tmp2_i32, cpu_env);
5922 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5923 s->mem_index, MO_LEUW);
5925 case 0x1d: /* fldt mem */
5926 gen_helper_fldt_ST0(cpu_env, cpu_A0);
5928 case 0x1f: /* fstpt mem */
5929 gen_helper_fstt_ST0(cpu_env, cpu_A0);
5930 gen_helper_fpop(cpu_env);
5932 case 0x2c: /* frstor mem */
5933 gen_helper_frstor(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5935 case 0x2e: /* fnsave mem */
5936 gen_helper_fsave(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5938 case 0x2f: /* fnstsw mem */
5939 gen_helper_fnstsw(cpu_tmp2_i32, cpu_env);
5940 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5941 s->mem_index, MO_LEUW);
5943 case 0x3c: /* fbld */
5944 gen_helper_fbld_ST0(cpu_env, cpu_A0);
5946 case 0x3e: /* fbstp */
5947 gen_helper_fbst_ST0(cpu_env, cpu_A0);
5948 gen_helper_fpop(cpu_env);
5950 case 0x3d: /* fildll */
5951 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
5952 gen_helper_fildll_ST0(cpu_env, cpu_tmp1_i64);
5954 case 0x3f: /* fistpll */
5955 gen_helper_fistll_ST0(cpu_tmp1_i64, cpu_env);
5956 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
5957 gen_helper_fpop(cpu_env);
5963 /* register float ops */
5967 case 0x08: /* fld sti */
5968 gen_helper_fpush(cpu_env);
5969 gen_helper_fmov_ST0_STN(cpu_env,
5970 tcg_const_i32((opreg + 1) & 7));
5972 case 0x09: /* fxchg sti */
5973 case 0x29: /* fxchg4 sti, undocumented op */
5974 case 0x39: /* fxchg7 sti, undocumented op */
5975 gen_helper_fxchg_ST0_STN(cpu_env, tcg_const_i32(opreg));
5977 case 0x0a: /* grp d9/2 */
5980 /* check exceptions (FreeBSD FPU probe) */
5981 gen_helper_fwait(cpu_env);
5987 case 0x0c: /* grp d9/4 */
5990 gen_helper_fchs_ST0(cpu_env);
5993 gen_helper_fabs_ST0(cpu_env);
5996 gen_helper_fldz_FT0(cpu_env);
5997 gen_helper_fcom_ST0_FT0(cpu_env);
6000 gen_helper_fxam_ST0(cpu_env);
6006 case 0x0d: /* grp d9/5 */
6010 gen_helper_fpush(cpu_env);
6011 gen_helper_fld1_ST0(cpu_env);
6014 gen_helper_fpush(cpu_env);
6015 gen_helper_fldl2t_ST0(cpu_env);
6018 gen_helper_fpush(cpu_env);
6019 gen_helper_fldl2e_ST0(cpu_env);
6022 gen_helper_fpush(cpu_env);
6023 gen_helper_fldpi_ST0(cpu_env);
6026 gen_helper_fpush(cpu_env);
6027 gen_helper_fldlg2_ST0(cpu_env);
6030 gen_helper_fpush(cpu_env);
6031 gen_helper_fldln2_ST0(cpu_env);
6034 gen_helper_fpush(cpu_env);
6035 gen_helper_fldz_ST0(cpu_env);
6042 case 0x0e: /* grp d9/6 */
6045 gen_helper_f2xm1(cpu_env);
6048 gen_helper_fyl2x(cpu_env);
6051 gen_helper_fptan(cpu_env);
6053 case 3: /* fpatan */
6054 gen_helper_fpatan(cpu_env);
6056 case 4: /* fxtract */
6057 gen_helper_fxtract(cpu_env);
6059 case 5: /* fprem1 */
6060 gen_helper_fprem1(cpu_env);
6062 case 6: /* fdecstp */
6063 gen_helper_fdecstp(cpu_env);
6066 case 7: /* fincstp */
6067 gen_helper_fincstp(cpu_env);
6071 case 0x0f: /* grp d9/7 */
6074 gen_helper_fprem(cpu_env);
6076 case 1: /* fyl2xp1 */
6077 gen_helper_fyl2xp1(cpu_env);
6080 gen_helper_fsqrt(cpu_env);
6082 case 3: /* fsincos */
6083 gen_helper_fsincos(cpu_env);
6085 case 5: /* fscale */
6086 gen_helper_fscale(cpu_env);
6088 case 4: /* frndint */
6089 gen_helper_frndint(cpu_env);
6092 gen_helper_fsin(cpu_env);
6096 gen_helper_fcos(cpu_env);
6100 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6101 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6102 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6108 gen_helper_fp_arith_STN_ST0(op1, opreg);
6110 gen_helper_fpop(cpu_env);
6112 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6113 gen_helper_fp_arith_ST0_FT0(op1);
6117 case 0x02: /* fcom */
6118 case 0x22: /* fcom2, undocumented op */
6119 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6120 gen_helper_fcom_ST0_FT0(cpu_env);
6122 case 0x03: /* fcomp */
6123 case 0x23: /* fcomp3, undocumented op */
6124 case 0x32: /* fcomp5, undocumented op */
6125 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6126 gen_helper_fcom_ST0_FT0(cpu_env);
6127 gen_helper_fpop(cpu_env);
6129 case 0x15: /* da/5 */
6131 case 1: /* fucompp */
6132 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
6133 gen_helper_fucom_ST0_FT0(cpu_env);
6134 gen_helper_fpop(cpu_env);
6135 gen_helper_fpop(cpu_env);
6143 case 0: /* feni (287 only, just do nop here) */
6145 case 1: /* fdisi (287 only, just do nop here) */
6148 gen_helper_fclex(cpu_env);
6150 case 3: /* fninit */
6151 gen_helper_fninit(cpu_env);
6153 case 4: /* fsetpm (287 only, just do nop here) */
6159 case 0x1d: /* fucomi */
6160 if (!(s->cpuid_features & CPUID_CMOV)) {
6163 gen_update_cc_op(s);
6164 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6165 gen_helper_fucomi_ST0_FT0(cpu_env);
6166 set_cc_op(s, CC_OP_EFLAGS);
6168 case 0x1e: /* fcomi */
6169 if (!(s->cpuid_features & CPUID_CMOV)) {
6172 gen_update_cc_op(s);
6173 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6174 gen_helper_fcomi_ST0_FT0(cpu_env);
6175 set_cc_op(s, CC_OP_EFLAGS);
6177 case 0x28: /* ffree sti */
6178 gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
6180 case 0x2a: /* fst sti */
6181 gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
6183 case 0x2b: /* fstp sti */
6184 case 0x0b: /* fstp1 sti, undocumented op */
6185 case 0x3a: /* fstp8 sti, undocumented op */
6186 case 0x3b: /* fstp9 sti, undocumented op */
6187 gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
6188 gen_helper_fpop(cpu_env);
6190 case 0x2c: /* fucom st(i) */
6191 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6192 gen_helper_fucom_ST0_FT0(cpu_env);
6194 case 0x2d: /* fucomp st(i) */
6195 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6196 gen_helper_fucom_ST0_FT0(cpu_env);
6197 gen_helper_fpop(cpu_env);
6199 case 0x33: /* de/3 */
6201 case 1: /* fcompp */
6202 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
6203 gen_helper_fcom_ST0_FT0(cpu_env);
6204 gen_helper_fpop(cpu_env);
6205 gen_helper_fpop(cpu_env);
6211 case 0x38: /* ffreep sti, undocumented op */
6212 gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
6213 gen_helper_fpop(cpu_env);
6215 case 0x3c: /* df/4 */
6218 gen_helper_fnstsw(cpu_tmp2_i32, cpu_env);
6219 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
6220 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
6226 case 0x3d: /* fucomip */
6227 if (!(s->cpuid_features & CPUID_CMOV)) {
6230 gen_update_cc_op(s);
6231 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6232 gen_helper_fucomi_ST0_FT0(cpu_env);
6233 gen_helper_fpop(cpu_env);
6234 set_cc_op(s, CC_OP_EFLAGS);
6236 case 0x3e: /* fcomip */
6237 if (!(s->cpuid_features & CPUID_CMOV)) {
6240 gen_update_cc_op(s);
6241 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6242 gen_helper_fcomi_ST0_FT0(cpu_env);
6243 gen_helper_fpop(cpu_env);
6244 set_cc_op(s, CC_OP_EFLAGS);
6246 case 0x10 ... 0x13: /* fcmovxx */
6251 static const uint8_t fcmov_cc[8] = {
6258 if (!(s->cpuid_features & CPUID_CMOV)) {
6261 op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1);
6262 l1 = gen_new_label();
6263 gen_jcc1_noeob(s, op1, l1);
6264 gen_helper_fmov_ST0_STN(cpu_env, tcg_const_i32(opreg));
6273 /************************/
6276 case 0xa4: /* movsS */
6278 ot = mo_b_d(b, dflag);
6279 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6280 gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6286 case 0xaa: /* stosS */
6288 ot = mo_b_d(b, dflag);
6289 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6290 gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6295 case 0xac: /* lodsS */
6297 ot = mo_b_d(b, dflag);
6298 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6299 gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6304 case 0xae: /* scasS */
6306 ot = mo_b_d(b, dflag);
6307 if (prefixes & PREFIX_REPNZ) {
6308 gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
6309 } else if (prefixes & PREFIX_REPZ) {
6310 gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
6316 case 0xa6: /* cmpsS */
6318 ot = mo_b_d(b, dflag);
6319 if (prefixes & PREFIX_REPNZ) {
6320 gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
6321 } else if (prefixes & PREFIX_REPZ) {
6322 gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
6327 case 0x6c: /* insS */
6329 ot = mo_b_d32(b, dflag);
6330 tcg_gen_ext16u_tl(cpu_T0, cpu_regs[R_EDX]);
6331 gen_check_io(s, ot, pc_start - s->cs_base,
6332 SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) | 4);
6333 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6334 gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6337 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6338 gen_jmp(s, s->pc - s->cs_base);
6342 case 0x6e: /* outsS */
6344 ot = mo_b_d32(b, dflag);
6345 tcg_gen_ext16u_tl(cpu_T0, cpu_regs[R_EDX]);
6346 gen_check_io(s, ot, pc_start - s->cs_base,
6347 svm_is_rep(prefixes) | 4);
6348 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6349 gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6352 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6353 gen_jmp(s, s->pc - s->cs_base);
6358 /************************/
6363 ot = mo_b_d32(b, dflag);
6364 val = x86_ldub_code(env, s);
6365 tcg_gen_movi_tl(cpu_T0, val);
6366 gen_check_io(s, ot, pc_start - s->cs_base,
6367 SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6368 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6371 tcg_gen_movi_i32(cpu_tmp2_i32, val);
6372 gen_helper_in_func(ot, cpu_T1, cpu_tmp2_i32);
6373 gen_op_mov_reg_v(ot, R_EAX, cpu_T1);
6374 gen_bpt_io(s, cpu_tmp2_i32, ot);
6375 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6377 gen_jmp(s, s->pc - s->cs_base);
6382 ot = mo_b_d32(b, dflag);
6383 val = x86_ldub_code(env, s);
6384 tcg_gen_movi_tl(cpu_T0, val);
6385 gen_check_io(s, ot, pc_start - s->cs_base,
6386 svm_is_rep(prefixes));
6387 gen_op_mov_v_reg(ot, cpu_T1, R_EAX);
6389 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6392 tcg_gen_movi_i32(cpu_tmp2_i32, val);
6393 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T1);
6394 gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6395 gen_bpt_io(s, cpu_tmp2_i32, ot);
6396 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6398 gen_jmp(s, s->pc - s->cs_base);
6403 ot = mo_b_d32(b, dflag);
6404 tcg_gen_ext16u_tl(cpu_T0, cpu_regs[R_EDX]);
6405 gen_check_io(s, ot, pc_start - s->cs_base,
6406 SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6407 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6410 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
6411 gen_helper_in_func(ot, cpu_T1, cpu_tmp2_i32);
6412 gen_op_mov_reg_v(ot, R_EAX, cpu_T1);
6413 gen_bpt_io(s, cpu_tmp2_i32, ot);
6414 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6416 gen_jmp(s, s->pc - s->cs_base);
6421 ot = mo_b_d32(b, dflag);
6422 tcg_gen_ext16u_tl(cpu_T0, cpu_regs[R_EDX]);
6423 gen_check_io(s, ot, pc_start - s->cs_base,
6424 svm_is_rep(prefixes));
6425 gen_op_mov_v_reg(ot, cpu_T1, R_EAX);
6427 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6430 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
6431 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T1);
6432 gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6433 gen_bpt_io(s, cpu_tmp2_i32, ot);
6434 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6436 gen_jmp(s, s->pc - s->cs_base);
6440 /************************/
6442 case 0xc2: /* ret im */
6443 val = x86_ldsw_code(env, s);
6445 gen_stack_update(s, val + (1 << ot));
6446 /* Note that gen_pop_T0 uses a zero-extending load. */
6447 gen_op_jmp_v(cpu_T0);
6451 case 0xc3: /* ret */
6453 gen_pop_update(s, ot);
6454 /* Note that gen_pop_T0 uses a zero-extending load. */
6455 gen_op_jmp_v(cpu_T0);
6459 case 0xca: /* lret im */
6460 val = x86_ldsw_code(env, s);
6462 if (s->pe && !s->vm86) {
6463 gen_update_cc_op(s);
6464 gen_jmp_im(pc_start - s->cs_base);
6465 gen_helper_lret_protected(cpu_env, tcg_const_i32(dflag - 1),
6466 tcg_const_i32(val));
6470 gen_op_ld_v(s, dflag, cpu_T0, cpu_A0);
6471 /* NOTE: keeping EIP updated is not a problem in case of
6473 gen_op_jmp_v(cpu_T0);
6475 gen_add_A0_im(s, 1 << dflag);
6476 gen_op_ld_v(s, dflag, cpu_T0, cpu_A0);
6477 gen_op_movl_seg_T0_vm(R_CS);
6478 /* add stack offset */
6479 gen_stack_update(s, val + (2 << dflag));
6483 case 0xcb: /* lret */
6486 case 0xcf: /* iret */
6487 gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET);
6490 gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
6491 set_cc_op(s, CC_OP_EFLAGS);
6492 } else if (s->vm86) {
6494 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6496 gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
6497 set_cc_op(s, CC_OP_EFLAGS);
6500 gen_helper_iret_protected(cpu_env, tcg_const_i32(dflag - 1),
6501 tcg_const_i32(s->pc - s->cs_base));
6502 set_cc_op(s, CC_OP_EFLAGS);
6506 case 0xe8: /* call im */
6508 if (dflag != MO_16) {
6509 tval = (int32_t)insn_get(env, s, MO_32);
6511 tval = (int16_t)insn_get(env, s, MO_16);
6513 next_eip = s->pc - s->cs_base;
6515 if (dflag == MO_16) {
6517 } else if (!CODE64(s)) {
6520 tcg_gen_movi_tl(cpu_T0, next_eip);
6521 gen_push_v(s, cpu_T0);
6526 case 0x9a: /* lcall im */
6528 unsigned int selector, offset;
6533 offset = insn_get(env, s, ot);
6534 selector = insn_get(env, s, MO_16);
6536 tcg_gen_movi_tl(cpu_T0, selector);
6537 tcg_gen_movi_tl(cpu_T1, offset);
6540 case 0xe9: /* jmp im */
6541 if (dflag != MO_16) {
6542 tval = (int32_t)insn_get(env, s, MO_32);
6544 tval = (int16_t)insn_get(env, s, MO_16);
6546 tval += s->pc - s->cs_base;
6547 if (dflag == MO_16) {
6549 } else if (!CODE64(s)) {
6555 case 0xea: /* ljmp im */
6557 unsigned int selector, offset;
6562 offset = insn_get(env, s, ot);
6563 selector = insn_get(env, s, MO_16);
6565 tcg_gen_movi_tl(cpu_T0, selector);
6566 tcg_gen_movi_tl(cpu_T1, offset);
6569 case 0xeb: /* jmp Jb */
6570 tval = (int8_t)insn_get(env, s, MO_8);
6571 tval += s->pc - s->cs_base;
6572 if (dflag == MO_16) {
6577 case 0x70 ... 0x7f: /* jcc Jb */
6578 tval = (int8_t)insn_get(env, s, MO_8);
6580 case 0x180 ... 0x18f: /* jcc Jv */
6581 if (dflag != MO_16) {
6582 tval = (int32_t)insn_get(env, s, MO_32);
6584 tval = (int16_t)insn_get(env, s, MO_16);
6587 next_eip = s->pc - s->cs_base;
6589 if (dflag == MO_16) {
6593 gen_jcc(s, b, tval, next_eip);
6596 case 0x190 ... 0x19f: /* setcc Gv */
6597 modrm = x86_ldub_code(env, s);
6598 gen_setcc1(s, b, cpu_T0);
6599 gen_ldst_modrm(env, s, modrm, MO_8, OR_TMP0, 1);
6601 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6602 if (!(s->cpuid_features & CPUID_CMOV)) {
6606 modrm = x86_ldub_code(env, s);
6607 reg = ((modrm >> 3) & 7) | rex_r;
6608 gen_cmovcc1(env, s, ot, b, modrm, reg);
6611 /************************/
6613 case 0x9c: /* pushf */
6614 gen_svm_check_intercept(s, pc_start, SVM_EXIT_PUSHF);
6615 if (s->vm86 && s->iopl != 3) {
6616 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6618 gen_update_cc_op(s);
6619 gen_helper_read_eflags(cpu_T0, cpu_env);
6620 gen_push_v(s, cpu_T0);
6623 case 0x9d: /* popf */
6624 gen_svm_check_intercept(s, pc_start, SVM_EXIT_POPF);
6625 if (s->vm86 && s->iopl != 3) {
6626 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6630 if (dflag != MO_16) {
6631 gen_helper_write_eflags(cpu_env, cpu_T0,
6632 tcg_const_i32((TF_MASK | AC_MASK |
6637 gen_helper_write_eflags(cpu_env, cpu_T0,
6638 tcg_const_i32((TF_MASK | AC_MASK |
6640 IF_MASK | IOPL_MASK)
6644 if (s->cpl <= s->iopl) {
6645 if (dflag != MO_16) {
6646 gen_helper_write_eflags(cpu_env, cpu_T0,
6647 tcg_const_i32((TF_MASK |
6653 gen_helper_write_eflags(cpu_env, cpu_T0,
6654 tcg_const_i32((TF_MASK |
6662 if (dflag != MO_16) {
6663 gen_helper_write_eflags(cpu_env, cpu_T0,
6664 tcg_const_i32((TF_MASK | AC_MASK |
6665 ID_MASK | NT_MASK)));
6667 gen_helper_write_eflags(cpu_env, cpu_T0,
6668 tcg_const_i32((TF_MASK | AC_MASK |
6674 gen_pop_update(s, ot);
6675 set_cc_op(s, CC_OP_EFLAGS);
6676 /* abort translation because TF/AC flag may change */
6677 gen_jmp_im(s->pc - s->cs_base);
6681 case 0x9e: /* sahf */
6682 if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6684 gen_op_mov_v_reg(MO_8, cpu_T0, R_AH);
6685 gen_compute_eflags(s);
6686 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O);
6687 tcg_gen_andi_tl(cpu_T0, cpu_T0, CC_S | CC_Z | CC_A | CC_P | CC_C);
6688 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_T0);
6690 case 0x9f: /* lahf */
6691 if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6693 gen_compute_eflags(s);
6694 /* Note: gen_compute_eflags() only gives the condition codes */
6695 tcg_gen_ori_tl(cpu_T0, cpu_cc_src, 0x02);
6696 gen_op_mov_reg_v(MO_8, R_AH, cpu_T0);
6698 case 0xf5: /* cmc */
6699 gen_compute_eflags(s);
6700 tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6702 case 0xf8: /* clc */
6703 gen_compute_eflags(s);
6704 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C);
6706 case 0xf9: /* stc */
6707 gen_compute_eflags(s);
6708 tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6710 case 0xfc: /* cld */
6711 tcg_gen_movi_i32(cpu_tmp2_i32, 1);
6712 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, df));
6714 case 0xfd: /* std */
6715 tcg_gen_movi_i32(cpu_tmp2_i32, -1);
6716 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, df));
6719 /************************/
6720 /* bit operations */
6721 case 0x1ba: /* bt/bts/btr/btc Gv, im */
6723 modrm = x86_ldub_code(env, s);
6724 op = (modrm >> 3) & 7;
6725 mod = (modrm >> 6) & 3;
6726 rm = (modrm & 7) | REX_B(s);
6729 gen_lea_modrm(env, s, modrm);
6730 if (!(s->prefix & PREFIX_LOCK)) {
6731 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
6734 gen_op_mov_v_reg(ot, cpu_T0, rm);
6737 val = x86_ldub_code(env, s);
6738 tcg_gen_movi_tl(cpu_T1, val);
6743 case 0x1a3: /* bt Gv, Ev */
6746 case 0x1ab: /* bts */
6749 case 0x1b3: /* btr */
6752 case 0x1bb: /* btc */
6756 modrm = x86_ldub_code(env, s);
6757 reg = ((modrm >> 3) & 7) | rex_r;
6758 mod = (modrm >> 6) & 3;
6759 rm = (modrm & 7) | REX_B(s);
6760 gen_op_mov_v_reg(MO_32, cpu_T1, reg);
6762 AddressParts a = gen_lea_modrm_0(env, s, modrm);
6763 /* specific case: we need to add a displacement */
6764 gen_exts(ot, cpu_T1);
6765 tcg_gen_sari_tl(cpu_tmp0, cpu_T1, 3 + ot);
6766 tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, ot);
6767 tcg_gen_add_tl(cpu_A0, gen_lea_modrm_1(a), cpu_tmp0);
6768 gen_lea_v_seg(s, s->aflag, cpu_A0, a.def_seg, s->override);
6769 if (!(s->prefix & PREFIX_LOCK)) {
6770 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
6773 gen_op_mov_v_reg(ot, cpu_T0, rm);
6776 tcg_gen_andi_tl(cpu_T1, cpu_T1, (1 << (3 + ot)) - 1);
6777 tcg_gen_movi_tl(cpu_tmp0, 1);
6778 tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T1);
6779 if (s->prefix & PREFIX_LOCK) {
6782 /* Needs no atomic ops; we surpressed the normal
6783 memory load for LOCK above so do it now. */
6784 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
6787 tcg_gen_atomic_fetch_or_tl(cpu_T0, cpu_A0, cpu_tmp0,
6788 s->mem_index, ot | MO_LE);
6791 tcg_gen_not_tl(cpu_tmp0, cpu_tmp0);
6792 tcg_gen_atomic_fetch_and_tl(cpu_T0, cpu_A0, cpu_tmp0,
6793 s->mem_index, ot | MO_LE);
6797 tcg_gen_atomic_fetch_xor_tl(cpu_T0, cpu_A0, cpu_tmp0,
6798 s->mem_index, ot | MO_LE);
6801 tcg_gen_shr_tl(cpu_tmp4, cpu_T0, cpu_T1);
6803 tcg_gen_shr_tl(cpu_tmp4, cpu_T0, cpu_T1);
6806 /* Data already loaded; nothing to do. */
6809 tcg_gen_or_tl(cpu_T0, cpu_T0, cpu_tmp0);
6812 tcg_gen_andc_tl(cpu_T0, cpu_T0, cpu_tmp0);
6816 tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_tmp0);
6821 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
6823 gen_op_mov_reg_v(ot, rm, cpu_T0);
6828 /* Delay all CC updates until after the store above. Note that
6829 C is the result of the test, Z is unchanged, and the others
6830 are all undefined. */
6832 case CC_OP_MULB ... CC_OP_MULQ:
6833 case CC_OP_ADDB ... CC_OP_ADDQ:
6834 case CC_OP_ADCB ... CC_OP_ADCQ:
6835 case CC_OP_SUBB ... CC_OP_SUBQ:
6836 case CC_OP_SBBB ... CC_OP_SBBQ:
6837 case CC_OP_LOGICB ... CC_OP_LOGICQ:
6838 case CC_OP_INCB ... CC_OP_INCQ:
6839 case CC_OP_DECB ... CC_OP_DECQ:
6840 case CC_OP_SHLB ... CC_OP_SHLQ:
6841 case CC_OP_SARB ... CC_OP_SARQ:
6842 case CC_OP_BMILGB ... CC_OP_BMILGQ:
6843 /* Z was going to be computed from the non-zero status of CC_DST.
6844 We can get that same Z value (and the new C value) by leaving
6845 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
6847 tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
6848 set_cc_op(s, ((s->cc_op - CC_OP_MULB) & 3) + CC_OP_SARB);
6851 /* Otherwise, generate EFLAGS and replace the C bit. */
6852 gen_compute_eflags(s);
6853 tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, cpu_tmp4,
6858 case 0x1bc: /* bsf / tzcnt */
6859 case 0x1bd: /* bsr / lzcnt */
6861 modrm = x86_ldub_code(env, s);
6862 reg = ((modrm >> 3) & 7) | rex_r;
6863 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
6864 gen_extu(ot, cpu_T0);
6866 /* Note that lzcnt and tzcnt are in different extensions. */
6867 if ((prefixes & PREFIX_REPZ)
6869 ? s->cpuid_ext3_features & CPUID_EXT3_ABM
6870 : s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)) {
6872 /* For lzcnt/tzcnt, C bit is defined related to the input. */
6873 tcg_gen_mov_tl(cpu_cc_src, cpu_T0);
6875 /* For lzcnt, reduce the target_ulong result by the
6876 number of zeros that we expect to find at the top. */
6877 tcg_gen_clzi_tl(cpu_T0, cpu_T0, TARGET_LONG_BITS);
6878 tcg_gen_subi_tl(cpu_T0, cpu_T0, TARGET_LONG_BITS - size);
6880 /* For tzcnt, a zero input must return the operand size. */
6881 tcg_gen_ctzi_tl(cpu_T0, cpu_T0, size);
6883 /* For lzcnt/tzcnt, Z bit is defined related to the result. */
6884 gen_op_update1_cc();
6885 set_cc_op(s, CC_OP_BMILGB + ot);
6887 /* For bsr/bsf, only the Z bit is defined and it is related
6888 to the input and not the result. */
6889 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
6890 set_cc_op(s, CC_OP_LOGICB + ot);
6892 /* ??? The manual says that the output is undefined when the
6893 input is zero, but real hardware leaves it unchanged, and
6894 real programs appear to depend on that. Accomplish this
6895 by passing the output as the value to return upon zero. */
6897 /* For bsr, return the bit index of the first 1 bit,
6898 not the count of leading zeros. */
6899 tcg_gen_xori_tl(cpu_T1, cpu_regs[reg], TARGET_LONG_BITS - 1);
6900 tcg_gen_clz_tl(cpu_T0, cpu_T0, cpu_T1);
6901 tcg_gen_xori_tl(cpu_T0, cpu_T0, TARGET_LONG_BITS - 1);
6903 tcg_gen_ctz_tl(cpu_T0, cpu_T0, cpu_regs[reg]);
6906 gen_op_mov_reg_v(ot, reg, cpu_T0);
6908 /************************/
6910 case 0x27: /* daa */
6913 gen_update_cc_op(s);
6914 gen_helper_daa(cpu_env);
6915 set_cc_op(s, CC_OP_EFLAGS);
6917 case 0x2f: /* das */
6920 gen_update_cc_op(s);
6921 gen_helper_das(cpu_env);
6922 set_cc_op(s, CC_OP_EFLAGS);
6924 case 0x37: /* aaa */
6927 gen_update_cc_op(s);
6928 gen_helper_aaa(cpu_env);
6929 set_cc_op(s, CC_OP_EFLAGS);
6931 case 0x3f: /* aas */
6934 gen_update_cc_op(s);
6935 gen_helper_aas(cpu_env);
6936 set_cc_op(s, CC_OP_EFLAGS);
6938 case 0xd4: /* aam */
6941 val = x86_ldub_code(env, s);
6943 gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base);
6945 gen_helper_aam(cpu_env, tcg_const_i32(val));
6946 set_cc_op(s, CC_OP_LOGICB);
6949 case 0xd5: /* aad */
6952 val = x86_ldub_code(env, s);
6953 gen_helper_aad(cpu_env, tcg_const_i32(val));
6954 set_cc_op(s, CC_OP_LOGICB);
6956 /************************/
6958 case 0x90: /* nop */
6959 /* XXX: correct lock test for all insn */
6960 if (prefixes & PREFIX_LOCK) {
6963 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
6965 goto do_xchg_reg_eax;
6967 if (prefixes & PREFIX_REPZ) {
6968 gen_update_cc_op(s);
6969 gen_jmp_im(pc_start - s->cs_base);
6970 gen_helper_pause(cpu_env, tcg_const_i32(s->pc - pc_start));
6971 s->base.is_jmp = DISAS_NORETURN;
6974 case 0x9b: /* fwait */
6975 if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
6976 (HF_MP_MASK | HF_TS_MASK)) {
6977 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
6979 gen_helper_fwait(cpu_env);
6982 case 0xcc: /* int3 */
6983 gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
6985 case 0xcd: /* int N */
6986 val = x86_ldub_code(env, s);
6987 if (s->vm86 && s->iopl != 3) {
6988 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6990 gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
6993 case 0xce: /* into */
6996 gen_update_cc_op(s);
6997 gen_jmp_im(pc_start - s->cs_base);
6998 gen_helper_into(cpu_env, tcg_const_i32(s->pc - pc_start));
7001 case 0xf1: /* icebp (undocumented, exits to external debugger) */
7002 gen_svm_check_intercept(s, pc_start, SVM_EXIT_ICEBP);
7004 gen_debug(s, pc_start - s->cs_base);
7007 tb_flush(CPU(x86_env_get_cpu(env)));
7008 qemu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM);
7012 case 0xfa: /* cli */
7014 if (s->cpl <= s->iopl) {
7015 gen_helper_cli(cpu_env);
7017 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7021 gen_helper_cli(cpu_env);
7023 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7027 case 0xfb: /* sti */
7028 if (s->vm86 ? s->iopl == 3 : s->cpl <= s->iopl) {
7029 gen_helper_sti(cpu_env);
7030 /* interruptions are enabled only the first insn after sti */
7031 gen_jmp_im(s->pc - s->cs_base);
7032 gen_eob_inhibit_irq(s, true);
7034 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7037 case 0x62: /* bound */
7041 modrm = x86_ldub_code(env, s);
7042 reg = (modrm >> 3) & 7;
7043 mod = (modrm >> 6) & 3;
7046 gen_op_mov_v_reg(ot, cpu_T0, reg);
7047 gen_lea_modrm(env, s, modrm);
7048 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
7050 gen_helper_boundw(cpu_env, cpu_A0, cpu_tmp2_i32);
7052 gen_helper_boundl(cpu_env, cpu_A0, cpu_tmp2_i32);
7055 case 0x1c8 ... 0x1cf: /* bswap reg */
7056 reg = (b & 7) | REX_B(s);
7057 #ifdef TARGET_X86_64
7058 if (dflag == MO_64) {
7059 gen_op_mov_v_reg(MO_64, cpu_T0, reg);
7060 tcg_gen_bswap64_i64(cpu_T0, cpu_T0);
7061 gen_op_mov_reg_v(MO_64, reg, cpu_T0);
7065 gen_op_mov_v_reg(MO_32, cpu_T0, reg);
7066 tcg_gen_ext32u_tl(cpu_T0, cpu_T0);
7067 tcg_gen_bswap32_tl(cpu_T0, cpu_T0);
7068 gen_op_mov_reg_v(MO_32, reg, cpu_T0);
7071 case 0xd6: /* salc */
7074 gen_compute_eflags_c(s, cpu_T0);
7075 tcg_gen_neg_tl(cpu_T0, cpu_T0);
7076 gen_op_mov_reg_v(MO_8, R_EAX, cpu_T0);
7078 case 0xe0: /* loopnz */
7079 case 0xe1: /* loopz */
7080 case 0xe2: /* loop */
7081 case 0xe3: /* jecxz */
7083 TCGLabel *l1, *l2, *l3;
7085 tval = (int8_t)insn_get(env, s, MO_8);
7086 next_eip = s->pc - s->cs_base;
7088 if (dflag == MO_16) {
7092 l1 = gen_new_label();
7093 l2 = gen_new_label();
7094 l3 = gen_new_label();
7097 case 0: /* loopnz */
7099 gen_op_add_reg_im(s->aflag, R_ECX, -1);
7100 gen_op_jz_ecx(s->aflag, l3);
7101 gen_jcc1(s, (JCC_Z << 1) | (b ^ 1), l1);
7104 gen_op_add_reg_im(s->aflag, R_ECX, -1);
7105 gen_op_jnz_ecx(s->aflag, l1);
7109 gen_op_jz_ecx(s->aflag, l1);
7114 gen_jmp_im(next_eip);
7123 case 0x130: /* wrmsr */
7124 case 0x132: /* rdmsr */
7126 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7128 gen_update_cc_op(s);
7129 gen_jmp_im(pc_start - s->cs_base);
7131 gen_helper_rdmsr(cpu_env);
7133 gen_helper_wrmsr(cpu_env);
7137 case 0x131: /* rdtsc */
7138 gen_update_cc_op(s);
7139 gen_jmp_im(pc_start - s->cs_base);
7140 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
7143 gen_helper_rdtsc(cpu_env);
7144 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
7146 gen_jmp(s, s->pc - s->cs_base);
7149 case 0x133: /* rdpmc */
7150 gen_update_cc_op(s);
7151 gen_jmp_im(pc_start - s->cs_base);
7152 gen_helper_rdpmc(cpu_env);
7154 case 0x134: /* sysenter */
7155 /* For Intel SYSENTER is valid on 64-bit */
7156 if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
7159 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7161 gen_helper_sysenter(cpu_env);
7165 case 0x135: /* sysexit */
7166 /* For Intel SYSEXIT is valid on 64-bit */
7167 if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
7170 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7172 gen_helper_sysexit(cpu_env, tcg_const_i32(dflag - 1));
7176 #ifdef TARGET_X86_64
7177 case 0x105: /* syscall */
7178 /* XXX: is it usable in real mode ? */
7179 gen_update_cc_op(s);
7180 gen_jmp_im(pc_start - s->cs_base);
7181 gen_helper_syscall(cpu_env, tcg_const_i32(s->pc - pc_start));
7182 /* TF handling for the syscall insn is different. The TF bit is checked
7183 after the syscall insn completes. This allows #DB to not be
7184 generated after one has entered CPL0 if TF is set in FMASK. */
7185 gen_eob_worker(s, false, true);
7187 case 0x107: /* sysret */
7189 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7191 gen_helper_sysret(cpu_env, tcg_const_i32(dflag - 1));
7192 /* condition codes are modified only in long mode */
7194 set_cc_op(s, CC_OP_EFLAGS);
7196 /* TF handling for the sysret insn is different. The TF bit is
7197 checked after the sysret insn completes. This allows #DB to be
7198 generated "as if" the syscall insn in userspace has just
7200 gen_eob_worker(s, false, true);
7204 case 0x1a2: /* cpuid */
7205 gen_update_cc_op(s);
7206 gen_jmp_im(pc_start - s->cs_base);
7207 gen_helper_cpuid(cpu_env);
7209 case 0xf4: /* hlt */
7211 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7213 gen_update_cc_op(s);
7214 gen_jmp_im(pc_start - s->cs_base);
7215 gen_helper_hlt(cpu_env, tcg_const_i32(s->pc - pc_start));
7216 s->base.is_jmp = DISAS_NORETURN;
7220 modrm = x86_ldub_code(env, s);
7221 mod = (modrm >> 6) & 3;
7222 op = (modrm >> 3) & 7;
7225 if (!s->pe || s->vm86)
7227 gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_READ);
7228 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
7229 offsetof(CPUX86State, ldt.selector));
7230 ot = mod == 3 ? dflag : MO_16;
7231 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7234 if (!s->pe || s->vm86)
7237 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7239 gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_WRITE);
7240 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7241 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
7242 gen_helper_lldt(cpu_env, cpu_tmp2_i32);
7246 if (!s->pe || s->vm86)
7248 gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_READ);
7249 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
7250 offsetof(CPUX86State, tr.selector));
7251 ot = mod == 3 ? dflag : MO_16;
7252 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7255 if (!s->pe || s->vm86)
7258 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7260 gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_WRITE);
7261 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7262 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
7263 gen_helper_ltr(cpu_env, cpu_tmp2_i32);
7268 if (!s->pe || s->vm86)
7270 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7271 gen_update_cc_op(s);
7273 gen_helper_verr(cpu_env, cpu_T0);
7275 gen_helper_verw(cpu_env, cpu_T0);
7277 set_cc_op(s, CC_OP_EFLAGS);
7285 modrm = x86_ldub_code(env, s);
7287 CASE_MODRM_MEM_OP(0): /* sgdt */
7288 gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_READ);
7289 gen_lea_modrm(env, s, modrm);
7290 tcg_gen_ld32u_tl(cpu_T0,
7291 cpu_env, offsetof(CPUX86State, gdt.limit));
7292 gen_op_st_v(s, MO_16, cpu_T0, cpu_A0);
7293 gen_add_A0_im(s, 2);
7294 tcg_gen_ld_tl(cpu_T0, cpu_env, offsetof(CPUX86State, gdt.base));
7295 if (dflag == MO_16) {
7296 tcg_gen_andi_tl(cpu_T0, cpu_T0, 0xffffff);
7298 gen_op_st_v(s, CODE64(s) + MO_32, cpu_T0, cpu_A0);
7301 case 0xc8: /* monitor */
7302 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || s->cpl != 0) {
7305 gen_update_cc_op(s);
7306 gen_jmp_im(pc_start - s->cs_base);
7307 tcg_gen_mov_tl(cpu_A0, cpu_regs[R_EAX]);
7308 gen_extu(s->aflag, cpu_A0);
7309 gen_add_A0_ds_seg(s);
7310 gen_helper_monitor(cpu_env, cpu_A0);
7313 case 0xc9: /* mwait */
7314 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || s->cpl != 0) {
7317 gen_update_cc_op(s);
7318 gen_jmp_im(pc_start - s->cs_base);
7319 gen_helper_mwait(cpu_env, tcg_const_i32(s->pc - pc_start));
7323 case 0xca: /* clac */
7324 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)
7328 gen_helper_clac(cpu_env);
7329 gen_jmp_im(s->pc - s->cs_base);
7333 case 0xcb: /* stac */
7334 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)
7338 gen_helper_stac(cpu_env);
7339 gen_jmp_im(s->pc - s->cs_base);
7343 CASE_MODRM_MEM_OP(1): /* sidt */
7344 gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_READ);
7345 gen_lea_modrm(env, s, modrm);
7346 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State, idt.limit));
7347 gen_op_st_v(s, MO_16, cpu_T0, cpu_A0);
7348 gen_add_A0_im(s, 2);
7349 tcg_gen_ld_tl(cpu_T0, cpu_env, offsetof(CPUX86State, idt.base));
7350 if (dflag == MO_16) {
7351 tcg_gen_andi_tl(cpu_T0, cpu_T0, 0xffffff);
7353 gen_op_st_v(s, CODE64(s) + MO_32, cpu_T0, cpu_A0);
7356 case 0xd0: /* xgetbv */
7357 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
7358 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA
7359 | PREFIX_REPZ | PREFIX_REPNZ))) {
7362 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_ECX]);
7363 gen_helper_xgetbv(cpu_tmp1_i64, cpu_env, cpu_tmp2_i32);
7364 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], cpu_tmp1_i64);
7367 case 0xd1: /* xsetbv */
7368 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
7369 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA
7370 | PREFIX_REPZ | PREFIX_REPNZ))) {
7374 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7377 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
7379 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_ECX]);
7380 gen_helper_xsetbv(cpu_env, cpu_tmp2_i32, cpu_tmp1_i64);
7381 /* End TB because translation flags may change. */
7382 gen_jmp_im(s->pc - s->cs_base);
7386 case 0xd8: /* VMRUN */
7387 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7391 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7394 gen_update_cc_op(s);
7395 gen_jmp_im(pc_start - s->cs_base);
7396 gen_helper_vmrun(cpu_env, tcg_const_i32(s->aflag - 1),
7397 tcg_const_i32(s->pc - pc_start));
7398 tcg_gen_exit_tb(NULL, 0);
7399 s->base.is_jmp = DISAS_NORETURN;
7402 case 0xd9: /* VMMCALL */
7403 if (!(s->flags & HF_SVME_MASK)) {
7406 gen_update_cc_op(s);
7407 gen_jmp_im(pc_start - s->cs_base);
7408 gen_helper_vmmcall(cpu_env);
7411 case 0xda: /* VMLOAD */
7412 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7416 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7419 gen_update_cc_op(s);
7420 gen_jmp_im(pc_start - s->cs_base);
7421 gen_helper_vmload(cpu_env, tcg_const_i32(s->aflag - 1));
7424 case 0xdb: /* VMSAVE */
7425 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7429 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7432 gen_update_cc_op(s);
7433 gen_jmp_im(pc_start - s->cs_base);
7434 gen_helper_vmsave(cpu_env, tcg_const_i32(s->aflag - 1));
7437 case 0xdc: /* STGI */
7438 if ((!(s->flags & HF_SVME_MASK)
7439 && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
7444 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7447 gen_update_cc_op(s);
7448 gen_helper_stgi(cpu_env);
7449 gen_jmp_im(s->pc - s->cs_base);
7453 case 0xdd: /* CLGI */
7454 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7458 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7461 gen_update_cc_op(s);
7462 gen_jmp_im(pc_start - s->cs_base);
7463 gen_helper_clgi(cpu_env);
7466 case 0xde: /* SKINIT */
7467 if ((!(s->flags & HF_SVME_MASK)
7468 && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
7472 gen_update_cc_op(s);
7473 gen_jmp_im(pc_start - s->cs_base);
7474 gen_helper_skinit(cpu_env);
7477 case 0xdf: /* INVLPGA */
7478 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7482 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7485 gen_update_cc_op(s);
7486 gen_jmp_im(pc_start - s->cs_base);
7487 gen_helper_invlpga(cpu_env, tcg_const_i32(s->aflag - 1));
7490 CASE_MODRM_MEM_OP(2): /* lgdt */
7492 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7495 gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_WRITE);
7496 gen_lea_modrm(env, s, modrm);
7497 gen_op_ld_v(s, MO_16, cpu_T1, cpu_A0);
7498 gen_add_A0_im(s, 2);
7499 gen_op_ld_v(s, CODE64(s) + MO_32, cpu_T0, cpu_A0);
7500 if (dflag == MO_16) {
7501 tcg_gen_andi_tl(cpu_T0, cpu_T0, 0xffffff);
7503 tcg_gen_st_tl(cpu_T0, cpu_env, offsetof(CPUX86State, gdt.base));
7504 tcg_gen_st32_tl(cpu_T1, cpu_env, offsetof(CPUX86State, gdt.limit));
7507 CASE_MODRM_MEM_OP(3): /* lidt */
7509 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7512 gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_WRITE);
7513 gen_lea_modrm(env, s, modrm);
7514 gen_op_ld_v(s, MO_16, cpu_T1, cpu_A0);
7515 gen_add_A0_im(s, 2);
7516 gen_op_ld_v(s, CODE64(s) + MO_32, cpu_T0, cpu_A0);
7517 if (dflag == MO_16) {
7518 tcg_gen_andi_tl(cpu_T0, cpu_T0, 0xffffff);
7520 tcg_gen_st_tl(cpu_T0, cpu_env, offsetof(CPUX86State, idt.base));
7521 tcg_gen_st32_tl(cpu_T1, cpu_env, offsetof(CPUX86State, idt.limit));
7524 CASE_MODRM_OP(4): /* smsw */
7525 gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0);
7526 tcg_gen_ld_tl(cpu_T0, cpu_env, offsetof(CPUX86State, cr[0]));
7528 mod = (modrm >> 6) & 3;
7529 ot = (mod != 3 ? MO_16 : s->dflag);
7533 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7535 case 0xee: /* rdpkru */
7536 if (prefixes & PREFIX_LOCK) {
7539 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_ECX]);
7540 gen_helper_rdpkru(cpu_tmp1_i64, cpu_env, cpu_tmp2_i32);
7541 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], cpu_tmp1_i64);
7543 case 0xef: /* wrpkru */
7544 if (prefixes & PREFIX_LOCK) {
7547 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
7549 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_ECX]);
7550 gen_helper_wrpkru(cpu_env, cpu_tmp2_i32, cpu_tmp1_i64);
7552 CASE_MODRM_OP(6): /* lmsw */
7554 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7557 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
7558 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7559 gen_helper_lmsw(cpu_env, cpu_T0);
7560 gen_jmp_im(s->pc - s->cs_base);
7564 CASE_MODRM_MEM_OP(7): /* invlpg */
7566 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7569 gen_update_cc_op(s);
7570 gen_jmp_im(pc_start - s->cs_base);
7571 gen_lea_modrm(env, s, modrm);
7572 gen_helper_invlpg(cpu_env, cpu_A0);
7573 gen_jmp_im(s->pc - s->cs_base);
7577 case 0xf8: /* swapgs */
7578 #ifdef TARGET_X86_64
7581 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7583 tcg_gen_mov_tl(cpu_T0, cpu_seg_base[R_GS]);
7584 tcg_gen_ld_tl(cpu_seg_base[R_GS], cpu_env,
7585 offsetof(CPUX86State, kernelgsbase));
7586 tcg_gen_st_tl(cpu_T0, cpu_env,
7587 offsetof(CPUX86State, kernelgsbase));
7594 case 0xf9: /* rdtscp */
7595 if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP)) {
7598 gen_update_cc_op(s);
7599 gen_jmp_im(pc_start - s->cs_base);
7600 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
7603 gen_helper_rdtscp(cpu_env);
7604 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
7606 gen_jmp(s, s->pc - s->cs_base);
7615 case 0x108: /* invd */
7616 case 0x109: /* wbinvd */
7618 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7620 gen_svm_check_intercept(s, pc_start, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD);
7624 case 0x63: /* arpl or movslS (x86_64) */
7625 #ifdef TARGET_X86_64
7628 /* d_ot is the size of destination */
7631 modrm = x86_ldub_code(env, s);
7632 reg = ((modrm >> 3) & 7) | rex_r;
7633 mod = (modrm >> 6) & 3;
7634 rm = (modrm & 7) | REX_B(s);
7637 gen_op_mov_v_reg(MO_32, cpu_T0, rm);
7639 if (d_ot == MO_64) {
7640 tcg_gen_ext32s_tl(cpu_T0, cpu_T0);
7642 gen_op_mov_reg_v(d_ot, reg, cpu_T0);
7644 gen_lea_modrm(env, s, modrm);
7645 gen_op_ld_v(s, MO_32 | MO_SIGN, cpu_T0, cpu_A0);
7646 gen_op_mov_reg_v(d_ot, reg, cpu_T0);
7652 TCGv t0, t1, t2, a0;
7654 if (!s->pe || s->vm86)
7656 t0 = tcg_temp_local_new();
7657 t1 = tcg_temp_local_new();
7658 t2 = tcg_temp_local_new();
7660 modrm = x86_ldub_code(env, s);
7661 reg = (modrm >> 3) & 7;
7662 mod = (modrm >> 6) & 3;
7665 gen_lea_modrm(env, s, modrm);
7666 gen_op_ld_v(s, ot, t0, cpu_A0);
7667 a0 = tcg_temp_local_new();
7668 tcg_gen_mov_tl(a0, cpu_A0);
7670 gen_op_mov_v_reg(ot, t0, rm);
7673 gen_op_mov_v_reg(ot, t1, reg);
7674 tcg_gen_andi_tl(cpu_tmp0, t0, 3);
7675 tcg_gen_andi_tl(t1, t1, 3);
7676 tcg_gen_movi_tl(t2, 0);
7677 label1 = gen_new_label();
7678 tcg_gen_brcond_tl(TCG_COND_GE, cpu_tmp0, t1, label1);
7679 tcg_gen_andi_tl(t0, t0, ~3);
7680 tcg_gen_or_tl(t0, t0, t1);
7681 tcg_gen_movi_tl(t2, CC_Z);
7682 gen_set_label(label1);
7684 gen_op_st_v(s, ot, t0, a0);
7687 gen_op_mov_reg_v(ot, rm, t0);
7689 gen_compute_eflags(s);
7690 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z);
7691 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t2);
7697 case 0x102: /* lar */
7698 case 0x103: /* lsl */
7702 if (!s->pe || s->vm86)
7704 ot = dflag != MO_16 ? MO_32 : MO_16;
7705 modrm = x86_ldub_code(env, s);
7706 reg = ((modrm >> 3) & 7) | rex_r;
7707 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7708 t0 = tcg_temp_local_new();
7709 gen_update_cc_op(s);
7711 gen_helper_lar(t0, cpu_env, cpu_T0);
7713 gen_helper_lsl(t0, cpu_env, cpu_T0);
7715 tcg_gen_andi_tl(cpu_tmp0, cpu_cc_src, CC_Z);
7716 label1 = gen_new_label();
7717 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
7718 gen_op_mov_reg_v(ot, reg, t0);
7719 gen_set_label(label1);
7720 set_cc_op(s, CC_OP_EFLAGS);
7725 modrm = x86_ldub_code(env, s);
7726 mod = (modrm >> 6) & 3;
7727 op = (modrm >> 3) & 7;
7729 case 0: /* prefetchnta */
7730 case 1: /* prefetchnt0 */
7731 case 2: /* prefetchnt0 */
7732 case 3: /* prefetchnt0 */
7735 gen_nop_modrm(env, s, modrm);
7736 /* nothing more to do */
7738 default: /* nop (multi byte) */
7739 gen_nop_modrm(env, s, modrm);
7744 modrm = x86_ldub_code(env, s);
7745 if (s->flags & HF_MPX_EN_MASK) {
7746 mod = (modrm >> 6) & 3;
7747 reg = ((modrm >> 3) & 7) | rex_r;
7748 if (prefixes & PREFIX_REPZ) {
7751 || (prefixes & PREFIX_LOCK)
7752 || s->aflag == MO_16) {
7755 gen_bndck(env, s, modrm, TCG_COND_LTU, cpu_bndl[reg]);
7756 } else if (prefixes & PREFIX_REPNZ) {
7759 || (prefixes & PREFIX_LOCK)
7760 || s->aflag == MO_16) {
7763 TCGv_i64 notu = tcg_temp_new_i64();
7764 tcg_gen_not_i64(notu, cpu_bndu[reg]);
7765 gen_bndck(env, s, modrm, TCG_COND_GTU, notu);
7766 tcg_temp_free_i64(notu);
7767 } else if (prefixes & PREFIX_DATA) {
7768 /* bndmov -- from reg/mem */
7769 if (reg >= 4 || s->aflag == MO_16) {
7773 int reg2 = (modrm & 7) | REX_B(s);
7774 if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) {
7777 if (s->flags & HF_MPX_IU_MASK) {
7778 tcg_gen_mov_i64(cpu_bndl[reg], cpu_bndl[reg2]);
7779 tcg_gen_mov_i64(cpu_bndu[reg], cpu_bndu[reg2]);
7782 gen_lea_modrm(env, s, modrm);
7784 tcg_gen_qemu_ld_i64(cpu_bndl[reg], cpu_A0,
7785 s->mem_index, MO_LEQ);
7786 tcg_gen_addi_tl(cpu_A0, cpu_A0, 8);
7787 tcg_gen_qemu_ld_i64(cpu_bndu[reg], cpu_A0,
7788 s->mem_index, MO_LEQ);
7790 tcg_gen_qemu_ld_i64(cpu_bndl[reg], cpu_A0,
7791 s->mem_index, MO_LEUL);
7792 tcg_gen_addi_tl(cpu_A0, cpu_A0, 4);
7793 tcg_gen_qemu_ld_i64(cpu_bndu[reg], cpu_A0,
7794 s->mem_index, MO_LEUL);
7796 /* bnd registers are now in-use */
7797 gen_set_hflag(s, HF_MPX_IU_MASK);
7799 } else if (mod != 3) {
7801 AddressParts a = gen_lea_modrm_0(env, s, modrm);
7803 || (prefixes & PREFIX_LOCK)
7804 || s->aflag == MO_16
7809 tcg_gen_addi_tl(cpu_A0, cpu_regs[a.base], a.disp);
7811 tcg_gen_movi_tl(cpu_A0, 0);
7813 gen_lea_v_seg(s, s->aflag, cpu_A0, a.def_seg, s->override);
7815 tcg_gen_mov_tl(cpu_T0, cpu_regs[a.index]);
7817 tcg_gen_movi_tl(cpu_T0, 0);
7820 gen_helper_bndldx64(cpu_bndl[reg], cpu_env, cpu_A0, cpu_T0);
7821 tcg_gen_ld_i64(cpu_bndu[reg], cpu_env,
7822 offsetof(CPUX86State, mmx_t0.MMX_Q(0)));
7824 gen_helper_bndldx32(cpu_bndu[reg], cpu_env, cpu_A0, cpu_T0);
7825 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndu[reg]);
7826 tcg_gen_shri_i64(cpu_bndu[reg], cpu_bndu[reg], 32);
7828 gen_set_hflag(s, HF_MPX_IU_MASK);
7831 gen_nop_modrm(env, s, modrm);
7834 modrm = x86_ldub_code(env, s);
7835 if (s->flags & HF_MPX_EN_MASK) {
7836 mod = (modrm >> 6) & 3;
7837 reg = ((modrm >> 3) & 7) | rex_r;
7838 if (mod != 3 && (prefixes & PREFIX_REPZ)) {
7841 || (prefixes & PREFIX_LOCK)
7842 || s->aflag == MO_16) {
7845 AddressParts a = gen_lea_modrm_0(env, s, modrm);
7847 tcg_gen_extu_tl_i64(cpu_bndl[reg], cpu_regs[a.base]);
7849 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndl[reg]);
7851 } else if (a.base == -1) {
7852 /* no base register has lower bound of 0 */
7853 tcg_gen_movi_i64(cpu_bndl[reg], 0);
7855 /* rip-relative generates #ud */
7858 tcg_gen_not_tl(cpu_A0, gen_lea_modrm_1(a));
7860 tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
7862 tcg_gen_extu_tl_i64(cpu_bndu[reg], cpu_A0);
7863 /* bnd registers are now in-use */
7864 gen_set_hflag(s, HF_MPX_IU_MASK);
7866 } else if (prefixes & PREFIX_REPNZ) {
7869 || (prefixes & PREFIX_LOCK)
7870 || s->aflag == MO_16) {
7873 gen_bndck(env, s, modrm, TCG_COND_GTU, cpu_bndu[reg]);
7874 } else if (prefixes & PREFIX_DATA) {
7875 /* bndmov -- to reg/mem */
7876 if (reg >= 4 || s->aflag == MO_16) {
7880 int reg2 = (modrm & 7) | REX_B(s);
7881 if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) {
7884 if (s->flags & HF_MPX_IU_MASK) {
7885 tcg_gen_mov_i64(cpu_bndl[reg2], cpu_bndl[reg]);
7886 tcg_gen_mov_i64(cpu_bndu[reg2], cpu_bndu[reg]);
7889 gen_lea_modrm(env, s, modrm);
7891 tcg_gen_qemu_st_i64(cpu_bndl[reg], cpu_A0,
7892 s->mem_index, MO_LEQ);
7893 tcg_gen_addi_tl(cpu_A0, cpu_A0, 8);
7894 tcg_gen_qemu_st_i64(cpu_bndu[reg], cpu_A0,
7895 s->mem_index, MO_LEQ);
7897 tcg_gen_qemu_st_i64(cpu_bndl[reg], cpu_A0,
7898 s->mem_index, MO_LEUL);
7899 tcg_gen_addi_tl(cpu_A0, cpu_A0, 4);
7900 tcg_gen_qemu_st_i64(cpu_bndu[reg], cpu_A0,
7901 s->mem_index, MO_LEUL);
7904 } else if (mod != 3) {
7906 AddressParts a = gen_lea_modrm_0(env, s, modrm);
7908 || (prefixes & PREFIX_LOCK)
7909 || s->aflag == MO_16
7914 tcg_gen_addi_tl(cpu_A0, cpu_regs[a.base], a.disp);
7916 tcg_gen_movi_tl(cpu_A0, 0);
7918 gen_lea_v_seg(s, s->aflag, cpu_A0, a.def_seg, s->override);
7920 tcg_gen_mov_tl(cpu_T0, cpu_regs[a.index]);
7922 tcg_gen_movi_tl(cpu_T0, 0);
7925 gen_helper_bndstx64(cpu_env, cpu_A0, cpu_T0,
7926 cpu_bndl[reg], cpu_bndu[reg]);
7928 gen_helper_bndstx32(cpu_env, cpu_A0, cpu_T0,
7929 cpu_bndl[reg], cpu_bndu[reg]);
7933 gen_nop_modrm(env, s, modrm);
7935 case 0x119: case 0x11c ... 0x11f: /* nop (multi byte) */
7936 modrm = x86_ldub_code(env, s);
7937 gen_nop_modrm(env, s, modrm);
7939 case 0x120: /* mov reg, crN */
7940 case 0x122: /* mov crN, reg */
7942 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7944 modrm = x86_ldub_code(env, s);
7945 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7946 * AMD documentation (24594.pdf) and testing of
7947 * intel 386 and 486 processors all show that the mod bits
7948 * are assumed to be 1's, regardless of actual values.
7950 rm = (modrm & 7) | REX_B(s);
7951 reg = ((modrm >> 3) & 7) | rex_r;
7956 if ((prefixes & PREFIX_LOCK) && (reg == 0) &&
7957 (s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) {
7966 gen_update_cc_op(s);
7967 gen_jmp_im(pc_start - s->cs_base);
7969 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
7972 gen_op_mov_v_reg(ot, cpu_T0, rm);
7973 gen_helper_write_crN(cpu_env, tcg_const_i32(reg),
7975 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
7978 gen_jmp_im(s->pc - s->cs_base);
7981 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
7984 gen_helper_read_crN(cpu_T0, cpu_env, tcg_const_i32(reg));
7985 gen_op_mov_reg_v(ot, rm, cpu_T0);
7986 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
7996 case 0x121: /* mov reg, drN */
7997 case 0x123: /* mov drN, reg */
7999 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
8001 modrm = x86_ldub_code(env, s);
8002 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
8003 * AMD documentation (24594.pdf) and testing of
8004 * intel 386 and 486 processors all show that the mod bits
8005 * are assumed to be 1's, regardless of actual values.
8007 rm = (modrm & 7) | REX_B(s);
8008 reg = ((modrm >> 3) & 7) | rex_r;
8017 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
8018 gen_op_mov_v_reg(ot, cpu_T0, rm);
8019 tcg_gen_movi_i32(cpu_tmp2_i32, reg);
8020 gen_helper_set_dr(cpu_env, cpu_tmp2_i32, cpu_T0);
8021 gen_jmp_im(s->pc - s->cs_base);
8024 gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_DR0 + reg);
8025 tcg_gen_movi_i32(cpu_tmp2_i32, reg);
8026 gen_helper_get_dr(cpu_T0, cpu_env, cpu_tmp2_i32);
8027 gen_op_mov_reg_v(ot, rm, cpu_T0);
8031 case 0x106: /* clts */
8033 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
8035 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
8036 gen_helper_clts(cpu_env);
8037 /* abort block because static cpu state changed */
8038 gen_jmp_im(s->pc - s->cs_base);
8042 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
8043 case 0x1c3: /* MOVNTI reg, mem */
8044 if (!(s->cpuid_features & CPUID_SSE2))
8046 ot = mo_64_32(dflag);
8047 modrm = x86_ldub_code(env, s);
8048 mod = (modrm >> 6) & 3;
8051 reg = ((modrm >> 3) & 7) | rex_r;
8052 /* generate a generic store */
8053 gen_ldst_modrm(env, s, modrm, ot, reg, 1);
8056 modrm = x86_ldub_code(env, s);
8058 CASE_MODRM_MEM_OP(0): /* fxsave */
8059 if (!(s->cpuid_features & CPUID_FXSR)
8060 || (prefixes & PREFIX_LOCK)) {
8063 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
8064 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
8067 gen_lea_modrm(env, s, modrm);
8068 gen_helper_fxsave(cpu_env, cpu_A0);
8071 CASE_MODRM_MEM_OP(1): /* fxrstor */
8072 if (!(s->cpuid_features & CPUID_FXSR)
8073 || (prefixes & PREFIX_LOCK)) {
8076 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
8077 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
8080 gen_lea_modrm(env, s, modrm);
8081 gen_helper_fxrstor(cpu_env, cpu_A0);
8084 CASE_MODRM_MEM_OP(2): /* ldmxcsr */
8085 if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) {
8088 if (s->flags & HF_TS_MASK) {
8089 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
8092 gen_lea_modrm(env, s, modrm);
8093 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0, s->mem_index, MO_LEUL);
8094 gen_helper_ldmxcsr(cpu_env, cpu_tmp2_i32);
8097 CASE_MODRM_MEM_OP(3): /* stmxcsr */
8098 if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) {
8101 if (s->flags & HF_TS_MASK) {
8102 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
8105 gen_lea_modrm(env, s, modrm);
8106 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State, mxcsr));
8107 gen_op_st_v(s, MO_32, cpu_T0, cpu_A0);
8110 CASE_MODRM_MEM_OP(4): /* xsave */
8111 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
8112 || (prefixes & (PREFIX_LOCK | PREFIX_DATA
8113 | PREFIX_REPZ | PREFIX_REPNZ))) {
8116 gen_lea_modrm(env, s, modrm);
8117 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
8119 gen_helper_xsave(cpu_env, cpu_A0, cpu_tmp1_i64);
8122 CASE_MODRM_MEM_OP(5): /* xrstor */
8123 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
8124 || (prefixes & (PREFIX_LOCK | PREFIX_DATA
8125 | PREFIX_REPZ | PREFIX_REPNZ))) {
8128 gen_lea_modrm(env, s, modrm);
8129 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
8131 gen_helper_xrstor(cpu_env, cpu_A0, cpu_tmp1_i64);
8132 /* XRSTOR is how MPX is enabled, which changes how
8133 we translate. Thus we need to end the TB. */
8134 gen_update_cc_op(s);
8135 gen_jmp_im(s->pc - s->cs_base);
8139 CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */
8140 if (prefixes & PREFIX_LOCK) {
8143 if (prefixes & PREFIX_DATA) {
8145 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLWB)) {
8148 gen_nop_modrm(env, s, modrm);
8151 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
8152 || (s->cpuid_xsave_features & CPUID_XSAVE_XSAVEOPT) == 0
8153 || (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))) {
8156 gen_lea_modrm(env, s, modrm);
8157 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
8159 gen_helper_xsaveopt(cpu_env, cpu_A0, cpu_tmp1_i64);
8163 CASE_MODRM_MEM_OP(7): /* clflush / clflushopt */
8164 if (prefixes & PREFIX_LOCK) {
8167 if (prefixes & PREFIX_DATA) {
8169 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLFLUSHOPT)) {
8174 if ((s->prefix & (PREFIX_REPZ | PREFIX_REPNZ))
8175 || !(s->cpuid_features & CPUID_CLFLUSH)) {
8179 gen_nop_modrm(env, s, modrm);
8182 case 0xc0 ... 0xc7: /* rdfsbase (f3 0f ae /0) */
8183 case 0xc8 ... 0xcf: /* rdgsbase (f3 0f ae /1) */
8184 case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */
8185 case 0xd8 ... 0xdf: /* wrgsbase (f3 0f ae /3) */
8187 && (prefixes & PREFIX_REPZ)
8188 && !(prefixes & PREFIX_LOCK)
8189 && (s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_FSGSBASE)) {
8190 TCGv base, treg, src, dst;
8192 /* Preserve hflags bits by testing CR4 at runtime. */
8193 tcg_gen_movi_i32(cpu_tmp2_i32, CR4_FSGSBASE_MASK);
8194 gen_helper_cr4_testbit(cpu_env, cpu_tmp2_i32);
8196 base = cpu_seg_base[modrm & 8 ? R_GS : R_FS];
8197 treg = cpu_regs[(modrm & 7) | REX_B(s)];
8201 dst = base, src = treg;
8204 dst = treg, src = base;
8207 if (s->dflag == MO_32) {
8208 tcg_gen_ext32u_tl(dst, src);
8210 tcg_gen_mov_tl(dst, src);
8216 case 0xf8: /* sfence / pcommit */
8217 if (prefixes & PREFIX_DATA) {
8219 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_PCOMMIT)
8220 || (prefixes & PREFIX_LOCK)) {
8226 case 0xf9 ... 0xff: /* sfence */
8227 if (!(s->cpuid_features & CPUID_SSE)
8228 || (prefixes & PREFIX_LOCK)) {
8231 tcg_gen_mb(TCG_MO_ST_ST | TCG_BAR_SC);
8233 case 0xe8 ... 0xef: /* lfence */
8234 if (!(s->cpuid_features & CPUID_SSE)
8235 || (prefixes & PREFIX_LOCK)) {
8238 tcg_gen_mb(TCG_MO_LD_LD | TCG_BAR_SC);
8240 case 0xf0 ... 0xf7: /* mfence */
8241 if (!(s->cpuid_features & CPUID_SSE2)
8242 || (prefixes & PREFIX_LOCK)) {
8245 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8253 case 0x10d: /* 3DNow! prefetch(w) */
8254 modrm = x86_ldub_code(env, s);
8255 mod = (modrm >> 6) & 3;
8258 gen_nop_modrm(env, s, modrm);
8260 case 0x1aa: /* rsm */
8261 gen_svm_check_intercept(s, pc_start, SVM_EXIT_RSM);
8262 if (!(s->flags & HF_SMM_MASK))
8264 gen_update_cc_op(s);
8265 gen_jmp_im(s->pc - s->cs_base);
8266 gen_helper_rsm(cpu_env);
8269 case 0x1b8: /* SSE4.2 popcnt */
8270 if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) !=
8273 if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT))
8276 modrm = x86_ldub_code(env, s);
8277 reg = ((modrm >> 3) & 7) | rex_r;
8279 if (s->prefix & PREFIX_DATA) {
8282 ot = mo_64_32(dflag);
8285 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
8286 gen_extu(ot, cpu_T0);
8287 tcg_gen_mov_tl(cpu_cc_src, cpu_T0);
8288 tcg_gen_ctpop_tl(cpu_T0, cpu_T0);
8289 gen_op_mov_reg_v(ot, reg, cpu_T0);
8291 set_cc_op(s, CC_OP_POPCNT);
8293 case 0x10e ... 0x10f:
8294 /* 3DNow! instructions, ignore prefixes */
8295 s->prefix &= ~(PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA);
8297 case 0x110 ... 0x117:
8298 case 0x128 ... 0x12f:
8299 case 0x138 ... 0x13a:
8300 case 0x150 ... 0x179:
8301 case 0x17c ... 0x17f:
8303 case 0x1c4 ... 0x1c6:
8304 case 0x1d0 ... 0x1fe:
8305 gen_sse(env, s, b, pc_start, rex_r);
8312 gen_illegal_opcode(s);
8315 gen_unknown_opcode(env, s);
8319 void tcg_x86_init(void)
8321 static const char reg_names[CPU_NB_REGS][4] = {
8322 #ifdef TARGET_X86_64
8350 static const char seg_base_names[6][8] = {
8358 static const char bnd_regl_names[4][8] = {
8359 "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb"
8361 static const char bnd_regu_names[4][8] = {
8362 "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub"
8366 cpu_cc_op = tcg_global_mem_new_i32(cpu_env,
8367 offsetof(CPUX86State, cc_op), "cc_op");
8368 cpu_cc_dst = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_dst),
8370 cpu_cc_src = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src),
8372 cpu_cc_src2 = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src2),
8375 for (i = 0; i < CPU_NB_REGS; ++i) {
8376 cpu_regs[i] = tcg_global_mem_new(cpu_env,
8377 offsetof(CPUX86State, regs[i]),
8381 for (i = 0; i < 6; ++i) {
8383 = tcg_global_mem_new(cpu_env,
8384 offsetof(CPUX86State, segs[i].base),
8388 for (i = 0; i < 4; ++i) {
8390 = tcg_global_mem_new_i64(cpu_env,
8391 offsetof(CPUX86State, bnd_regs[i].lb),
8394 = tcg_global_mem_new_i64(cpu_env,
8395 offsetof(CPUX86State, bnd_regs[i].ub),
8400 static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
8402 DisasContext *dc = container_of(dcbase, DisasContext, base);
8403 CPUX86State *env = cpu->env_ptr;
8404 uint32_t flags = dc->base.tb->flags;
8405 target_ulong cs_base = dc->base.tb->cs_base;
8407 dc->pe = (flags >> HF_PE_SHIFT) & 1;
8408 dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
8409 dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
8410 dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
8412 dc->vm86 = (flags >> VM_SHIFT) & 1;
8413 dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
8414 dc->iopl = (flags >> IOPL_SHIFT) & 3;
8415 dc->tf = (flags >> TF_SHIFT) & 1;
8416 dc->cc_op = CC_OP_DYNAMIC;
8417 dc->cc_op_dirty = false;
8418 dc->cs_base = cs_base;
8419 dc->popl_esp_hack = 0;
8420 /* select memory access functions */
8422 #ifdef CONFIG_SOFTMMU
8423 dc->mem_index = cpu_mmu_index(env, false);
8425 dc->cpuid_features = env->features[FEAT_1_EDX];
8426 dc->cpuid_ext_features = env->features[FEAT_1_ECX];
8427 dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX];
8428 dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX];
8429 dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX];
8430 dc->cpuid_xsave_features = env->features[FEAT_XSAVE];
8431 #ifdef TARGET_X86_64
8432 dc->lma = (flags >> HF_LMA_SHIFT) & 1;
8433 dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
8436 dc->jmp_opt = !(dc->tf || dc->base.singlestep_enabled ||
8437 (flags & HF_INHIBIT_IRQ_MASK));
8438 /* Do not optimize repz jumps at all in icount mode, because
8439 rep movsS instructions are execured with different paths
8440 in !repz_opt and repz_opt modes. The first one was used
8441 always except single step mode. And this setting
8442 disables jumps optimization and control paths become
8443 equivalent in run and single step modes.
8444 Now there will be no jump optimization for repz in
8445 record/replay modes and there will always be an
8446 additional step for ecx=0 when icount is enabled.
8448 dc->repz_opt = !dc->jmp_opt && !(tb_cflags(dc->base.tb) & CF_USE_ICOUNT);
8450 /* check addseg logic */
8451 if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
8452 printf("ERROR addseg\n");
8455 cpu_T0 = tcg_temp_new();
8456 cpu_T1 = tcg_temp_new();
8457 cpu_A0 = tcg_temp_new();
8459 cpu_tmp0 = tcg_temp_new();
8460 cpu_tmp1_i64 = tcg_temp_new_i64();
8461 cpu_tmp2_i32 = tcg_temp_new_i32();
8462 cpu_tmp3_i32 = tcg_temp_new_i32();
8463 cpu_tmp4 = tcg_temp_new();
8464 cpu_ptr0 = tcg_temp_new_ptr();
8465 cpu_ptr1 = tcg_temp_new_ptr();
8466 cpu_cc_srcT = tcg_temp_local_new();
8469 static void i386_tr_tb_start(DisasContextBase *db, CPUState *cpu)
8473 static void i386_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
8475 DisasContext *dc = container_of(dcbase, DisasContext, base);
8477 tcg_gen_insn_start(dc->base.pc_next, dc->cc_op);
8480 static bool i386_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
8481 const CPUBreakpoint *bp)
8483 DisasContext *dc = container_of(dcbase, DisasContext, base);
8484 /* If RF is set, suppress an internally generated breakpoint. */
8485 int flags = dc->base.tb->flags & HF_RF_MASK ? BP_GDB : BP_ANY;
8486 if (bp->flags & flags) {
8487 gen_debug(dc, dc->base.pc_next - dc->cs_base);
8488 dc->base.is_jmp = DISAS_NORETURN;
8489 /* The address covered by the breakpoint must be included in
8490 [tb->pc, tb->pc + tb->size) in order to for it to be
8491 properly cleared -- thus we increment the PC here so that
8492 the generic logic setting tb->size later does the right thing. */
8493 dc->base.pc_next += 1;
8500 static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
8502 DisasContext *dc = container_of(dcbase, DisasContext, base);
8503 target_ulong pc_next = disas_insn(dc, cpu);
8505 if (dc->tf || (dc->base.tb->flags & HF_INHIBIT_IRQ_MASK)) {
8506 /* if single step mode, we generate only one instruction and
8507 generate an exception */
8508 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
8509 the flag and abort the translation to give the irqs a
8511 dc->base.is_jmp = DISAS_TOO_MANY;
8512 } else if ((tb_cflags(dc->base.tb) & CF_USE_ICOUNT)
8513 && ((dc->base.pc_next & TARGET_PAGE_MASK)
8514 != ((dc->base.pc_next + TARGET_MAX_INSN_SIZE - 1)
8516 || (dc->base.pc_next & ~TARGET_PAGE_MASK) == 0)) {
8517 /* Do not cross the boundary of the pages in icount mode,
8518 it can cause an exception. Do it only when boundary is
8519 crossed by the first instruction in the block.
8520 If current instruction already crossed the bound - it's ok,
8521 because an exception hasn't stopped this code.
8523 dc->base.is_jmp = DISAS_TOO_MANY;
8524 } else if ((pc_next - dc->base.pc_first) >= (TARGET_PAGE_SIZE - 32)) {
8525 dc->base.is_jmp = DISAS_TOO_MANY;
8528 dc->base.pc_next = pc_next;
8531 static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
8533 DisasContext *dc = container_of(dcbase, DisasContext, base);
8535 if (dc->base.is_jmp == DISAS_TOO_MANY) {
8536 gen_jmp_im(dc->base.pc_next - dc->cs_base);
8541 static void i386_tr_disas_log(const DisasContextBase *dcbase,
8544 DisasContext *dc = container_of(dcbase, DisasContext, base);
8546 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
8547 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
8550 static const TranslatorOps i386_tr_ops = {
8551 .init_disas_context = i386_tr_init_disas_context,
8552 .tb_start = i386_tr_tb_start,
8553 .insn_start = i386_tr_insn_start,
8554 .breakpoint_check = i386_tr_breakpoint_check,
8555 .translate_insn = i386_tr_translate_insn,
8556 .tb_stop = i386_tr_tb_stop,
8557 .disas_log = i386_tr_disas_log,
8560 /* generate intermediate code for basic block 'tb'. */
8561 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
8565 translator_loop(&i386_tr_ops, &dc.base, cpu, tb);
8568 void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb,
8571 int cc_op = data[1];
8572 env->eip = data[0] - tb->cs_base;
8573 if (cc_op != CC_OP_DYNAMIC) {