4 * Copyright (c) 2003 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 #include "qemu/osdep.h"
21 #include "qemu/host-utils.h"
23 #include "disas/disas.h"
24 #include "exec/exec-all.h"
26 #include "exec/cpu_ldst.h"
28 #include "exec/helper-proto.h"
29 #include "exec/helper-gen.h"
31 #include "trace-tcg.h"
34 #include "sysemu/hax.h"
36 #define PREFIX_REPZ 0x01
37 #define PREFIX_REPNZ 0x02
38 #define PREFIX_LOCK 0x04
39 #define PREFIX_DATA 0x08
40 #define PREFIX_ADR 0x10
41 #define PREFIX_VEX 0x20
44 #define CODE64(s) ((s)->code64)
45 #define REX_X(s) ((s)->rex_x)
46 #define REX_B(s) ((s)->rex_b)
61 /* For a switch indexed by MODRM, match all memory operands for a given OP. */
62 #define CASE_MODRM_MEM_OP(OP) \
63 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
64 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
65 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7
67 #define CASE_MODRM_OP(OP) \
68 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
69 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
70 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7: \
71 case (3 << 6) | (OP << 3) | 0 ... (3 << 6) | (OP << 3) | 7
73 //#define MACRO_TEST 1
75 /* global register indexes */
76 static TCGv_env cpu_env;
78 static TCGv cpu_cc_dst, cpu_cc_src, cpu_cc_src2, cpu_cc_srcT;
79 static TCGv_i32 cpu_cc_op;
80 static TCGv cpu_regs[CPU_NB_REGS];
81 static TCGv cpu_seg_base[6];
82 static TCGv_i64 cpu_bndl[4];
83 static TCGv_i64 cpu_bndu[4];
85 static TCGv cpu_T0, cpu_T1;
86 /* local register indexes (only used inside old micro ops) */
87 static TCGv cpu_tmp0, cpu_tmp4;
88 static TCGv_ptr cpu_ptr0, cpu_ptr1;
89 static TCGv_i32 cpu_tmp2_i32, cpu_tmp3_i32;
90 static TCGv_i64 cpu_tmp1_i64;
92 #include "exec/gen-icount.h"
95 static int x86_64_hregs;
98 typedef struct DisasContext {
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 int is_jmp; /* 1 = means jump (stop translation), 2 means CPU
107 static state change (stop translation) */
108 /* current block context */
109 target_ulong cs_base; /* base of CS segment */
110 int pe; /* protected mode */
111 int code32; /* 32 bit code segment */
113 int lma; /* long mode active */
114 int code64; /* 64 bit code segment */
117 int vex_l; /* vex vector length */
118 int vex_v; /* vex vvvv register, without 1's compliment. */
119 int ss32; /* 32 bit stack segment */
120 CCOp cc_op; /* current CC operation */
122 int addseg; /* non zero if either DS/ES/SS have a non zero base */
123 int f_st; /* currently unused */
124 int vm86; /* vm86 mode */
127 int tf; /* TF cpu flag */
128 int singlestep_enabled; /* "hardware" single step enabled */
129 int jmp_opt; /* use direct block chaining for direct jumps */
130 int repz_opt; /* optimize jumps within repz instructions */
131 int mem_index; /* select memory access functions */
132 uint64_t flags; /* all execution flags */
133 struct TranslationBlock *tb;
134 int popl_esp_hack; /* for correct popl with esp base handling */
135 int rip_offset; /* only used in x86_64, but left for simplicity */
137 int cpuid_ext_features;
138 int cpuid_ext2_features;
139 int cpuid_ext3_features;
140 int cpuid_7_0_ebx_features;
141 int cpuid_xsave_features;
144 static void gen_eob(DisasContext *s);
145 static void gen_jmp(DisasContext *s, target_ulong eip);
146 static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num);
147 static void gen_op(DisasContext *s1, int op, TCGMemOp ot, int d);
149 /* i386 arith/logic operations */
169 OP_SHL1, /* undocumented */
185 /* I386 int registers */
186 OR_EAX, /* MUST be even numbered */
195 OR_TMP0 = 16, /* temporary operand register */
197 OR_A0, /* temporary register used when doing address evaluation */
207 /* Bit set if the global variable is live after setting CC_OP to X. */
208 static const uint8_t cc_op_live[CC_OP_NB] = {
209 [CC_OP_DYNAMIC] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
210 [CC_OP_EFLAGS] = USES_CC_SRC,
211 [CC_OP_MULB ... CC_OP_MULQ] = USES_CC_DST | USES_CC_SRC,
212 [CC_OP_ADDB ... CC_OP_ADDQ] = USES_CC_DST | USES_CC_SRC,
213 [CC_OP_ADCB ... CC_OP_ADCQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
214 [CC_OP_SUBB ... CC_OP_SUBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRCT,
215 [CC_OP_SBBB ... CC_OP_SBBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
216 [CC_OP_LOGICB ... CC_OP_LOGICQ] = USES_CC_DST,
217 [CC_OP_INCB ... CC_OP_INCQ] = USES_CC_DST | USES_CC_SRC,
218 [CC_OP_DECB ... CC_OP_DECQ] = USES_CC_DST | USES_CC_SRC,
219 [CC_OP_SHLB ... CC_OP_SHLQ] = USES_CC_DST | USES_CC_SRC,
220 [CC_OP_SARB ... CC_OP_SARQ] = USES_CC_DST | USES_CC_SRC,
221 [CC_OP_BMILGB ... CC_OP_BMILGQ] = USES_CC_DST | USES_CC_SRC,
222 [CC_OP_ADCX] = USES_CC_DST | USES_CC_SRC,
223 [CC_OP_ADOX] = USES_CC_SRC | USES_CC_SRC2,
224 [CC_OP_ADCOX] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
228 static void set_cc_op(DisasContext *s, CCOp op)
232 if (s->cc_op == op) {
236 /* Discard CC computation that will no longer be used. */
237 dead = cc_op_live[s->cc_op] & ~cc_op_live[op];
238 if (dead & USES_CC_DST) {
239 tcg_gen_discard_tl(cpu_cc_dst);
241 if (dead & USES_CC_SRC) {
242 tcg_gen_discard_tl(cpu_cc_src);
244 if (dead & USES_CC_SRC2) {
245 tcg_gen_discard_tl(cpu_cc_src2);
247 if (dead & USES_CC_SRCT) {
248 tcg_gen_discard_tl(cpu_cc_srcT);
251 if (op == CC_OP_DYNAMIC) {
252 /* The DYNAMIC setting is translator only, and should never be
253 stored. Thus we always consider it clean. */
254 s->cc_op_dirty = false;
256 /* Discard any computed CC_OP value (see shifts). */
257 if (s->cc_op == CC_OP_DYNAMIC) {
258 tcg_gen_discard_i32(cpu_cc_op);
260 s->cc_op_dirty = true;
265 static void gen_update_cc_op(DisasContext *s)
267 if (s->cc_op_dirty) {
268 tcg_gen_movi_i32(cpu_cc_op, s->cc_op);
269 s->cc_op_dirty = false;
275 #define NB_OP_SIZES 4
277 #else /* !TARGET_X86_64 */
279 #define NB_OP_SIZES 3
281 #endif /* !TARGET_X86_64 */
283 #if defined(HOST_WORDS_BIGENDIAN)
284 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
285 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
286 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
287 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
288 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
290 #define REG_B_OFFSET 0
291 #define REG_H_OFFSET 1
292 #define REG_W_OFFSET 0
293 #define REG_L_OFFSET 0
294 #define REG_LH_OFFSET 4
297 /* In instruction encodings for byte register accesses the
298 * register number usually indicates "low 8 bits of register N";
299 * however there are some special cases where N 4..7 indicates
300 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
301 * true for this special case, false otherwise.
303 static inline bool byte_reg_is_xH(int reg)
309 if (reg >= 8 || x86_64_hregs) {
316 /* Select the size of a push/pop operation. */
317 static inline TCGMemOp mo_pushpop(DisasContext *s, TCGMemOp ot)
320 return ot == MO_16 ? MO_16 : MO_64;
326 /* Select the size of the stack pointer. */
327 static inline TCGMemOp mo_stacksize(DisasContext *s)
329 return CODE64(s) ? MO_64 : s->ss32 ? MO_32 : MO_16;
332 /* Select only size 64 else 32. Used for SSE operand sizes. */
333 static inline TCGMemOp mo_64_32(TCGMemOp ot)
336 return ot == MO_64 ? MO_64 : MO_32;
342 /* Select size 8 if lsb of B is clear, else OT. Used for decoding
343 byte vs word opcodes. */
344 static inline TCGMemOp mo_b_d(int b, TCGMemOp ot)
346 return b & 1 ? ot : MO_8;
349 /* Select size 8 if lsb of B is clear, else OT capped at 32.
350 Used for decoding operand size of port opcodes. */
351 static inline TCGMemOp mo_b_d32(int b, TCGMemOp ot)
353 return b & 1 ? (ot == MO_16 ? MO_16 : MO_32) : MO_8;
356 static void gen_op_mov_reg_v(TCGMemOp ot, int reg, TCGv t0)
360 if (!byte_reg_is_xH(reg)) {
361 tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 8);
363 tcg_gen_deposit_tl(cpu_regs[reg - 4], cpu_regs[reg - 4], t0, 8, 8);
367 tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 16);
370 /* For x86_64, this sets the higher half of register to zero.
371 For i386, this is equivalent to a mov. */
372 tcg_gen_ext32u_tl(cpu_regs[reg], t0);
376 tcg_gen_mov_tl(cpu_regs[reg], t0);
384 static inline void gen_op_mov_v_reg(TCGMemOp ot, TCGv t0, int reg)
386 if (ot == MO_8 && byte_reg_is_xH(reg)) {
387 tcg_gen_shri_tl(t0, cpu_regs[reg - 4], 8);
388 tcg_gen_ext8u_tl(t0, t0);
390 tcg_gen_mov_tl(t0, cpu_regs[reg]);
394 static void gen_add_A0_im(DisasContext *s, int val)
396 tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
398 tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
402 static inline void gen_op_jmp_v(TCGv dest)
404 tcg_gen_st_tl(dest, cpu_env, offsetof(CPUX86State, eip));
407 static inline void gen_op_add_reg_im(TCGMemOp size, int reg, int32_t val)
409 tcg_gen_addi_tl(cpu_tmp0, cpu_regs[reg], val);
410 gen_op_mov_reg_v(size, reg, cpu_tmp0);
413 static inline void gen_op_add_reg_T0(TCGMemOp size, int reg)
415 tcg_gen_add_tl(cpu_tmp0, cpu_regs[reg], cpu_T0);
416 gen_op_mov_reg_v(size, reg, cpu_tmp0);
419 static inline void gen_op_ld_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
421 tcg_gen_qemu_ld_tl(t0, a0, s->mem_index, idx | MO_LE);
424 static inline void gen_op_st_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
426 tcg_gen_qemu_st_tl(t0, a0, s->mem_index, idx | MO_LE);
429 static inline void gen_op_st_rm_T0_A0(DisasContext *s, int idx, int d)
432 gen_op_st_v(s, idx, cpu_T0, cpu_A0);
434 gen_op_mov_reg_v(idx, d, cpu_T0);
438 static inline void gen_jmp_im(target_ulong pc)
440 tcg_gen_movi_tl(cpu_tmp0, pc);
441 gen_op_jmp_v(cpu_tmp0);
444 /* Compute SEG:REG into A0. SEG is selected from the override segment
445 (OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to
446 indicate no override. */
447 static void gen_lea_v_seg(DisasContext *s, TCGMemOp aflag, TCGv a0,
448 int def_seg, int ovr_seg)
454 tcg_gen_mov_tl(cpu_A0, a0);
461 if (ovr_seg < 0 && s->addseg) {
465 tcg_gen_ext32u_tl(cpu_A0, a0);
471 tcg_gen_ext16u_tl(cpu_A0, a0);
486 TCGv seg = cpu_seg_base[ovr_seg];
488 if (aflag == MO_64) {
489 tcg_gen_add_tl(cpu_A0, a0, seg);
490 } else if (CODE64(s)) {
491 tcg_gen_ext32u_tl(cpu_A0, a0);
492 tcg_gen_add_tl(cpu_A0, cpu_A0, seg);
494 tcg_gen_add_tl(cpu_A0, a0, seg);
495 tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
500 static inline void gen_string_movl_A0_ESI(DisasContext *s)
502 gen_lea_v_seg(s, s->aflag, cpu_regs[R_ESI], R_DS, s->override);
505 static inline void gen_string_movl_A0_EDI(DisasContext *s)
507 gen_lea_v_seg(s, s->aflag, cpu_regs[R_EDI], R_ES, -1);
510 static inline void gen_op_movl_T0_Dshift(TCGMemOp ot)
512 tcg_gen_ld32s_tl(cpu_T0, cpu_env, offsetof(CPUX86State, df));
513 tcg_gen_shli_tl(cpu_T0, cpu_T0, ot);
516 static TCGv gen_ext_tl(TCGv dst, TCGv src, TCGMemOp size, bool sign)
521 tcg_gen_ext8s_tl(dst, src);
523 tcg_gen_ext8u_tl(dst, src);
528 tcg_gen_ext16s_tl(dst, src);
530 tcg_gen_ext16u_tl(dst, src);
536 tcg_gen_ext32s_tl(dst, src);
538 tcg_gen_ext32u_tl(dst, src);
547 static void gen_extu(TCGMemOp ot, TCGv reg)
549 gen_ext_tl(reg, reg, ot, false);
552 static void gen_exts(TCGMemOp ot, TCGv reg)
554 gen_ext_tl(reg, reg, ot, true);
557 static inline void gen_op_jnz_ecx(TCGMemOp size, TCGLabel *label1)
559 tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
560 gen_extu(size, cpu_tmp0);
561 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_tmp0, 0, label1);
564 static inline void gen_op_jz_ecx(TCGMemOp size, TCGLabel *label1)
566 tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
567 gen_extu(size, cpu_tmp0);
568 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
571 static void gen_helper_in_func(TCGMemOp ot, TCGv v, TCGv_i32 n)
575 gen_helper_inb(v, cpu_env, n);
578 gen_helper_inw(v, cpu_env, n);
581 gen_helper_inl(v, cpu_env, n);
588 static void gen_helper_out_func(TCGMemOp ot, TCGv_i32 v, TCGv_i32 n)
592 gen_helper_outb(cpu_env, v, n);
595 gen_helper_outw(cpu_env, v, n);
598 gen_helper_outl(cpu_env, v, n);
605 static void gen_check_io(DisasContext *s, TCGMemOp ot, target_ulong cur_eip,
608 target_ulong next_eip;
610 if (s->pe && (s->cpl > s->iopl || s->vm86)) {
611 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
614 gen_helper_check_iob(cpu_env, cpu_tmp2_i32);
617 gen_helper_check_iow(cpu_env, cpu_tmp2_i32);
620 gen_helper_check_iol(cpu_env, cpu_tmp2_i32);
626 if(s->flags & HF_SVMI_MASK) {
629 svm_flags |= (1 << (4 + ot));
630 next_eip = s->pc - s->cs_base;
631 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
632 gen_helper_svm_check_io(cpu_env, cpu_tmp2_i32,
633 tcg_const_i32(svm_flags),
634 tcg_const_i32(next_eip - cur_eip));
638 static inline void gen_movs(DisasContext *s, TCGMemOp ot)
640 gen_string_movl_A0_ESI(s);
641 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
642 gen_string_movl_A0_EDI(s);
643 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
644 gen_op_movl_T0_Dshift(ot);
645 gen_op_add_reg_T0(s->aflag, R_ESI);
646 gen_op_add_reg_T0(s->aflag, R_EDI);
649 static void gen_op_update1_cc(void)
651 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
654 static void gen_op_update2_cc(void)
656 tcg_gen_mov_tl(cpu_cc_src, cpu_T1);
657 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
660 static void gen_op_update3_cc(TCGv reg)
662 tcg_gen_mov_tl(cpu_cc_src2, reg);
663 tcg_gen_mov_tl(cpu_cc_src, cpu_T1);
664 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
667 static inline void gen_op_testl_T0_T1_cc(void)
669 tcg_gen_and_tl(cpu_cc_dst, cpu_T0, cpu_T1);
672 static void gen_op_update_neg_cc(void)
674 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
675 tcg_gen_neg_tl(cpu_cc_src, cpu_T0);
676 tcg_gen_movi_tl(cpu_cc_srcT, 0);
679 /* compute all eflags to cc_src */
680 static void gen_compute_eflags(DisasContext *s)
682 TCGv zero, dst, src1, src2;
685 if (s->cc_op == CC_OP_EFLAGS) {
688 if (s->cc_op == CC_OP_CLR) {
689 tcg_gen_movi_tl(cpu_cc_src, CC_Z | CC_P);
690 set_cc_op(s, CC_OP_EFLAGS);
699 /* Take care to not read values that are not live. */
700 live = cc_op_live[s->cc_op] & ~USES_CC_SRCT;
701 dead = live ^ (USES_CC_DST | USES_CC_SRC | USES_CC_SRC2);
703 zero = tcg_const_tl(0);
704 if (dead & USES_CC_DST) {
707 if (dead & USES_CC_SRC) {
710 if (dead & USES_CC_SRC2) {
716 gen_helper_cc_compute_all(cpu_cc_src, dst, src1, src2, cpu_cc_op);
717 set_cc_op(s, CC_OP_EFLAGS);
724 typedef struct CCPrepare {
734 /* compute eflags.C to reg */
735 static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg)
741 case CC_OP_SUBB ... CC_OP_SUBQ:
742 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
743 size = s->cc_op - CC_OP_SUBB;
744 t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
745 /* If no temporary was used, be careful not to alias t1 and t0. */
746 t0 = TCGV_EQUAL(t1, cpu_cc_src) ? cpu_tmp0 : reg;
747 tcg_gen_mov_tl(t0, cpu_cc_srcT);
751 case CC_OP_ADDB ... CC_OP_ADDQ:
752 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
753 size = s->cc_op - CC_OP_ADDB;
754 t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
755 t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
757 return (CCPrepare) { .cond = TCG_COND_LTU, .reg = t0,
758 .reg2 = t1, .mask = -1, .use_reg2 = true };
760 case CC_OP_LOGICB ... CC_OP_LOGICQ:
762 return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
764 case CC_OP_INCB ... CC_OP_INCQ:
765 case CC_OP_DECB ... CC_OP_DECQ:
766 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
767 .mask = -1, .no_setcond = true };
769 case CC_OP_SHLB ... CC_OP_SHLQ:
770 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
771 size = s->cc_op - CC_OP_SHLB;
772 shift = (8 << size) - 1;
773 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
774 .mask = (target_ulong)1 << shift };
776 case CC_OP_MULB ... CC_OP_MULQ:
777 return (CCPrepare) { .cond = TCG_COND_NE,
778 .reg = cpu_cc_src, .mask = -1 };
780 case CC_OP_BMILGB ... CC_OP_BMILGQ:
781 size = s->cc_op - CC_OP_BMILGB;
782 t0 = gen_ext_tl(reg, cpu_cc_src, size, false);
783 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 };
787 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_dst,
788 .mask = -1, .no_setcond = true };
791 case CC_OP_SARB ... CC_OP_SARQ:
793 return (CCPrepare) { .cond = TCG_COND_NE,
794 .reg = cpu_cc_src, .mask = CC_C };
797 /* The need to compute only C from CC_OP_DYNAMIC is important
798 in efficiently implementing e.g. INC at the start of a TB. */
800 gen_helper_cc_compute_c(reg, cpu_cc_dst, cpu_cc_src,
801 cpu_cc_src2, cpu_cc_op);
802 return (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
803 .mask = -1, .no_setcond = true };
807 /* compute eflags.P to reg */
808 static CCPrepare gen_prepare_eflags_p(DisasContext *s, TCGv reg)
810 gen_compute_eflags(s);
811 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
815 /* compute eflags.S to reg */
816 static CCPrepare gen_prepare_eflags_s(DisasContext *s, TCGv reg)
820 gen_compute_eflags(s);
826 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
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 };
848 return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
850 gen_compute_eflags(s);
851 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
856 /* compute eflags.Z to reg */
857 static CCPrepare gen_prepare_eflags_z(DisasContext *s, TCGv reg)
861 gen_compute_eflags(s);
867 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
870 return (CCPrepare) { .cond = TCG_COND_ALWAYS, .mask = -1 };
873 TCGMemOp size = (s->cc_op - CC_OP_ADDB) & 3;
874 TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
875 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 };
880 /* perform a conditional store into register 'reg' according to jump opcode
881 value 'b'. In the fast case, T0 is guaranted not to be used. */
882 static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg)
884 int inv, jcc_op, cond;
890 jcc_op = (b >> 1) & 7;
893 case CC_OP_SUBB ... CC_OP_SUBQ:
894 /* We optimize relational operators for the cmp/jcc case. */
895 size = s->cc_op - CC_OP_SUBB;
898 tcg_gen_mov_tl(cpu_tmp4, cpu_cc_srcT);
899 gen_extu(size, cpu_tmp4);
900 t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
901 cc = (CCPrepare) { .cond = TCG_COND_LEU, .reg = cpu_tmp4,
902 .reg2 = t0, .mask = -1, .use_reg2 = true };
911 tcg_gen_mov_tl(cpu_tmp4, cpu_cc_srcT);
912 gen_exts(size, cpu_tmp4);
913 t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, true);
914 cc = (CCPrepare) { .cond = cond, .reg = cpu_tmp4,
915 .reg2 = t0, .mask = -1, .use_reg2 = true };
925 /* This actually generates good code for JC, JZ and JS. */
928 cc = gen_prepare_eflags_o(s, reg);
931 cc = gen_prepare_eflags_c(s, reg);
934 cc = gen_prepare_eflags_z(s, reg);
937 gen_compute_eflags(s);
938 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
939 .mask = CC_Z | CC_C };
942 cc = gen_prepare_eflags_s(s, reg);
945 cc = gen_prepare_eflags_p(s, reg);
948 gen_compute_eflags(s);
949 if (TCGV_EQUAL(reg, cpu_cc_src)) {
952 tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */
953 tcg_gen_xor_tl(reg, reg, cpu_cc_src);
954 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
959 gen_compute_eflags(s);
960 if (TCGV_EQUAL(reg, cpu_cc_src)) {
963 tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */
964 tcg_gen_xor_tl(reg, reg, cpu_cc_src);
965 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
966 .mask = CC_S | CC_Z };
973 cc.cond = tcg_invert_cond(cc.cond);
978 static void gen_setcc1(DisasContext *s, int b, TCGv reg)
980 CCPrepare cc = gen_prepare_cc(s, b, reg);
983 if (cc.cond == TCG_COND_EQ) {
984 tcg_gen_xori_tl(reg, cc.reg, 1);
986 tcg_gen_mov_tl(reg, cc.reg);
991 if (cc.cond == TCG_COND_NE && !cc.use_reg2 && cc.imm == 0 &&
992 cc.mask != 0 && (cc.mask & (cc.mask - 1)) == 0) {
993 tcg_gen_shri_tl(reg, cc.reg, ctztl(cc.mask));
994 tcg_gen_andi_tl(reg, reg, 1);
998 tcg_gen_andi_tl(reg, cc.reg, cc.mask);
1002 tcg_gen_setcond_tl(cc.cond, reg, cc.reg, cc.reg2);
1004 tcg_gen_setcondi_tl(cc.cond, reg, cc.reg, cc.imm);
1008 static inline void gen_compute_eflags_c(DisasContext *s, TCGv reg)
1010 gen_setcc1(s, JCC_B << 1, reg);
1013 /* generate a conditional jump to label 'l1' according to jump opcode
1014 value 'b'. In the fast case, T0 is guaranted not to be used. */
1015 static inline void gen_jcc1_noeob(DisasContext *s, int b, TCGLabel *l1)
1017 CCPrepare cc = gen_prepare_cc(s, b, cpu_T0);
1019 if (cc.mask != -1) {
1020 tcg_gen_andi_tl(cpu_T0, cc.reg, cc.mask);
1024 tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1026 tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1030 /* Generate a conditional jump to label 'l1' according to jump opcode
1031 value 'b'. In the fast case, T0 is guaranted not to be used.
1032 A translation block must end soon. */
1033 static inline void gen_jcc1(DisasContext *s, int b, TCGLabel *l1)
1035 CCPrepare cc = gen_prepare_cc(s, b, cpu_T0);
1037 gen_update_cc_op(s);
1038 if (cc.mask != -1) {
1039 tcg_gen_andi_tl(cpu_T0, cc.reg, cc.mask);
1042 set_cc_op(s, CC_OP_DYNAMIC);
1044 tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1046 tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1050 /* XXX: does not work with gdbstub "ice" single step - not a
1052 static TCGLabel *gen_jz_ecx_string(DisasContext *s, target_ulong next_eip)
1054 TCGLabel *l1 = gen_new_label();
1055 TCGLabel *l2 = gen_new_label();
1056 gen_op_jnz_ecx(s->aflag, l1);
1058 gen_jmp_tb(s, next_eip, 1);
1063 static inline void gen_stos(DisasContext *s, TCGMemOp ot)
1065 gen_op_mov_v_reg(MO_32, cpu_T0, R_EAX);
1066 gen_string_movl_A0_EDI(s);
1067 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
1068 gen_op_movl_T0_Dshift(ot);
1069 gen_op_add_reg_T0(s->aflag, R_EDI);
1072 static inline void gen_lods(DisasContext *s, TCGMemOp ot)
1074 gen_string_movl_A0_ESI(s);
1075 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1076 gen_op_mov_reg_v(ot, R_EAX, cpu_T0);
1077 gen_op_movl_T0_Dshift(ot);
1078 gen_op_add_reg_T0(s->aflag, R_ESI);
1081 static inline void gen_scas(DisasContext *s, TCGMemOp ot)
1083 gen_string_movl_A0_EDI(s);
1084 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
1085 gen_op(s, OP_CMPL, ot, R_EAX);
1086 gen_op_movl_T0_Dshift(ot);
1087 gen_op_add_reg_T0(s->aflag, R_EDI);
1090 static inline void gen_cmps(DisasContext *s, TCGMemOp ot)
1092 gen_string_movl_A0_EDI(s);
1093 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
1094 gen_string_movl_A0_ESI(s);
1095 gen_op(s, OP_CMPL, ot, OR_TMP0);
1096 gen_op_movl_T0_Dshift(ot);
1097 gen_op_add_reg_T0(s->aflag, R_ESI);
1098 gen_op_add_reg_T0(s->aflag, R_EDI);
1101 static void gen_bpt_io(DisasContext *s, TCGv_i32 t_port, int ot)
1103 if (s->flags & HF_IOBPT_MASK) {
1104 TCGv_i32 t_size = tcg_const_i32(1 << ot);
1105 TCGv t_next = tcg_const_tl(s->pc - s->cs_base);
1107 gen_helper_bpt_io(cpu_env, t_port, t_size, t_next);
1108 tcg_temp_free_i32(t_size);
1109 tcg_temp_free(t_next);
1114 static inline void gen_ins(DisasContext *s, TCGMemOp ot)
1116 if (s->tb->cflags & CF_USE_ICOUNT) {
1119 gen_string_movl_A0_EDI(s);
1120 /* Note: we must do this dummy write first to be restartable in
1121 case of page fault. */
1122 tcg_gen_movi_tl(cpu_T0, 0);
1123 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
1124 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_EDX]);
1125 tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1126 gen_helper_in_func(ot, cpu_T0, cpu_tmp2_i32);
1127 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
1128 gen_op_movl_T0_Dshift(ot);
1129 gen_op_add_reg_T0(s->aflag, R_EDI);
1130 gen_bpt_io(s, cpu_tmp2_i32, ot);
1131 if (s->tb->cflags & CF_USE_ICOUNT) {
1136 static inline void gen_outs(DisasContext *s, TCGMemOp ot)
1138 if (s->tb->cflags & CF_USE_ICOUNT) {
1141 gen_string_movl_A0_ESI(s);
1142 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1144 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_EDX]);
1145 tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1146 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T0);
1147 gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
1148 gen_op_movl_T0_Dshift(ot);
1149 gen_op_add_reg_T0(s->aflag, R_ESI);
1150 gen_bpt_io(s, cpu_tmp2_i32, ot);
1151 if (s->tb->cflags & CF_USE_ICOUNT) {
1156 /* same method as Valgrind : we generate jumps to current or next
1158 #define GEN_REPZ(op) \
1159 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1160 target_ulong cur_eip, target_ulong next_eip) \
1163 gen_update_cc_op(s); \
1164 l2 = gen_jz_ecx_string(s, next_eip); \
1165 gen_ ## op(s, ot); \
1166 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1167 /* a loop would cause two single step exceptions if ECX = 1 \
1168 before rep string_insn */ \
1170 gen_op_jz_ecx(s->aflag, l2); \
1171 gen_jmp(s, cur_eip); \
1174 #define GEN_REPZ2(op) \
1175 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1176 target_ulong cur_eip, \
1177 target_ulong next_eip, \
1181 gen_update_cc_op(s); \
1182 l2 = gen_jz_ecx_string(s, next_eip); \
1183 gen_ ## op(s, ot); \
1184 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1185 gen_update_cc_op(s); \
1186 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
1188 gen_op_jz_ecx(s->aflag, l2); \
1189 gen_jmp(s, cur_eip); \
1200 static void gen_helper_fp_arith_ST0_FT0(int op)
1204 gen_helper_fadd_ST0_FT0(cpu_env);
1207 gen_helper_fmul_ST0_FT0(cpu_env);
1210 gen_helper_fcom_ST0_FT0(cpu_env);
1213 gen_helper_fcom_ST0_FT0(cpu_env);
1216 gen_helper_fsub_ST0_FT0(cpu_env);
1219 gen_helper_fsubr_ST0_FT0(cpu_env);
1222 gen_helper_fdiv_ST0_FT0(cpu_env);
1225 gen_helper_fdivr_ST0_FT0(cpu_env);
1230 /* NOTE the exception in "r" op ordering */
1231 static void gen_helper_fp_arith_STN_ST0(int op, int opreg)
1233 TCGv_i32 tmp = tcg_const_i32(opreg);
1236 gen_helper_fadd_STN_ST0(cpu_env, tmp);
1239 gen_helper_fmul_STN_ST0(cpu_env, tmp);
1242 gen_helper_fsubr_STN_ST0(cpu_env, tmp);
1245 gen_helper_fsub_STN_ST0(cpu_env, tmp);
1248 gen_helper_fdivr_STN_ST0(cpu_env, tmp);
1251 gen_helper_fdiv_STN_ST0(cpu_env, tmp);
1256 /* if d == OR_TMP0, it means memory operand (address in A0) */
1257 static void gen_op(DisasContext *s1, int op, TCGMemOp ot, int d)
1260 gen_op_mov_v_reg(ot, cpu_T0, d);
1261 } else if (!(s1->prefix & PREFIX_LOCK)) {
1262 gen_op_ld_v(s1, ot, cpu_T0, cpu_A0);
1266 gen_compute_eflags_c(s1, cpu_tmp4);
1267 if (s1->prefix & PREFIX_LOCK) {
1268 tcg_gen_add_tl(cpu_T0, cpu_tmp4, cpu_T1);
1269 tcg_gen_atomic_add_fetch_tl(cpu_T0, cpu_A0, cpu_T0,
1270 s1->mem_index, ot | MO_LE);
1272 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
1273 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_tmp4);
1274 gen_op_st_rm_T0_A0(s1, ot, d);
1276 gen_op_update3_cc(cpu_tmp4);
1277 set_cc_op(s1, CC_OP_ADCB + ot);
1280 gen_compute_eflags_c(s1, cpu_tmp4);
1281 if (s1->prefix & PREFIX_LOCK) {
1282 tcg_gen_add_tl(cpu_T0, cpu_T1, cpu_tmp4);
1283 tcg_gen_neg_tl(cpu_T0, cpu_T0);
1284 tcg_gen_atomic_add_fetch_tl(cpu_T0, cpu_A0, cpu_T0,
1285 s1->mem_index, ot | MO_LE);
1287 tcg_gen_sub_tl(cpu_T0, cpu_T0, cpu_T1);
1288 tcg_gen_sub_tl(cpu_T0, cpu_T0, cpu_tmp4);
1289 gen_op_st_rm_T0_A0(s1, ot, d);
1291 gen_op_update3_cc(cpu_tmp4);
1292 set_cc_op(s1, CC_OP_SBBB + ot);
1295 if (s1->prefix & PREFIX_LOCK) {
1296 tcg_gen_atomic_add_fetch_tl(cpu_T0, cpu_A0, cpu_T1,
1297 s1->mem_index, ot | MO_LE);
1299 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
1300 gen_op_st_rm_T0_A0(s1, ot, d);
1302 gen_op_update2_cc();
1303 set_cc_op(s1, CC_OP_ADDB + ot);
1306 if (s1->prefix & PREFIX_LOCK) {
1307 tcg_gen_neg_tl(cpu_T0, cpu_T1);
1308 tcg_gen_atomic_fetch_add_tl(cpu_cc_srcT, cpu_A0, cpu_T0,
1309 s1->mem_index, ot | MO_LE);
1310 tcg_gen_sub_tl(cpu_T0, cpu_cc_srcT, cpu_T1);
1312 tcg_gen_mov_tl(cpu_cc_srcT, cpu_T0);
1313 tcg_gen_sub_tl(cpu_T0, cpu_T0, cpu_T1);
1314 gen_op_st_rm_T0_A0(s1, ot, d);
1316 gen_op_update2_cc();
1317 set_cc_op(s1, CC_OP_SUBB + ot);
1321 if (s1->prefix & PREFIX_LOCK) {
1322 tcg_gen_atomic_and_fetch_tl(cpu_T0, cpu_A0, cpu_T1,
1323 s1->mem_index, ot | MO_LE);
1325 tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1);
1326 gen_op_st_rm_T0_A0(s1, ot, d);
1328 gen_op_update1_cc();
1329 set_cc_op(s1, CC_OP_LOGICB + ot);
1332 if (s1->prefix & PREFIX_LOCK) {
1333 tcg_gen_atomic_or_fetch_tl(cpu_T0, cpu_A0, cpu_T1,
1334 s1->mem_index, ot | MO_LE);
1336 tcg_gen_or_tl(cpu_T0, cpu_T0, cpu_T1);
1337 gen_op_st_rm_T0_A0(s1, ot, d);
1339 gen_op_update1_cc();
1340 set_cc_op(s1, CC_OP_LOGICB + ot);
1343 if (s1->prefix & PREFIX_LOCK) {
1344 tcg_gen_atomic_xor_fetch_tl(cpu_T0, cpu_A0, cpu_T1,
1345 s1->mem_index, ot | MO_LE);
1347 tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_T1);
1348 gen_op_st_rm_T0_A0(s1, ot, d);
1350 gen_op_update1_cc();
1351 set_cc_op(s1, CC_OP_LOGICB + ot);
1354 tcg_gen_mov_tl(cpu_cc_src, cpu_T1);
1355 tcg_gen_mov_tl(cpu_cc_srcT, cpu_T0);
1356 tcg_gen_sub_tl(cpu_cc_dst, cpu_T0, cpu_T1);
1357 set_cc_op(s1, CC_OP_SUBB + ot);
1362 /* if d == OR_TMP0, it means memory operand (address in A0) */
1363 static void gen_inc(DisasContext *s1, TCGMemOp ot, int d, int c)
1365 if (s1->prefix & PREFIX_LOCK) {
1366 tcg_gen_movi_tl(cpu_T0, c > 0 ? 1 : -1);
1367 tcg_gen_atomic_add_fetch_tl(cpu_T0, cpu_A0, cpu_T0,
1368 s1->mem_index, ot | MO_LE);
1371 gen_op_mov_v_reg(ot, cpu_T0, d);
1373 gen_op_ld_v(s1, ot, cpu_T0, cpu_A0);
1375 tcg_gen_addi_tl(cpu_T0, cpu_T0, (c > 0 ? 1 : -1));
1376 gen_op_st_rm_T0_A0(s1, ot, d);
1379 gen_compute_eflags_c(s1, cpu_cc_src);
1380 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
1381 set_cc_op(s1, (c > 0 ? CC_OP_INCB : CC_OP_DECB) + ot);
1384 static void gen_shift_flags(DisasContext *s, TCGMemOp ot, TCGv result,
1385 TCGv shm1, TCGv count, bool is_right)
1387 TCGv_i32 z32, s32, oldop;
1390 /* Store the results into the CC variables. If we know that the
1391 variable must be dead, store unconditionally. Otherwise we'll
1392 need to not disrupt the current contents. */
1393 z_tl = tcg_const_tl(0);
1394 if (cc_op_live[s->cc_op] & USES_CC_DST) {
1395 tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_dst, count, z_tl,
1396 result, cpu_cc_dst);
1398 tcg_gen_mov_tl(cpu_cc_dst, result);
1400 if (cc_op_live[s->cc_op] & USES_CC_SRC) {
1401 tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_src, count, z_tl,
1404 tcg_gen_mov_tl(cpu_cc_src, shm1);
1406 tcg_temp_free(z_tl);
1408 /* Get the two potential CC_OP values into temporaries. */
1409 tcg_gen_movi_i32(cpu_tmp2_i32, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot);
1410 if (s->cc_op == CC_OP_DYNAMIC) {
1413 tcg_gen_movi_i32(cpu_tmp3_i32, s->cc_op);
1414 oldop = cpu_tmp3_i32;
1417 /* Conditionally store the CC_OP value. */
1418 z32 = tcg_const_i32(0);
1419 s32 = tcg_temp_new_i32();
1420 tcg_gen_trunc_tl_i32(s32, count);
1421 tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, s32, z32, cpu_tmp2_i32, oldop);
1422 tcg_temp_free_i32(z32);
1423 tcg_temp_free_i32(s32);
1425 /* The CC_OP value is no longer predictable. */
1426 set_cc_op(s, CC_OP_DYNAMIC);
1429 static void gen_shift_rm_T1(DisasContext *s, TCGMemOp ot, int op1,
1430 int is_right, int is_arith)
1432 target_ulong mask = (ot == MO_64 ? 0x3f : 0x1f);
1435 if (op1 == OR_TMP0) {
1436 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1438 gen_op_mov_v_reg(ot, cpu_T0, op1);
1441 tcg_gen_andi_tl(cpu_T1, cpu_T1, mask);
1442 tcg_gen_subi_tl(cpu_tmp0, cpu_T1, 1);
1446 gen_exts(ot, cpu_T0);
1447 tcg_gen_sar_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1448 tcg_gen_sar_tl(cpu_T0, cpu_T0, cpu_T1);
1450 gen_extu(ot, cpu_T0);
1451 tcg_gen_shr_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1452 tcg_gen_shr_tl(cpu_T0, cpu_T0, cpu_T1);
1455 tcg_gen_shl_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1456 tcg_gen_shl_tl(cpu_T0, cpu_T0, cpu_T1);
1460 gen_op_st_rm_T0_A0(s, ot, op1);
1462 gen_shift_flags(s, ot, cpu_T0, cpu_tmp0, cpu_T1, is_right);
1465 static void gen_shift_rm_im(DisasContext *s, TCGMemOp ot, int op1, int op2,
1466 int is_right, int is_arith)
1468 int mask = (ot == MO_64 ? 0x3f : 0x1f);
1472 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1474 gen_op_mov_v_reg(ot, cpu_T0, op1);
1480 gen_exts(ot, cpu_T0);
1481 tcg_gen_sari_tl(cpu_tmp4, cpu_T0, op2 - 1);
1482 tcg_gen_sari_tl(cpu_T0, cpu_T0, op2);
1484 gen_extu(ot, cpu_T0);
1485 tcg_gen_shri_tl(cpu_tmp4, cpu_T0, op2 - 1);
1486 tcg_gen_shri_tl(cpu_T0, cpu_T0, op2);
1489 tcg_gen_shli_tl(cpu_tmp4, cpu_T0, op2 - 1);
1490 tcg_gen_shli_tl(cpu_T0, cpu_T0, op2);
1495 gen_op_st_rm_T0_A0(s, ot, op1);
1497 /* update eflags if non zero shift */
1499 tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
1500 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
1501 set_cc_op(s, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot);
1505 static void gen_rot_rm_T1(DisasContext *s, TCGMemOp ot, int op1, int is_right)
1507 target_ulong mask = (ot == MO_64 ? 0x3f : 0x1f);
1511 if (op1 == OR_TMP0) {
1512 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1514 gen_op_mov_v_reg(ot, cpu_T0, op1);
1517 tcg_gen_andi_tl(cpu_T1, cpu_T1, mask);
1521 /* Replicate the 8-bit input so that a 32-bit rotate works. */
1522 tcg_gen_ext8u_tl(cpu_T0, cpu_T0);
1523 tcg_gen_muli_tl(cpu_T0, cpu_T0, 0x01010101);
1526 /* Replicate the 16-bit input so that a 32-bit rotate works. */
1527 tcg_gen_deposit_tl(cpu_T0, cpu_T0, cpu_T0, 16, 16);
1530 #ifdef TARGET_X86_64
1532 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
1533 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T1);
1535 tcg_gen_rotr_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
1537 tcg_gen_rotl_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
1539 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
1544 tcg_gen_rotr_tl(cpu_T0, cpu_T0, cpu_T1);
1546 tcg_gen_rotl_tl(cpu_T0, cpu_T0, cpu_T1);
1552 gen_op_st_rm_T0_A0(s, ot, op1);
1554 /* We'll need the flags computed into CC_SRC. */
1555 gen_compute_eflags(s);
1557 /* The value that was "rotated out" is now present at the other end
1558 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1559 since we've computed the flags into CC_SRC, these variables are
1562 tcg_gen_shri_tl(cpu_cc_src2, cpu_T0, mask - 1);
1563 tcg_gen_shri_tl(cpu_cc_dst, cpu_T0, mask);
1564 tcg_gen_andi_tl(cpu_cc_dst, cpu_cc_dst, 1);
1566 tcg_gen_shri_tl(cpu_cc_src2, cpu_T0, mask);
1567 tcg_gen_andi_tl(cpu_cc_dst, cpu_T0, 1);
1569 tcg_gen_andi_tl(cpu_cc_src2, cpu_cc_src2, 1);
1570 tcg_gen_xor_tl(cpu_cc_src2, cpu_cc_src2, cpu_cc_dst);
1572 /* Now conditionally store the new CC_OP value. If the shift count
1573 is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1574 Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1575 exactly as we computed above. */
1576 t0 = tcg_const_i32(0);
1577 t1 = tcg_temp_new_i32();
1578 tcg_gen_trunc_tl_i32(t1, cpu_T1);
1579 tcg_gen_movi_i32(cpu_tmp2_i32, CC_OP_ADCOX);
1580 tcg_gen_movi_i32(cpu_tmp3_i32, CC_OP_EFLAGS);
1581 tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, t1, t0,
1582 cpu_tmp2_i32, cpu_tmp3_i32);
1583 tcg_temp_free_i32(t0);
1584 tcg_temp_free_i32(t1);
1586 /* The CC_OP value is no longer predictable. */
1587 set_cc_op(s, CC_OP_DYNAMIC);
1590 static void gen_rot_rm_im(DisasContext *s, TCGMemOp ot, int op1, int op2,
1593 int mask = (ot == MO_64 ? 0x3f : 0x1f);
1597 if (op1 == OR_TMP0) {
1598 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1600 gen_op_mov_v_reg(ot, cpu_T0, op1);
1606 #ifdef TARGET_X86_64
1608 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
1610 tcg_gen_rotri_i32(cpu_tmp2_i32, cpu_tmp2_i32, op2);
1612 tcg_gen_rotli_i32(cpu_tmp2_i32, cpu_tmp2_i32, op2);
1614 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
1619 tcg_gen_rotri_tl(cpu_T0, cpu_T0, op2);
1621 tcg_gen_rotli_tl(cpu_T0, cpu_T0, op2);
1632 shift = mask + 1 - shift;
1634 gen_extu(ot, cpu_T0);
1635 tcg_gen_shli_tl(cpu_tmp0, cpu_T0, shift);
1636 tcg_gen_shri_tl(cpu_T0, cpu_T0, mask + 1 - shift);
1637 tcg_gen_or_tl(cpu_T0, cpu_T0, cpu_tmp0);
1643 gen_op_st_rm_T0_A0(s, ot, op1);
1646 /* Compute the flags into CC_SRC. */
1647 gen_compute_eflags(s);
1649 /* The value that was "rotated out" is now present at the other end
1650 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1651 since we've computed the flags into CC_SRC, these variables are
1654 tcg_gen_shri_tl(cpu_cc_src2, cpu_T0, mask - 1);
1655 tcg_gen_shri_tl(cpu_cc_dst, cpu_T0, mask);
1656 tcg_gen_andi_tl(cpu_cc_dst, cpu_cc_dst, 1);
1658 tcg_gen_shri_tl(cpu_cc_src2, cpu_T0, mask);
1659 tcg_gen_andi_tl(cpu_cc_dst, cpu_T0, 1);
1661 tcg_gen_andi_tl(cpu_cc_src2, cpu_cc_src2, 1);
1662 tcg_gen_xor_tl(cpu_cc_src2, cpu_cc_src2, cpu_cc_dst);
1663 set_cc_op(s, CC_OP_ADCOX);
1667 /* XXX: add faster immediate = 1 case */
1668 static void gen_rotc_rm_T1(DisasContext *s, TCGMemOp ot, int op1,
1671 gen_compute_eflags(s);
1672 assert(s->cc_op == CC_OP_EFLAGS);
1676 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1678 gen_op_mov_v_reg(ot, cpu_T0, op1);
1683 gen_helper_rcrb(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1686 gen_helper_rcrw(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1689 gen_helper_rcrl(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1691 #ifdef TARGET_X86_64
1693 gen_helper_rcrq(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1702 gen_helper_rclb(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1705 gen_helper_rclw(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1708 gen_helper_rcll(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1710 #ifdef TARGET_X86_64
1712 gen_helper_rclq(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1720 gen_op_st_rm_T0_A0(s, ot, op1);
1723 /* XXX: add faster immediate case */
1724 static void gen_shiftd_rm_T1(DisasContext *s, TCGMemOp ot, int op1,
1725 bool is_right, TCGv count_in)
1727 target_ulong mask = (ot == MO_64 ? 63 : 31);
1731 if (op1 == OR_TMP0) {
1732 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1734 gen_op_mov_v_reg(ot, cpu_T0, op1);
1737 count = tcg_temp_new();
1738 tcg_gen_andi_tl(count, count_in, mask);
1742 /* Note: we implement the Intel behaviour for shift count > 16.
1743 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A
1744 portion by constructing it as a 32-bit value. */
1746 tcg_gen_deposit_tl(cpu_tmp0, cpu_T0, cpu_T1, 16, 16);
1747 tcg_gen_mov_tl(cpu_T1, cpu_T0);
1748 tcg_gen_mov_tl(cpu_T0, cpu_tmp0);
1750 tcg_gen_deposit_tl(cpu_T1, cpu_T0, cpu_T1, 16, 16);
1753 #ifdef TARGET_X86_64
1755 /* Concatenate the two 32-bit values and use a 64-bit shift. */
1756 tcg_gen_subi_tl(cpu_tmp0, count, 1);
1758 tcg_gen_concat_tl_i64(cpu_T0, cpu_T0, cpu_T1);
1759 tcg_gen_shr_i64(cpu_tmp0, cpu_T0, cpu_tmp0);
1760 tcg_gen_shr_i64(cpu_T0, cpu_T0, count);
1762 tcg_gen_concat_tl_i64(cpu_T0, cpu_T1, cpu_T0);
1763 tcg_gen_shl_i64(cpu_tmp0, cpu_T0, cpu_tmp0);
1764 tcg_gen_shl_i64(cpu_T0, cpu_T0, count);
1765 tcg_gen_shri_i64(cpu_tmp0, cpu_tmp0, 32);
1766 tcg_gen_shri_i64(cpu_T0, cpu_T0, 32);
1771 tcg_gen_subi_tl(cpu_tmp0, count, 1);
1773 tcg_gen_shr_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1775 tcg_gen_subfi_tl(cpu_tmp4, mask + 1, count);
1776 tcg_gen_shr_tl(cpu_T0, cpu_T0, count);
1777 tcg_gen_shl_tl(cpu_T1, cpu_T1, cpu_tmp4);
1779 tcg_gen_shl_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1781 /* Only needed if count > 16, for Intel behaviour. */
1782 tcg_gen_subfi_tl(cpu_tmp4, 33, count);
1783 tcg_gen_shr_tl(cpu_tmp4, cpu_T1, cpu_tmp4);
1784 tcg_gen_or_tl(cpu_tmp0, cpu_tmp0, cpu_tmp4);
1787 tcg_gen_subfi_tl(cpu_tmp4, mask + 1, count);
1788 tcg_gen_shl_tl(cpu_T0, cpu_T0, count);
1789 tcg_gen_shr_tl(cpu_T1, cpu_T1, cpu_tmp4);
1791 tcg_gen_movi_tl(cpu_tmp4, 0);
1792 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_T1, count, cpu_tmp4,
1794 tcg_gen_or_tl(cpu_T0, cpu_T0, cpu_T1);
1799 gen_op_st_rm_T0_A0(s, ot, op1);
1801 gen_shift_flags(s, ot, cpu_T0, cpu_tmp0, count, is_right);
1802 tcg_temp_free(count);
1805 static void gen_shift(DisasContext *s1, int op, TCGMemOp ot, int d, int s)
1808 gen_op_mov_v_reg(ot, cpu_T1, s);
1811 gen_rot_rm_T1(s1, ot, d, 0);
1814 gen_rot_rm_T1(s1, ot, d, 1);
1818 gen_shift_rm_T1(s1, ot, d, 0, 0);
1821 gen_shift_rm_T1(s1, ot, d, 1, 0);
1824 gen_shift_rm_T1(s1, ot, d, 1, 1);
1827 gen_rotc_rm_T1(s1, ot, d, 0);
1830 gen_rotc_rm_T1(s1, ot, d, 1);
1835 static void gen_shifti(DisasContext *s1, int op, TCGMemOp ot, int d, int c)
1839 gen_rot_rm_im(s1, ot, d, c, 0);
1842 gen_rot_rm_im(s1, ot, d, c, 1);
1846 gen_shift_rm_im(s1, ot, d, c, 0, 0);
1849 gen_shift_rm_im(s1, ot, d, c, 1, 0);
1852 gen_shift_rm_im(s1, ot, d, c, 1, 1);
1855 /* currently not optimized */
1856 tcg_gen_movi_tl(cpu_T1, c);
1857 gen_shift(s1, op, ot, d, OR_TMP1);
1862 /* Decompose an address. */
1864 typedef struct AddressParts {
1872 static AddressParts gen_lea_modrm_0(CPUX86State *env, DisasContext *s,
1875 int def_seg, base, index, scale, mod, rm;
1884 mod = (modrm >> 6) & 3;
1886 base = rm | REX_B(s);
1889 /* Normally filtered out earlier, but including this path
1890 simplifies multi-byte nop, as well as bndcl, bndcu, bndcn. */
1899 int code = cpu_ldub_code(env, s->pc++);
1900 scale = (code >> 6) & 3;
1901 index = ((code >> 3) & 7) | REX_X(s);
1903 index = -1; /* no index */
1905 base = (code & 7) | REX_B(s);
1911 if ((base & 7) == 5) {
1913 disp = (int32_t)cpu_ldl_code(env, s->pc);
1915 if (CODE64(s) && !havesib) {
1917 disp += s->pc + s->rip_offset;
1922 disp = (int8_t)cpu_ldub_code(env, s->pc++);
1926 disp = (int32_t)cpu_ldl_code(env, s->pc);
1931 /* For correct popl handling with esp. */
1932 if (base == R_ESP && s->popl_esp_hack) {
1933 disp += s->popl_esp_hack;
1935 if (base == R_EBP || base == R_ESP) {
1944 disp = cpu_lduw_code(env, s->pc);
1948 } else if (mod == 1) {
1949 disp = (int8_t)cpu_ldub_code(env, s->pc++);
1951 disp = (int16_t)cpu_lduw_code(env, s->pc);
1996 return (AddressParts){ def_seg, base, index, scale, disp };
1999 /* Compute the address, with a minimum number of TCG ops. */
2000 static TCGv gen_lea_modrm_1(AddressParts a)
2007 ea = cpu_regs[a.index];
2009 tcg_gen_shli_tl(cpu_A0, cpu_regs[a.index], a.scale);
2013 tcg_gen_add_tl(cpu_A0, ea, cpu_regs[a.base]);
2016 } else if (a.base >= 0) {
2017 ea = cpu_regs[a.base];
2019 if (TCGV_IS_UNUSED(ea)) {
2020 tcg_gen_movi_tl(cpu_A0, a.disp);
2022 } else if (a.disp != 0) {
2023 tcg_gen_addi_tl(cpu_A0, ea, a.disp);
2030 static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm)
2032 AddressParts a = gen_lea_modrm_0(env, s, modrm);
2033 TCGv ea = gen_lea_modrm_1(a);
2034 gen_lea_v_seg(s, s->aflag, ea, a.def_seg, s->override);
2037 static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm)
2039 (void)gen_lea_modrm_0(env, s, modrm);
2042 /* Used for BNDCL, BNDCU, BNDCN. */
2043 static void gen_bndck(CPUX86State *env, DisasContext *s, int modrm,
2044 TCGCond cond, TCGv_i64 bndv)
2046 TCGv ea = gen_lea_modrm_1(gen_lea_modrm_0(env, s, modrm));
2048 tcg_gen_extu_tl_i64(cpu_tmp1_i64, ea);
2050 tcg_gen_ext32u_i64(cpu_tmp1_i64, cpu_tmp1_i64);
2052 tcg_gen_setcond_i64(cond, cpu_tmp1_i64, cpu_tmp1_i64, bndv);
2053 tcg_gen_extrl_i64_i32(cpu_tmp2_i32, cpu_tmp1_i64);
2054 gen_helper_bndck(cpu_env, cpu_tmp2_i32);
2057 /* used for LEA and MOV AX, mem */
2058 static void gen_add_A0_ds_seg(DisasContext *s)
2060 gen_lea_v_seg(s, s->aflag, cpu_A0, R_DS, s->override);
2063 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2065 static void gen_ldst_modrm(CPUX86State *env, DisasContext *s, int modrm,
2066 TCGMemOp ot, int reg, int is_store)
2070 mod = (modrm >> 6) & 3;
2071 rm = (modrm & 7) | REX_B(s);
2075 gen_op_mov_v_reg(ot, cpu_T0, reg);
2076 gen_op_mov_reg_v(ot, rm, cpu_T0);
2078 gen_op_mov_v_reg(ot, cpu_T0, rm);
2080 gen_op_mov_reg_v(ot, reg, cpu_T0);
2083 gen_lea_modrm(env, s, modrm);
2086 gen_op_mov_v_reg(ot, cpu_T0, reg);
2087 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
2089 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
2091 gen_op_mov_reg_v(ot, reg, cpu_T0);
2096 static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, TCGMemOp ot)
2102 ret = cpu_ldub_code(env, s->pc);
2106 ret = cpu_lduw_code(env, s->pc);
2110 #ifdef TARGET_X86_64
2113 ret = cpu_ldl_code(env, s->pc);
2122 static inline int insn_const_size(TCGMemOp ot)
2131 static inline bool use_goto_tb(DisasContext *s, target_ulong pc)
2133 #ifndef CONFIG_USER_ONLY
2134 return (pc & TARGET_PAGE_MASK) == (s->tb->pc & TARGET_PAGE_MASK) ||
2135 (pc & TARGET_PAGE_MASK) == (s->pc_start & TARGET_PAGE_MASK);
2141 static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
2143 target_ulong pc = s->cs_base + eip;
2145 if (use_goto_tb(s, pc)) {
2146 /* jump to same page: we can use a direct jump */
2147 tcg_gen_goto_tb(tb_num);
2149 tcg_gen_exit_tb((uintptr_t)s->tb + tb_num);
2151 /* jump to another page: currently not optimized */
2157 static inline void gen_jcc(DisasContext *s, int b,
2158 target_ulong val, target_ulong next_eip)
2163 l1 = gen_new_label();
2166 gen_goto_tb(s, 0, next_eip);
2169 gen_goto_tb(s, 1, val);
2170 s->is_jmp = DISAS_TB_JUMP;
2172 l1 = gen_new_label();
2173 l2 = gen_new_label();
2176 gen_jmp_im(next_eip);
2186 static void gen_cmovcc1(CPUX86State *env, DisasContext *s, TCGMemOp ot, int b,
2191 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
2193 cc = gen_prepare_cc(s, b, cpu_T1);
2194 if (cc.mask != -1) {
2195 TCGv t0 = tcg_temp_new();
2196 tcg_gen_andi_tl(t0, cc.reg, cc.mask);
2200 cc.reg2 = tcg_const_tl(cc.imm);
2203 tcg_gen_movcond_tl(cc.cond, cpu_T0, cc.reg, cc.reg2,
2204 cpu_T0, cpu_regs[reg]);
2205 gen_op_mov_reg_v(ot, reg, cpu_T0);
2207 if (cc.mask != -1) {
2208 tcg_temp_free(cc.reg);
2211 tcg_temp_free(cc.reg2);
2215 static inline void gen_op_movl_T0_seg(int seg_reg)
2217 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
2218 offsetof(CPUX86State,segs[seg_reg].selector));
2221 static inline void gen_op_movl_seg_T0_vm(int seg_reg)
2223 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
2224 tcg_gen_st32_tl(cpu_T0, cpu_env,
2225 offsetof(CPUX86State,segs[seg_reg].selector));
2226 tcg_gen_shli_tl(cpu_seg_base[seg_reg], cpu_T0, 4);
2229 /* move T0 to seg_reg and compute if the CPU state may change. Never
2230 call this function with seg_reg == R_CS */
2231 static void gen_movl_seg_T0(DisasContext *s, int seg_reg)
2233 if (s->pe && !s->vm86) {
2234 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
2235 gen_helper_load_seg(cpu_env, tcg_const_i32(seg_reg), cpu_tmp2_i32);
2236 /* abort translation because the addseg value may change or
2237 because ss32 may change. For R_SS, translation must always
2238 stop as a special handling must be done to disable hardware
2239 interrupts for the next instruction */
2240 if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS))
2241 s->is_jmp = DISAS_TB_JUMP;
2243 gen_op_movl_seg_T0_vm(seg_reg);
2244 if (seg_reg == R_SS)
2245 s->is_jmp = DISAS_TB_JUMP;
2249 static inline int svm_is_rep(int prefixes)
2251 return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0);
2255 gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
2256 uint32_t type, uint64_t param)
2258 /* no SVM activated; fast case */
2259 if (likely(!(s->flags & HF_SVMI_MASK)))
2261 gen_update_cc_op(s);
2262 gen_jmp_im(pc_start - s->cs_base);
2263 gen_helper_svm_check_intercept_param(cpu_env, tcg_const_i32(type),
2264 tcg_const_i64(param));
2268 gen_svm_check_intercept(DisasContext *s, target_ulong pc_start, uint64_t type)
2270 gen_svm_check_intercept_param(s, pc_start, type, 0);
2273 static inline void gen_stack_update(DisasContext *s, int addend)
2275 gen_op_add_reg_im(mo_stacksize(s), R_ESP, addend);
2278 /* Generate a push. It depends on ss32, addseg and dflag. */
2279 static void gen_push_v(DisasContext *s, TCGv val)
2281 TCGMemOp d_ot = mo_pushpop(s, s->dflag);
2282 TCGMemOp a_ot = mo_stacksize(s);
2283 int size = 1 << d_ot;
2284 TCGv new_esp = cpu_A0;
2286 tcg_gen_subi_tl(cpu_A0, cpu_regs[R_ESP], size);
2291 tcg_gen_mov_tl(new_esp, cpu_A0);
2293 gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1);
2296 gen_op_st_v(s, d_ot, val, cpu_A0);
2297 gen_op_mov_reg_v(a_ot, R_ESP, new_esp);
2300 /* two step pop is necessary for precise exceptions */
2301 static TCGMemOp gen_pop_T0(DisasContext *s)
2303 TCGMemOp d_ot = mo_pushpop(s, s->dflag);
2305 gen_lea_v_seg(s, mo_stacksize(s), cpu_regs[R_ESP], R_SS, -1);
2306 gen_op_ld_v(s, d_ot, cpu_T0, cpu_A0);
2311 static inline void gen_pop_update(DisasContext *s, TCGMemOp ot)
2313 gen_stack_update(s, 1 << ot);
2316 static inline void gen_stack_A0(DisasContext *s)
2318 gen_lea_v_seg(s, s->ss32 ? MO_32 : MO_16, cpu_regs[R_ESP], R_SS, -1);
2321 static void gen_pusha(DisasContext *s)
2323 TCGMemOp s_ot = s->ss32 ? MO_32 : MO_16;
2324 TCGMemOp d_ot = s->dflag;
2325 int size = 1 << d_ot;
2328 for (i = 0; i < 8; i++) {
2329 tcg_gen_addi_tl(cpu_A0, cpu_regs[R_ESP], (i - 8) * size);
2330 gen_lea_v_seg(s, s_ot, cpu_A0, R_SS, -1);
2331 gen_op_st_v(s, d_ot, cpu_regs[7 - i], cpu_A0);
2334 gen_stack_update(s, -8 * size);
2337 static void gen_popa(DisasContext *s)
2339 TCGMemOp s_ot = s->ss32 ? MO_32 : MO_16;
2340 TCGMemOp d_ot = s->dflag;
2341 int size = 1 << d_ot;
2344 for (i = 0; i < 8; i++) {
2345 /* ESP is not reloaded */
2346 if (7 - i == R_ESP) {
2349 tcg_gen_addi_tl(cpu_A0, cpu_regs[R_ESP], i * size);
2350 gen_lea_v_seg(s, s_ot, cpu_A0, R_SS, -1);
2351 gen_op_ld_v(s, d_ot, cpu_T0, cpu_A0);
2352 gen_op_mov_reg_v(d_ot, 7 - i, cpu_T0);
2355 gen_stack_update(s, 8 * size);
2358 static void gen_enter(DisasContext *s, int esp_addend, int level)
2360 TCGMemOp d_ot = mo_pushpop(s, s->dflag);
2361 TCGMemOp a_ot = CODE64(s) ? MO_64 : s->ss32 ? MO_32 : MO_16;
2362 int size = 1 << d_ot;
2364 /* Push BP; compute FrameTemp into T1. */
2365 tcg_gen_subi_tl(cpu_T1, cpu_regs[R_ESP], size);
2366 gen_lea_v_seg(s, a_ot, cpu_T1, R_SS, -1);
2367 gen_op_st_v(s, d_ot, cpu_regs[R_EBP], cpu_A0);
2373 /* Copy level-1 pointers from the previous frame. */
2374 for (i = 1; i < level; ++i) {
2375 tcg_gen_subi_tl(cpu_A0, cpu_regs[R_EBP], size * i);
2376 gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1);
2377 gen_op_ld_v(s, d_ot, cpu_tmp0, cpu_A0);
2379 tcg_gen_subi_tl(cpu_A0, cpu_T1, size * i);
2380 gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1);
2381 gen_op_st_v(s, d_ot, cpu_tmp0, cpu_A0);
2384 /* Push the current FrameTemp as the last level. */
2385 tcg_gen_subi_tl(cpu_A0, cpu_T1, size * level);
2386 gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1);
2387 gen_op_st_v(s, d_ot, cpu_T1, cpu_A0);
2390 /* Copy the FrameTemp value to EBP. */
2391 gen_op_mov_reg_v(a_ot, R_EBP, cpu_T1);
2393 /* Compute the final value of ESP. */
2394 tcg_gen_subi_tl(cpu_T1, cpu_T1, esp_addend + size * level);
2395 gen_op_mov_reg_v(a_ot, R_ESP, cpu_T1);
2398 static void gen_leave(DisasContext *s)
2400 TCGMemOp d_ot = mo_pushpop(s, s->dflag);
2401 TCGMemOp a_ot = mo_stacksize(s);
2403 gen_lea_v_seg(s, a_ot, cpu_regs[R_EBP], R_SS, -1);
2404 gen_op_ld_v(s, d_ot, cpu_T0, cpu_A0);
2406 tcg_gen_addi_tl(cpu_T1, cpu_regs[R_EBP], 1 << d_ot);
2408 gen_op_mov_reg_v(d_ot, R_EBP, cpu_T0);
2409 gen_op_mov_reg_v(a_ot, R_ESP, cpu_T1);
2412 static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
2414 gen_update_cc_op(s);
2415 gen_jmp_im(cur_eip);
2416 gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno));
2417 s->is_jmp = DISAS_TB_JUMP;
2420 /* Generate #UD for the current instruction. The assumption here is that
2421 the instruction is known, but it isn't allowed in the current cpu mode. */
2422 static void gen_illegal_opcode(DisasContext *s)
2424 gen_exception(s, EXCP06_ILLOP, s->pc_start - s->cs_base);
2427 /* Similarly, except that the assumption here is that we don't decode
2428 the instruction at all -- either a missing opcode, an unimplemented
2429 feature, or just a bogus instruction stream. */
2430 static void gen_unknown_opcode(CPUX86State *env, DisasContext *s)
2432 gen_illegal_opcode(s);
2434 if (qemu_loglevel_mask(LOG_UNIMP)) {
2435 target_ulong pc = s->pc_start, end = s->pc;
2437 qemu_log("ILLOPC: " TARGET_FMT_lx ":", pc);
2438 for (; pc < end; ++pc) {
2439 qemu_log(" %02x", cpu_ldub_code(env, pc));
2446 /* an interrupt is different from an exception because of the
2448 static void gen_interrupt(DisasContext *s, int intno,
2449 target_ulong cur_eip, target_ulong next_eip)
2451 gen_update_cc_op(s);
2452 gen_jmp_im(cur_eip);
2453 gen_helper_raise_interrupt(cpu_env, tcg_const_i32(intno),
2454 tcg_const_i32(next_eip - cur_eip));
2455 s->is_jmp = DISAS_TB_JUMP;
2458 static void gen_debug(DisasContext *s, target_ulong cur_eip)
2460 gen_update_cc_op(s);
2461 gen_jmp_im(cur_eip);
2462 gen_helper_debug(cpu_env);
2463 s->is_jmp = DISAS_TB_JUMP;
2466 static void gen_set_hflag(DisasContext *s, uint32_t mask)
2468 if ((s->flags & mask) == 0) {
2469 TCGv_i32 t = tcg_temp_new_i32();
2470 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2471 tcg_gen_ori_i32(t, t, mask);
2472 tcg_gen_st_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2473 tcg_temp_free_i32(t);
2478 static void gen_reset_hflag(DisasContext *s, uint32_t mask)
2480 if (s->flags & mask) {
2481 TCGv_i32 t = tcg_temp_new_i32();
2482 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2483 tcg_gen_andi_i32(t, t, ~mask);
2484 tcg_gen_st_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2485 tcg_temp_free_i32(t);
2490 /* Clear BND registers during legacy branches. */
2491 static void gen_bnd_jmp(DisasContext *s)
2493 /* Clear the registers only if BND prefix is missing, MPX is enabled,
2494 and if the BNDREGs are known to be in use (non-zero) already.
2495 The helper itself will check BNDPRESERVE at runtime. */
2496 if ((s->prefix & PREFIX_REPNZ) == 0
2497 && (s->flags & HF_MPX_EN_MASK) != 0
2498 && (s->flags & HF_MPX_IU_MASK) != 0) {
2499 gen_helper_bnd_jmp(cpu_env);
2503 /* Generate an end of block. Trace exception is also generated if needed.
2504 If IIM, set HF_INHIBIT_IRQ_MASK if it isn't already set. */
2505 static void gen_eob_inhibit_irq(DisasContext *s, bool inhibit)
2507 gen_update_cc_op(s);
2509 /* If several instructions disable interrupts, only the first does it. */
2510 if (inhibit && !(s->flags & HF_INHIBIT_IRQ_MASK)) {
2511 gen_set_hflag(s, HF_INHIBIT_IRQ_MASK);
2513 gen_reset_hflag(s, HF_INHIBIT_IRQ_MASK);
2516 if (s->tb->flags & HF_RF_MASK) {
2517 gen_helper_reset_rf(cpu_env);
2519 if (s->singlestep_enabled) {
2520 gen_helper_debug(cpu_env);
2522 gen_helper_single_step(cpu_env);
2526 s->is_jmp = DISAS_TB_JUMP;
2529 /* End of block, resetting the inhibit irq flag. */
2530 static void gen_eob(DisasContext *s)
2532 gen_eob_inhibit_irq(s, false);
2535 /* generate a jump to eip. No segment change must happen before as a
2536 direct call to the next block may occur */
2537 static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
2539 gen_update_cc_op(s);
2540 set_cc_op(s, CC_OP_DYNAMIC);
2542 gen_goto_tb(s, tb_num, eip);
2543 s->is_jmp = DISAS_TB_JUMP;
2550 static void gen_jmp(DisasContext *s, target_ulong eip)
2552 gen_jmp_tb(s, eip, 0);
2555 static inline void gen_ldq_env_A0(DisasContext *s, int offset)
2557 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
2558 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset);
2561 static inline void gen_stq_env_A0(DisasContext *s, int offset)
2563 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset);
2564 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
2567 static inline void gen_ldo_env_A0(DisasContext *s, int offset)
2569 int mem_index = s->mem_index;
2570 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, mem_index, MO_LEQ);
2571 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(0)));
2572 tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2573 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_tmp0, mem_index, MO_LEQ);
2574 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(1)));
2577 static inline void gen_sto_env_A0(DisasContext *s, int offset)
2579 int mem_index = s->mem_index;
2580 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(0)));
2581 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, mem_index, MO_LEQ);
2582 tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2583 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(1)));
2584 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_tmp0, mem_index, MO_LEQ);
2587 static inline void gen_op_movo(int d_offset, int s_offset)
2589 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + offsetof(ZMMReg, ZMM_Q(0)));
2590 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + offsetof(ZMMReg, ZMM_Q(0)));
2591 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + offsetof(ZMMReg, ZMM_Q(1)));
2592 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + offsetof(ZMMReg, ZMM_Q(1)));
2595 static inline void gen_op_movq(int d_offset, int s_offset)
2597 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
2598 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2601 static inline void gen_op_movl(int d_offset, int s_offset)
2603 tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env, s_offset);
2604 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, d_offset);
2607 static inline void gen_op_movq_env_0(int d_offset)
2609 tcg_gen_movi_i64(cpu_tmp1_i64, 0);
2610 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2613 typedef void (*SSEFunc_i_ep)(TCGv_i32 val, TCGv_ptr env, TCGv_ptr reg);
2614 typedef void (*SSEFunc_l_ep)(TCGv_i64 val, TCGv_ptr env, TCGv_ptr reg);
2615 typedef void (*SSEFunc_0_epi)(TCGv_ptr env, TCGv_ptr reg, TCGv_i32 val);
2616 typedef void (*SSEFunc_0_epl)(TCGv_ptr env, TCGv_ptr reg, TCGv_i64 val);
2617 typedef void (*SSEFunc_0_epp)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b);
2618 typedef void (*SSEFunc_0_eppi)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2620 typedef void (*SSEFunc_0_ppi)(TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv_i32 val);
2621 typedef void (*SSEFunc_0_eppt)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2624 #define SSE_SPECIAL ((void *)1)
2625 #define SSE_DUMMY ((void *)2)
2627 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2628 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2629 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2631 static const SSEFunc_0_epp sse_op_table1[256][4] = {
2632 /* 3DNow! extensions */
2633 [0x0e] = { SSE_DUMMY }, /* femms */
2634 [0x0f] = { SSE_DUMMY }, /* pf... */
2635 /* pure SSE operations */
2636 [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2637 [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2638 [0x12] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd, movsldup, movddup */
2639 [0x13] = { SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd */
2640 [0x14] = { gen_helper_punpckldq_xmm, gen_helper_punpcklqdq_xmm },
2641 [0x15] = { gen_helper_punpckhdq_xmm, gen_helper_punpckhqdq_xmm },
2642 [0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movhps, movhpd, movshdup */
2643 [0x17] = { SSE_SPECIAL, SSE_SPECIAL }, /* movhps, movhpd */
2645 [0x28] = { SSE_SPECIAL, SSE_SPECIAL }, /* movaps, movapd */
2646 [0x29] = { SSE_SPECIAL, SSE_SPECIAL }, /* movaps, movapd */
2647 [0x2a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2648 [0x2b] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movntps, movntpd, movntss, movntsd */
2649 [0x2c] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2650 [0x2d] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2651 [0x2e] = { gen_helper_ucomiss, gen_helper_ucomisd },
2652 [0x2f] = { gen_helper_comiss, gen_helper_comisd },
2653 [0x50] = { SSE_SPECIAL, SSE_SPECIAL }, /* movmskps, movmskpd */
2654 [0x51] = SSE_FOP(sqrt),
2655 [0x52] = { gen_helper_rsqrtps, NULL, gen_helper_rsqrtss, NULL },
2656 [0x53] = { gen_helper_rcpps, NULL, gen_helper_rcpss, NULL },
2657 [0x54] = { gen_helper_pand_xmm, gen_helper_pand_xmm }, /* andps, andpd */
2658 [0x55] = { gen_helper_pandn_xmm, gen_helper_pandn_xmm }, /* andnps, andnpd */
2659 [0x56] = { gen_helper_por_xmm, gen_helper_por_xmm }, /* orps, orpd */
2660 [0x57] = { gen_helper_pxor_xmm, gen_helper_pxor_xmm }, /* xorps, xorpd */
2661 [0x58] = SSE_FOP(add),
2662 [0x59] = SSE_FOP(mul),
2663 [0x5a] = { gen_helper_cvtps2pd, gen_helper_cvtpd2ps,
2664 gen_helper_cvtss2sd, gen_helper_cvtsd2ss },
2665 [0x5b] = { gen_helper_cvtdq2ps, gen_helper_cvtps2dq, gen_helper_cvttps2dq },
2666 [0x5c] = SSE_FOP(sub),
2667 [0x5d] = SSE_FOP(min),
2668 [0x5e] = SSE_FOP(div),
2669 [0x5f] = SSE_FOP(max),
2671 [0xc2] = SSE_FOP(cmpeq),
2672 [0xc6] = { (SSEFunc_0_epp)gen_helper_shufps,
2673 (SSEFunc_0_epp)gen_helper_shufpd }, /* XXX: casts */
2675 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */
2676 [0x38] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2677 [0x3a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2679 /* MMX ops and their SSE extensions */
2680 [0x60] = MMX_OP2(punpcklbw),
2681 [0x61] = MMX_OP2(punpcklwd),
2682 [0x62] = MMX_OP2(punpckldq),
2683 [0x63] = MMX_OP2(packsswb),
2684 [0x64] = MMX_OP2(pcmpgtb),
2685 [0x65] = MMX_OP2(pcmpgtw),
2686 [0x66] = MMX_OP2(pcmpgtl),
2687 [0x67] = MMX_OP2(packuswb),
2688 [0x68] = MMX_OP2(punpckhbw),
2689 [0x69] = MMX_OP2(punpckhwd),
2690 [0x6a] = MMX_OP2(punpckhdq),
2691 [0x6b] = MMX_OP2(packssdw),
2692 [0x6c] = { NULL, gen_helper_punpcklqdq_xmm },
2693 [0x6d] = { NULL, gen_helper_punpckhqdq_xmm },
2694 [0x6e] = { SSE_SPECIAL, SSE_SPECIAL }, /* movd mm, ea */
2695 [0x6f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, , movqdu */
2696 [0x70] = { (SSEFunc_0_epp)gen_helper_pshufw_mmx,
2697 (SSEFunc_0_epp)gen_helper_pshufd_xmm,
2698 (SSEFunc_0_epp)gen_helper_pshufhw_xmm,
2699 (SSEFunc_0_epp)gen_helper_pshuflw_xmm }, /* XXX: casts */
2700 [0x71] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftw */
2701 [0x72] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftd */
2702 [0x73] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftq */
2703 [0x74] = MMX_OP2(pcmpeqb),
2704 [0x75] = MMX_OP2(pcmpeqw),
2705 [0x76] = MMX_OP2(pcmpeql),
2706 [0x77] = { SSE_DUMMY }, /* emms */
2707 [0x78] = { NULL, SSE_SPECIAL, NULL, SSE_SPECIAL }, /* extrq_i, insertq_i */
2708 [0x79] = { NULL, gen_helper_extrq_r, NULL, gen_helper_insertq_r },
2709 [0x7c] = { NULL, gen_helper_haddpd, NULL, gen_helper_haddps },
2710 [0x7d] = { NULL, gen_helper_hsubpd, NULL, gen_helper_hsubps },
2711 [0x7e] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movd, movd, , movq */
2712 [0x7f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, movdqu */
2713 [0xc4] = { SSE_SPECIAL, SSE_SPECIAL }, /* pinsrw */
2714 [0xc5] = { SSE_SPECIAL, SSE_SPECIAL }, /* pextrw */
2715 [0xd0] = { NULL, gen_helper_addsubpd, NULL, gen_helper_addsubps },
2716 [0xd1] = MMX_OP2(psrlw),
2717 [0xd2] = MMX_OP2(psrld),
2718 [0xd3] = MMX_OP2(psrlq),
2719 [0xd4] = MMX_OP2(paddq),
2720 [0xd5] = MMX_OP2(pmullw),
2721 [0xd6] = { NULL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2722 [0xd7] = { SSE_SPECIAL, SSE_SPECIAL }, /* pmovmskb */
2723 [0xd8] = MMX_OP2(psubusb),
2724 [0xd9] = MMX_OP2(psubusw),
2725 [0xda] = MMX_OP2(pminub),
2726 [0xdb] = MMX_OP2(pand),
2727 [0xdc] = MMX_OP2(paddusb),
2728 [0xdd] = MMX_OP2(paddusw),
2729 [0xde] = MMX_OP2(pmaxub),
2730 [0xdf] = MMX_OP2(pandn),
2731 [0xe0] = MMX_OP2(pavgb),
2732 [0xe1] = MMX_OP2(psraw),
2733 [0xe2] = MMX_OP2(psrad),
2734 [0xe3] = MMX_OP2(pavgw),
2735 [0xe4] = MMX_OP2(pmulhuw),
2736 [0xe5] = MMX_OP2(pmulhw),
2737 [0xe6] = { NULL, gen_helper_cvttpd2dq, gen_helper_cvtdq2pd, gen_helper_cvtpd2dq },
2738 [0xe7] = { SSE_SPECIAL , SSE_SPECIAL }, /* movntq, movntq */
2739 [0xe8] = MMX_OP2(psubsb),
2740 [0xe9] = MMX_OP2(psubsw),
2741 [0xea] = MMX_OP2(pminsw),
2742 [0xeb] = MMX_OP2(por),
2743 [0xec] = MMX_OP2(paddsb),
2744 [0xed] = MMX_OP2(paddsw),
2745 [0xee] = MMX_OP2(pmaxsw),
2746 [0xef] = MMX_OP2(pxor),
2747 [0xf0] = { NULL, NULL, NULL, SSE_SPECIAL }, /* lddqu */
2748 [0xf1] = MMX_OP2(psllw),
2749 [0xf2] = MMX_OP2(pslld),
2750 [0xf3] = MMX_OP2(psllq),
2751 [0xf4] = MMX_OP2(pmuludq),
2752 [0xf5] = MMX_OP2(pmaddwd),
2753 [0xf6] = MMX_OP2(psadbw),
2754 [0xf7] = { (SSEFunc_0_epp)gen_helper_maskmov_mmx,
2755 (SSEFunc_0_epp)gen_helper_maskmov_xmm }, /* XXX: casts */
2756 [0xf8] = MMX_OP2(psubb),
2757 [0xf9] = MMX_OP2(psubw),
2758 [0xfa] = MMX_OP2(psubl),
2759 [0xfb] = MMX_OP2(psubq),
2760 [0xfc] = MMX_OP2(paddb),
2761 [0xfd] = MMX_OP2(paddw),
2762 [0xfe] = MMX_OP2(paddl),
2765 static const SSEFunc_0_epp sse_op_table2[3 * 8][2] = {
2766 [0 + 2] = MMX_OP2(psrlw),
2767 [0 + 4] = MMX_OP2(psraw),
2768 [0 + 6] = MMX_OP2(psllw),
2769 [8 + 2] = MMX_OP2(psrld),
2770 [8 + 4] = MMX_OP2(psrad),
2771 [8 + 6] = MMX_OP2(pslld),
2772 [16 + 2] = MMX_OP2(psrlq),
2773 [16 + 3] = { NULL, gen_helper_psrldq_xmm },
2774 [16 + 6] = MMX_OP2(psllq),
2775 [16 + 7] = { NULL, gen_helper_pslldq_xmm },
2778 static const SSEFunc_0_epi sse_op_table3ai[] = {
2779 gen_helper_cvtsi2ss,
2783 #ifdef TARGET_X86_64
2784 static const SSEFunc_0_epl sse_op_table3aq[] = {
2785 gen_helper_cvtsq2ss,
2790 static const SSEFunc_i_ep sse_op_table3bi[] = {
2791 gen_helper_cvttss2si,
2792 gen_helper_cvtss2si,
2793 gen_helper_cvttsd2si,
2797 #ifdef TARGET_X86_64
2798 static const SSEFunc_l_ep sse_op_table3bq[] = {
2799 gen_helper_cvttss2sq,
2800 gen_helper_cvtss2sq,
2801 gen_helper_cvttsd2sq,
2806 static const SSEFunc_0_epp sse_op_table4[8][4] = {
2817 static const SSEFunc_0_epp sse_op_table5[256] = {
2818 [0x0c] = gen_helper_pi2fw,
2819 [0x0d] = gen_helper_pi2fd,
2820 [0x1c] = gen_helper_pf2iw,
2821 [0x1d] = gen_helper_pf2id,
2822 [0x8a] = gen_helper_pfnacc,
2823 [0x8e] = gen_helper_pfpnacc,
2824 [0x90] = gen_helper_pfcmpge,
2825 [0x94] = gen_helper_pfmin,
2826 [0x96] = gen_helper_pfrcp,
2827 [0x97] = gen_helper_pfrsqrt,
2828 [0x9a] = gen_helper_pfsub,
2829 [0x9e] = gen_helper_pfadd,
2830 [0xa0] = gen_helper_pfcmpgt,
2831 [0xa4] = gen_helper_pfmax,
2832 [0xa6] = gen_helper_movq, /* pfrcpit1; no need to actually increase precision */
2833 [0xa7] = gen_helper_movq, /* pfrsqit1 */
2834 [0xaa] = gen_helper_pfsubr,
2835 [0xae] = gen_helper_pfacc,
2836 [0xb0] = gen_helper_pfcmpeq,
2837 [0xb4] = gen_helper_pfmul,
2838 [0xb6] = gen_helper_movq, /* pfrcpit2 */
2839 [0xb7] = gen_helper_pmulhrw_mmx,
2840 [0xbb] = gen_helper_pswapd,
2841 [0xbf] = gen_helper_pavgb_mmx /* pavgusb */
2844 struct SSEOpHelper_epp {
2845 SSEFunc_0_epp op[2];
2849 struct SSEOpHelper_eppi {
2850 SSEFunc_0_eppi op[2];
2854 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
2855 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
2856 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
2857 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
2858 #define PCLMULQDQ_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, \
2859 CPUID_EXT_PCLMULQDQ }
2860 #define AESNI_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_AES }
2862 static const struct SSEOpHelper_epp sse_op_table6[256] = {
2863 [0x00] = SSSE3_OP(pshufb),
2864 [0x01] = SSSE3_OP(phaddw),
2865 [0x02] = SSSE3_OP(phaddd),
2866 [0x03] = SSSE3_OP(phaddsw),
2867 [0x04] = SSSE3_OP(pmaddubsw),
2868 [0x05] = SSSE3_OP(phsubw),
2869 [0x06] = SSSE3_OP(phsubd),
2870 [0x07] = SSSE3_OP(phsubsw),
2871 [0x08] = SSSE3_OP(psignb),
2872 [0x09] = SSSE3_OP(psignw),
2873 [0x0a] = SSSE3_OP(psignd),
2874 [0x0b] = SSSE3_OP(pmulhrsw),
2875 [0x10] = SSE41_OP(pblendvb),
2876 [0x14] = SSE41_OP(blendvps),
2877 [0x15] = SSE41_OP(blendvpd),
2878 [0x17] = SSE41_OP(ptest),
2879 [0x1c] = SSSE3_OP(pabsb),
2880 [0x1d] = SSSE3_OP(pabsw),
2881 [0x1e] = SSSE3_OP(pabsd),
2882 [0x20] = SSE41_OP(pmovsxbw),
2883 [0x21] = SSE41_OP(pmovsxbd),
2884 [0x22] = SSE41_OP(pmovsxbq),
2885 [0x23] = SSE41_OP(pmovsxwd),
2886 [0x24] = SSE41_OP(pmovsxwq),
2887 [0x25] = SSE41_OP(pmovsxdq),
2888 [0x28] = SSE41_OP(pmuldq),
2889 [0x29] = SSE41_OP(pcmpeqq),
2890 [0x2a] = SSE41_SPECIAL, /* movntqda */
2891 [0x2b] = SSE41_OP(packusdw),
2892 [0x30] = SSE41_OP(pmovzxbw),
2893 [0x31] = SSE41_OP(pmovzxbd),
2894 [0x32] = SSE41_OP(pmovzxbq),
2895 [0x33] = SSE41_OP(pmovzxwd),
2896 [0x34] = SSE41_OP(pmovzxwq),
2897 [0x35] = SSE41_OP(pmovzxdq),
2898 [0x37] = SSE42_OP(pcmpgtq),
2899 [0x38] = SSE41_OP(pminsb),
2900 [0x39] = SSE41_OP(pminsd),
2901 [0x3a] = SSE41_OP(pminuw),
2902 [0x3b] = SSE41_OP(pminud),
2903 [0x3c] = SSE41_OP(pmaxsb),
2904 [0x3d] = SSE41_OP(pmaxsd),
2905 [0x3e] = SSE41_OP(pmaxuw),
2906 [0x3f] = SSE41_OP(pmaxud),
2907 [0x40] = SSE41_OP(pmulld),
2908 [0x41] = SSE41_OP(phminposuw),
2909 [0xdb] = AESNI_OP(aesimc),
2910 [0xdc] = AESNI_OP(aesenc),
2911 [0xdd] = AESNI_OP(aesenclast),
2912 [0xde] = AESNI_OP(aesdec),
2913 [0xdf] = AESNI_OP(aesdeclast),
2916 static const struct SSEOpHelper_eppi sse_op_table7[256] = {
2917 [0x08] = SSE41_OP(roundps),
2918 [0x09] = SSE41_OP(roundpd),
2919 [0x0a] = SSE41_OP(roundss),
2920 [0x0b] = SSE41_OP(roundsd),
2921 [0x0c] = SSE41_OP(blendps),
2922 [0x0d] = SSE41_OP(blendpd),
2923 [0x0e] = SSE41_OP(pblendw),
2924 [0x0f] = SSSE3_OP(palignr),
2925 [0x14] = SSE41_SPECIAL, /* pextrb */
2926 [0x15] = SSE41_SPECIAL, /* pextrw */
2927 [0x16] = SSE41_SPECIAL, /* pextrd/pextrq */
2928 [0x17] = SSE41_SPECIAL, /* extractps */
2929 [0x20] = SSE41_SPECIAL, /* pinsrb */
2930 [0x21] = SSE41_SPECIAL, /* insertps */
2931 [0x22] = SSE41_SPECIAL, /* pinsrd/pinsrq */
2932 [0x40] = SSE41_OP(dpps),
2933 [0x41] = SSE41_OP(dppd),
2934 [0x42] = SSE41_OP(mpsadbw),
2935 [0x44] = PCLMULQDQ_OP(pclmulqdq),
2936 [0x60] = SSE42_OP(pcmpestrm),
2937 [0x61] = SSE42_OP(pcmpestri),
2938 [0x62] = SSE42_OP(pcmpistrm),
2939 [0x63] = SSE42_OP(pcmpistri),
2940 [0xdf] = AESNI_OP(aeskeygenassist),
2943 static void gen_sse(CPUX86State *env, DisasContext *s, int b,
2944 target_ulong pc_start, int rex_r)
2946 int b1, op1_offset, op2_offset, is_xmm, val;
2947 int modrm, mod, rm, reg;
2948 SSEFunc_0_epp sse_fn_epp;
2949 SSEFunc_0_eppi sse_fn_eppi;
2950 SSEFunc_0_ppi sse_fn_ppi;
2951 SSEFunc_0_eppt sse_fn_eppt;
2955 if (s->prefix & PREFIX_DATA)
2957 else if (s->prefix & PREFIX_REPZ)
2959 else if (s->prefix & PREFIX_REPNZ)
2963 sse_fn_epp = sse_op_table1[b][b1];
2967 if ((b <= 0x5f && b >= 0x10) || b == 0xc6 || b == 0xc2) {
2977 /* simple MMX/SSE operation */
2978 if (s->flags & HF_TS_MASK) {
2979 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
2982 if (s->flags & HF_EM_MASK) {
2984 gen_illegal_opcode(s);
2988 && !(s->flags & HF_OSFXSR_MASK)
2989 && ((b != 0x38 && b != 0x3a) || (s->prefix & PREFIX_DATA))) {
2993 if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) {
2994 /* If we were fully decoding this we might use illegal_op. */
2998 gen_helper_emms(cpu_env);
3003 gen_helper_emms(cpu_env);
3006 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3007 the static cpu state) */
3009 gen_helper_enter_mmx(cpu_env);
3012 modrm = cpu_ldub_code(env, s->pc++);
3013 reg = ((modrm >> 3) & 7);
3016 mod = (modrm >> 6) & 3;
3017 if (sse_fn_epp == SSE_SPECIAL) {
3020 case 0x0e7: /* movntq */
3024 gen_lea_modrm(env, s, modrm);
3025 gen_stq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
3027 case 0x1e7: /* movntdq */
3028 case 0x02b: /* movntps */
3029 case 0x12b: /* movntps */
3032 gen_lea_modrm(env, s, modrm);
3033 gen_sto_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3035 case 0x3f0: /* lddqu */
3038 gen_lea_modrm(env, s, modrm);
3039 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3041 case 0x22b: /* movntss */
3042 case 0x32b: /* movntsd */
3045 gen_lea_modrm(env, s, modrm);
3047 gen_stq_env_A0(s, offsetof(CPUX86State,
3048 xmm_regs[reg].ZMM_Q(0)));
3050 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
3051 xmm_regs[reg].ZMM_L(0)));
3052 gen_op_st_v(s, MO_32, cpu_T0, cpu_A0);
3055 case 0x6e: /* movd mm, ea */
3056 #ifdef TARGET_X86_64
3057 if (s->dflag == MO_64) {
3058 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 0);
3059 tcg_gen_st_tl(cpu_T0, cpu_env, offsetof(CPUX86State,fpregs[reg].mmx));
3063 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 0);
3064 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3065 offsetof(CPUX86State,fpregs[reg].mmx));
3066 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
3067 gen_helper_movl_mm_T0_mmx(cpu_ptr0, cpu_tmp2_i32);
3070 case 0x16e: /* movd xmm, ea */
3071 #ifdef TARGET_X86_64
3072 if (s->dflag == MO_64) {
3073 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 0);
3074 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3075 offsetof(CPUX86State,xmm_regs[reg]));
3076 gen_helper_movq_mm_T0_xmm(cpu_ptr0, cpu_T0);
3080 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 0);
3081 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3082 offsetof(CPUX86State,xmm_regs[reg]));
3083 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
3084 gen_helper_movl_mm_T0_xmm(cpu_ptr0, cpu_tmp2_i32);
3087 case 0x6f: /* movq mm, ea */
3089 gen_lea_modrm(env, s, modrm);
3090 gen_ldq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
3093 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
3094 offsetof(CPUX86State,fpregs[rm].mmx));
3095 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
3096 offsetof(CPUX86State,fpregs[reg].mmx));
3099 case 0x010: /* movups */
3100 case 0x110: /* movupd */
3101 case 0x028: /* movaps */
3102 case 0x128: /* movapd */
3103 case 0x16f: /* movdqa xmm, ea */
3104 case 0x26f: /* movdqu xmm, ea */
3106 gen_lea_modrm(env, s, modrm);
3107 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3109 rm = (modrm & 7) | REX_B(s);
3110 gen_op_movo(offsetof(CPUX86State,xmm_regs[reg]),
3111 offsetof(CPUX86State,xmm_regs[rm]));
3114 case 0x210: /* movss xmm, ea */
3116 gen_lea_modrm(env, s, modrm);
3117 gen_op_ld_v(s, MO_32, cpu_T0, cpu_A0);
3118 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3119 tcg_gen_movi_tl(cpu_T0, 0);
3120 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)));
3121 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)));
3122 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)));
3124 rm = (modrm & 7) | REX_B(s);
3125 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)),
3126 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0)));
3129 case 0x310: /* movsd xmm, ea */
3131 gen_lea_modrm(env, s, modrm);
3132 gen_ldq_env_A0(s, offsetof(CPUX86State,
3133 xmm_regs[reg].ZMM_Q(0)));
3134 tcg_gen_movi_tl(cpu_T0, 0);
3135 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)));
3136 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)));
3138 rm = (modrm & 7) | REX_B(s);
3139 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3140 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3143 case 0x012: /* movlps */
3144 case 0x112: /* movlpd */
3146 gen_lea_modrm(env, s, modrm);
3147 gen_ldq_env_A0(s, offsetof(CPUX86State,
3148 xmm_regs[reg].ZMM_Q(0)));
3151 rm = (modrm & 7) | REX_B(s);
3152 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3153 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(1)));
3156 case 0x212: /* movsldup */
3158 gen_lea_modrm(env, s, modrm);
3159 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3161 rm = (modrm & 7) | REX_B(s);
3162 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)),
3163 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0)));
3164 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)),
3165 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(2)));
3167 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)),
3168 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3169 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)),
3170 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)));
3172 case 0x312: /* movddup */
3174 gen_lea_modrm(env, s, modrm);
3175 gen_ldq_env_A0(s, offsetof(CPUX86State,
3176 xmm_regs[reg].ZMM_Q(0)));
3178 rm = (modrm & 7) | REX_B(s);
3179 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3180 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3182 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)),
3183 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3185 case 0x016: /* movhps */
3186 case 0x116: /* movhpd */
3188 gen_lea_modrm(env, s, modrm);
3189 gen_ldq_env_A0(s, offsetof(CPUX86State,
3190 xmm_regs[reg].ZMM_Q(1)));
3193 rm = (modrm & 7) | REX_B(s);
3194 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)),
3195 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3198 case 0x216: /* movshdup */
3200 gen_lea_modrm(env, s, modrm);
3201 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3203 rm = (modrm & 7) | REX_B(s);
3204 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)),
3205 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(1)));
3206 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)),
3207 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(3)));
3209 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)),
3210 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)));
3211 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)),
3212 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)));
3217 int bit_index, field_length;
3219 if (b1 == 1 && reg != 0)
3221 field_length = cpu_ldub_code(env, s->pc++) & 0x3F;
3222 bit_index = cpu_ldub_code(env, s->pc++) & 0x3F;
3223 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3224 offsetof(CPUX86State,xmm_regs[reg]));
3226 gen_helper_extrq_i(cpu_env, cpu_ptr0,
3227 tcg_const_i32(bit_index),
3228 tcg_const_i32(field_length));
3230 gen_helper_insertq_i(cpu_env, cpu_ptr0,
3231 tcg_const_i32(bit_index),
3232 tcg_const_i32(field_length));
3235 case 0x7e: /* movd ea, mm */
3236 #ifdef TARGET_X86_64
3237 if (s->dflag == MO_64) {
3238 tcg_gen_ld_i64(cpu_T0, cpu_env,
3239 offsetof(CPUX86State,fpregs[reg].mmx));
3240 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 1);
3244 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
3245 offsetof(CPUX86State,fpregs[reg].mmx.MMX_L(0)));
3246 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 1);
3249 case 0x17e: /* movd ea, xmm */
3250 #ifdef TARGET_X86_64
3251 if (s->dflag == MO_64) {
3252 tcg_gen_ld_i64(cpu_T0, cpu_env,
3253 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3254 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 1);
3258 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
3259 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3260 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 1);
3263 case 0x27e: /* movq xmm, ea */
3265 gen_lea_modrm(env, s, modrm);
3266 gen_ldq_env_A0(s, offsetof(CPUX86State,
3267 xmm_regs[reg].ZMM_Q(0)));
3269 rm = (modrm & 7) | REX_B(s);
3270 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3271 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3273 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)));
3275 case 0x7f: /* movq ea, mm */
3277 gen_lea_modrm(env, s, modrm);
3278 gen_stq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
3281 gen_op_movq(offsetof(CPUX86State,fpregs[rm].mmx),
3282 offsetof(CPUX86State,fpregs[reg].mmx));
3285 case 0x011: /* movups */
3286 case 0x111: /* movupd */
3287 case 0x029: /* movaps */
3288 case 0x129: /* movapd */
3289 case 0x17f: /* movdqa ea, xmm */
3290 case 0x27f: /* movdqu ea, xmm */
3292 gen_lea_modrm(env, s, modrm);
3293 gen_sto_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3295 rm = (modrm & 7) | REX_B(s);
3296 gen_op_movo(offsetof(CPUX86State,xmm_regs[rm]),
3297 offsetof(CPUX86State,xmm_regs[reg]));
3300 case 0x211: /* movss ea, xmm */
3302 gen_lea_modrm(env, s, modrm);
3303 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3304 gen_op_st_v(s, MO_32, cpu_T0, cpu_A0);
3306 rm = (modrm & 7) | REX_B(s);
3307 gen_op_movl(offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0)),
3308 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3311 case 0x311: /* movsd ea, xmm */
3313 gen_lea_modrm(env, s, modrm);
3314 gen_stq_env_A0(s, offsetof(CPUX86State,
3315 xmm_regs[reg].ZMM_Q(0)));
3317 rm = (modrm & 7) | REX_B(s);
3318 gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)),
3319 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3322 case 0x013: /* movlps */
3323 case 0x113: /* movlpd */
3325 gen_lea_modrm(env, s, modrm);
3326 gen_stq_env_A0(s, offsetof(CPUX86State,
3327 xmm_regs[reg].ZMM_Q(0)));
3332 case 0x017: /* movhps */
3333 case 0x117: /* movhpd */
3335 gen_lea_modrm(env, s, modrm);
3336 gen_stq_env_A0(s, offsetof(CPUX86State,
3337 xmm_regs[reg].ZMM_Q(1)));
3342 case 0x71: /* shift mm, im */
3345 case 0x171: /* shift xmm, im */
3351 val = cpu_ldub_code(env, s->pc++);
3353 tcg_gen_movi_tl(cpu_T0, val);
3354 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(0)));
3355 tcg_gen_movi_tl(cpu_T0, 0);
3356 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(1)));
3357 op1_offset = offsetof(CPUX86State,xmm_t0);
3359 tcg_gen_movi_tl(cpu_T0, val);
3360 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(0)));
3361 tcg_gen_movi_tl(cpu_T0, 0);
3362 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(1)));
3363 op1_offset = offsetof(CPUX86State,mmx_t0);
3365 sse_fn_epp = sse_op_table2[((b - 1) & 3) * 8 +
3366 (((modrm >> 3)) & 7)][b1];
3371 rm = (modrm & 7) | REX_B(s);
3372 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3375 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3377 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
3378 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op1_offset);
3379 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
3381 case 0x050: /* movmskps */
3382 rm = (modrm & 7) | REX_B(s);
3383 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3384 offsetof(CPUX86State,xmm_regs[rm]));
3385 gen_helper_movmskps(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3386 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
3388 case 0x150: /* movmskpd */
3389 rm = (modrm & 7) | REX_B(s);
3390 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3391 offsetof(CPUX86State,xmm_regs[rm]));
3392 gen_helper_movmskpd(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3393 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
3395 case 0x02a: /* cvtpi2ps */
3396 case 0x12a: /* cvtpi2pd */
3397 gen_helper_enter_mmx(cpu_env);
3399 gen_lea_modrm(env, s, modrm);
3400 op2_offset = offsetof(CPUX86State,mmx_t0);
3401 gen_ldq_env_A0(s, op2_offset);
3404 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3406 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3407 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3408 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3411 gen_helper_cvtpi2ps(cpu_env, cpu_ptr0, cpu_ptr1);
3415 gen_helper_cvtpi2pd(cpu_env, cpu_ptr0, cpu_ptr1);
3419 case 0x22a: /* cvtsi2ss */
3420 case 0x32a: /* cvtsi2sd */
3421 ot = mo_64_32(s->dflag);
3422 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3423 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3424 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3426 SSEFunc_0_epi sse_fn_epi = sse_op_table3ai[(b >> 8) & 1];
3427 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
3428 sse_fn_epi(cpu_env, cpu_ptr0, cpu_tmp2_i32);
3430 #ifdef TARGET_X86_64
3431 SSEFunc_0_epl sse_fn_epl = sse_op_table3aq[(b >> 8) & 1];
3432 sse_fn_epl(cpu_env, cpu_ptr0, cpu_T0);
3438 case 0x02c: /* cvttps2pi */
3439 case 0x12c: /* cvttpd2pi */
3440 case 0x02d: /* cvtps2pi */
3441 case 0x12d: /* cvtpd2pi */
3442 gen_helper_enter_mmx(cpu_env);
3444 gen_lea_modrm(env, s, modrm);
3445 op2_offset = offsetof(CPUX86State,xmm_t0);
3446 gen_ldo_env_A0(s, op2_offset);
3448 rm = (modrm & 7) | REX_B(s);
3449 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3451 op1_offset = offsetof(CPUX86State,fpregs[reg & 7].mmx);
3452 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3453 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3456 gen_helper_cvttps2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3459 gen_helper_cvttpd2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3462 gen_helper_cvtps2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3465 gen_helper_cvtpd2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3469 case 0x22c: /* cvttss2si */
3470 case 0x32c: /* cvttsd2si */
3471 case 0x22d: /* cvtss2si */
3472 case 0x32d: /* cvtsd2si */
3473 ot = mo_64_32(s->dflag);
3475 gen_lea_modrm(env, s, modrm);
3477 gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_Q(0)));
3479 gen_op_ld_v(s, MO_32, cpu_T0, cpu_A0);
3480 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(0)));
3482 op2_offset = offsetof(CPUX86State,xmm_t0);
3484 rm = (modrm & 7) | REX_B(s);
3485 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3487 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
3489 SSEFunc_i_ep sse_fn_i_ep =
3490 sse_op_table3bi[((b >> 7) & 2) | (b & 1)];
3491 sse_fn_i_ep(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3492 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
3494 #ifdef TARGET_X86_64
3495 SSEFunc_l_ep sse_fn_l_ep =
3496 sse_op_table3bq[((b >> 7) & 2) | (b & 1)];
3497 sse_fn_l_ep(cpu_T0, cpu_env, cpu_ptr0);
3502 gen_op_mov_reg_v(ot, reg, cpu_T0);
3504 case 0xc4: /* pinsrw */
3507 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
3508 val = cpu_ldub_code(env, s->pc++);
3511 tcg_gen_st16_tl(cpu_T0, cpu_env,
3512 offsetof(CPUX86State,xmm_regs[reg].ZMM_W(val)));
3515 tcg_gen_st16_tl(cpu_T0, cpu_env,
3516 offsetof(CPUX86State,fpregs[reg].mmx.MMX_W(val)));
3519 case 0xc5: /* pextrw */
3523 ot = mo_64_32(s->dflag);
3524 val = cpu_ldub_code(env, s->pc++);
3527 rm = (modrm & 7) | REX_B(s);
3528 tcg_gen_ld16u_tl(cpu_T0, cpu_env,
3529 offsetof(CPUX86State,xmm_regs[rm].ZMM_W(val)));
3533 tcg_gen_ld16u_tl(cpu_T0, cpu_env,
3534 offsetof(CPUX86State,fpregs[rm].mmx.MMX_W(val)));
3536 reg = ((modrm >> 3) & 7) | rex_r;
3537 gen_op_mov_reg_v(ot, reg, cpu_T0);
3539 case 0x1d6: /* movq ea, xmm */
3541 gen_lea_modrm(env, s, modrm);
3542 gen_stq_env_A0(s, offsetof(CPUX86State,
3543 xmm_regs[reg].ZMM_Q(0)));
3545 rm = (modrm & 7) | REX_B(s);
3546 gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)),
3547 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3548 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(1)));
3551 case 0x2d6: /* movq2dq */
3552 gen_helper_enter_mmx(cpu_env);
3554 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3555 offsetof(CPUX86State,fpregs[rm].mmx));
3556 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)));
3558 case 0x3d6: /* movdq2q */
3559 gen_helper_enter_mmx(cpu_env);
3560 rm = (modrm & 7) | REX_B(s);
3561 gen_op_movq(offsetof(CPUX86State,fpregs[reg & 7].mmx),
3562 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3564 case 0xd7: /* pmovmskb */
3569 rm = (modrm & 7) | REX_B(s);
3570 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[rm]));
3571 gen_helper_pmovmskb_xmm(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3574 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,fpregs[rm].mmx));
3575 gen_helper_pmovmskb_mmx(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3577 reg = ((modrm >> 3) & 7) | rex_r;
3578 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
3584 if ((b & 0xf0) == 0xf0) {
3587 modrm = cpu_ldub_code(env, s->pc++);
3589 reg = ((modrm >> 3) & 7) | rex_r;
3590 mod = (modrm >> 6) & 3;
3595 sse_fn_epp = sse_op_table6[b].op[b1];
3599 if (!(s->cpuid_ext_features & sse_op_table6[b].ext_mask))
3603 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3605 op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
3607 op2_offset = offsetof(CPUX86State,xmm_t0);
3608 gen_lea_modrm(env, s, modrm);
3610 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3611 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3612 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3613 gen_ldq_env_A0(s, op2_offset +
3614 offsetof(ZMMReg, ZMM_Q(0)));
3616 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3617 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3618 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
3619 s->mem_index, MO_LEUL);
3620 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, op2_offset +
3621 offsetof(ZMMReg, ZMM_L(0)));
3623 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3624 tcg_gen_qemu_ld_tl(cpu_tmp0, cpu_A0,
3625 s->mem_index, MO_LEUW);
3626 tcg_gen_st16_tl(cpu_tmp0, cpu_env, op2_offset +
3627 offsetof(ZMMReg, ZMM_W(0)));
3629 case 0x2a: /* movntqda */
3630 gen_ldo_env_A0(s, op1_offset);
3633 gen_ldo_env_A0(s, op2_offset);
3637 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
3639 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3641 op2_offset = offsetof(CPUX86State,mmx_t0);
3642 gen_lea_modrm(env, s, modrm);
3643 gen_ldq_env_A0(s, op2_offset);
3646 if (sse_fn_epp == SSE_SPECIAL) {
3650 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3651 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3652 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
3655 set_cc_op(s, CC_OP_EFLAGS);
3662 /* Various integer extensions at 0f 38 f[0-f]. */
3663 b = modrm | (b1 << 8);
3664 modrm = cpu_ldub_code(env, s->pc++);
3665 reg = ((modrm >> 3) & 7) | rex_r;
3668 case 0x3f0: /* crc32 Gd,Eb */
3669 case 0x3f1: /* crc32 Gd,Ey */
3671 if (!(s->cpuid_ext_features & CPUID_EXT_SSE42)) {
3674 if ((b & 0xff) == 0xf0) {
3676 } else if (s->dflag != MO_64) {
3677 ot = (s->prefix & PREFIX_DATA ? MO_16 : MO_32);
3682 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[reg]);
3683 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3684 gen_helper_crc32(cpu_T0, cpu_tmp2_i32,
3685 cpu_T0, tcg_const_i32(8 << ot));
3687 ot = mo_64_32(s->dflag);
3688 gen_op_mov_reg_v(ot, reg, cpu_T0);
3691 case 0x1f0: /* crc32 or movbe */
3693 /* For these insns, the f3 prefix is supposed to have priority
3694 over the 66 prefix, but that's not what we implement above
3696 if (s->prefix & PREFIX_REPNZ) {
3700 case 0x0f0: /* movbe Gy,My */
3701 case 0x0f1: /* movbe My,Gy */
3702 if (!(s->cpuid_ext_features & CPUID_EXT_MOVBE)) {
3705 if (s->dflag != MO_64) {
3706 ot = (s->prefix & PREFIX_DATA ? MO_16 : MO_32);
3711 gen_lea_modrm(env, s, modrm);
3713 tcg_gen_qemu_ld_tl(cpu_T0, cpu_A0,
3714 s->mem_index, ot | MO_BE);
3715 gen_op_mov_reg_v(ot, reg, cpu_T0);
3717 tcg_gen_qemu_st_tl(cpu_regs[reg], cpu_A0,
3718 s->mem_index, ot | MO_BE);
3722 case 0x0f2: /* andn Gy, By, Ey */
3723 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
3724 || !(s->prefix & PREFIX_VEX)
3728 ot = mo_64_32(s->dflag);
3729 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3730 tcg_gen_andc_tl(cpu_T0, cpu_regs[s->vex_v], cpu_T0);
3731 gen_op_mov_reg_v(ot, reg, cpu_T0);
3732 gen_op_update1_cc();
3733 set_cc_op(s, CC_OP_LOGICB + ot);
3736 case 0x0f7: /* bextr Gy, Ey, By */
3737 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
3738 || !(s->prefix & PREFIX_VEX)
3742 ot = mo_64_32(s->dflag);
3746 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3747 /* Extract START, and shift the operand.
3748 Shifts larger than operand size get zeros. */
3749 tcg_gen_ext8u_tl(cpu_A0, cpu_regs[s->vex_v]);
3750 tcg_gen_shr_tl(cpu_T0, cpu_T0, cpu_A0);
3752 bound = tcg_const_tl(ot == MO_64 ? 63 : 31);
3753 zero = tcg_const_tl(0);
3754 tcg_gen_movcond_tl(TCG_COND_LEU, cpu_T0, cpu_A0, bound,
3756 tcg_temp_free(zero);
3758 /* Extract the LEN into a mask. Lengths larger than
3759 operand size get all ones. */
3760 tcg_gen_shri_tl(cpu_A0, cpu_regs[s->vex_v], 8);
3761 tcg_gen_ext8u_tl(cpu_A0, cpu_A0);
3762 tcg_gen_movcond_tl(TCG_COND_LEU, cpu_A0, cpu_A0, bound,
3764 tcg_temp_free(bound);
3765 tcg_gen_movi_tl(cpu_T1, 1);
3766 tcg_gen_shl_tl(cpu_T1, cpu_T1, cpu_A0);
3767 tcg_gen_subi_tl(cpu_T1, cpu_T1, 1);
3768 tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1);
3770 gen_op_mov_reg_v(ot, reg, cpu_T0);
3771 gen_op_update1_cc();
3772 set_cc_op(s, CC_OP_LOGICB + ot);
3776 case 0x0f5: /* bzhi Gy, Ey, By */
3777 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3778 || !(s->prefix & PREFIX_VEX)
3782 ot = mo_64_32(s->dflag);
3783 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3784 tcg_gen_ext8u_tl(cpu_T1, cpu_regs[s->vex_v]);
3786 TCGv bound = tcg_const_tl(ot == MO_64 ? 63 : 31);
3787 /* Note that since we're using BMILG (in order to get O
3788 cleared) we need to store the inverse into C. */
3789 tcg_gen_setcond_tl(TCG_COND_LT, cpu_cc_src,
3791 tcg_gen_movcond_tl(TCG_COND_GT, cpu_T1, cpu_T1,
3792 bound, bound, cpu_T1);
3793 tcg_temp_free(bound);
3795 tcg_gen_movi_tl(cpu_A0, -1);
3796 tcg_gen_shl_tl(cpu_A0, cpu_A0, cpu_T1);
3797 tcg_gen_andc_tl(cpu_T0, cpu_T0, cpu_A0);
3798 gen_op_mov_reg_v(ot, reg, cpu_T0);
3799 gen_op_update1_cc();
3800 set_cc_op(s, CC_OP_BMILGB + ot);
3803 case 0x3f6: /* mulx By, Gy, rdx, Ey */
3804 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3805 || !(s->prefix & PREFIX_VEX)
3809 ot = mo_64_32(s->dflag);
3810 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3813 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
3814 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_regs[R_EDX]);
3815 tcg_gen_mulu2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
3816 cpu_tmp2_i32, cpu_tmp3_i32);
3817 tcg_gen_extu_i32_tl(cpu_regs[s->vex_v], cpu_tmp2_i32);
3818 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp3_i32);
3820 #ifdef TARGET_X86_64
3822 tcg_gen_mulu2_i64(cpu_T0, cpu_T1,
3823 cpu_T0, cpu_regs[R_EDX]);
3824 tcg_gen_mov_i64(cpu_regs[s->vex_v], cpu_T0);
3825 tcg_gen_mov_i64(cpu_regs[reg], cpu_T1);
3831 case 0x3f5: /* pdep Gy, By, Ey */
3832 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3833 || !(s->prefix & PREFIX_VEX)
3837 ot = mo_64_32(s->dflag);
3838 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3839 /* Note that by zero-extending the mask operand, we
3840 automatically handle zero-extending the result. */
3842 tcg_gen_mov_tl(cpu_T1, cpu_regs[s->vex_v]);
3844 tcg_gen_ext32u_tl(cpu_T1, cpu_regs[s->vex_v]);
3846 gen_helper_pdep(cpu_regs[reg], cpu_T0, cpu_T1);
3849 case 0x2f5: /* pext Gy, By, Ey */
3850 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3851 || !(s->prefix & PREFIX_VEX)
3855 ot = mo_64_32(s->dflag);
3856 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3857 /* Note that by zero-extending the mask operand, we
3858 automatically handle zero-extending the result. */
3860 tcg_gen_mov_tl(cpu_T1, cpu_regs[s->vex_v]);
3862 tcg_gen_ext32u_tl(cpu_T1, cpu_regs[s->vex_v]);
3864 gen_helper_pext(cpu_regs[reg], cpu_T0, cpu_T1);
3867 case 0x1f6: /* adcx Gy, Ey */
3868 case 0x2f6: /* adox Gy, Ey */
3869 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_ADX)) {
3872 TCGv carry_in, carry_out, zero;
3875 ot = mo_64_32(s->dflag);
3876 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3878 /* Re-use the carry-out from a previous round. */
3879 TCGV_UNUSED(carry_in);
3880 carry_out = (b == 0x1f6 ? cpu_cc_dst : cpu_cc_src2);
3884 carry_in = cpu_cc_dst;
3885 end_op = CC_OP_ADCX;
3887 end_op = CC_OP_ADCOX;
3892 end_op = CC_OP_ADCOX;
3894 carry_in = cpu_cc_src2;
3895 end_op = CC_OP_ADOX;
3899 end_op = CC_OP_ADCOX;
3900 carry_in = carry_out;
3903 end_op = (b == 0x1f6 ? CC_OP_ADCX : CC_OP_ADOX);
3906 /* If we can't reuse carry-out, get it out of EFLAGS. */
3907 if (TCGV_IS_UNUSED(carry_in)) {
3908 if (s->cc_op != CC_OP_ADCX && s->cc_op != CC_OP_ADOX) {
3909 gen_compute_eflags(s);
3911 carry_in = cpu_tmp0;
3912 tcg_gen_shri_tl(carry_in, cpu_cc_src,
3913 ctz32(b == 0x1f6 ? CC_C : CC_O));
3914 tcg_gen_andi_tl(carry_in, carry_in, 1);
3918 #ifdef TARGET_X86_64
3920 /* If we know TL is 64-bit, and we want a 32-bit
3921 result, just do everything in 64-bit arithmetic. */
3922 tcg_gen_ext32u_i64(cpu_regs[reg], cpu_regs[reg]);
3923 tcg_gen_ext32u_i64(cpu_T0, cpu_T0);
3924 tcg_gen_add_i64(cpu_T0, cpu_T0, cpu_regs[reg]);
3925 tcg_gen_add_i64(cpu_T0, cpu_T0, carry_in);
3926 tcg_gen_ext32u_i64(cpu_regs[reg], cpu_T0);
3927 tcg_gen_shri_i64(carry_out, cpu_T0, 32);
3931 /* Otherwise compute the carry-out in two steps. */
3932 zero = tcg_const_tl(0);
3933 tcg_gen_add2_tl(cpu_T0, carry_out,
3936 tcg_gen_add2_tl(cpu_regs[reg], carry_out,
3937 cpu_regs[reg], carry_out,
3939 tcg_temp_free(zero);
3942 set_cc_op(s, end_op);
3946 case 0x1f7: /* shlx Gy, Ey, By */
3947 case 0x2f7: /* sarx Gy, Ey, By */
3948 case 0x3f7: /* shrx Gy, Ey, By */
3949 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3950 || !(s->prefix & PREFIX_VEX)
3954 ot = mo_64_32(s->dflag);
3955 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3957 tcg_gen_andi_tl(cpu_T1, cpu_regs[s->vex_v], 63);
3959 tcg_gen_andi_tl(cpu_T1, cpu_regs[s->vex_v], 31);
3962 tcg_gen_shl_tl(cpu_T0, cpu_T0, cpu_T1);
3963 } else if (b == 0x2f7) {
3965 tcg_gen_ext32s_tl(cpu_T0, cpu_T0);
3967 tcg_gen_sar_tl(cpu_T0, cpu_T0, cpu_T1);
3970 tcg_gen_ext32u_tl(cpu_T0, cpu_T0);
3972 tcg_gen_shr_tl(cpu_T0, cpu_T0, cpu_T1);
3974 gen_op_mov_reg_v(ot, reg, cpu_T0);
3980 case 0x3f3: /* Group 17 */
3981 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
3982 || !(s->prefix & PREFIX_VEX)
3986 ot = mo_64_32(s->dflag);
3987 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3990 case 1: /* blsr By,Ey */
3991 tcg_gen_neg_tl(cpu_T1, cpu_T0);
3992 tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1);
3993 gen_op_mov_reg_v(ot, s->vex_v, cpu_T0);
3994 gen_op_update2_cc();
3995 set_cc_op(s, CC_OP_BMILGB + ot);
3998 case 2: /* blsmsk By,Ey */
3999 tcg_gen_mov_tl(cpu_cc_src, cpu_T0);
4000 tcg_gen_subi_tl(cpu_T0, cpu_T0, 1);
4001 tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_cc_src);
4002 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4003 set_cc_op(s, CC_OP_BMILGB + ot);
4006 case 3: /* blsi By, Ey */
4007 tcg_gen_mov_tl(cpu_cc_src, cpu_T0);
4008 tcg_gen_subi_tl(cpu_T0, cpu_T0, 1);
4009 tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_cc_src);
4010 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4011 set_cc_op(s, CC_OP_BMILGB + ot);
4027 modrm = cpu_ldub_code(env, s->pc++);
4029 reg = ((modrm >> 3) & 7) | rex_r;
4030 mod = (modrm >> 6) & 3;
4035 sse_fn_eppi = sse_op_table7[b].op[b1];
4039 if (!(s->cpuid_ext_features & sse_op_table7[b].ext_mask))
4042 if (sse_fn_eppi == SSE_SPECIAL) {
4043 ot = mo_64_32(s->dflag);
4044 rm = (modrm & 7) | REX_B(s);
4046 gen_lea_modrm(env, s, modrm);
4047 reg = ((modrm >> 3) & 7) | rex_r;
4048 val = cpu_ldub_code(env, s->pc++);
4050 case 0x14: /* pextrb */
4051 tcg_gen_ld8u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
4052 xmm_regs[reg].ZMM_B(val & 15)));
4054 gen_op_mov_reg_v(ot, rm, cpu_T0);
4056 tcg_gen_qemu_st_tl(cpu_T0, cpu_A0,
4057 s->mem_index, MO_UB);
4060 case 0x15: /* pextrw */
4061 tcg_gen_ld16u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
4062 xmm_regs[reg].ZMM_W(val & 7)));
4064 gen_op_mov_reg_v(ot, rm, cpu_T0);
4066 tcg_gen_qemu_st_tl(cpu_T0, cpu_A0,
4067 s->mem_index, MO_LEUW);
4071 if (ot == MO_32) { /* pextrd */
4072 tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
4073 offsetof(CPUX86State,
4074 xmm_regs[reg].ZMM_L(val & 3)));
4076 tcg_gen_extu_i32_tl(cpu_regs[rm], cpu_tmp2_i32);
4078 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
4079 s->mem_index, MO_LEUL);
4081 } else { /* pextrq */
4082 #ifdef TARGET_X86_64
4083 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
4084 offsetof(CPUX86State,
4085 xmm_regs[reg].ZMM_Q(val & 1)));
4087 tcg_gen_mov_i64(cpu_regs[rm], cpu_tmp1_i64);
4089 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0,
4090 s->mem_index, MO_LEQ);
4097 case 0x17: /* extractps */
4098 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
4099 xmm_regs[reg].ZMM_L(val & 3)));
4101 gen_op_mov_reg_v(ot, rm, cpu_T0);
4103 tcg_gen_qemu_st_tl(cpu_T0, cpu_A0,
4104 s->mem_index, MO_LEUL);
4107 case 0x20: /* pinsrb */
4109 gen_op_mov_v_reg(MO_32, cpu_T0, rm);
4111 tcg_gen_qemu_ld_tl(cpu_T0, cpu_A0,
4112 s->mem_index, MO_UB);
4114 tcg_gen_st8_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
4115 xmm_regs[reg].ZMM_B(val & 15)));
4117 case 0x21: /* insertps */
4119 tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
4120 offsetof(CPUX86State,xmm_regs[rm]
4121 .ZMM_L((val >> 6) & 3)));
4123 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
4124 s->mem_index, MO_LEUL);
4126 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
4127 offsetof(CPUX86State,xmm_regs[reg]
4128 .ZMM_L((val >> 4) & 3)));
4130 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4131 cpu_env, offsetof(CPUX86State,
4132 xmm_regs[reg].ZMM_L(0)));
4134 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4135 cpu_env, offsetof(CPUX86State,
4136 xmm_regs[reg].ZMM_L(1)));
4138 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4139 cpu_env, offsetof(CPUX86State,
4140 xmm_regs[reg].ZMM_L(2)));
4142 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4143 cpu_env, offsetof(CPUX86State,
4144 xmm_regs[reg].ZMM_L(3)));
4147 if (ot == MO_32) { /* pinsrd */
4149 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[rm]);
4151 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
4152 s->mem_index, MO_LEUL);
4154 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
4155 offsetof(CPUX86State,
4156 xmm_regs[reg].ZMM_L(val & 3)));
4157 } else { /* pinsrq */
4158 #ifdef TARGET_X86_64
4160 gen_op_mov_v_reg(ot, cpu_tmp1_i64, rm);
4162 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0,
4163 s->mem_index, MO_LEQ);
4165 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
4166 offsetof(CPUX86State,
4167 xmm_regs[reg].ZMM_Q(val & 1)));
4178 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
4180 op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
4182 op2_offset = offsetof(CPUX86State,xmm_t0);
4183 gen_lea_modrm(env, s, modrm);
4184 gen_ldo_env_A0(s, op2_offset);
4187 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
4189 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
4191 op2_offset = offsetof(CPUX86State,mmx_t0);
4192 gen_lea_modrm(env, s, modrm);
4193 gen_ldq_env_A0(s, op2_offset);
4196 val = cpu_ldub_code(env, s->pc++);
4198 if ((b & 0xfc) == 0x60) { /* pcmpXstrX */
4199 set_cc_op(s, CC_OP_EFLAGS);
4201 if (s->dflag == MO_64) {
4202 /* The helper must use entire 64-bit gp registers */
4207 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4208 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4209 sse_fn_eppi(cpu_env, cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
4213 /* Various integer extensions at 0f 3a f[0-f]. */
4214 b = modrm | (b1 << 8);
4215 modrm = cpu_ldub_code(env, s->pc++);
4216 reg = ((modrm >> 3) & 7) | rex_r;
4219 case 0x3f0: /* rorx Gy,Ey, Ib */
4220 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
4221 || !(s->prefix & PREFIX_VEX)
4225 ot = mo_64_32(s->dflag);
4226 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4227 b = cpu_ldub_code(env, s->pc++);
4229 tcg_gen_rotri_tl(cpu_T0, cpu_T0, b & 63);
4231 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
4232 tcg_gen_rotri_i32(cpu_tmp2_i32, cpu_tmp2_i32, b & 31);
4233 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
4235 gen_op_mov_reg_v(ot, reg, cpu_T0);
4245 gen_unknown_opcode(env, s);
4249 /* generic MMX or SSE operation */
4251 case 0x70: /* pshufx insn */
4252 case 0xc6: /* pshufx insn */
4253 case 0xc2: /* compare insns */
4260 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
4264 gen_lea_modrm(env, s, modrm);
4265 op2_offset = offsetof(CPUX86State,xmm_t0);
4271 /* Most sse scalar operations. */
4274 } else if (b1 == 3) {
4279 case 0x2e: /* ucomis[sd] */
4280 case 0x2f: /* comis[sd] */
4292 gen_op_ld_v(s, MO_32, cpu_T0, cpu_A0);
4293 tcg_gen_st32_tl(cpu_T0, cpu_env,
4294 offsetof(CPUX86State,xmm_t0.ZMM_L(0)));
4298 gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_D(0)));
4301 /* 128 bit access */
4302 gen_ldo_env_A0(s, op2_offset);
4306 rm = (modrm & 7) | REX_B(s);
4307 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
4310 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
4312 gen_lea_modrm(env, s, modrm);
4313 op2_offset = offsetof(CPUX86State,mmx_t0);
4314 gen_ldq_env_A0(s, op2_offset);
4317 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
4321 case 0x0f: /* 3DNow! data insns */
4322 val = cpu_ldub_code(env, s->pc++);
4323 sse_fn_epp = sse_op_table5[val];
4327 if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) {
4330 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4331 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4332 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4334 case 0x70: /* pshufx insn */
4335 case 0xc6: /* pshufx insn */
4336 val = cpu_ldub_code(env, s->pc++);
4337 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4338 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4339 /* XXX: introduce a new table? */
4340 sse_fn_ppi = (SSEFunc_0_ppi)sse_fn_epp;
4341 sse_fn_ppi(cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
4345 val = cpu_ldub_code(env, s->pc++);
4348 sse_fn_epp = sse_op_table4[val][b1];
4350 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4351 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4352 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4355 /* maskmov : we must prepare A0 */
4358 tcg_gen_mov_tl(cpu_A0, cpu_regs[R_EDI]);
4359 gen_extu(s->aflag, cpu_A0);
4360 gen_add_A0_ds_seg(s);
4362 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4363 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4364 /* XXX: introduce a new table? */
4365 sse_fn_eppt = (SSEFunc_0_eppt)sse_fn_epp;
4366 sse_fn_eppt(cpu_env, cpu_ptr0, cpu_ptr1, cpu_A0);
4369 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4370 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4371 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4374 if (b == 0x2e || b == 0x2f) {
4375 set_cc_op(s, CC_OP_EFLAGS);
4380 /* convert one instruction. s->is_jmp is set if the translation must
4381 be stopped. Return the next pc value */
4382 static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
4383 target_ulong pc_start)
4387 TCGMemOp ot, aflag, dflag;
4388 int modrm, reg, rm, mod, op, opreg, val;
4389 target_ulong next_eip, tval;
4392 s->pc_start = s->pc = pc_start;
4397 #ifdef TARGET_X86_64
4402 s->rip_offset = 0; /* for relative ip address */
4406 b = cpu_ldub_code(env, s->pc);
4408 /* Collect prefixes. */
4411 prefixes |= PREFIX_REPZ;
4414 prefixes |= PREFIX_REPNZ;
4417 prefixes |= PREFIX_LOCK;
4438 prefixes |= PREFIX_DATA;
4441 prefixes |= PREFIX_ADR;
4443 #ifdef TARGET_X86_64
4447 rex_w = (b >> 3) & 1;
4448 rex_r = (b & 0x4) << 1;
4449 s->rex_x = (b & 0x2) << 2;
4450 REX_B(s) = (b & 0x1) << 3;
4451 x86_64_hregs = 1; /* select uniform byte register addressing */
4456 case 0xc5: /* 2-byte VEX */
4457 case 0xc4: /* 3-byte VEX */
4458 /* VEX prefixes cannot be used except in 32-bit mode.
4459 Otherwise the instruction is LES or LDS. */
4460 if (s->code32 && !s->vm86) {
4461 static const int pp_prefix[4] = {
4462 0, PREFIX_DATA, PREFIX_REPZ, PREFIX_REPNZ
4464 int vex3, vex2 = cpu_ldub_code(env, s->pc);
4466 if (!CODE64(s) && (vex2 & 0xc0) != 0xc0) {
4467 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4468 otherwise the instruction is LES or LDS. */
4473 /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
4474 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ
4475 | PREFIX_LOCK | PREFIX_DATA)) {
4478 #ifdef TARGET_X86_64
4483 rex_r = (~vex2 >> 4) & 8;
4486 b = cpu_ldub_code(env, s->pc++);
4488 #ifdef TARGET_X86_64
4489 s->rex_x = (~vex2 >> 3) & 8;
4490 s->rex_b = (~vex2 >> 2) & 8;
4492 vex3 = cpu_ldub_code(env, s->pc++);
4493 rex_w = (vex3 >> 7) & 1;
4494 switch (vex2 & 0x1f) {
4495 case 0x01: /* Implied 0f leading opcode bytes. */
4496 b = cpu_ldub_code(env, s->pc++) | 0x100;
4498 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4501 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4504 default: /* Reserved for future use. */
4508 s->vex_v = (~vex3 >> 3) & 0xf;
4509 s->vex_l = (vex3 >> 2) & 1;
4510 prefixes |= pp_prefix[vex3 & 3] | PREFIX_VEX;
4515 /* Post-process prefixes. */
4517 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit
4518 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4519 over 0x66 if both are present. */
4520 dflag = (rex_w > 0 ? MO_64 : prefixes & PREFIX_DATA ? MO_16 : MO_32);
4521 /* In 64-bit mode, 0x67 selects 32-bit addressing. */
4522 aflag = (prefixes & PREFIX_ADR ? MO_32 : MO_64);
4524 /* In 16/32-bit mode, 0x66 selects the opposite data size. */
4525 if (s->code32 ^ ((prefixes & PREFIX_DATA) != 0)) {
4530 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */
4531 if (s->code32 ^ ((prefixes & PREFIX_ADR) != 0)) {
4538 s->prefix = prefixes;
4542 /* now check op code */
4546 /**************************/
4547 /* extended op code */
4548 b = cpu_ldub_code(env, s->pc++) | 0x100;
4551 /**************************/
4566 ot = mo_b_d(b, dflag);
4569 case 0: /* OP Ev, Gv */
4570 modrm = cpu_ldub_code(env, s->pc++);
4571 reg = ((modrm >> 3) & 7) | rex_r;
4572 mod = (modrm >> 6) & 3;
4573 rm = (modrm & 7) | REX_B(s);
4575 gen_lea_modrm(env, s, modrm);
4577 } else if (op == OP_XORL && rm == reg) {
4579 /* xor reg, reg optimisation */
4580 set_cc_op(s, CC_OP_CLR);
4581 tcg_gen_movi_tl(cpu_T0, 0);
4582 gen_op_mov_reg_v(ot, reg, cpu_T0);
4587 gen_op_mov_v_reg(ot, cpu_T1, reg);
4588 gen_op(s, op, ot, opreg);
4590 case 1: /* OP Gv, Ev */
4591 modrm = cpu_ldub_code(env, s->pc++);
4592 mod = (modrm >> 6) & 3;
4593 reg = ((modrm >> 3) & 7) | rex_r;
4594 rm = (modrm & 7) | REX_B(s);
4596 gen_lea_modrm(env, s, modrm);
4597 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
4598 } else if (op == OP_XORL && rm == reg) {
4601 gen_op_mov_v_reg(ot, cpu_T1, rm);
4603 gen_op(s, op, ot, reg);
4605 case 2: /* OP A, Iv */
4606 val = insn_get(env, s, ot);
4607 tcg_gen_movi_tl(cpu_T1, val);
4608 gen_op(s, op, ot, OR_EAX);
4617 case 0x80: /* GRP1 */
4623 ot = mo_b_d(b, dflag);
4625 modrm = cpu_ldub_code(env, s->pc++);
4626 mod = (modrm >> 6) & 3;
4627 rm = (modrm & 7) | REX_B(s);
4628 op = (modrm >> 3) & 7;
4634 s->rip_offset = insn_const_size(ot);
4635 gen_lea_modrm(env, s, modrm);
4646 val = insn_get(env, s, ot);
4649 val = (int8_t)insn_get(env, s, MO_8);
4652 tcg_gen_movi_tl(cpu_T1, val);
4653 gen_op(s, op, ot, opreg);
4657 /**************************/
4658 /* inc, dec, and other misc arith */
4659 case 0x40 ... 0x47: /* inc Gv */
4661 gen_inc(s, ot, OR_EAX + (b & 7), 1);
4663 case 0x48 ... 0x4f: /* dec Gv */
4665 gen_inc(s, ot, OR_EAX + (b & 7), -1);
4667 case 0xf6: /* GRP3 */
4669 ot = mo_b_d(b, dflag);
4671 modrm = cpu_ldub_code(env, s->pc++);
4672 mod = (modrm >> 6) & 3;
4673 rm = (modrm & 7) | REX_B(s);
4674 op = (modrm >> 3) & 7;
4677 s->rip_offset = insn_const_size(ot);
4679 gen_lea_modrm(env, s, modrm);
4680 /* For those below that handle locked memory, don't load here. */
4681 if (!(s->prefix & PREFIX_LOCK)
4683 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
4686 gen_op_mov_v_reg(ot, cpu_T0, rm);
4691 val = insn_get(env, s, ot);
4692 tcg_gen_movi_tl(cpu_T1, val);
4693 gen_op_testl_T0_T1_cc();
4694 set_cc_op(s, CC_OP_LOGICB + ot);
4697 if (s->prefix & PREFIX_LOCK) {
4701 tcg_gen_movi_tl(cpu_T0, ~0);
4702 tcg_gen_atomic_xor_fetch_tl(cpu_T0, cpu_A0, cpu_T0,
4703 s->mem_index, ot | MO_LE);
4705 tcg_gen_not_tl(cpu_T0, cpu_T0);
4707 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
4709 gen_op_mov_reg_v(ot, rm, cpu_T0);
4714 if (s->prefix & PREFIX_LOCK) {
4716 TCGv a0, t0, t1, t2;
4721 a0 = tcg_temp_local_new();
4722 t0 = tcg_temp_local_new();
4723 label1 = gen_new_label();
4725 tcg_gen_mov_tl(a0, cpu_A0);
4726 tcg_gen_mov_tl(t0, cpu_T0);
4728 gen_set_label(label1);
4729 t1 = tcg_temp_new();
4730 t2 = tcg_temp_new();
4731 tcg_gen_mov_tl(t2, t0);
4732 tcg_gen_neg_tl(t1, t0);
4733 tcg_gen_atomic_cmpxchg_tl(t0, a0, t0, t1,
4734 s->mem_index, ot | MO_LE);
4736 tcg_gen_brcond_tl(TCG_COND_NE, t0, t2, label1);
4740 tcg_gen_mov_tl(cpu_T0, t0);
4743 tcg_gen_neg_tl(cpu_T0, cpu_T0);
4745 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
4747 gen_op_mov_reg_v(ot, rm, cpu_T0);
4750 gen_op_update_neg_cc();
4751 set_cc_op(s, CC_OP_SUBB + ot);
4756 gen_op_mov_v_reg(MO_8, cpu_T1, R_EAX);
4757 tcg_gen_ext8u_tl(cpu_T0, cpu_T0);
4758 tcg_gen_ext8u_tl(cpu_T1, cpu_T1);
4759 /* XXX: use 32 bit mul which could be faster */
4760 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
4761 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
4762 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4763 tcg_gen_andi_tl(cpu_cc_src, cpu_T0, 0xff00);
4764 set_cc_op(s, CC_OP_MULB);
4767 gen_op_mov_v_reg(MO_16, cpu_T1, R_EAX);
4768 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
4769 tcg_gen_ext16u_tl(cpu_T1, cpu_T1);
4770 /* XXX: use 32 bit mul which could be faster */
4771 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
4772 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
4773 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4774 tcg_gen_shri_tl(cpu_T0, cpu_T0, 16);
4775 gen_op_mov_reg_v(MO_16, R_EDX, cpu_T0);
4776 tcg_gen_mov_tl(cpu_cc_src, cpu_T0);
4777 set_cc_op(s, CC_OP_MULW);
4781 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
4782 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_regs[R_EAX]);
4783 tcg_gen_mulu2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
4784 cpu_tmp2_i32, cpu_tmp3_i32);
4785 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], cpu_tmp2_i32);
4786 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], cpu_tmp3_i32);
4787 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4788 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]);
4789 set_cc_op(s, CC_OP_MULL);
4791 #ifdef TARGET_X86_64
4793 tcg_gen_mulu2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX],
4794 cpu_T0, cpu_regs[R_EAX]);
4795 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4796 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]);
4797 set_cc_op(s, CC_OP_MULQ);
4805 gen_op_mov_v_reg(MO_8, cpu_T1, R_EAX);
4806 tcg_gen_ext8s_tl(cpu_T0, cpu_T0);
4807 tcg_gen_ext8s_tl(cpu_T1, cpu_T1);
4808 /* XXX: use 32 bit mul which could be faster */
4809 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
4810 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
4811 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4812 tcg_gen_ext8s_tl(cpu_tmp0, cpu_T0);
4813 tcg_gen_sub_tl(cpu_cc_src, cpu_T0, cpu_tmp0);
4814 set_cc_op(s, CC_OP_MULB);
4817 gen_op_mov_v_reg(MO_16, cpu_T1, R_EAX);
4818 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
4819 tcg_gen_ext16s_tl(cpu_T1, cpu_T1);
4820 /* XXX: use 32 bit mul which could be faster */
4821 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
4822 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
4823 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4824 tcg_gen_ext16s_tl(cpu_tmp0, cpu_T0);
4825 tcg_gen_sub_tl(cpu_cc_src, cpu_T0, cpu_tmp0);
4826 tcg_gen_shri_tl(cpu_T0, cpu_T0, 16);
4827 gen_op_mov_reg_v(MO_16, R_EDX, cpu_T0);
4828 set_cc_op(s, CC_OP_MULW);
4832 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
4833 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_regs[R_EAX]);
4834 tcg_gen_muls2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
4835 cpu_tmp2_i32, cpu_tmp3_i32);
4836 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], cpu_tmp2_i32);
4837 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], cpu_tmp3_i32);
4838 tcg_gen_sari_i32(cpu_tmp2_i32, cpu_tmp2_i32, 31);
4839 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4840 tcg_gen_sub_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
4841 tcg_gen_extu_i32_tl(cpu_cc_src, cpu_tmp2_i32);
4842 set_cc_op(s, CC_OP_MULL);
4844 #ifdef TARGET_X86_64
4846 tcg_gen_muls2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX],
4847 cpu_T0, cpu_regs[R_EAX]);
4848 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4849 tcg_gen_sari_tl(cpu_cc_src, cpu_regs[R_EAX], 63);
4850 tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, cpu_regs[R_EDX]);
4851 set_cc_op(s, CC_OP_MULQ);
4859 gen_helper_divb_AL(cpu_env, cpu_T0);
4862 gen_helper_divw_AX(cpu_env, cpu_T0);
4866 gen_helper_divl_EAX(cpu_env, cpu_T0);
4868 #ifdef TARGET_X86_64
4870 gen_helper_divq_EAX(cpu_env, cpu_T0);
4878 gen_helper_idivb_AL(cpu_env, cpu_T0);
4881 gen_helper_idivw_AX(cpu_env, cpu_T0);
4885 gen_helper_idivl_EAX(cpu_env, cpu_T0);
4887 #ifdef TARGET_X86_64
4889 gen_helper_idivq_EAX(cpu_env, cpu_T0);
4899 case 0xfe: /* GRP4 */
4900 case 0xff: /* GRP5 */
4901 ot = mo_b_d(b, dflag);
4903 modrm = cpu_ldub_code(env, s->pc++);
4904 mod = (modrm >> 6) & 3;
4905 rm = (modrm & 7) | REX_B(s);
4906 op = (modrm >> 3) & 7;
4907 if (op >= 2 && b == 0xfe) {
4911 if (op == 2 || op == 4) {
4912 /* operand size for jumps is 64 bit */
4914 } else if (op == 3 || op == 5) {
4915 ot = dflag != MO_16 ? MO_32 + (rex_w == 1) : MO_16;
4916 } else if (op == 6) {
4917 /* default push size is 64 bit */
4918 ot = mo_pushpop(s, dflag);
4922 gen_lea_modrm(env, s, modrm);
4923 if (op >= 2 && op != 3 && op != 5)
4924 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
4926 gen_op_mov_v_reg(ot, cpu_T0, rm);
4930 case 0: /* inc Ev */
4935 gen_inc(s, ot, opreg, 1);
4937 case 1: /* dec Ev */
4942 gen_inc(s, ot, opreg, -1);
4944 case 2: /* call Ev */
4945 /* XXX: optimize if memory (no 'and' is necessary) */
4946 if (dflag == MO_16) {
4947 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
4949 next_eip = s->pc - s->cs_base;
4950 tcg_gen_movi_tl(cpu_T1, next_eip);
4951 gen_push_v(s, cpu_T1);
4952 gen_op_jmp_v(cpu_T0);
4956 case 3: /* lcall Ev */
4957 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
4958 gen_add_A0_im(s, 1 << ot);
4959 gen_op_ld_v(s, MO_16, cpu_T0, cpu_A0);
4961 if (s->pe && !s->vm86) {
4962 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
4963 gen_helper_lcall_protected(cpu_env, cpu_tmp2_i32, cpu_T1,
4964 tcg_const_i32(dflag - 1),
4965 tcg_const_tl(s->pc - s->cs_base));
4967 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
4968 gen_helper_lcall_real(cpu_env, cpu_tmp2_i32, cpu_T1,
4969 tcg_const_i32(dflag - 1),
4970 tcg_const_i32(s->pc - s->cs_base));
4974 case 4: /* jmp Ev */
4975 if (dflag == MO_16) {
4976 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
4978 gen_op_jmp_v(cpu_T0);
4982 case 5: /* ljmp Ev */
4983 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
4984 gen_add_A0_im(s, 1 << ot);
4985 gen_op_ld_v(s, MO_16, cpu_T0, cpu_A0);
4987 if (s->pe && !s->vm86) {
4988 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
4989 gen_helper_ljmp_protected(cpu_env, cpu_tmp2_i32, cpu_T1,
4990 tcg_const_tl(s->pc - s->cs_base));
4992 gen_op_movl_seg_T0_vm(R_CS);
4993 gen_op_jmp_v(cpu_T1);
4997 case 6: /* push Ev */
4998 gen_push_v(s, cpu_T0);
5005 case 0x84: /* test Ev, Gv */
5007 ot = mo_b_d(b, dflag);
5009 modrm = cpu_ldub_code(env, s->pc++);
5010 reg = ((modrm >> 3) & 7) | rex_r;
5012 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5013 gen_op_mov_v_reg(ot, cpu_T1, reg);
5014 gen_op_testl_T0_T1_cc();
5015 set_cc_op(s, CC_OP_LOGICB + ot);
5018 case 0xa8: /* test eAX, Iv */
5020 ot = mo_b_d(b, dflag);
5021 val = insn_get(env, s, ot);
5023 gen_op_mov_v_reg(ot, cpu_T0, OR_EAX);
5024 tcg_gen_movi_tl(cpu_T1, val);
5025 gen_op_testl_T0_T1_cc();
5026 set_cc_op(s, CC_OP_LOGICB + ot);
5029 case 0x98: /* CWDE/CBW */
5031 #ifdef TARGET_X86_64
5033 gen_op_mov_v_reg(MO_32, cpu_T0, R_EAX);
5034 tcg_gen_ext32s_tl(cpu_T0, cpu_T0);
5035 gen_op_mov_reg_v(MO_64, R_EAX, cpu_T0);
5039 gen_op_mov_v_reg(MO_16, cpu_T0, R_EAX);
5040 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
5041 gen_op_mov_reg_v(MO_32, R_EAX, cpu_T0);
5044 gen_op_mov_v_reg(MO_8, cpu_T0, R_EAX);
5045 tcg_gen_ext8s_tl(cpu_T0, cpu_T0);
5046 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
5052 case 0x99: /* CDQ/CWD */
5054 #ifdef TARGET_X86_64
5056 gen_op_mov_v_reg(MO_64, cpu_T0, R_EAX);
5057 tcg_gen_sari_tl(cpu_T0, cpu_T0, 63);
5058 gen_op_mov_reg_v(MO_64, R_EDX, cpu_T0);
5062 gen_op_mov_v_reg(MO_32, cpu_T0, R_EAX);
5063 tcg_gen_ext32s_tl(cpu_T0, cpu_T0);
5064 tcg_gen_sari_tl(cpu_T0, cpu_T0, 31);
5065 gen_op_mov_reg_v(MO_32, R_EDX, cpu_T0);
5068 gen_op_mov_v_reg(MO_16, cpu_T0, R_EAX);
5069 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
5070 tcg_gen_sari_tl(cpu_T0, cpu_T0, 15);
5071 gen_op_mov_reg_v(MO_16, R_EDX, cpu_T0);
5077 case 0x1af: /* imul Gv, Ev */
5078 case 0x69: /* imul Gv, Ev, I */
5081 modrm = cpu_ldub_code(env, s->pc++);
5082 reg = ((modrm >> 3) & 7) | rex_r;
5084 s->rip_offset = insn_const_size(ot);
5087 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5089 val = insn_get(env, s, ot);
5090 tcg_gen_movi_tl(cpu_T1, val);
5091 } else if (b == 0x6b) {
5092 val = (int8_t)insn_get(env, s, MO_8);
5093 tcg_gen_movi_tl(cpu_T1, val);
5095 gen_op_mov_v_reg(ot, cpu_T1, reg);
5098 #ifdef TARGET_X86_64
5100 tcg_gen_muls2_i64(cpu_regs[reg], cpu_T1, cpu_T0, cpu_T1);
5101 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]);
5102 tcg_gen_sari_tl(cpu_cc_src, cpu_cc_dst, 63);
5103 tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, cpu_T1);
5107 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
5108 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T1);
5109 tcg_gen_muls2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
5110 cpu_tmp2_i32, cpu_tmp3_i32);
5111 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
5112 tcg_gen_sari_i32(cpu_tmp2_i32, cpu_tmp2_i32, 31);
5113 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]);
5114 tcg_gen_sub_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
5115 tcg_gen_extu_i32_tl(cpu_cc_src, cpu_tmp2_i32);
5118 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
5119 tcg_gen_ext16s_tl(cpu_T1, cpu_T1);
5120 /* XXX: use 32 bit mul which could be faster */
5121 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
5122 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
5123 tcg_gen_ext16s_tl(cpu_tmp0, cpu_T0);
5124 tcg_gen_sub_tl(cpu_cc_src, cpu_T0, cpu_tmp0);
5125 gen_op_mov_reg_v(ot, reg, cpu_T0);
5128 set_cc_op(s, CC_OP_MULB + ot);
5131 case 0x1c1: /* xadd Ev, Gv */
5132 ot = mo_b_d(b, dflag);
5133 modrm = cpu_ldub_code(env, s->pc++);
5134 reg = ((modrm >> 3) & 7) | rex_r;
5135 mod = (modrm >> 6) & 3;
5136 gen_op_mov_v_reg(ot, cpu_T0, reg);
5138 rm = (modrm & 7) | REX_B(s);
5139 gen_op_mov_v_reg(ot, cpu_T1, rm);
5140 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
5141 gen_op_mov_reg_v(ot, reg, cpu_T1);
5142 gen_op_mov_reg_v(ot, rm, cpu_T0);
5144 gen_lea_modrm(env, s, modrm);
5145 if (s->prefix & PREFIX_LOCK) {
5146 tcg_gen_atomic_fetch_add_tl(cpu_T1, cpu_A0, cpu_T0,
5147 s->mem_index, ot | MO_LE);
5148 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
5150 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
5151 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
5152 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
5154 gen_op_mov_reg_v(ot, reg, cpu_T1);
5156 gen_op_update2_cc();
5157 set_cc_op(s, CC_OP_ADDB + ot);
5160 case 0x1b1: /* cmpxchg Ev, Gv */
5162 TCGv oldv, newv, cmpv;
5164 ot = mo_b_d(b, dflag);
5165 modrm = cpu_ldub_code(env, s->pc++);
5166 reg = ((modrm >> 3) & 7) | rex_r;
5167 mod = (modrm >> 6) & 3;
5168 oldv = tcg_temp_new();
5169 newv = tcg_temp_new();
5170 cmpv = tcg_temp_new();
5171 gen_op_mov_v_reg(ot, newv, reg);
5172 tcg_gen_mov_tl(cmpv, cpu_regs[R_EAX]);
5174 if (s->prefix & PREFIX_LOCK) {
5178 gen_lea_modrm(env, s, modrm);
5179 tcg_gen_atomic_cmpxchg_tl(oldv, cpu_A0, cmpv, newv,
5180 s->mem_index, ot | MO_LE);
5181 gen_op_mov_reg_v(ot, R_EAX, oldv);
5184 rm = (modrm & 7) | REX_B(s);
5185 gen_op_mov_v_reg(ot, oldv, rm);
5187 gen_lea_modrm(env, s, modrm);
5188 gen_op_ld_v(s, ot, oldv, cpu_A0);
5189 rm = 0; /* avoid warning */
5193 /* store value = (old == cmp ? new : old); */
5194 tcg_gen_movcond_tl(TCG_COND_EQ, newv, oldv, cmpv, newv, oldv);
5196 gen_op_mov_reg_v(ot, R_EAX, oldv);
5197 gen_op_mov_reg_v(ot, rm, newv);
5199 /* Perform an unconditional store cycle like physical cpu;
5200 must be before changing accumulator to ensure
5201 idempotency if the store faults and the instruction
5203 gen_op_st_v(s, ot, newv, cpu_A0);
5204 gen_op_mov_reg_v(ot, R_EAX, oldv);
5207 tcg_gen_mov_tl(cpu_cc_src, oldv);
5208 tcg_gen_mov_tl(cpu_cc_srcT, cmpv);
5209 tcg_gen_sub_tl(cpu_cc_dst, cmpv, oldv);
5210 set_cc_op(s, CC_OP_SUBB + ot);
5211 tcg_temp_free(oldv);
5212 tcg_temp_free(newv);
5213 tcg_temp_free(cmpv);
5216 case 0x1c7: /* cmpxchg8b */
5217 modrm = cpu_ldub_code(env, s->pc++);
5218 mod = (modrm >> 6) & 3;
5219 if ((mod == 3) || ((modrm & 0x38) != 0x8))
5221 #ifdef TARGET_X86_64
5222 if (dflag == MO_64) {
5223 if (!(s->cpuid_ext_features & CPUID_EXT_CX16))
5225 gen_lea_modrm(env, s, modrm);
5226 if ((s->prefix & PREFIX_LOCK) && parallel_cpus) {
5227 gen_helper_cmpxchg16b(cpu_env, cpu_A0);
5229 gen_helper_cmpxchg16b_unlocked(cpu_env, cpu_A0);
5234 if (!(s->cpuid_features & CPUID_CX8))
5236 gen_lea_modrm(env, s, modrm);
5237 if ((s->prefix & PREFIX_LOCK) && parallel_cpus) {
5238 gen_helper_cmpxchg8b(cpu_env, cpu_A0);
5240 gen_helper_cmpxchg8b_unlocked(cpu_env, cpu_A0);
5243 set_cc_op(s, CC_OP_EFLAGS);
5246 /**************************/
5248 case 0x50 ... 0x57: /* push */
5249 gen_op_mov_v_reg(MO_32, cpu_T0, (b & 7) | REX_B(s));
5250 gen_push_v(s, cpu_T0);
5252 case 0x58 ... 0x5f: /* pop */
5254 /* NOTE: order is important for pop %sp */
5255 gen_pop_update(s, ot);
5256 gen_op_mov_reg_v(ot, (b & 7) | REX_B(s), cpu_T0);
5258 case 0x60: /* pusha */
5263 case 0x61: /* popa */
5268 case 0x68: /* push Iv */
5270 ot = mo_pushpop(s, dflag);
5272 val = insn_get(env, s, ot);
5274 val = (int8_t)insn_get(env, s, MO_8);
5275 tcg_gen_movi_tl(cpu_T0, val);
5276 gen_push_v(s, cpu_T0);
5278 case 0x8f: /* pop Ev */
5279 modrm = cpu_ldub_code(env, s->pc++);
5280 mod = (modrm >> 6) & 3;
5283 /* NOTE: order is important for pop %sp */
5284 gen_pop_update(s, ot);
5285 rm = (modrm & 7) | REX_B(s);
5286 gen_op_mov_reg_v(ot, rm, cpu_T0);
5288 /* NOTE: order is important too for MMU exceptions */
5289 s->popl_esp_hack = 1 << ot;
5290 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5291 s->popl_esp_hack = 0;
5292 gen_pop_update(s, ot);
5295 case 0xc8: /* enter */
5298 val = cpu_lduw_code(env, s->pc);
5300 level = cpu_ldub_code(env, s->pc++);
5301 gen_enter(s, val, level);
5304 case 0xc9: /* leave */
5307 case 0x06: /* push es */
5308 case 0x0e: /* push cs */
5309 case 0x16: /* push ss */
5310 case 0x1e: /* push ds */
5313 gen_op_movl_T0_seg(b >> 3);
5314 gen_push_v(s, cpu_T0);
5316 case 0x1a0: /* push fs */
5317 case 0x1a8: /* push gs */
5318 gen_op_movl_T0_seg((b >> 3) & 7);
5319 gen_push_v(s, cpu_T0);
5321 case 0x07: /* pop es */
5322 case 0x17: /* pop ss */
5323 case 0x1f: /* pop ds */
5328 gen_movl_seg_T0(s, reg);
5329 gen_pop_update(s, ot);
5330 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5332 gen_jmp_im(s->pc - s->cs_base);
5335 gen_eob_inhibit_irq(s, true);
5341 case 0x1a1: /* pop fs */
5342 case 0x1a9: /* pop gs */
5344 gen_movl_seg_T0(s, (b >> 3) & 7);
5345 gen_pop_update(s, ot);
5347 gen_jmp_im(s->pc - s->cs_base);
5352 /**************************/
5355 case 0x89: /* mov Gv, Ev */
5356 ot = mo_b_d(b, dflag);
5357 modrm = cpu_ldub_code(env, s->pc++);
5358 reg = ((modrm >> 3) & 7) | rex_r;
5360 /* generate a generic store */
5361 gen_ldst_modrm(env, s, modrm, ot, reg, 1);
5364 case 0xc7: /* mov Ev, Iv */
5365 ot = mo_b_d(b, dflag);
5366 modrm = cpu_ldub_code(env, s->pc++);
5367 mod = (modrm >> 6) & 3;
5369 s->rip_offset = insn_const_size(ot);
5370 gen_lea_modrm(env, s, modrm);
5372 val = insn_get(env, s, ot);
5373 tcg_gen_movi_tl(cpu_T0, val);
5375 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
5377 gen_op_mov_reg_v(ot, (modrm & 7) | REX_B(s), cpu_T0);
5381 case 0x8b: /* mov Ev, Gv */
5382 ot = mo_b_d(b, dflag);
5383 modrm = cpu_ldub_code(env, s->pc++);
5384 reg = ((modrm >> 3) & 7) | rex_r;
5386 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5387 gen_op_mov_reg_v(ot, reg, cpu_T0);
5389 case 0x8e: /* mov seg, Gv */
5390 modrm = cpu_ldub_code(env, s->pc++);
5391 reg = (modrm >> 3) & 7;
5392 if (reg >= 6 || reg == R_CS)
5394 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
5395 gen_movl_seg_T0(s, reg);
5396 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5398 gen_jmp_im(s->pc - s->cs_base);
5401 gen_eob_inhibit_irq(s, true);
5407 case 0x8c: /* mov Gv, seg */
5408 modrm = cpu_ldub_code(env, s->pc++);
5409 reg = (modrm >> 3) & 7;
5410 mod = (modrm >> 6) & 3;
5413 gen_op_movl_T0_seg(reg);
5414 ot = mod == 3 ? dflag : MO_16;
5415 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5418 case 0x1b6: /* movzbS Gv, Eb */
5419 case 0x1b7: /* movzwS Gv, Eb */
5420 case 0x1be: /* movsbS Gv, Eb */
5421 case 0x1bf: /* movswS Gv, Eb */
5426 /* d_ot is the size of destination */
5428 /* ot is the size of source */
5429 ot = (b & 1) + MO_8;
5430 /* s_ot is the sign+size of source */
5431 s_ot = b & 8 ? MO_SIGN | ot : ot;
5433 modrm = cpu_ldub_code(env, s->pc++);
5434 reg = ((modrm >> 3) & 7) | rex_r;
5435 mod = (modrm >> 6) & 3;
5436 rm = (modrm & 7) | REX_B(s);
5439 gen_op_mov_v_reg(ot, cpu_T0, rm);
5442 tcg_gen_ext8u_tl(cpu_T0, cpu_T0);
5445 tcg_gen_ext8s_tl(cpu_T0, cpu_T0);
5448 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
5452 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
5455 gen_op_mov_reg_v(d_ot, reg, cpu_T0);
5457 gen_lea_modrm(env, s, modrm);
5458 gen_op_ld_v(s, s_ot, cpu_T0, cpu_A0);
5459 gen_op_mov_reg_v(d_ot, reg, cpu_T0);
5464 case 0x8d: /* lea */
5465 modrm = cpu_ldub_code(env, s->pc++);
5466 mod = (modrm >> 6) & 3;
5469 reg = ((modrm >> 3) & 7) | rex_r;
5471 AddressParts a = gen_lea_modrm_0(env, s, modrm);
5472 TCGv ea = gen_lea_modrm_1(a);
5473 gen_lea_v_seg(s, s->aflag, ea, -1, -1);
5474 gen_op_mov_reg_v(dflag, reg, cpu_A0);
5478 case 0xa0: /* mov EAX, Ov */
5480 case 0xa2: /* mov Ov, EAX */
5483 target_ulong offset_addr;
5485 ot = mo_b_d(b, dflag);
5487 #ifdef TARGET_X86_64
5489 offset_addr = cpu_ldq_code(env, s->pc);
5494 offset_addr = insn_get(env, s, s->aflag);
5497 tcg_gen_movi_tl(cpu_A0, offset_addr);
5498 gen_add_A0_ds_seg(s);
5500 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
5501 gen_op_mov_reg_v(ot, R_EAX, cpu_T0);
5503 gen_op_mov_v_reg(ot, cpu_T0, R_EAX);
5504 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
5508 case 0xd7: /* xlat */
5509 tcg_gen_mov_tl(cpu_A0, cpu_regs[R_EBX]);
5510 tcg_gen_ext8u_tl(cpu_T0, cpu_regs[R_EAX]);
5511 tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T0);
5512 gen_extu(s->aflag, cpu_A0);
5513 gen_add_A0_ds_seg(s);
5514 gen_op_ld_v(s, MO_8, cpu_T0, cpu_A0);
5515 gen_op_mov_reg_v(MO_8, R_EAX, cpu_T0);
5517 case 0xb0 ... 0xb7: /* mov R, Ib */
5518 val = insn_get(env, s, MO_8);
5519 tcg_gen_movi_tl(cpu_T0, val);
5520 gen_op_mov_reg_v(MO_8, (b & 7) | REX_B(s), cpu_T0);
5522 case 0xb8 ... 0xbf: /* mov R, Iv */
5523 #ifdef TARGET_X86_64
5524 if (dflag == MO_64) {
5527 tmp = cpu_ldq_code(env, s->pc);
5529 reg = (b & 7) | REX_B(s);
5530 tcg_gen_movi_tl(cpu_T0, tmp);
5531 gen_op_mov_reg_v(MO_64, reg, cpu_T0);
5536 val = insn_get(env, s, ot);
5537 reg = (b & 7) | REX_B(s);
5538 tcg_gen_movi_tl(cpu_T0, val);
5539 gen_op_mov_reg_v(ot, reg, cpu_T0);
5543 case 0x91 ... 0x97: /* xchg R, EAX */
5546 reg = (b & 7) | REX_B(s);
5550 case 0x87: /* xchg Ev, Gv */
5551 ot = mo_b_d(b, dflag);
5552 modrm = cpu_ldub_code(env, s->pc++);
5553 reg = ((modrm >> 3) & 7) | rex_r;
5554 mod = (modrm >> 6) & 3;
5556 rm = (modrm & 7) | REX_B(s);
5558 gen_op_mov_v_reg(ot, cpu_T0, reg);
5559 gen_op_mov_v_reg(ot, cpu_T1, rm);
5560 gen_op_mov_reg_v(ot, rm, cpu_T0);
5561 gen_op_mov_reg_v(ot, reg, cpu_T1);
5563 gen_lea_modrm(env, s, modrm);
5564 gen_op_mov_v_reg(ot, cpu_T0, reg);
5565 /* for xchg, lock is implicit */
5566 tcg_gen_atomic_xchg_tl(cpu_T1, cpu_A0, cpu_T0,
5567 s->mem_index, ot | MO_LE);
5568 gen_op_mov_reg_v(ot, reg, cpu_T1);
5571 case 0xc4: /* les Gv */
5572 /* In CODE64 this is VEX3; see above. */
5575 case 0xc5: /* lds Gv */
5576 /* In CODE64 this is VEX2; see above. */
5579 case 0x1b2: /* lss Gv */
5582 case 0x1b4: /* lfs Gv */
5585 case 0x1b5: /* lgs Gv */
5588 ot = dflag != MO_16 ? MO_32 : MO_16;
5589 modrm = cpu_ldub_code(env, s->pc++);
5590 reg = ((modrm >> 3) & 7) | rex_r;
5591 mod = (modrm >> 6) & 3;
5594 gen_lea_modrm(env, s, modrm);
5595 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
5596 gen_add_A0_im(s, 1 << ot);
5597 /* load the segment first to handle exceptions properly */
5598 gen_op_ld_v(s, MO_16, cpu_T0, cpu_A0);
5599 gen_movl_seg_T0(s, op);
5600 /* then put the data */
5601 gen_op_mov_reg_v(ot, reg, cpu_T1);
5603 gen_jmp_im(s->pc - s->cs_base);
5608 /************************/
5616 ot = mo_b_d(b, dflag);
5617 modrm = cpu_ldub_code(env, s->pc++);
5618 mod = (modrm >> 6) & 3;
5619 op = (modrm >> 3) & 7;
5625 gen_lea_modrm(env, s, modrm);
5628 opreg = (modrm & 7) | REX_B(s);
5633 gen_shift(s, op, ot, opreg, OR_ECX);
5636 shift = cpu_ldub_code(env, s->pc++);
5638 gen_shifti(s, op, ot, opreg, shift);
5653 case 0x1a4: /* shld imm */
5657 case 0x1a5: /* shld cl */
5661 case 0x1ac: /* shrd imm */
5665 case 0x1ad: /* shrd cl */
5670 modrm = cpu_ldub_code(env, s->pc++);
5671 mod = (modrm >> 6) & 3;
5672 rm = (modrm & 7) | REX_B(s);
5673 reg = ((modrm >> 3) & 7) | rex_r;
5675 gen_lea_modrm(env, s, modrm);
5680 gen_op_mov_v_reg(ot, cpu_T1, reg);
5683 TCGv imm = tcg_const_tl(cpu_ldub_code(env, s->pc++));
5684 gen_shiftd_rm_T1(s, ot, opreg, op, imm);
5687 gen_shiftd_rm_T1(s, ot, opreg, op, cpu_regs[R_ECX]);
5691 /************************/
5694 if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
5695 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5696 /* XXX: what to do if illegal op ? */
5697 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
5700 modrm = cpu_ldub_code(env, s->pc++);
5701 mod = (modrm >> 6) & 3;
5703 op = ((b & 7) << 3) | ((modrm >> 3) & 7);
5706 gen_lea_modrm(env, s, modrm);
5708 case 0x00 ... 0x07: /* fxxxs */
5709 case 0x10 ... 0x17: /* fixxxl */
5710 case 0x20 ... 0x27: /* fxxxl */
5711 case 0x30 ... 0x37: /* fixxx */
5718 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5719 s->mem_index, MO_LEUL);
5720 gen_helper_flds_FT0(cpu_env, cpu_tmp2_i32);
5723 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5724 s->mem_index, MO_LEUL);
5725 gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32);
5728 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0,
5729 s->mem_index, MO_LEQ);
5730 gen_helper_fldl_FT0(cpu_env, cpu_tmp1_i64);
5734 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5735 s->mem_index, MO_LESW);
5736 gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32);
5740 gen_helper_fp_arith_ST0_FT0(op1);
5742 /* fcomp needs pop */
5743 gen_helper_fpop(cpu_env);
5747 case 0x08: /* flds */
5748 case 0x0a: /* fsts */
5749 case 0x0b: /* fstps */
5750 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5751 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5752 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5757 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5758 s->mem_index, MO_LEUL);
5759 gen_helper_flds_ST0(cpu_env, cpu_tmp2_i32);
5762 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5763 s->mem_index, MO_LEUL);
5764 gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32);
5767 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0,
5768 s->mem_index, MO_LEQ);
5769 gen_helper_fldl_ST0(cpu_env, cpu_tmp1_i64);
5773 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5774 s->mem_index, MO_LESW);
5775 gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32);
5780 /* XXX: the corresponding CPUID bit must be tested ! */
5783 gen_helper_fisttl_ST0(cpu_tmp2_i32, cpu_env);
5784 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5785 s->mem_index, MO_LEUL);
5788 gen_helper_fisttll_ST0(cpu_tmp1_i64, cpu_env);
5789 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0,
5790 s->mem_index, MO_LEQ);
5794 gen_helper_fistt_ST0(cpu_tmp2_i32, cpu_env);
5795 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5796 s->mem_index, MO_LEUW);
5799 gen_helper_fpop(cpu_env);
5804 gen_helper_fsts_ST0(cpu_tmp2_i32, cpu_env);
5805 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5806 s->mem_index, MO_LEUL);
5809 gen_helper_fistl_ST0(cpu_tmp2_i32, cpu_env);
5810 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5811 s->mem_index, MO_LEUL);
5814 gen_helper_fstl_ST0(cpu_tmp1_i64, cpu_env);
5815 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0,
5816 s->mem_index, MO_LEQ);
5820 gen_helper_fist_ST0(cpu_tmp2_i32, cpu_env);
5821 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5822 s->mem_index, MO_LEUW);
5826 gen_helper_fpop(cpu_env);
5830 case 0x0c: /* fldenv mem */
5831 gen_helper_fldenv(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5833 case 0x0d: /* fldcw mem */
5834 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5835 s->mem_index, MO_LEUW);
5836 gen_helper_fldcw(cpu_env, cpu_tmp2_i32);
5838 case 0x0e: /* fnstenv mem */
5839 gen_helper_fstenv(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5841 case 0x0f: /* fnstcw mem */
5842 gen_helper_fnstcw(cpu_tmp2_i32, cpu_env);
5843 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5844 s->mem_index, MO_LEUW);
5846 case 0x1d: /* fldt mem */
5847 gen_helper_fldt_ST0(cpu_env, cpu_A0);
5849 case 0x1f: /* fstpt mem */
5850 gen_helper_fstt_ST0(cpu_env, cpu_A0);
5851 gen_helper_fpop(cpu_env);
5853 case 0x2c: /* frstor mem */
5854 gen_helper_frstor(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5856 case 0x2e: /* fnsave mem */
5857 gen_helper_fsave(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5859 case 0x2f: /* fnstsw mem */
5860 gen_helper_fnstsw(cpu_tmp2_i32, cpu_env);
5861 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5862 s->mem_index, MO_LEUW);
5864 case 0x3c: /* fbld */
5865 gen_helper_fbld_ST0(cpu_env, cpu_A0);
5867 case 0x3e: /* fbstp */
5868 gen_helper_fbst_ST0(cpu_env, cpu_A0);
5869 gen_helper_fpop(cpu_env);
5871 case 0x3d: /* fildll */
5872 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
5873 gen_helper_fildll_ST0(cpu_env, cpu_tmp1_i64);
5875 case 0x3f: /* fistpll */
5876 gen_helper_fistll_ST0(cpu_tmp1_i64, cpu_env);
5877 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
5878 gen_helper_fpop(cpu_env);
5884 /* register float ops */
5888 case 0x08: /* fld sti */
5889 gen_helper_fpush(cpu_env);
5890 gen_helper_fmov_ST0_STN(cpu_env,
5891 tcg_const_i32((opreg + 1) & 7));
5893 case 0x09: /* fxchg sti */
5894 case 0x29: /* fxchg4 sti, undocumented op */
5895 case 0x39: /* fxchg7 sti, undocumented op */
5896 gen_helper_fxchg_ST0_STN(cpu_env, tcg_const_i32(opreg));
5898 case 0x0a: /* grp d9/2 */
5901 /* check exceptions (FreeBSD FPU probe) */
5902 gen_helper_fwait(cpu_env);
5908 case 0x0c: /* grp d9/4 */
5911 gen_helper_fchs_ST0(cpu_env);
5914 gen_helper_fabs_ST0(cpu_env);
5917 gen_helper_fldz_FT0(cpu_env);
5918 gen_helper_fcom_ST0_FT0(cpu_env);
5921 gen_helper_fxam_ST0(cpu_env);
5927 case 0x0d: /* grp d9/5 */
5931 gen_helper_fpush(cpu_env);
5932 gen_helper_fld1_ST0(cpu_env);
5935 gen_helper_fpush(cpu_env);
5936 gen_helper_fldl2t_ST0(cpu_env);
5939 gen_helper_fpush(cpu_env);
5940 gen_helper_fldl2e_ST0(cpu_env);
5943 gen_helper_fpush(cpu_env);
5944 gen_helper_fldpi_ST0(cpu_env);
5947 gen_helper_fpush(cpu_env);
5948 gen_helper_fldlg2_ST0(cpu_env);
5951 gen_helper_fpush(cpu_env);
5952 gen_helper_fldln2_ST0(cpu_env);
5955 gen_helper_fpush(cpu_env);
5956 gen_helper_fldz_ST0(cpu_env);
5963 case 0x0e: /* grp d9/6 */
5966 gen_helper_f2xm1(cpu_env);
5969 gen_helper_fyl2x(cpu_env);
5972 gen_helper_fptan(cpu_env);
5974 case 3: /* fpatan */
5975 gen_helper_fpatan(cpu_env);
5977 case 4: /* fxtract */
5978 gen_helper_fxtract(cpu_env);
5980 case 5: /* fprem1 */
5981 gen_helper_fprem1(cpu_env);
5983 case 6: /* fdecstp */
5984 gen_helper_fdecstp(cpu_env);
5987 case 7: /* fincstp */
5988 gen_helper_fincstp(cpu_env);
5992 case 0x0f: /* grp d9/7 */
5995 gen_helper_fprem(cpu_env);
5997 case 1: /* fyl2xp1 */
5998 gen_helper_fyl2xp1(cpu_env);
6001 gen_helper_fsqrt(cpu_env);
6003 case 3: /* fsincos */
6004 gen_helper_fsincos(cpu_env);
6006 case 5: /* fscale */
6007 gen_helper_fscale(cpu_env);
6009 case 4: /* frndint */
6010 gen_helper_frndint(cpu_env);
6013 gen_helper_fsin(cpu_env);
6017 gen_helper_fcos(cpu_env);
6021 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6022 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6023 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6029 gen_helper_fp_arith_STN_ST0(op1, opreg);
6031 gen_helper_fpop(cpu_env);
6033 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6034 gen_helper_fp_arith_ST0_FT0(op1);
6038 case 0x02: /* fcom */
6039 case 0x22: /* fcom2, undocumented op */
6040 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6041 gen_helper_fcom_ST0_FT0(cpu_env);
6043 case 0x03: /* fcomp */
6044 case 0x23: /* fcomp3, undocumented op */
6045 case 0x32: /* fcomp5, undocumented op */
6046 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6047 gen_helper_fcom_ST0_FT0(cpu_env);
6048 gen_helper_fpop(cpu_env);
6050 case 0x15: /* da/5 */
6052 case 1: /* fucompp */
6053 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
6054 gen_helper_fucom_ST0_FT0(cpu_env);
6055 gen_helper_fpop(cpu_env);
6056 gen_helper_fpop(cpu_env);
6064 case 0: /* feni (287 only, just do nop here) */
6066 case 1: /* fdisi (287 only, just do nop here) */
6069 gen_helper_fclex(cpu_env);
6071 case 3: /* fninit */
6072 gen_helper_fninit(cpu_env);
6074 case 4: /* fsetpm (287 only, just do nop here) */
6080 case 0x1d: /* fucomi */
6081 if (!(s->cpuid_features & CPUID_CMOV)) {
6084 gen_update_cc_op(s);
6085 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6086 gen_helper_fucomi_ST0_FT0(cpu_env);
6087 set_cc_op(s, CC_OP_EFLAGS);
6089 case 0x1e: /* fcomi */
6090 if (!(s->cpuid_features & CPUID_CMOV)) {
6093 gen_update_cc_op(s);
6094 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6095 gen_helper_fcomi_ST0_FT0(cpu_env);
6096 set_cc_op(s, CC_OP_EFLAGS);
6098 case 0x28: /* ffree sti */
6099 gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
6101 case 0x2a: /* fst sti */
6102 gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
6104 case 0x2b: /* fstp sti */
6105 case 0x0b: /* fstp1 sti, undocumented op */
6106 case 0x3a: /* fstp8 sti, undocumented op */
6107 case 0x3b: /* fstp9 sti, undocumented op */
6108 gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
6109 gen_helper_fpop(cpu_env);
6111 case 0x2c: /* fucom st(i) */
6112 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6113 gen_helper_fucom_ST0_FT0(cpu_env);
6115 case 0x2d: /* fucomp st(i) */
6116 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6117 gen_helper_fucom_ST0_FT0(cpu_env);
6118 gen_helper_fpop(cpu_env);
6120 case 0x33: /* de/3 */
6122 case 1: /* fcompp */
6123 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
6124 gen_helper_fcom_ST0_FT0(cpu_env);
6125 gen_helper_fpop(cpu_env);
6126 gen_helper_fpop(cpu_env);
6132 case 0x38: /* ffreep sti, undocumented op */
6133 gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
6134 gen_helper_fpop(cpu_env);
6136 case 0x3c: /* df/4 */
6139 gen_helper_fnstsw(cpu_tmp2_i32, cpu_env);
6140 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
6141 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
6147 case 0x3d: /* fucomip */
6148 if (!(s->cpuid_features & CPUID_CMOV)) {
6151 gen_update_cc_op(s);
6152 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6153 gen_helper_fucomi_ST0_FT0(cpu_env);
6154 gen_helper_fpop(cpu_env);
6155 set_cc_op(s, CC_OP_EFLAGS);
6157 case 0x3e: /* fcomip */
6158 if (!(s->cpuid_features & CPUID_CMOV)) {
6161 gen_update_cc_op(s);
6162 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6163 gen_helper_fcomi_ST0_FT0(cpu_env);
6164 gen_helper_fpop(cpu_env);
6165 set_cc_op(s, CC_OP_EFLAGS);
6167 case 0x10 ... 0x13: /* fcmovxx */
6172 static const uint8_t fcmov_cc[8] = {
6179 if (!(s->cpuid_features & CPUID_CMOV)) {
6182 op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1);
6183 l1 = gen_new_label();
6184 gen_jcc1_noeob(s, op1, l1);
6185 gen_helper_fmov_ST0_STN(cpu_env, tcg_const_i32(opreg));
6194 /************************/
6197 case 0xa4: /* movsS */
6199 ot = mo_b_d(b, dflag);
6200 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6201 gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6207 case 0xaa: /* stosS */
6209 ot = mo_b_d(b, dflag);
6210 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6211 gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6216 case 0xac: /* lodsS */
6218 ot = mo_b_d(b, dflag);
6219 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6220 gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6225 case 0xae: /* scasS */
6227 ot = mo_b_d(b, dflag);
6228 if (prefixes & PREFIX_REPNZ) {
6229 gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
6230 } else if (prefixes & PREFIX_REPZ) {
6231 gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
6237 case 0xa6: /* cmpsS */
6239 ot = mo_b_d(b, dflag);
6240 if (prefixes & PREFIX_REPNZ) {
6241 gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
6242 } else if (prefixes & PREFIX_REPZ) {
6243 gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
6248 case 0x6c: /* insS */
6250 ot = mo_b_d32(b, dflag);
6251 tcg_gen_ext16u_tl(cpu_T0, cpu_regs[R_EDX]);
6252 gen_check_io(s, ot, pc_start - s->cs_base,
6253 SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) | 4);
6254 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6255 gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6258 if (s->tb->cflags & CF_USE_ICOUNT) {
6259 gen_jmp(s, s->pc - s->cs_base);
6263 case 0x6e: /* outsS */
6265 ot = mo_b_d32(b, dflag);
6266 tcg_gen_ext16u_tl(cpu_T0, cpu_regs[R_EDX]);
6267 gen_check_io(s, ot, pc_start - s->cs_base,
6268 svm_is_rep(prefixes) | 4);
6269 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6270 gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6273 if (s->tb->cflags & CF_USE_ICOUNT) {
6274 gen_jmp(s, s->pc - s->cs_base);
6279 /************************/
6284 ot = mo_b_d32(b, dflag);
6285 val = cpu_ldub_code(env, s->pc++);
6286 tcg_gen_movi_tl(cpu_T0, val);
6287 gen_check_io(s, ot, pc_start - s->cs_base,
6288 SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6289 if (s->tb->cflags & CF_USE_ICOUNT) {
6292 tcg_gen_movi_i32(cpu_tmp2_i32, val);
6293 gen_helper_in_func(ot, cpu_T1, cpu_tmp2_i32);
6294 gen_op_mov_reg_v(ot, R_EAX, cpu_T1);
6295 gen_bpt_io(s, cpu_tmp2_i32, ot);
6296 if (s->tb->cflags & CF_USE_ICOUNT) {
6298 gen_jmp(s, s->pc - s->cs_base);
6303 ot = mo_b_d32(b, dflag);
6304 val = cpu_ldub_code(env, s->pc++);
6305 tcg_gen_movi_tl(cpu_T0, val);
6306 gen_check_io(s, ot, pc_start - s->cs_base,
6307 svm_is_rep(prefixes));
6308 gen_op_mov_v_reg(ot, cpu_T1, R_EAX);
6310 if (s->tb->cflags & CF_USE_ICOUNT) {
6313 tcg_gen_movi_i32(cpu_tmp2_i32, val);
6314 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T1);
6315 gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6316 gen_bpt_io(s, cpu_tmp2_i32, ot);
6317 if (s->tb->cflags & CF_USE_ICOUNT) {
6319 gen_jmp(s, s->pc - s->cs_base);
6324 ot = mo_b_d32(b, dflag);
6325 tcg_gen_ext16u_tl(cpu_T0, cpu_regs[R_EDX]);
6326 gen_check_io(s, ot, pc_start - s->cs_base,
6327 SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6328 if (s->tb->cflags & CF_USE_ICOUNT) {
6331 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
6332 gen_helper_in_func(ot, cpu_T1, cpu_tmp2_i32);
6333 gen_op_mov_reg_v(ot, R_EAX, cpu_T1);
6334 gen_bpt_io(s, cpu_tmp2_i32, ot);
6335 if (s->tb->cflags & CF_USE_ICOUNT) {
6337 gen_jmp(s, s->pc - s->cs_base);
6342 ot = mo_b_d32(b, dflag);
6343 tcg_gen_ext16u_tl(cpu_T0, cpu_regs[R_EDX]);
6344 gen_check_io(s, ot, pc_start - s->cs_base,
6345 svm_is_rep(prefixes));
6346 gen_op_mov_v_reg(ot, cpu_T1, R_EAX);
6348 if (s->tb->cflags & CF_USE_ICOUNT) {
6351 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
6352 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T1);
6353 gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6354 gen_bpt_io(s, cpu_tmp2_i32, ot);
6355 if (s->tb->cflags & CF_USE_ICOUNT) {
6357 gen_jmp(s, s->pc - s->cs_base);
6361 /************************/
6363 case 0xc2: /* ret im */
6364 val = cpu_ldsw_code(env, s->pc);
6367 gen_stack_update(s, val + (1 << ot));
6368 /* Note that gen_pop_T0 uses a zero-extending load. */
6369 gen_op_jmp_v(cpu_T0);
6373 case 0xc3: /* ret */
6375 gen_pop_update(s, ot);
6376 /* Note that gen_pop_T0 uses a zero-extending load. */
6377 gen_op_jmp_v(cpu_T0);
6381 case 0xca: /* lret im */
6382 val = cpu_ldsw_code(env, s->pc);
6385 if (s->pe && !s->vm86) {
6386 gen_update_cc_op(s);
6387 gen_jmp_im(pc_start - s->cs_base);
6388 gen_helper_lret_protected(cpu_env, tcg_const_i32(dflag - 1),
6389 tcg_const_i32(val));
6393 gen_op_ld_v(s, dflag, cpu_T0, cpu_A0);
6394 /* NOTE: keeping EIP updated is not a problem in case of
6396 gen_op_jmp_v(cpu_T0);
6398 gen_add_A0_im(s, 1 << dflag);
6399 gen_op_ld_v(s, dflag, cpu_T0, cpu_A0);
6400 gen_op_movl_seg_T0_vm(R_CS);
6401 /* add stack offset */
6402 gen_stack_update(s, val + (2 << dflag));
6406 case 0xcb: /* lret */
6409 case 0xcf: /* iret */
6410 gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET);
6413 gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
6414 set_cc_op(s, CC_OP_EFLAGS);
6415 } else if (s->vm86) {
6417 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6419 gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
6420 set_cc_op(s, CC_OP_EFLAGS);
6423 gen_helper_iret_protected(cpu_env, tcg_const_i32(dflag - 1),
6424 tcg_const_i32(s->pc - s->cs_base));
6425 set_cc_op(s, CC_OP_EFLAGS);
6429 case 0xe8: /* call im */
6431 if (dflag != MO_16) {
6432 tval = (int32_t)insn_get(env, s, MO_32);
6434 tval = (int16_t)insn_get(env, s, MO_16);
6436 next_eip = s->pc - s->cs_base;
6438 if (dflag == MO_16) {
6440 } else if (!CODE64(s)) {
6443 tcg_gen_movi_tl(cpu_T0, next_eip);
6444 gen_push_v(s, cpu_T0);
6449 case 0x9a: /* lcall im */
6451 unsigned int selector, offset;
6456 offset = insn_get(env, s, ot);
6457 selector = insn_get(env, s, MO_16);
6459 tcg_gen_movi_tl(cpu_T0, selector);
6460 tcg_gen_movi_tl(cpu_T1, offset);
6463 case 0xe9: /* jmp im */
6464 if (dflag != MO_16) {
6465 tval = (int32_t)insn_get(env, s, MO_32);
6467 tval = (int16_t)insn_get(env, s, MO_16);
6469 tval += s->pc - s->cs_base;
6470 if (dflag == MO_16) {
6472 } else if (!CODE64(s)) {
6478 case 0xea: /* ljmp im */
6480 unsigned int selector, offset;
6485 offset = insn_get(env, s, ot);
6486 selector = insn_get(env, s, MO_16);
6488 tcg_gen_movi_tl(cpu_T0, selector);
6489 tcg_gen_movi_tl(cpu_T1, offset);
6492 case 0xeb: /* jmp Jb */
6493 tval = (int8_t)insn_get(env, s, MO_8);
6494 tval += s->pc - s->cs_base;
6495 if (dflag == MO_16) {
6500 case 0x70 ... 0x7f: /* jcc Jb */
6501 tval = (int8_t)insn_get(env, s, MO_8);
6503 case 0x180 ... 0x18f: /* jcc Jv */
6504 if (dflag != MO_16) {
6505 tval = (int32_t)insn_get(env, s, MO_32);
6507 tval = (int16_t)insn_get(env, s, MO_16);
6510 next_eip = s->pc - s->cs_base;
6512 if (dflag == MO_16) {
6516 gen_jcc(s, b, tval, next_eip);
6519 case 0x190 ... 0x19f: /* setcc Gv */
6520 modrm = cpu_ldub_code(env, s->pc++);
6521 gen_setcc1(s, b, cpu_T0);
6522 gen_ldst_modrm(env, s, modrm, MO_8, OR_TMP0, 1);
6524 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6525 if (!(s->cpuid_features & CPUID_CMOV)) {
6529 modrm = cpu_ldub_code(env, s->pc++);
6530 reg = ((modrm >> 3) & 7) | rex_r;
6531 gen_cmovcc1(env, s, ot, b, modrm, reg);
6534 /************************/
6536 case 0x9c: /* pushf */
6537 gen_svm_check_intercept(s, pc_start, SVM_EXIT_PUSHF);
6538 if (s->vm86 && s->iopl != 3) {
6539 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6541 gen_update_cc_op(s);
6542 gen_helper_read_eflags(cpu_T0, cpu_env);
6543 gen_push_v(s, cpu_T0);
6546 case 0x9d: /* popf */
6547 gen_svm_check_intercept(s, pc_start, SVM_EXIT_POPF);
6548 if (s->vm86 && s->iopl != 3) {
6549 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6553 if (dflag != MO_16) {
6554 gen_helper_write_eflags(cpu_env, cpu_T0,
6555 tcg_const_i32((TF_MASK | AC_MASK |
6560 gen_helper_write_eflags(cpu_env, cpu_T0,
6561 tcg_const_i32((TF_MASK | AC_MASK |
6563 IF_MASK | IOPL_MASK)
6567 if (s->cpl <= s->iopl) {
6568 if (dflag != MO_16) {
6569 gen_helper_write_eflags(cpu_env, cpu_T0,
6570 tcg_const_i32((TF_MASK |
6576 gen_helper_write_eflags(cpu_env, cpu_T0,
6577 tcg_const_i32((TF_MASK |
6585 if (dflag != MO_16) {
6586 gen_helper_write_eflags(cpu_env, cpu_T0,
6587 tcg_const_i32((TF_MASK | AC_MASK |
6588 ID_MASK | NT_MASK)));
6590 gen_helper_write_eflags(cpu_env, cpu_T0,
6591 tcg_const_i32((TF_MASK | AC_MASK |
6597 gen_pop_update(s, ot);
6598 set_cc_op(s, CC_OP_EFLAGS);
6599 /* abort translation because TF/AC flag may change */
6600 gen_jmp_im(s->pc - s->cs_base);
6604 case 0x9e: /* sahf */
6605 if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6607 gen_op_mov_v_reg(MO_8, cpu_T0, R_AH);
6608 gen_compute_eflags(s);
6609 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O);
6610 tcg_gen_andi_tl(cpu_T0, cpu_T0, CC_S | CC_Z | CC_A | CC_P | CC_C);
6611 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_T0);
6613 case 0x9f: /* lahf */
6614 if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6616 gen_compute_eflags(s);
6617 /* Note: gen_compute_eflags() only gives the condition codes */
6618 tcg_gen_ori_tl(cpu_T0, cpu_cc_src, 0x02);
6619 gen_op_mov_reg_v(MO_8, R_AH, cpu_T0);
6621 case 0xf5: /* cmc */
6622 gen_compute_eflags(s);
6623 tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6625 case 0xf8: /* clc */
6626 gen_compute_eflags(s);
6627 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C);
6629 case 0xf9: /* stc */
6630 gen_compute_eflags(s);
6631 tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6633 case 0xfc: /* cld */
6634 tcg_gen_movi_i32(cpu_tmp2_i32, 1);
6635 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, df));
6637 case 0xfd: /* std */
6638 tcg_gen_movi_i32(cpu_tmp2_i32, -1);
6639 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, df));
6642 /************************/
6643 /* bit operations */
6644 case 0x1ba: /* bt/bts/btr/btc Gv, im */
6646 modrm = cpu_ldub_code(env, s->pc++);
6647 op = (modrm >> 3) & 7;
6648 mod = (modrm >> 6) & 3;
6649 rm = (modrm & 7) | REX_B(s);
6652 gen_lea_modrm(env, s, modrm);
6653 if (!(s->prefix & PREFIX_LOCK)) {
6654 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
6657 gen_op_mov_v_reg(ot, cpu_T0, rm);
6660 val = cpu_ldub_code(env, s->pc++);
6661 tcg_gen_movi_tl(cpu_T1, val);
6666 case 0x1a3: /* bt Gv, Ev */
6669 case 0x1ab: /* bts */
6672 case 0x1b3: /* btr */
6675 case 0x1bb: /* btc */
6679 modrm = cpu_ldub_code(env, s->pc++);
6680 reg = ((modrm >> 3) & 7) | rex_r;
6681 mod = (modrm >> 6) & 3;
6682 rm = (modrm & 7) | REX_B(s);
6683 gen_op_mov_v_reg(MO_32, cpu_T1, reg);
6685 AddressParts a = gen_lea_modrm_0(env, s, modrm);
6686 /* specific case: we need to add a displacement */
6687 gen_exts(ot, cpu_T1);
6688 tcg_gen_sari_tl(cpu_tmp0, cpu_T1, 3 + ot);
6689 tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, ot);
6690 tcg_gen_add_tl(cpu_A0, gen_lea_modrm_1(a), cpu_tmp0);
6691 gen_lea_v_seg(s, s->aflag, cpu_A0, a.def_seg, s->override);
6692 if (!(s->prefix & PREFIX_LOCK)) {
6693 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
6696 gen_op_mov_v_reg(ot, cpu_T0, rm);
6699 tcg_gen_andi_tl(cpu_T1, cpu_T1, (1 << (3 + ot)) - 1);
6700 tcg_gen_movi_tl(cpu_tmp0, 1);
6701 tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T1);
6702 if (s->prefix & PREFIX_LOCK) {
6705 /* Needs no atomic ops; we surpressed the normal
6706 memory load for LOCK above so do it now. */
6707 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
6710 tcg_gen_atomic_fetch_or_tl(cpu_T0, cpu_A0, cpu_tmp0,
6711 s->mem_index, ot | MO_LE);
6714 tcg_gen_not_tl(cpu_tmp0, cpu_tmp0);
6715 tcg_gen_atomic_fetch_and_tl(cpu_T0, cpu_A0, cpu_tmp0,
6716 s->mem_index, ot | MO_LE);
6720 tcg_gen_atomic_fetch_xor_tl(cpu_T0, cpu_A0, cpu_tmp0,
6721 s->mem_index, ot | MO_LE);
6724 tcg_gen_shr_tl(cpu_tmp4, cpu_T0, cpu_T1);
6726 tcg_gen_shr_tl(cpu_tmp4, cpu_T0, cpu_T1);
6729 /* Data already loaded; nothing to do. */
6732 tcg_gen_or_tl(cpu_T0, cpu_T0, cpu_tmp0);
6735 tcg_gen_andc_tl(cpu_T0, cpu_T0, cpu_tmp0);
6739 tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_tmp0);
6744 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
6746 gen_op_mov_reg_v(ot, rm, cpu_T0);
6751 /* Delay all CC updates until after the store above. Note that
6752 C is the result of the test, Z is unchanged, and the others
6753 are all undefined. */
6755 case CC_OP_MULB ... CC_OP_MULQ:
6756 case CC_OP_ADDB ... CC_OP_ADDQ:
6757 case CC_OP_ADCB ... CC_OP_ADCQ:
6758 case CC_OP_SUBB ... CC_OP_SUBQ:
6759 case CC_OP_SBBB ... CC_OP_SBBQ:
6760 case CC_OP_LOGICB ... CC_OP_LOGICQ:
6761 case CC_OP_INCB ... CC_OP_INCQ:
6762 case CC_OP_DECB ... CC_OP_DECQ:
6763 case CC_OP_SHLB ... CC_OP_SHLQ:
6764 case CC_OP_SARB ... CC_OP_SARQ:
6765 case CC_OP_BMILGB ... CC_OP_BMILGQ:
6766 /* Z was going to be computed from the non-zero status of CC_DST.
6767 We can get that same Z value (and the new C value) by leaving
6768 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
6770 tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
6771 set_cc_op(s, ((s->cc_op - CC_OP_MULB) & 3) + CC_OP_SARB);
6774 /* Otherwise, generate EFLAGS and replace the C bit. */
6775 gen_compute_eflags(s);
6776 tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, cpu_tmp4,
6781 case 0x1bc: /* bsf / tzcnt */
6782 case 0x1bd: /* bsr / lzcnt */
6784 modrm = cpu_ldub_code(env, s->pc++);
6785 reg = ((modrm >> 3) & 7) | rex_r;
6786 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
6787 gen_extu(ot, cpu_T0);
6789 /* Note that lzcnt and tzcnt are in different extensions. */
6790 if ((prefixes & PREFIX_REPZ)
6792 ? s->cpuid_ext3_features & CPUID_EXT3_ABM
6793 : s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)) {
6795 tcg_gen_mov_tl(cpu_cc_src, cpu_T0);
6797 /* For lzcnt, reduce the target_ulong result by the
6798 number of zeros that we expect to find at the top. */
6799 gen_helper_clz(cpu_T0, cpu_T0);
6800 tcg_gen_subi_tl(cpu_T0, cpu_T0, TARGET_LONG_BITS - size);
6802 /* For tzcnt, a zero input must return the operand size:
6803 force all bits outside the operand size to 1. */
6804 target_ulong mask = (target_ulong)-2 << (size - 1);
6805 tcg_gen_ori_tl(cpu_T0, cpu_T0, mask);
6806 gen_helper_ctz(cpu_T0, cpu_T0);
6808 /* For lzcnt/tzcnt, C and Z bits are defined and are
6809 related to the result. */
6810 gen_op_update1_cc();
6811 set_cc_op(s, CC_OP_BMILGB + ot);
6813 /* For bsr/bsf, only the Z bit is defined and it is related
6814 to the input and not the result. */
6815 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
6816 set_cc_op(s, CC_OP_LOGICB + ot);
6818 /* For bsr, return the bit index of the first 1 bit,
6819 not the count of leading zeros. */
6820 gen_helper_clz(cpu_T0, cpu_T0);
6821 tcg_gen_xori_tl(cpu_T0, cpu_T0, TARGET_LONG_BITS - 1);
6823 gen_helper_ctz(cpu_T0, cpu_T0);
6825 /* ??? The manual says that the output is undefined when the
6826 input is zero, but real hardware leaves it unchanged, and
6827 real programs appear to depend on that. */
6828 tcg_gen_movi_tl(cpu_tmp0, 0);
6829 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_T0, cpu_cc_dst, cpu_tmp0,
6830 cpu_regs[reg], cpu_T0);
6832 gen_op_mov_reg_v(ot, reg, cpu_T0);
6834 /************************/
6836 case 0x27: /* daa */
6839 gen_update_cc_op(s);
6840 gen_helper_daa(cpu_env);
6841 set_cc_op(s, CC_OP_EFLAGS);
6843 case 0x2f: /* das */
6846 gen_update_cc_op(s);
6847 gen_helper_das(cpu_env);
6848 set_cc_op(s, CC_OP_EFLAGS);
6850 case 0x37: /* aaa */
6853 gen_update_cc_op(s);
6854 gen_helper_aaa(cpu_env);
6855 set_cc_op(s, CC_OP_EFLAGS);
6857 case 0x3f: /* aas */
6860 gen_update_cc_op(s);
6861 gen_helper_aas(cpu_env);
6862 set_cc_op(s, CC_OP_EFLAGS);
6864 case 0xd4: /* aam */
6867 val = cpu_ldub_code(env, s->pc++);
6869 gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base);
6871 gen_helper_aam(cpu_env, tcg_const_i32(val));
6872 set_cc_op(s, CC_OP_LOGICB);
6875 case 0xd5: /* aad */
6878 val = cpu_ldub_code(env, s->pc++);
6879 gen_helper_aad(cpu_env, tcg_const_i32(val));
6880 set_cc_op(s, CC_OP_LOGICB);
6882 /************************/
6884 case 0x90: /* nop */
6885 /* XXX: correct lock test for all insn */
6886 if (prefixes & PREFIX_LOCK) {
6889 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
6891 goto do_xchg_reg_eax;
6893 if (prefixes & PREFIX_REPZ) {
6894 gen_update_cc_op(s);
6895 gen_jmp_im(pc_start - s->cs_base);
6896 gen_helper_pause(cpu_env, tcg_const_i32(s->pc - pc_start));
6897 s->is_jmp = DISAS_TB_JUMP;
6900 case 0x9b: /* fwait */
6901 if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
6902 (HF_MP_MASK | HF_TS_MASK)) {
6903 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
6905 gen_helper_fwait(cpu_env);
6908 case 0xcc: /* int3 */
6909 gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
6911 case 0xcd: /* int N */
6912 val = cpu_ldub_code(env, s->pc++);
6913 if (s->vm86 && s->iopl != 3) {
6914 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6916 gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
6919 case 0xce: /* into */
6922 gen_update_cc_op(s);
6923 gen_jmp_im(pc_start - s->cs_base);
6924 gen_helper_into(cpu_env, tcg_const_i32(s->pc - pc_start));
6927 case 0xf1: /* icebp (undocumented, exits to external debugger) */
6928 gen_svm_check_intercept(s, pc_start, SVM_EXIT_ICEBP);
6930 gen_debug(s, pc_start - s->cs_base);
6933 tb_flush(CPU(x86_env_get_cpu(env)));
6934 qemu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM);
6938 case 0xfa: /* cli */
6940 if (s->cpl <= s->iopl) {
6941 gen_helper_cli(cpu_env);
6943 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6947 gen_helper_cli(cpu_env);
6949 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6953 case 0xfb: /* sti */
6954 if (s->vm86 ? s->iopl == 3 : s->cpl <= s->iopl) {
6955 gen_helper_sti(cpu_env);
6956 /* interruptions are enabled only the first insn after sti */
6957 gen_jmp_im(s->pc - s->cs_base);
6958 gen_eob_inhibit_irq(s, true);
6960 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6963 case 0x62: /* bound */
6967 modrm = cpu_ldub_code(env, s->pc++);
6968 reg = (modrm >> 3) & 7;
6969 mod = (modrm >> 6) & 3;
6972 gen_op_mov_v_reg(ot, cpu_T0, reg);
6973 gen_lea_modrm(env, s, modrm);
6974 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
6976 gen_helper_boundw(cpu_env, cpu_A0, cpu_tmp2_i32);
6978 gen_helper_boundl(cpu_env, cpu_A0, cpu_tmp2_i32);
6981 case 0x1c8 ... 0x1cf: /* bswap reg */
6982 reg = (b & 7) | REX_B(s);
6983 #ifdef TARGET_X86_64
6984 if (dflag == MO_64) {
6985 gen_op_mov_v_reg(MO_64, cpu_T0, reg);
6986 tcg_gen_bswap64_i64(cpu_T0, cpu_T0);
6987 gen_op_mov_reg_v(MO_64, reg, cpu_T0);
6991 gen_op_mov_v_reg(MO_32, cpu_T0, reg);
6992 tcg_gen_ext32u_tl(cpu_T0, cpu_T0);
6993 tcg_gen_bswap32_tl(cpu_T0, cpu_T0);
6994 gen_op_mov_reg_v(MO_32, reg, cpu_T0);
6997 case 0xd6: /* salc */
7000 gen_compute_eflags_c(s, cpu_T0);
7001 tcg_gen_neg_tl(cpu_T0, cpu_T0);
7002 gen_op_mov_reg_v(MO_8, R_EAX, cpu_T0);
7004 case 0xe0: /* loopnz */
7005 case 0xe1: /* loopz */
7006 case 0xe2: /* loop */
7007 case 0xe3: /* jecxz */
7009 TCGLabel *l1, *l2, *l3;
7011 tval = (int8_t)insn_get(env, s, MO_8);
7012 next_eip = s->pc - s->cs_base;
7014 if (dflag == MO_16) {
7018 l1 = gen_new_label();
7019 l2 = gen_new_label();
7020 l3 = gen_new_label();
7023 case 0: /* loopnz */
7025 gen_op_add_reg_im(s->aflag, R_ECX, -1);
7026 gen_op_jz_ecx(s->aflag, l3);
7027 gen_jcc1(s, (JCC_Z << 1) | (b ^ 1), l1);
7030 gen_op_add_reg_im(s->aflag, R_ECX, -1);
7031 gen_op_jnz_ecx(s->aflag, l1);
7035 gen_op_jz_ecx(s->aflag, l1);
7040 gen_jmp_im(next_eip);
7049 case 0x130: /* wrmsr */
7050 case 0x132: /* rdmsr */
7052 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7054 gen_update_cc_op(s);
7055 gen_jmp_im(pc_start - s->cs_base);
7057 gen_helper_rdmsr(cpu_env);
7059 gen_helper_wrmsr(cpu_env);
7063 case 0x131: /* rdtsc */
7064 gen_update_cc_op(s);
7065 gen_jmp_im(pc_start - s->cs_base);
7066 if (s->tb->cflags & CF_USE_ICOUNT) {
7069 gen_helper_rdtsc(cpu_env);
7070 if (s->tb->cflags & CF_USE_ICOUNT) {
7072 gen_jmp(s, s->pc - s->cs_base);
7075 case 0x133: /* rdpmc */
7076 gen_update_cc_op(s);
7077 gen_jmp_im(pc_start - s->cs_base);
7078 gen_helper_rdpmc(cpu_env);
7080 case 0x134: /* sysenter */
7081 /* For Intel SYSENTER is valid on 64-bit */
7082 if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
7085 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7087 gen_helper_sysenter(cpu_env);
7091 case 0x135: /* sysexit */
7092 /* For Intel SYSEXIT is valid on 64-bit */
7093 if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
7096 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7098 gen_helper_sysexit(cpu_env, tcg_const_i32(dflag - 1));
7102 #ifdef TARGET_X86_64
7103 case 0x105: /* syscall */
7104 /* XXX: is it usable in real mode ? */
7105 gen_update_cc_op(s);
7106 gen_jmp_im(pc_start - s->cs_base);
7107 gen_helper_syscall(cpu_env, tcg_const_i32(s->pc - pc_start));
7110 case 0x107: /* sysret */
7112 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7114 gen_helper_sysret(cpu_env, tcg_const_i32(dflag - 1));
7115 /* condition codes are modified only in long mode */
7117 set_cc_op(s, CC_OP_EFLAGS);
7123 case 0x1a2: /* cpuid */
7124 gen_update_cc_op(s);
7125 gen_jmp_im(pc_start - s->cs_base);
7126 gen_helper_cpuid(cpu_env);
7128 case 0xf4: /* hlt */
7130 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7132 gen_update_cc_op(s);
7133 gen_jmp_im(pc_start - s->cs_base);
7134 gen_helper_hlt(cpu_env, tcg_const_i32(s->pc - pc_start));
7135 s->is_jmp = DISAS_TB_JUMP;
7139 modrm = cpu_ldub_code(env, s->pc++);
7140 mod = (modrm >> 6) & 3;
7141 op = (modrm >> 3) & 7;
7144 if (!s->pe || s->vm86)
7146 gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_READ);
7147 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
7148 offsetof(CPUX86State, ldt.selector));
7149 ot = mod == 3 ? dflag : MO_16;
7150 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7153 if (!s->pe || s->vm86)
7156 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7158 gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_WRITE);
7159 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7160 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
7161 gen_helper_lldt(cpu_env, cpu_tmp2_i32);
7165 if (!s->pe || s->vm86)
7167 gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_READ);
7168 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
7169 offsetof(CPUX86State, tr.selector));
7170 ot = mod == 3 ? dflag : MO_16;
7171 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7174 if (!s->pe || s->vm86)
7177 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7179 gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_WRITE);
7180 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7181 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
7182 gen_helper_ltr(cpu_env, cpu_tmp2_i32);
7187 if (!s->pe || s->vm86)
7189 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7190 gen_update_cc_op(s);
7192 gen_helper_verr(cpu_env, cpu_T0);
7194 gen_helper_verw(cpu_env, cpu_T0);
7196 set_cc_op(s, CC_OP_EFLAGS);
7204 modrm = cpu_ldub_code(env, s->pc++);
7206 CASE_MODRM_MEM_OP(0): /* sgdt */
7207 gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_READ);
7208 gen_lea_modrm(env, s, modrm);
7209 tcg_gen_ld32u_tl(cpu_T0,
7210 cpu_env, offsetof(CPUX86State, gdt.limit));
7211 gen_op_st_v(s, MO_16, cpu_T0, cpu_A0);
7212 gen_add_A0_im(s, 2);
7213 tcg_gen_ld_tl(cpu_T0, cpu_env, offsetof(CPUX86State, gdt.base));
7214 if (dflag == MO_16) {
7215 tcg_gen_andi_tl(cpu_T0, cpu_T0, 0xffffff);
7217 gen_op_st_v(s, CODE64(s) + MO_32, cpu_T0, cpu_A0);
7220 case 0xc8: /* monitor */
7221 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || s->cpl != 0) {
7224 gen_update_cc_op(s);
7225 gen_jmp_im(pc_start - s->cs_base);
7226 tcg_gen_mov_tl(cpu_A0, cpu_regs[R_EAX]);
7227 gen_extu(s->aflag, cpu_A0);
7228 gen_add_A0_ds_seg(s);
7229 gen_helper_monitor(cpu_env, cpu_A0);
7232 case 0xc9: /* mwait */
7233 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || s->cpl != 0) {
7236 gen_update_cc_op(s);
7237 gen_jmp_im(pc_start - s->cs_base);
7238 gen_helper_mwait(cpu_env, tcg_const_i32(s->pc - pc_start));
7242 case 0xca: /* clac */
7243 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)
7247 gen_helper_clac(cpu_env);
7248 gen_jmp_im(s->pc - s->cs_base);
7252 case 0xcb: /* stac */
7253 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)
7257 gen_helper_stac(cpu_env);
7258 gen_jmp_im(s->pc - s->cs_base);
7262 CASE_MODRM_MEM_OP(1): /* sidt */
7263 gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_READ);
7264 gen_lea_modrm(env, s, modrm);
7265 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State, idt.limit));
7266 gen_op_st_v(s, MO_16, cpu_T0, cpu_A0);
7267 gen_add_A0_im(s, 2);
7268 tcg_gen_ld_tl(cpu_T0, cpu_env, offsetof(CPUX86State, idt.base));
7269 if (dflag == MO_16) {
7270 tcg_gen_andi_tl(cpu_T0, cpu_T0, 0xffffff);
7272 gen_op_st_v(s, CODE64(s) + MO_32, cpu_T0, cpu_A0);
7275 case 0xd0: /* xgetbv */
7276 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
7277 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA
7278 | PREFIX_REPZ | PREFIX_REPNZ))) {
7281 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_ECX]);
7282 gen_helper_xgetbv(cpu_tmp1_i64, cpu_env, cpu_tmp2_i32);
7283 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], cpu_tmp1_i64);
7286 case 0xd1: /* xsetbv */
7287 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
7288 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA
7289 | PREFIX_REPZ | PREFIX_REPNZ))) {
7293 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7296 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
7298 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_ECX]);
7299 gen_helper_xsetbv(cpu_env, cpu_tmp2_i32, cpu_tmp1_i64);
7300 /* End TB because translation flags may change. */
7301 gen_jmp_im(s->pc - s->cs_base);
7305 case 0xd8: /* VMRUN */
7306 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7310 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7313 gen_update_cc_op(s);
7314 gen_jmp_im(pc_start - s->cs_base);
7315 gen_helper_vmrun(cpu_env, tcg_const_i32(s->aflag - 1),
7316 tcg_const_i32(s->pc - pc_start));
7318 s->is_jmp = DISAS_TB_JUMP;
7321 case 0xd9: /* VMMCALL */
7322 if (!(s->flags & HF_SVME_MASK)) {
7325 gen_update_cc_op(s);
7326 gen_jmp_im(pc_start - s->cs_base);
7327 gen_helper_vmmcall(cpu_env);
7330 case 0xda: /* VMLOAD */
7331 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7335 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7338 gen_update_cc_op(s);
7339 gen_jmp_im(pc_start - s->cs_base);
7340 gen_helper_vmload(cpu_env, tcg_const_i32(s->aflag - 1));
7343 case 0xdb: /* VMSAVE */
7344 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7348 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7351 gen_update_cc_op(s);
7352 gen_jmp_im(pc_start - s->cs_base);
7353 gen_helper_vmsave(cpu_env, tcg_const_i32(s->aflag - 1));
7356 case 0xdc: /* STGI */
7357 if ((!(s->flags & HF_SVME_MASK)
7358 && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
7363 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7366 gen_update_cc_op(s);
7367 gen_jmp_im(pc_start - s->cs_base);
7368 gen_helper_stgi(cpu_env);
7371 case 0xdd: /* CLGI */
7372 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7376 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7379 gen_update_cc_op(s);
7380 gen_jmp_im(pc_start - s->cs_base);
7381 gen_helper_clgi(cpu_env);
7384 case 0xde: /* SKINIT */
7385 if ((!(s->flags & HF_SVME_MASK)
7386 && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
7390 gen_update_cc_op(s);
7391 gen_jmp_im(pc_start - s->cs_base);
7392 gen_helper_skinit(cpu_env);
7395 case 0xdf: /* INVLPGA */
7396 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7400 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7403 gen_update_cc_op(s);
7404 gen_jmp_im(pc_start - s->cs_base);
7405 gen_helper_invlpga(cpu_env, tcg_const_i32(s->aflag - 1));
7408 CASE_MODRM_MEM_OP(2): /* lgdt */
7410 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7413 gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_WRITE);
7414 gen_lea_modrm(env, s, modrm);
7415 gen_op_ld_v(s, MO_16, cpu_T1, cpu_A0);
7416 gen_add_A0_im(s, 2);
7417 gen_op_ld_v(s, CODE64(s) + MO_32, cpu_T0, cpu_A0);
7418 if (dflag == MO_16) {
7419 tcg_gen_andi_tl(cpu_T0, cpu_T0, 0xffffff);
7421 tcg_gen_st_tl(cpu_T0, cpu_env, offsetof(CPUX86State, gdt.base));
7422 tcg_gen_st32_tl(cpu_T1, cpu_env, offsetof(CPUX86State, gdt.limit));
7425 CASE_MODRM_MEM_OP(3): /* lidt */
7427 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7430 gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_WRITE);
7431 gen_lea_modrm(env, s, modrm);
7432 gen_op_ld_v(s, MO_16, cpu_T1, cpu_A0);
7433 gen_add_A0_im(s, 2);
7434 gen_op_ld_v(s, CODE64(s) + MO_32, cpu_T0, cpu_A0);
7435 if (dflag == MO_16) {
7436 tcg_gen_andi_tl(cpu_T0, cpu_T0, 0xffffff);
7438 tcg_gen_st_tl(cpu_T0, cpu_env, offsetof(CPUX86State, idt.base));
7439 tcg_gen_st32_tl(cpu_T1, cpu_env, offsetof(CPUX86State, idt.limit));
7442 CASE_MODRM_OP(4): /* smsw */
7443 gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0);
7444 tcg_gen_ld_tl(cpu_T0, cpu_env, offsetof(CPUX86State, cr[0]));
7446 mod = (modrm >> 6) & 3;
7447 ot = (mod != 3 ? MO_16 : s->dflag);
7451 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7453 case 0xee: /* rdpkru */
7454 if (prefixes & PREFIX_LOCK) {
7457 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_ECX]);
7458 gen_helper_rdpkru(cpu_tmp1_i64, cpu_env, cpu_tmp2_i32);
7459 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], cpu_tmp1_i64);
7461 case 0xef: /* wrpkru */
7462 if (prefixes & PREFIX_LOCK) {
7465 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
7467 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_ECX]);
7468 gen_helper_wrpkru(cpu_env, cpu_tmp2_i32, cpu_tmp1_i64);
7470 CASE_MODRM_OP(6): /* lmsw */
7472 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7475 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
7476 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7477 gen_helper_lmsw(cpu_env, cpu_T0);
7478 gen_jmp_im(s->pc - s->cs_base);
7482 CASE_MODRM_MEM_OP(7): /* invlpg */
7484 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7487 gen_update_cc_op(s);
7488 gen_jmp_im(pc_start - s->cs_base);
7489 gen_lea_modrm(env, s, modrm);
7490 gen_helper_invlpg(cpu_env, cpu_A0);
7491 gen_jmp_im(s->pc - s->cs_base);
7495 case 0xf8: /* swapgs */
7496 #ifdef TARGET_X86_64
7499 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7501 tcg_gen_mov_tl(cpu_T0, cpu_seg_base[R_GS]);
7502 tcg_gen_ld_tl(cpu_seg_base[R_GS], cpu_env,
7503 offsetof(CPUX86State, kernelgsbase));
7504 tcg_gen_st_tl(cpu_T0, cpu_env,
7505 offsetof(CPUX86State, kernelgsbase));
7512 case 0xf9: /* rdtscp */
7513 if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP)) {
7516 gen_update_cc_op(s);
7517 gen_jmp_im(pc_start - s->cs_base);
7518 if (s->tb->cflags & CF_USE_ICOUNT) {
7521 gen_helper_rdtscp(cpu_env);
7522 if (s->tb->cflags & CF_USE_ICOUNT) {
7524 gen_jmp(s, s->pc - s->cs_base);
7533 case 0x108: /* invd */
7534 case 0x109: /* wbinvd */
7536 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7538 gen_svm_check_intercept(s, pc_start, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD);
7542 case 0x63: /* arpl or movslS (x86_64) */
7543 #ifdef TARGET_X86_64
7546 /* d_ot is the size of destination */
7549 modrm = cpu_ldub_code(env, s->pc++);
7550 reg = ((modrm >> 3) & 7) | rex_r;
7551 mod = (modrm >> 6) & 3;
7552 rm = (modrm & 7) | REX_B(s);
7555 gen_op_mov_v_reg(MO_32, cpu_T0, rm);
7557 if (d_ot == MO_64) {
7558 tcg_gen_ext32s_tl(cpu_T0, cpu_T0);
7560 gen_op_mov_reg_v(d_ot, reg, cpu_T0);
7562 gen_lea_modrm(env, s, modrm);
7563 gen_op_ld_v(s, MO_32 | MO_SIGN, cpu_T0, cpu_A0);
7564 gen_op_mov_reg_v(d_ot, reg, cpu_T0);
7570 TCGv t0, t1, t2, a0;
7572 if (!s->pe || s->vm86)
7574 t0 = tcg_temp_local_new();
7575 t1 = tcg_temp_local_new();
7576 t2 = tcg_temp_local_new();
7578 modrm = cpu_ldub_code(env, s->pc++);
7579 reg = (modrm >> 3) & 7;
7580 mod = (modrm >> 6) & 3;
7583 gen_lea_modrm(env, s, modrm);
7584 gen_op_ld_v(s, ot, t0, cpu_A0);
7585 a0 = tcg_temp_local_new();
7586 tcg_gen_mov_tl(a0, cpu_A0);
7588 gen_op_mov_v_reg(ot, t0, rm);
7591 gen_op_mov_v_reg(ot, t1, reg);
7592 tcg_gen_andi_tl(cpu_tmp0, t0, 3);
7593 tcg_gen_andi_tl(t1, t1, 3);
7594 tcg_gen_movi_tl(t2, 0);
7595 label1 = gen_new_label();
7596 tcg_gen_brcond_tl(TCG_COND_GE, cpu_tmp0, t1, label1);
7597 tcg_gen_andi_tl(t0, t0, ~3);
7598 tcg_gen_or_tl(t0, t0, t1);
7599 tcg_gen_movi_tl(t2, CC_Z);
7600 gen_set_label(label1);
7602 gen_op_st_v(s, ot, t0, a0);
7605 gen_op_mov_reg_v(ot, rm, t0);
7607 gen_compute_eflags(s);
7608 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z);
7609 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t2);
7615 case 0x102: /* lar */
7616 case 0x103: /* lsl */
7620 if (!s->pe || s->vm86)
7622 ot = dflag != MO_16 ? MO_32 : MO_16;
7623 modrm = cpu_ldub_code(env, s->pc++);
7624 reg = ((modrm >> 3) & 7) | rex_r;
7625 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7626 t0 = tcg_temp_local_new();
7627 gen_update_cc_op(s);
7629 gen_helper_lar(t0, cpu_env, cpu_T0);
7631 gen_helper_lsl(t0, cpu_env, cpu_T0);
7633 tcg_gen_andi_tl(cpu_tmp0, cpu_cc_src, CC_Z);
7634 label1 = gen_new_label();
7635 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
7636 gen_op_mov_reg_v(ot, reg, t0);
7637 gen_set_label(label1);
7638 set_cc_op(s, CC_OP_EFLAGS);
7643 modrm = cpu_ldub_code(env, s->pc++);
7644 mod = (modrm >> 6) & 3;
7645 op = (modrm >> 3) & 7;
7647 case 0: /* prefetchnta */
7648 case 1: /* prefetchnt0 */
7649 case 2: /* prefetchnt0 */
7650 case 3: /* prefetchnt0 */
7653 gen_nop_modrm(env, s, modrm);
7654 /* nothing more to do */
7656 default: /* nop (multi byte) */
7657 gen_nop_modrm(env, s, modrm);
7662 modrm = cpu_ldub_code(env, s->pc++);
7663 if (s->flags & HF_MPX_EN_MASK) {
7664 mod = (modrm >> 6) & 3;
7665 reg = ((modrm >> 3) & 7) | rex_r;
7666 if (prefixes & PREFIX_REPZ) {
7669 || (prefixes & PREFIX_LOCK)
7670 || s->aflag == MO_16) {
7673 gen_bndck(env, s, modrm, TCG_COND_LTU, cpu_bndl[reg]);
7674 } else if (prefixes & PREFIX_REPNZ) {
7677 || (prefixes & PREFIX_LOCK)
7678 || s->aflag == MO_16) {
7681 TCGv_i64 notu = tcg_temp_new_i64();
7682 tcg_gen_not_i64(notu, cpu_bndu[reg]);
7683 gen_bndck(env, s, modrm, TCG_COND_GTU, notu);
7684 tcg_temp_free_i64(notu);
7685 } else if (prefixes & PREFIX_DATA) {
7686 /* bndmov -- from reg/mem */
7687 if (reg >= 4 || s->aflag == MO_16) {
7691 int reg2 = (modrm & 7) | REX_B(s);
7692 if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) {
7695 if (s->flags & HF_MPX_IU_MASK) {
7696 tcg_gen_mov_i64(cpu_bndl[reg], cpu_bndl[reg2]);
7697 tcg_gen_mov_i64(cpu_bndu[reg], cpu_bndu[reg2]);
7700 gen_lea_modrm(env, s, modrm);
7702 tcg_gen_qemu_ld_i64(cpu_bndl[reg], cpu_A0,
7703 s->mem_index, MO_LEQ);
7704 tcg_gen_addi_tl(cpu_A0, cpu_A0, 8);
7705 tcg_gen_qemu_ld_i64(cpu_bndu[reg], cpu_A0,
7706 s->mem_index, MO_LEQ);
7708 tcg_gen_qemu_ld_i64(cpu_bndl[reg], cpu_A0,
7709 s->mem_index, MO_LEUL);
7710 tcg_gen_addi_tl(cpu_A0, cpu_A0, 4);
7711 tcg_gen_qemu_ld_i64(cpu_bndu[reg], cpu_A0,
7712 s->mem_index, MO_LEUL);
7714 /* bnd registers are now in-use */
7715 gen_set_hflag(s, HF_MPX_IU_MASK);
7717 } else if (mod != 3) {
7719 AddressParts a = gen_lea_modrm_0(env, s, modrm);
7721 || (prefixes & PREFIX_LOCK)
7722 || s->aflag == MO_16
7727 tcg_gen_addi_tl(cpu_A0, cpu_regs[a.base], a.disp);
7729 tcg_gen_movi_tl(cpu_A0, 0);
7731 gen_lea_v_seg(s, s->aflag, cpu_A0, a.def_seg, s->override);
7733 tcg_gen_mov_tl(cpu_T0, cpu_regs[a.index]);
7735 tcg_gen_movi_tl(cpu_T0, 0);
7738 gen_helper_bndldx64(cpu_bndl[reg], cpu_env, cpu_A0, cpu_T0);
7739 tcg_gen_ld_i64(cpu_bndu[reg], cpu_env,
7740 offsetof(CPUX86State, mmx_t0.MMX_Q(0)));
7742 gen_helper_bndldx32(cpu_bndu[reg], cpu_env, cpu_A0, cpu_T0);
7743 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndu[reg]);
7744 tcg_gen_shri_i64(cpu_bndu[reg], cpu_bndu[reg], 32);
7746 gen_set_hflag(s, HF_MPX_IU_MASK);
7749 gen_nop_modrm(env, s, modrm);
7752 modrm = cpu_ldub_code(env, s->pc++);
7753 if (s->flags & HF_MPX_EN_MASK) {
7754 mod = (modrm >> 6) & 3;
7755 reg = ((modrm >> 3) & 7) | rex_r;
7756 if (mod != 3 && (prefixes & PREFIX_REPZ)) {
7759 || (prefixes & PREFIX_LOCK)
7760 || s->aflag == MO_16) {
7763 AddressParts a = gen_lea_modrm_0(env, s, modrm);
7765 tcg_gen_extu_tl_i64(cpu_bndl[reg], cpu_regs[a.base]);
7767 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndl[reg]);
7769 } else if (a.base == -1) {
7770 /* no base register has lower bound of 0 */
7771 tcg_gen_movi_i64(cpu_bndl[reg], 0);
7773 /* rip-relative generates #ud */
7776 tcg_gen_not_tl(cpu_A0, gen_lea_modrm_1(a));
7778 tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
7780 tcg_gen_extu_tl_i64(cpu_bndu[reg], cpu_A0);
7781 /* bnd registers are now in-use */
7782 gen_set_hflag(s, HF_MPX_IU_MASK);
7784 } else if (prefixes & PREFIX_REPNZ) {
7787 || (prefixes & PREFIX_LOCK)
7788 || s->aflag == MO_16) {
7791 gen_bndck(env, s, modrm, TCG_COND_GTU, cpu_bndu[reg]);
7792 } else if (prefixes & PREFIX_DATA) {
7793 /* bndmov -- to reg/mem */
7794 if (reg >= 4 || s->aflag == MO_16) {
7798 int reg2 = (modrm & 7) | REX_B(s);
7799 if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) {
7802 if (s->flags & HF_MPX_IU_MASK) {
7803 tcg_gen_mov_i64(cpu_bndl[reg2], cpu_bndl[reg]);
7804 tcg_gen_mov_i64(cpu_bndu[reg2], cpu_bndu[reg]);
7807 gen_lea_modrm(env, s, modrm);
7809 tcg_gen_qemu_st_i64(cpu_bndl[reg], cpu_A0,
7810 s->mem_index, MO_LEQ);
7811 tcg_gen_addi_tl(cpu_A0, cpu_A0, 8);
7812 tcg_gen_qemu_st_i64(cpu_bndu[reg], cpu_A0,
7813 s->mem_index, MO_LEQ);
7815 tcg_gen_qemu_st_i64(cpu_bndl[reg], cpu_A0,
7816 s->mem_index, MO_LEUL);
7817 tcg_gen_addi_tl(cpu_A0, cpu_A0, 4);
7818 tcg_gen_qemu_st_i64(cpu_bndu[reg], cpu_A0,
7819 s->mem_index, MO_LEUL);
7822 } else if (mod != 3) {
7824 AddressParts a = gen_lea_modrm_0(env, s, modrm);
7826 || (prefixes & PREFIX_LOCK)
7827 || s->aflag == MO_16
7832 tcg_gen_addi_tl(cpu_A0, cpu_regs[a.base], a.disp);
7834 tcg_gen_movi_tl(cpu_A0, 0);
7836 gen_lea_v_seg(s, s->aflag, cpu_A0, a.def_seg, s->override);
7838 tcg_gen_mov_tl(cpu_T0, cpu_regs[a.index]);
7840 tcg_gen_movi_tl(cpu_T0, 0);
7843 gen_helper_bndstx64(cpu_env, cpu_A0, cpu_T0,
7844 cpu_bndl[reg], cpu_bndu[reg]);
7846 gen_helper_bndstx32(cpu_env, cpu_A0, cpu_T0,
7847 cpu_bndl[reg], cpu_bndu[reg]);
7851 gen_nop_modrm(env, s, modrm);
7853 case 0x119: case 0x11c ... 0x11f: /* nop (multi byte) */
7854 modrm = cpu_ldub_code(env, s->pc++);
7855 gen_nop_modrm(env, s, modrm);
7857 case 0x120: /* mov reg, crN */
7858 case 0x122: /* mov crN, reg */
7860 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7862 modrm = cpu_ldub_code(env, s->pc++);
7863 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7864 * AMD documentation (24594.pdf) and testing of
7865 * intel 386 and 486 processors all show that the mod bits
7866 * are assumed to be 1's, regardless of actual values.
7868 rm = (modrm & 7) | REX_B(s);
7869 reg = ((modrm >> 3) & 7) | rex_r;
7874 if ((prefixes & PREFIX_LOCK) && (reg == 0) &&
7875 (s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) {
7884 gen_update_cc_op(s);
7885 gen_jmp_im(pc_start - s->cs_base);
7887 gen_op_mov_v_reg(ot, cpu_T0, rm);
7888 gen_helper_write_crN(cpu_env, tcg_const_i32(reg),
7890 gen_jmp_im(s->pc - s->cs_base);
7893 gen_helper_read_crN(cpu_T0, cpu_env, tcg_const_i32(reg));
7894 gen_op_mov_reg_v(ot, rm, cpu_T0);
7902 case 0x121: /* mov reg, drN */
7903 case 0x123: /* mov drN, reg */
7905 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7907 modrm = cpu_ldub_code(env, s->pc++);
7908 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7909 * AMD documentation (24594.pdf) and testing of
7910 * intel 386 and 486 processors all show that the mod bits
7911 * are assumed to be 1's, regardless of actual values.
7913 rm = (modrm & 7) | REX_B(s);
7914 reg = ((modrm >> 3) & 7) | rex_r;
7923 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
7924 gen_op_mov_v_reg(ot, cpu_T0, rm);
7925 tcg_gen_movi_i32(cpu_tmp2_i32, reg);
7926 gen_helper_set_dr(cpu_env, cpu_tmp2_i32, cpu_T0);
7927 gen_jmp_im(s->pc - s->cs_base);
7930 gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_DR0 + reg);
7931 tcg_gen_movi_i32(cpu_tmp2_i32, reg);
7932 gen_helper_get_dr(cpu_T0, cpu_env, cpu_tmp2_i32);
7933 gen_op_mov_reg_v(ot, rm, cpu_T0);
7937 case 0x106: /* clts */
7939 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7941 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
7942 gen_helper_clts(cpu_env);
7943 /* abort block because static cpu state changed */
7944 gen_jmp_im(s->pc - s->cs_base);
7948 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
7949 case 0x1c3: /* MOVNTI reg, mem */
7950 if (!(s->cpuid_features & CPUID_SSE2))
7952 ot = mo_64_32(dflag);
7953 modrm = cpu_ldub_code(env, s->pc++);
7954 mod = (modrm >> 6) & 3;
7957 reg = ((modrm >> 3) & 7) | rex_r;
7958 /* generate a generic store */
7959 gen_ldst_modrm(env, s, modrm, ot, reg, 1);
7962 modrm = cpu_ldub_code(env, s->pc++);
7964 CASE_MODRM_MEM_OP(0): /* fxsave */
7965 if (!(s->cpuid_features & CPUID_FXSR)
7966 || (prefixes & PREFIX_LOCK)) {
7969 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
7970 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
7973 gen_lea_modrm(env, s, modrm);
7974 gen_helper_fxsave(cpu_env, cpu_A0);
7977 CASE_MODRM_MEM_OP(1): /* fxrstor */
7978 if (!(s->cpuid_features & CPUID_FXSR)
7979 || (prefixes & PREFIX_LOCK)) {
7982 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
7983 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
7986 gen_lea_modrm(env, s, modrm);
7987 gen_helper_fxrstor(cpu_env, cpu_A0);
7990 CASE_MODRM_MEM_OP(2): /* ldmxcsr */
7991 if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) {
7994 if (s->flags & HF_TS_MASK) {
7995 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
7998 gen_lea_modrm(env, s, modrm);
7999 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0, s->mem_index, MO_LEUL);
8000 gen_helper_ldmxcsr(cpu_env, cpu_tmp2_i32);
8003 CASE_MODRM_MEM_OP(3): /* stmxcsr */
8004 if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) {
8007 if (s->flags & HF_TS_MASK) {
8008 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
8011 gen_lea_modrm(env, s, modrm);
8012 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State, mxcsr));
8013 gen_op_st_v(s, MO_32, cpu_T0, cpu_A0);
8016 CASE_MODRM_MEM_OP(4): /* xsave */
8017 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
8018 || (prefixes & (PREFIX_LOCK | PREFIX_DATA
8019 | PREFIX_REPZ | PREFIX_REPNZ))) {
8022 gen_lea_modrm(env, s, modrm);
8023 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
8025 gen_helper_xsave(cpu_env, cpu_A0, cpu_tmp1_i64);
8028 CASE_MODRM_MEM_OP(5): /* xrstor */
8029 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
8030 || (prefixes & (PREFIX_LOCK | PREFIX_DATA
8031 | PREFIX_REPZ | PREFIX_REPNZ))) {
8034 gen_lea_modrm(env, s, modrm);
8035 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
8037 gen_helper_xrstor(cpu_env, cpu_A0, cpu_tmp1_i64);
8038 /* XRSTOR is how MPX is enabled, which changes how
8039 we translate. Thus we need to end the TB. */
8040 gen_update_cc_op(s);
8041 gen_jmp_im(s->pc - s->cs_base);
8045 CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */
8046 if (prefixes & PREFIX_LOCK) {
8049 if (prefixes & PREFIX_DATA) {
8051 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLWB)) {
8054 gen_nop_modrm(env, s, modrm);
8057 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
8058 || (s->cpuid_xsave_features & CPUID_XSAVE_XSAVEOPT) == 0
8059 || (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))) {
8062 gen_lea_modrm(env, s, modrm);
8063 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
8065 gen_helper_xsaveopt(cpu_env, cpu_A0, cpu_tmp1_i64);
8069 CASE_MODRM_MEM_OP(7): /* clflush / clflushopt */
8070 if (prefixes & PREFIX_LOCK) {
8073 if (prefixes & PREFIX_DATA) {
8075 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLFLUSHOPT)) {
8080 if ((s->prefix & (PREFIX_REPZ | PREFIX_REPNZ))
8081 || !(s->cpuid_features & CPUID_CLFLUSH)) {
8085 gen_nop_modrm(env, s, modrm);
8088 case 0xc0 ... 0xc7: /* rdfsbase (f3 0f ae /0) */
8089 case 0xc8 ... 0xc8: /* rdgsbase (f3 0f ae /1) */
8090 case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */
8091 case 0xd8 ... 0xd8: /* wrgsbase (f3 0f ae /3) */
8093 && (prefixes & PREFIX_REPZ)
8094 && !(prefixes & PREFIX_LOCK)
8095 && (s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_FSGSBASE)) {
8096 TCGv base, treg, src, dst;
8098 /* Preserve hflags bits by testing CR4 at runtime. */
8099 tcg_gen_movi_i32(cpu_tmp2_i32, CR4_FSGSBASE_MASK);
8100 gen_helper_cr4_testbit(cpu_env, cpu_tmp2_i32);
8102 base = cpu_seg_base[modrm & 8 ? R_GS : R_FS];
8103 treg = cpu_regs[(modrm & 7) | REX_B(s)];
8107 dst = base, src = treg;
8110 dst = treg, src = base;
8113 if (s->dflag == MO_32) {
8114 tcg_gen_ext32u_tl(dst, src);
8116 tcg_gen_mov_tl(dst, src);
8122 case 0xf8: /* sfence / pcommit */
8123 if (prefixes & PREFIX_DATA) {
8125 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_PCOMMIT)
8126 || (prefixes & PREFIX_LOCK)) {
8132 case 0xf9 ... 0xff: /* sfence */
8133 if (!(s->cpuid_features & CPUID_SSE)
8134 || (prefixes & PREFIX_LOCK)) {
8137 tcg_gen_mb(TCG_MO_ST_ST | TCG_BAR_SC);
8139 case 0xe8 ... 0xef: /* lfence */
8140 if (!(s->cpuid_features & CPUID_SSE)
8141 || (prefixes & PREFIX_LOCK)) {
8144 tcg_gen_mb(TCG_MO_LD_LD | TCG_BAR_SC);
8146 case 0xf0 ... 0xf7: /* mfence */
8147 if (!(s->cpuid_features & CPUID_SSE2)
8148 || (prefixes & PREFIX_LOCK)) {
8151 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8159 case 0x10d: /* 3DNow! prefetch(w) */
8160 modrm = cpu_ldub_code(env, s->pc++);
8161 mod = (modrm >> 6) & 3;
8164 gen_nop_modrm(env, s, modrm);
8166 case 0x1aa: /* rsm */
8167 gen_svm_check_intercept(s, pc_start, SVM_EXIT_RSM);
8168 if (!(s->flags & HF_SMM_MASK))
8170 gen_update_cc_op(s);
8171 gen_jmp_im(s->pc - s->cs_base);
8172 gen_helper_rsm(cpu_env);
8175 case 0x1b8: /* SSE4.2 popcnt */
8176 if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) !=
8179 if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT))
8182 modrm = cpu_ldub_code(env, s->pc++);
8183 reg = ((modrm >> 3) & 7) | rex_r;
8185 if (s->prefix & PREFIX_DATA) {
8188 ot = mo_64_32(dflag);
8191 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
8192 gen_helper_popcnt(cpu_T0, cpu_env, cpu_T0, tcg_const_i32(ot));
8193 gen_op_mov_reg_v(ot, reg, cpu_T0);
8195 set_cc_op(s, CC_OP_EFLAGS);
8197 case 0x10e ... 0x10f:
8198 /* 3DNow! instructions, ignore prefixes */
8199 s->prefix &= ~(PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA);
8200 case 0x110 ... 0x117:
8201 case 0x128 ... 0x12f:
8202 case 0x138 ... 0x13a:
8203 case 0x150 ... 0x179:
8204 case 0x17c ... 0x17f:
8206 case 0x1c4 ... 0x1c6:
8207 case 0x1d0 ... 0x1fe:
8208 gen_sse(env, s, b, pc_start, rex_r);
8215 gen_illegal_opcode(s);
8218 gen_unknown_opcode(env, s);
8222 void tcg_x86_init(void)
8224 static const char reg_names[CPU_NB_REGS][4] = {
8225 #ifdef TARGET_X86_64
8253 static const char seg_base_names[6][8] = {
8261 static const char bnd_regl_names[4][8] = {
8262 "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb"
8264 static const char bnd_regu_names[4][8] = {
8265 "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub"
8268 static bool initialized;
8275 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
8276 tcg_ctx.tcg_env = cpu_env;
8277 cpu_cc_op = tcg_global_mem_new_i32(cpu_env,
8278 offsetof(CPUX86State, cc_op), "cc_op");
8279 cpu_cc_dst = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_dst),
8281 cpu_cc_src = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src),
8283 cpu_cc_src2 = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src2),
8286 for (i = 0; i < CPU_NB_REGS; ++i) {
8287 cpu_regs[i] = tcg_global_mem_new(cpu_env,
8288 offsetof(CPUX86State, regs[i]),
8292 for (i = 0; i < 6; ++i) {
8294 = tcg_global_mem_new(cpu_env,
8295 offsetof(CPUX86State, segs[i].base),
8299 for (i = 0; i < 4; ++i) {
8301 = tcg_global_mem_new_i64(cpu_env,
8302 offsetof(CPUX86State, bnd_regs[i].lb),
8305 = tcg_global_mem_new_i64(cpu_env,
8306 offsetof(CPUX86State, bnd_regs[i].ub),
8311 /* generate intermediate code for basic block 'tb'. */
8312 void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb)
8314 X86CPU *cpu = x86_env_get_cpu(env);
8315 CPUState *cs = CPU(cpu);
8316 DisasContext dc1, *dc = &dc1;
8317 target_ulong pc_ptr;
8319 target_ulong pc_start;
8320 target_ulong cs_base;
8324 /* generate intermediate code */
8326 cs_base = tb->cs_base;
8329 dc->pe = (flags >> HF_PE_SHIFT) & 1;
8330 dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
8331 dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
8332 dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
8334 dc->vm86 = (flags >> VM_SHIFT) & 1;
8335 dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
8336 dc->iopl = (flags >> IOPL_SHIFT) & 3;
8337 dc->tf = (flags >> TF_SHIFT) & 1;
8338 dc->singlestep_enabled = cs->singlestep_enabled;
8339 dc->cc_op = CC_OP_DYNAMIC;
8340 dc->cc_op_dirty = false;
8341 dc->cs_base = cs_base;
8343 dc->popl_esp_hack = 0;
8344 /* select memory access functions */
8346 #ifdef CONFIG_SOFTMMU
8347 dc->mem_index = cpu_mmu_index(env, false);
8349 dc->cpuid_features = env->features[FEAT_1_EDX];
8350 dc->cpuid_ext_features = env->features[FEAT_1_ECX];
8351 dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX];
8352 dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX];
8353 dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX];
8354 dc->cpuid_xsave_features = env->features[FEAT_XSAVE];
8355 #ifdef TARGET_X86_64
8356 dc->lma = (flags >> HF_LMA_SHIFT) & 1;
8357 dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
8360 dc->jmp_opt = !(dc->tf || cs->singlestep_enabled ||
8361 (flags & HF_INHIBIT_IRQ_MASK));
8362 /* Do not optimize repz jumps at all in icount mode, because
8363 rep movsS instructions are execured with different paths
8364 in !repz_opt and repz_opt modes. The first one was used
8365 always except single step mode. And this setting
8366 disables jumps optimization and control paths become
8367 equivalent in run and single step modes.
8368 Now there will be no jump optimization for repz in
8369 record/replay modes and there will always be an
8370 additional step for ecx=0 when icount is enabled.
8372 dc->repz_opt = !dc->jmp_opt && !(tb->cflags & CF_USE_ICOUNT);
8374 /* check addseg logic */
8375 if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
8376 printf("ERROR addseg\n");
8379 cpu_T0 = tcg_temp_new();
8380 cpu_T1 = tcg_temp_new();
8381 cpu_A0 = tcg_temp_new();
8383 cpu_tmp0 = tcg_temp_new();
8384 cpu_tmp1_i64 = tcg_temp_new_i64();
8385 cpu_tmp2_i32 = tcg_temp_new_i32();
8386 cpu_tmp3_i32 = tcg_temp_new_i32();
8387 cpu_tmp4 = tcg_temp_new();
8388 cpu_ptr0 = tcg_temp_new_ptr();
8389 cpu_ptr1 = tcg_temp_new_ptr();
8390 cpu_cc_srcT = tcg_temp_local_new();
8392 dc->is_jmp = DISAS_NEXT;
8395 max_insns = tb->cflags & CF_COUNT_MASK;
8396 if (max_insns == 0) {
8397 max_insns = CF_COUNT_MASK;
8399 if (max_insns > TCG_MAX_INSNS) {
8400 max_insns = TCG_MAX_INSNS;
8405 tcg_gen_insn_start(pc_ptr, dc->cc_op);
8408 /* If RF is set, suppress an internally generated breakpoint. */
8409 if (unlikely(cpu_breakpoint_test(cs, pc_ptr,
8410 tb->flags & HF_RF_MASK
8411 ? BP_GDB : BP_ANY))) {
8412 gen_debug(dc, pc_ptr - dc->cs_base);
8413 /* The address covered by the breakpoint must be included in
8414 [tb->pc, tb->pc + tb->size) in order to for it to be
8415 properly cleared -- thus we increment the PC here so that
8416 the logic setting tb->size below does the right thing. */
8418 goto done_generating;
8420 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
8424 pc_ptr = disas_insn(env, dc, pc_ptr);
8426 if (hax_enabled() && hax_stop_translate(cs))
8428 gen_jmp_im(pc_ptr - dc->cs_base);
8433 /* stop translation if indicated */
8436 /* if single step mode, we generate only one instruction and
8437 generate an exception */
8438 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
8439 the flag and abort the translation to give the irqs a
8440 change to be happen */
8441 if (dc->tf || dc->singlestep_enabled ||
8442 (flags & HF_INHIBIT_IRQ_MASK)) {
8443 gen_jmp_im(pc_ptr - dc->cs_base);
8447 /* Do not cross the boundary of the pages in icount mode,
8448 it can cause an exception. Do it only when boundary is
8449 crossed by the first instruction in the block.
8450 If current instruction already crossed the bound - it's ok,
8451 because an exception hasn't stopped this code.
8453 if ((tb->cflags & CF_USE_ICOUNT)
8454 && ((pc_ptr & TARGET_PAGE_MASK)
8455 != ((pc_ptr + TARGET_MAX_INSN_SIZE - 1) & TARGET_PAGE_MASK)
8456 || (pc_ptr & ~TARGET_PAGE_MASK) == 0)) {
8457 gen_jmp_im(pc_ptr - dc->cs_base);
8461 /* if too long translation, stop generation too */
8462 if (tcg_op_buf_full() ||
8463 (pc_ptr - pc_start) >= (TARGET_PAGE_SIZE - 32) ||
8464 num_insns >= max_insns) {
8465 gen_jmp_im(pc_ptr - dc->cs_base);
8470 gen_jmp_im(pc_ptr - dc->cs_base);
8475 if (tb->cflags & CF_LAST_IO)
8478 gen_tb_end(tb, num_insns);
8481 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
8482 && qemu_log_in_addr_range(pc_start)) {
8485 qemu_log("----------------\n");
8486 qemu_log("IN: %s\n", lookup_symbol(pc_start));
8487 #ifdef TARGET_X86_64
8492 disas_flags = !dc->code32;
8493 log_target_disas(cs, pc_start, pc_ptr - pc_start, disas_flags);
8499 tb->size = pc_ptr - pc_start;
8500 tb->icount = num_insns;
8503 void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb,
8506 int cc_op = data[1];
8507 env->eip = data[0] - tb->cs_base;
8508 if (cc_op != CC_OP_DYNAMIC) {