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/>.
26 #include "qemu/host-utils.h"
28 #include "disas/disas.h"
30 #include "exec/cpu_ldst.h"
32 #include "exec/helper-proto.h"
33 #include "exec/helper-gen.h"
35 #include "trace-tcg.h"
38 #define PREFIX_REPZ 0x01
39 #define PREFIX_REPNZ 0x02
40 #define PREFIX_LOCK 0x04
41 #define PREFIX_DATA 0x08
42 #define PREFIX_ADR 0x10
43 #define PREFIX_VEX 0x20
46 #define CODE64(s) ((s)->code64)
47 #define REX_X(s) ((s)->rex_x)
48 #define REX_B(s) ((s)->rex_b)
63 //#define MACRO_TEST 1
65 /* global register indexes */
66 static TCGv_ptr cpu_env;
68 static TCGv cpu_cc_dst, cpu_cc_src, cpu_cc_src2, cpu_cc_srcT;
69 static TCGv_i32 cpu_cc_op;
70 static TCGv cpu_regs[CPU_NB_REGS];
73 /* local register indexes (only used inside old micro ops) */
74 static TCGv cpu_tmp0, cpu_tmp4;
75 static TCGv_ptr cpu_ptr0, cpu_ptr1;
76 static TCGv_i32 cpu_tmp2_i32, cpu_tmp3_i32;
77 static TCGv_i64 cpu_tmp1_i64;
79 static uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
81 #include "exec/gen-icount.h"
84 static int x86_64_hregs;
87 typedef struct DisasContext {
88 /* current insn context */
89 int override; /* -1 if no override */
93 target_ulong pc; /* pc = eip + cs_base */
94 int is_jmp; /* 1 = means jump (stop translation), 2 means CPU
95 static state change (stop translation) */
96 /* current block context */
97 target_ulong cs_base; /* base of CS segment */
98 int pe; /* protected mode */
99 int code32; /* 32 bit code segment */
101 int lma; /* long mode active */
102 int code64; /* 64 bit code segment */
105 int vex_l; /* vex vector length */
106 int vex_v; /* vex vvvv register, without 1's compliment. */
107 int ss32; /* 32 bit stack segment */
108 CCOp cc_op; /* current CC operation */
110 int addseg; /* non zero if either DS/ES/SS have a non zero base */
111 int f_st; /* currently unused */
112 int vm86; /* vm86 mode */
115 int tf; /* TF cpu flag */
116 int singlestep_enabled; /* "hardware" single step enabled */
117 int jmp_opt; /* use direct block chaining for direct jumps */
118 int repz_opt; /* optimize jumps within repz instructions */
119 int mem_index; /* select memory access functions */
120 uint64_t flags; /* all execution flags */
121 struct TranslationBlock *tb;
122 int popl_esp_hack; /* for correct popl with esp base handling */
123 int rip_offset; /* only used in x86_64, but left for simplicity */
125 int cpuid_ext_features;
126 int cpuid_ext2_features;
127 int cpuid_ext3_features;
128 int cpuid_7_0_ebx_features;
131 static void gen_eob(DisasContext *s);
132 static void gen_jmp(DisasContext *s, target_ulong eip);
133 static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num);
134 static void gen_op(DisasContext *s1, int op, TCGMemOp ot, int d);
136 /* i386 arith/logic operations */
156 OP_SHL1, /* undocumented */
172 /* I386 int registers */
173 OR_EAX, /* MUST be even numbered */
182 OR_TMP0 = 16, /* temporary operand register */
184 OR_A0, /* temporary register used when doing address evaluation */
194 /* Bit set if the global variable is live after setting CC_OP to X. */
195 static const uint8_t cc_op_live[CC_OP_NB] = {
196 [CC_OP_DYNAMIC] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
197 [CC_OP_EFLAGS] = USES_CC_SRC,
198 [CC_OP_MULB ... CC_OP_MULQ] = USES_CC_DST | USES_CC_SRC,
199 [CC_OP_ADDB ... CC_OP_ADDQ] = USES_CC_DST | USES_CC_SRC,
200 [CC_OP_ADCB ... CC_OP_ADCQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
201 [CC_OP_SUBB ... CC_OP_SUBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRCT,
202 [CC_OP_SBBB ... CC_OP_SBBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
203 [CC_OP_LOGICB ... CC_OP_LOGICQ] = USES_CC_DST,
204 [CC_OP_INCB ... CC_OP_INCQ] = USES_CC_DST | USES_CC_SRC,
205 [CC_OP_DECB ... CC_OP_DECQ] = USES_CC_DST | USES_CC_SRC,
206 [CC_OP_SHLB ... CC_OP_SHLQ] = USES_CC_DST | USES_CC_SRC,
207 [CC_OP_SARB ... CC_OP_SARQ] = USES_CC_DST | USES_CC_SRC,
208 [CC_OP_BMILGB ... CC_OP_BMILGQ] = USES_CC_DST | USES_CC_SRC,
209 [CC_OP_ADCX] = USES_CC_DST | USES_CC_SRC,
210 [CC_OP_ADOX] = USES_CC_SRC | USES_CC_SRC2,
211 [CC_OP_ADCOX] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
215 static void set_cc_op(DisasContext *s, CCOp op)
219 if (s->cc_op == op) {
223 /* Discard CC computation that will no longer be used. */
224 dead = cc_op_live[s->cc_op] & ~cc_op_live[op];
225 if (dead & USES_CC_DST) {
226 tcg_gen_discard_tl(cpu_cc_dst);
228 if (dead & USES_CC_SRC) {
229 tcg_gen_discard_tl(cpu_cc_src);
231 if (dead & USES_CC_SRC2) {
232 tcg_gen_discard_tl(cpu_cc_src2);
234 if (dead & USES_CC_SRCT) {
235 tcg_gen_discard_tl(cpu_cc_srcT);
238 if (op == CC_OP_DYNAMIC) {
239 /* The DYNAMIC setting is translator only, and should never be
240 stored. Thus we always consider it clean. */
241 s->cc_op_dirty = false;
243 /* Discard any computed CC_OP value (see shifts). */
244 if (s->cc_op == CC_OP_DYNAMIC) {
245 tcg_gen_discard_i32(cpu_cc_op);
247 s->cc_op_dirty = true;
252 static void gen_update_cc_op(DisasContext *s)
254 if (s->cc_op_dirty) {
255 tcg_gen_movi_i32(cpu_cc_op, s->cc_op);
256 s->cc_op_dirty = false;
262 #define NB_OP_SIZES 4
264 #else /* !TARGET_X86_64 */
266 #define NB_OP_SIZES 3
268 #endif /* !TARGET_X86_64 */
270 #if defined(HOST_WORDS_BIGENDIAN)
271 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
272 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
273 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
274 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
275 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
277 #define REG_B_OFFSET 0
278 #define REG_H_OFFSET 1
279 #define REG_W_OFFSET 0
280 #define REG_L_OFFSET 0
281 #define REG_LH_OFFSET 4
284 /* In instruction encodings for byte register accesses the
285 * register number usually indicates "low 8 bits of register N";
286 * however there are some special cases where N 4..7 indicates
287 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
288 * true for this special case, false otherwise.
290 static inline bool byte_reg_is_xH(int reg)
296 if (reg >= 8 || x86_64_hregs) {
303 /* Select the size of a push/pop operation. */
304 static inline TCGMemOp mo_pushpop(DisasContext *s, TCGMemOp ot)
307 return ot == MO_16 ? MO_16 : MO_64;
313 /* Select only size 64 else 32. Used for SSE operand sizes. */
314 static inline TCGMemOp mo_64_32(TCGMemOp ot)
317 return ot == MO_64 ? MO_64 : MO_32;
323 /* Select size 8 if lsb of B is clear, else OT. Used for decoding
324 byte vs word opcodes. */
325 static inline TCGMemOp mo_b_d(int b, TCGMemOp ot)
327 return b & 1 ? ot : MO_8;
330 /* Select size 8 if lsb of B is clear, else OT capped at 32.
331 Used for decoding operand size of port opcodes. */
332 static inline TCGMemOp mo_b_d32(int b, TCGMemOp ot)
334 return b & 1 ? (ot == MO_16 ? MO_16 : MO_32) : MO_8;
337 static void gen_op_mov_reg_v(TCGMemOp ot, int reg, TCGv t0)
341 if (!byte_reg_is_xH(reg)) {
342 tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 8);
344 tcg_gen_deposit_tl(cpu_regs[reg - 4], cpu_regs[reg - 4], t0, 8, 8);
348 tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 16);
351 /* For x86_64, this sets the higher half of register to zero.
352 For i386, this is equivalent to a mov. */
353 tcg_gen_ext32u_tl(cpu_regs[reg], t0);
357 tcg_gen_mov_tl(cpu_regs[reg], t0);
365 static inline void gen_op_mov_v_reg(TCGMemOp ot, TCGv t0, int reg)
367 if (ot == MO_8 && byte_reg_is_xH(reg)) {
368 tcg_gen_shri_tl(t0, cpu_regs[reg - 4], 8);
369 tcg_gen_ext8u_tl(t0, t0);
371 tcg_gen_mov_tl(t0, cpu_regs[reg]);
375 static inline void gen_op_movl_A0_reg(int reg)
377 tcg_gen_mov_tl(cpu_A0, cpu_regs[reg]);
380 static inline void gen_op_addl_A0_im(int32_t val)
382 tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
384 tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
389 static inline void gen_op_addq_A0_im(int64_t val)
391 tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
395 static void gen_add_A0_im(DisasContext *s, int val)
399 gen_op_addq_A0_im(val);
402 gen_op_addl_A0_im(val);
405 static inline void gen_op_jmp_v(TCGv dest)
407 tcg_gen_st_tl(dest, cpu_env, offsetof(CPUX86State, eip));
410 static inline void gen_op_add_reg_im(TCGMemOp size, int reg, int32_t val)
412 tcg_gen_addi_tl(cpu_tmp0, cpu_regs[reg], val);
413 gen_op_mov_reg_v(size, reg, cpu_tmp0);
416 static inline void gen_op_add_reg_T0(TCGMemOp size, int reg)
418 tcg_gen_add_tl(cpu_tmp0, cpu_regs[reg], cpu_T[0]);
419 gen_op_mov_reg_v(size, reg, cpu_tmp0);
422 static inline void gen_op_addl_A0_reg_sN(int shift, int reg)
424 tcg_gen_mov_tl(cpu_tmp0, cpu_regs[reg]);
426 tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift);
427 tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
428 /* For x86_64, this sets the higher half of register to zero.
429 For i386, this is equivalent to a nop. */
430 tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
433 static inline void gen_op_movl_A0_seg(int reg)
435 tcg_gen_ld32u_tl(cpu_A0, cpu_env, offsetof(CPUX86State, segs[reg].base) + REG_L_OFFSET);
438 static inline void gen_op_addl_A0_seg(DisasContext *s, int reg)
440 tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, segs[reg].base));
443 tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
444 tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
446 tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
447 tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
450 tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
455 static inline void gen_op_movq_A0_seg(int reg)
457 tcg_gen_ld_tl(cpu_A0, cpu_env, offsetof(CPUX86State, segs[reg].base));
460 static inline void gen_op_addq_A0_seg(int reg)
462 tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, segs[reg].base));
463 tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
466 static inline void gen_op_movq_A0_reg(int reg)
468 tcg_gen_mov_tl(cpu_A0, cpu_regs[reg]);
471 static inline void gen_op_addq_A0_reg_sN(int shift, int reg)
473 tcg_gen_mov_tl(cpu_tmp0, cpu_regs[reg]);
475 tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift);
476 tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
480 static inline void gen_op_ld_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
482 tcg_gen_qemu_ld_tl(t0, a0, s->mem_index, idx | MO_LE);
485 static inline void gen_op_st_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
487 tcg_gen_qemu_st_tl(t0, a0, s->mem_index, idx | MO_LE);
490 static inline void gen_op_st_rm_T0_A0(DisasContext *s, int idx, int d)
493 gen_op_st_v(s, idx, cpu_T[0], cpu_A0);
495 gen_op_mov_reg_v(idx, d, cpu_T[0]);
499 static inline void gen_jmp_im(target_ulong pc)
501 tcg_gen_movi_tl(cpu_tmp0, pc);
502 gen_op_jmp_v(cpu_tmp0);
505 static inline void gen_string_movl_A0_ESI(DisasContext *s)
509 override = s->override;
514 gen_op_movq_A0_seg(override);
515 gen_op_addq_A0_reg_sN(0, R_ESI);
517 gen_op_movq_A0_reg(R_ESI);
523 if (s->addseg && override < 0)
526 gen_op_movl_A0_seg(override);
527 gen_op_addl_A0_reg_sN(0, R_ESI);
529 gen_op_movl_A0_reg(R_ESI);
533 /* 16 address, always override */
536 tcg_gen_ext16u_tl(cpu_A0, cpu_regs[R_ESI]);
537 gen_op_addl_A0_seg(s, override);
544 static inline void gen_string_movl_A0_EDI(DisasContext *s)
549 gen_op_movq_A0_reg(R_EDI);
554 gen_op_movl_A0_seg(R_ES);
555 gen_op_addl_A0_reg_sN(0, R_EDI);
557 gen_op_movl_A0_reg(R_EDI);
561 tcg_gen_ext16u_tl(cpu_A0, cpu_regs[R_EDI]);
562 gen_op_addl_A0_seg(s, R_ES);
569 static inline void gen_op_movl_T0_Dshift(TCGMemOp ot)
571 tcg_gen_ld32s_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, df));
572 tcg_gen_shli_tl(cpu_T[0], cpu_T[0], ot);
575 static TCGv gen_ext_tl(TCGv dst, TCGv src, TCGMemOp size, bool sign)
580 tcg_gen_ext8s_tl(dst, src);
582 tcg_gen_ext8u_tl(dst, src);
587 tcg_gen_ext16s_tl(dst, src);
589 tcg_gen_ext16u_tl(dst, src);
595 tcg_gen_ext32s_tl(dst, src);
597 tcg_gen_ext32u_tl(dst, src);
606 static void gen_extu(TCGMemOp ot, TCGv reg)
608 gen_ext_tl(reg, reg, ot, false);
611 static void gen_exts(TCGMemOp ot, TCGv reg)
613 gen_ext_tl(reg, reg, ot, true);
616 static inline void gen_op_jnz_ecx(TCGMemOp size, int label1)
618 tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
619 gen_extu(size, cpu_tmp0);
620 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_tmp0, 0, label1);
623 static inline void gen_op_jz_ecx(TCGMemOp size, int label1)
625 tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
626 gen_extu(size, cpu_tmp0);
627 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
630 static void gen_helper_in_func(TCGMemOp ot, TCGv v, TCGv_i32 n)
634 gen_helper_inb(v, n);
637 gen_helper_inw(v, n);
640 gen_helper_inl(v, n);
647 static void gen_helper_out_func(TCGMemOp ot, TCGv_i32 v, TCGv_i32 n)
651 gen_helper_outb(v, n);
654 gen_helper_outw(v, n);
657 gen_helper_outl(v, n);
664 static void gen_check_io(DisasContext *s, TCGMemOp ot, target_ulong cur_eip,
668 target_ulong next_eip;
671 if (s->pe && (s->cpl > s->iopl || s->vm86)) {
675 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
678 gen_helper_check_iob(cpu_env, cpu_tmp2_i32);
681 gen_helper_check_iow(cpu_env, cpu_tmp2_i32);
684 gen_helper_check_iol(cpu_env, cpu_tmp2_i32);
690 if(s->flags & HF_SVMI_MASK) {
695 svm_flags |= (1 << (4 + ot));
696 next_eip = s->pc - s->cs_base;
697 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
698 gen_helper_svm_check_io(cpu_env, cpu_tmp2_i32,
699 tcg_const_i32(svm_flags),
700 tcg_const_i32(next_eip - cur_eip));
704 static inline void gen_movs(DisasContext *s, TCGMemOp ot)
706 gen_string_movl_A0_ESI(s);
707 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
708 gen_string_movl_A0_EDI(s);
709 gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
710 gen_op_movl_T0_Dshift(ot);
711 gen_op_add_reg_T0(s->aflag, R_ESI);
712 gen_op_add_reg_T0(s->aflag, R_EDI);
715 static void gen_op_update1_cc(void)
717 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
720 static void gen_op_update2_cc(void)
722 tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
723 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
726 static void gen_op_update3_cc(TCGv reg)
728 tcg_gen_mov_tl(cpu_cc_src2, reg);
729 tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
730 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
733 static inline void gen_op_testl_T0_T1_cc(void)
735 tcg_gen_and_tl(cpu_cc_dst, cpu_T[0], cpu_T[1]);
738 static void gen_op_update_neg_cc(void)
740 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
741 tcg_gen_neg_tl(cpu_cc_src, cpu_T[0]);
742 tcg_gen_movi_tl(cpu_cc_srcT, 0);
745 /* compute all eflags to cc_src */
746 static void gen_compute_eflags(DisasContext *s)
748 TCGv zero, dst, src1, src2;
751 if (s->cc_op == CC_OP_EFLAGS) {
754 if (s->cc_op == CC_OP_CLR) {
755 tcg_gen_movi_tl(cpu_cc_src, CC_Z | CC_P);
756 set_cc_op(s, CC_OP_EFLAGS);
765 /* Take care to not read values that are not live. */
766 live = cc_op_live[s->cc_op] & ~USES_CC_SRCT;
767 dead = live ^ (USES_CC_DST | USES_CC_SRC | USES_CC_SRC2);
769 zero = tcg_const_tl(0);
770 if (dead & USES_CC_DST) {
773 if (dead & USES_CC_SRC) {
776 if (dead & USES_CC_SRC2) {
782 gen_helper_cc_compute_all(cpu_cc_src, dst, src1, src2, cpu_cc_op);
783 set_cc_op(s, CC_OP_EFLAGS);
790 typedef struct CCPrepare {
800 /* compute eflags.C to reg */
801 static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg)
807 case CC_OP_SUBB ... CC_OP_SUBQ:
808 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
809 size = s->cc_op - CC_OP_SUBB;
810 t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
811 /* If no temporary was used, be careful not to alias t1 and t0. */
812 t0 = TCGV_EQUAL(t1, cpu_cc_src) ? cpu_tmp0 : reg;
813 tcg_gen_mov_tl(t0, cpu_cc_srcT);
817 case CC_OP_ADDB ... CC_OP_ADDQ:
818 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
819 size = s->cc_op - CC_OP_ADDB;
820 t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
821 t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
823 return (CCPrepare) { .cond = TCG_COND_LTU, .reg = t0,
824 .reg2 = t1, .mask = -1, .use_reg2 = true };
826 case CC_OP_LOGICB ... CC_OP_LOGICQ:
828 return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
830 case CC_OP_INCB ... CC_OP_INCQ:
831 case CC_OP_DECB ... CC_OP_DECQ:
832 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
833 .mask = -1, .no_setcond = true };
835 case CC_OP_SHLB ... CC_OP_SHLQ:
836 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
837 size = s->cc_op - CC_OP_SHLB;
838 shift = (8 << size) - 1;
839 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
840 .mask = (target_ulong)1 << shift };
842 case CC_OP_MULB ... CC_OP_MULQ:
843 return (CCPrepare) { .cond = TCG_COND_NE,
844 .reg = cpu_cc_src, .mask = -1 };
846 case CC_OP_BMILGB ... CC_OP_BMILGQ:
847 size = s->cc_op - CC_OP_BMILGB;
848 t0 = gen_ext_tl(reg, cpu_cc_src, size, false);
849 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 };
853 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_dst,
854 .mask = -1, .no_setcond = true };
857 case CC_OP_SARB ... CC_OP_SARQ:
859 return (CCPrepare) { .cond = TCG_COND_NE,
860 .reg = cpu_cc_src, .mask = CC_C };
863 /* The need to compute only C from CC_OP_DYNAMIC is important
864 in efficiently implementing e.g. INC at the start of a TB. */
866 gen_helper_cc_compute_c(reg, cpu_cc_dst, cpu_cc_src,
867 cpu_cc_src2, cpu_cc_op);
868 return (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
869 .mask = -1, .no_setcond = true };
873 /* compute eflags.P to reg */
874 static CCPrepare gen_prepare_eflags_p(DisasContext *s, TCGv reg)
876 gen_compute_eflags(s);
877 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
881 /* compute eflags.S to reg */
882 static CCPrepare gen_prepare_eflags_s(DisasContext *s, TCGv reg)
886 gen_compute_eflags(s);
892 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
895 return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
898 TCGMemOp size = (s->cc_op - CC_OP_ADDB) & 3;
899 TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, true);
900 return (CCPrepare) { .cond = TCG_COND_LT, .reg = t0, .mask = -1 };
905 /* compute eflags.O to reg */
906 static CCPrepare gen_prepare_eflags_o(DisasContext *s, TCGv reg)
911 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src2,
912 .mask = -1, .no_setcond = true };
914 return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
916 gen_compute_eflags(s);
917 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
922 /* compute eflags.Z to reg */
923 static CCPrepare gen_prepare_eflags_z(DisasContext *s, TCGv reg)
927 gen_compute_eflags(s);
933 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
936 return (CCPrepare) { .cond = TCG_COND_ALWAYS, .mask = -1 };
939 TCGMemOp size = (s->cc_op - CC_OP_ADDB) & 3;
940 TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
941 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 };
946 /* perform a conditional store into register 'reg' according to jump opcode
947 value 'b'. In the fast case, T0 is guaranted not to be used. */
948 static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg)
950 int inv, jcc_op, cond;
956 jcc_op = (b >> 1) & 7;
959 case CC_OP_SUBB ... CC_OP_SUBQ:
960 /* We optimize relational operators for the cmp/jcc case. */
961 size = s->cc_op - CC_OP_SUBB;
964 tcg_gen_mov_tl(cpu_tmp4, cpu_cc_srcT);
965 gen_extu(size, cpu_tmp4);
966 t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
967 cc = (CCPrepare) { .cond = TCG_COND_LEU, .reg = cpu_tmp4,
968 .reg2 = t0, .mask = -1, .use_reg2 = true };
977 tcg_gen_mov_tl(cpu_tmp4, cpu_cc_srcT);
978 gen_exts(size, cpu_tmp4);
979 t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, true);
980 cc = (CCPrepare) { .cond = cond, .reg = cpu_tmp4,
981 .reg2 = t0, .mask = -1, .use_reg2 = true };
991 /* This actually generates good code for JC, JZ and JS. */
994 cc = gen_prepare_eflags_o(s, reg);
997 cc = gen_prepare_eflags_c(s, reg);
1000 cc = gen_prepare_eflags_z(s, reg);
1003 gen_compute_eflags(s);
1004 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1005 .mask = CC_Z | CC_C };
1008 cc = gen_prepare_eflags_s(s, reg);
1011 cc = gen_prepare_eflags_p(s, reg);
1014 gen_compute_eflags(s);
1015 if (TCGV_EQUAL(reg, cpu_cc_src)) {
1018 tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */
1019 tcg_gen_xor_tl(reg, reg, cpu_cc_src);
1020 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
1025 gen_compute_eflags(s);
1026 if (TCGV_EQUAL(reg, cpu_cc_src)) {
1029 tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */
1030 tcg_gen_xor_tl(reg, reg, cpu_cc_src);
1031 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
1032 .mask = CC_S | CC_Z };
1039 cc.cond = tcg_invert_cond(cc.cond);
1044 static void gen_setcc1(DisasContext *s, int b, TCGv reg)
1046 CCPrepare cc = gen_prepare_cc(s, b, reg);
1048 if (cc.no_setcond) {
1049 if (cc.cond == TCG_COND_EQ) {
1050 tcg_gen_xori_tl(reg, cc.reg, 1);
1052 tcg_gen_mov_tl(reg, cc.reg);
1057 if (cc.cond == TCG_COND_NE && !cc.use_reg2 && cc.imm == 0 &&
1058 cc.mask != 0 && (cc.mask & (cc.mask - 1)) == 0) {
1059 tcg_gen_shri_tl(reg, cc.reg, ctztl(cc.mask));
1060 tcg_gen_andi_tl(reg, reg, 1);
1063 if (cc.mask != -1) {
1064 tcg_gen_andi_tl(reg, cc.reg, cc.mask);
1068 tcg_gen_setcond_tl(cc.cond, reg, cc.reg, cc.reg2);
1070 tcg_gen_setcondi_tl(cc.cond, reg, cc.reg, cc.imm);
1074 static inline void gen_compute_eflags_c(DisasContext *s, TCGv reg)
1076 gen_setcc1(s, JCC_B << 1, reg);
1079 /* generate a conditional jump to label 'l1' according to jump opcode
1080 value 'b'. In the fast case, T0 is guaranted not to be used. */
1081 static inline void gen_jcc1_noeob(DisasContext *s, int b, int l1)
1083 CCPrepare cc = gen_prepare_cc(s, b, cpu_T[0]);
1085 if (cc.mask != -1) {
1086 tcg_gen_andi_tl(cpu_T[0], cc.reg, cc.mask);
1090 tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1092 tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1096 /* Generate a conditional jump to label 'l1' according to jump opcode
1097 value 'b'. In the fast case, T0 is guaranted not to be used.
1098 A translation block must end soon. */
1099 static inline void gen_jcc1(DisasContext *s, int b, int l1)
1101 CCPrepare cc = gen_prepare_cc(s, b, cpu_T[0]);
1103 gen_update_cc_op(s);
1104 if (cc.mask != -1) {
1105 tcg_gen_andi_tl(cpu_T[0], cc.reg, cc.mask);
1108 set_cc_op(s, CC_OP_DYNAMIC);
1110 tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1112 tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1116 /* XXX: does not work with gdbstub "ice" single step - not a
1118 static int gen_jz_ecx_string(DisasContext *s, target_ulong next_eip)
1122 l1 = gen_new_label();
1123 l2 = gen_new_label();
1124 gen_op_jnz_ecx(s->aflag, l1);
1126 gen_jmp_tb(s, next_eip, 1);
1131 static inline void gen_stos(DisasContext *s, TCGMemOp ot)
1133 gen_op_mov_v_reg(MO_32, cpu_T[0], R_EAX);
1134 gen_string_movl_A0_EDI(s);
1135 gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
1136 gen_op_movl_T0_Dshift(ot);
1137 gen_op_add_reg_T0(s->aflag, R_EDI);
1140 static inline void gen_lods(DisasContext *s, TCGMemOp ot)
1142 gen_string_movl_A0_ESI(s);
1143 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
1144 gen_op_mov_reg_v(ot, R_EAX, cpu_T[0]);
1145 gen_op_movl_T0_Dshift(ot);
1146 gen_op_add_reg_T0(s->aflag, R_ESI);
1149 static inline void gen_scas(DisasContext *s, TCGMemOp ot)
1151 gen_string_movl_A0_EDI(s);
1152 gen_op_ld_v(s, ot, cpu_T[1], cpu_A0);
1153 gen_op(s, OP_CMPL, ot, R_EAX);
1154 gen_op_movl_T0_Dshift(ot);
1155 gen_op_add_reg_T0(s->aflag, R_EDI);
1158 static inline void gen_cmps(DisasContext *s, TCGMemOp ot)
1160 gen_string_movl_A0_EDI(s);
1161 gen_op_ld_v(s, ot, cpu_T[1], cpu_A0);
1162 gen_string_movl_A0_ESI(s);
1163 gen_op(s, OP_CMPL, ot, OR_TMP0);
1164 gen_op_movl_T0_Dshift(ot);
1165 gen_op_add_reg_T0(s->aflag, R_ESI);
1166 gen_op_add_reg_T0(s->aflag, R_EDI);
1169 static inline void gen_ins(DisasContext *s, TCGMemOp ot)
1171 if (s->tb->cflags & CF_USE_ICOUNT) {
1174 gen_string_movl_A0_EDI(s);
1175 /* Note: we must do this dummy write first to be restartable in
1176 case of page fault. */
1177 tcg_gen_movi_tl(cpu_T[0], 0);
1178 gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
1179 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_EDX]);
1180 tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1181 gen_helper_in_func(ot, cpu_T[0], cpu_tmp2_i32);
1182 gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
1183 gen_op_movl_T0_Dshift(ot);
1184 gen_op_add_reg_T0(s->aflag, R_EDI);
1185 if (s->tb->cflags & CF_USE_ICOUNT) {
1190 static inline void gen_outs(DisasContext *s, TCGMemOp ot)
1192 if (s->tb->cflags & CF_USE_ICOUNT) {
1195 gen_string_movl_A0_ESI(s);
1196 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
1198 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_EDX]);
1199 tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1200 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[0]);
1201 gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
1203 gen_op_movl_T0_Dshift(ot);
1204 gen_op_add_reg_T0(s->aflag, R_ESI);
1205 if (s->tb->cflags & CF_USE_ICOUNT) {
1210 /* same method as Valgrind : we generate jumps to current or next
1212 #define GEN_REPZ(op) \
1213 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1214 target_ulong cur_eip, target_ulong next_eip) \
1217 gen_update_cc_op(s); \
1218 l2 = gen_jz_ecx_string(s, next_eip); \
1219 gen_ ## op(s, ot); \
1220 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1221 /* a loop would cause two single step exceptions if ECX = 1 \
1222 before rep string_insn */ \
1224 gen_op_jz_ecx(s->aflag, l2); \
1225 gen_jmp(s, cur_eip); \
1228 #define GEN_REPZ2(op) \
1229 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1230 target_ulong cur_eip, \
1231 target_ulong next_eip, \
1235 gen_update_cc_op(s); \
1236 l2 = gen_jz_ecx_string(s, next_eip); \
1237 gen_ ## op(s, ot); \
1238 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1239 gen_update_cc_op(s); \
1240 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
1242 gen_op_jz_ecx(s->aflag, l2); \
1243 gen_jmp(s, cur_eip); \
1254 static void gen_helper_fp_arith_ST0_FT0(int op)
1258 gen_helper_fadd_ST0_FT0(cpu_env);
1261 gen_helper_fmul_ST0_FT0(cpu_env);
1264 gen_helper_fcom_ST0_FT0(cpu_env);
1267 gen_helper_fcom_ST0_FT0(cpu_env);
1270 gen_helper_fsub_ST0_FT0(cpu_env);
1273 gen_helper_fsubr_ST0_FT0(cpu_env);
1276 gen_helper_fdiv_ST0_FT0(cpu_env);
1279 gen_helper_fdivr_ST0_FT0(cpu_env);
1284 /* NOTE the exception in "r" op ordering */
1285 static void gen_helper_fp_arith_STN_ST0(int op, int opreg)
1287 TCGv_i32 tmp = tcg_const_i32(opreg);
1290 gen_helper_fadd_STN_ST0(cpu_env, tmp);
1293 gen_helper_fmul_STN_ST0(cpu_env, tmp);
1296 gen_helper_fsubr_STN_ST0(cpu_env, tmp);
1299 gen_helper_fsub_STN_ST0(cpu_env, tmp);
1302 gen_helper_fdivr_STN_ST0(cpu_env, tmp);
1305 gen_helper_fdiv_STN_ST0(cpu_env, tmp);
1310 /* if d == OR_TMP0, it means memory operand (address in A0) */
1311 static void gen_op(DisasContext *s1, int op, TCGMemOp ot, int d)
1314 gen_op_mov_v_reg(ot, cpu_T[0], d);
1316 gen_op_ld_v(s1, ot, cpu_T[0], cpu_A0);
1320 gen_compute_eflags_c(s1, cpu_tmp4);
1321 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1322 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_tmp4);
1323 gen_op_st_rm_T0_A0(s1, ot, d);
1324 gen_op_update3_cc(cpu_tmp4);
1325 set_cc_op(s1, CC_OP_ADCB + ot);
1328 gen_compute_eflags_c(s1, cpu_tmp4);
1329 tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1330 tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_tmp4);
1331 gen_op_st_rm_T0_A0(s1, ot, d);
1332 gen_op_update3_cc(cpu_tmp4);
1333 set_cc_op(s1, CC_OP_SBBB + ot);
1336 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1337 gen_op_st_rm_T0_A0(s1, ot, d);
1338 gen_op_update2_cc();
1339 set_cc_op(s1, CC_OP_ADDB + ot);
1342 tcg_gen_mov_tl(cpu_cc_srcT, cpu_T[0]);
1343 tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1344 gen_op_st_rm_T0_A0(s1, ot, d);
1345 gen_op_update2_cc();
1346 set_cc_op(s1, CC_OP_SUBB + ot);
1350 tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1351 gen_op_st_rm_T0_A0(s1, ot, d);
1352 gen_op_update1_cc();
1353 set_cc_op(s1, CC_OP_LOGICB + ot);
1356 tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1357 gen_op_st_rm_T0_A0(s1, ot, d);
1358 gen_op_update1_cc();
1359 set_cc_op(s1, CC_OP_LOGICB + ot);
1362 tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1363 gen_op_st_rm_T0_A0(s1, ot, d);
1364 gen_op_update1_cc();
1365 set_cc_op(s1, CC_OP_LOGICB + ot);
1368 tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
1369 tcg_gen_mov_tl(cpu_cc_srcT, cpu_T[0]);
1370 tcg_gen_sub_tl(cpu_cc_dst, cpu_T[0], cpu_T[1]);
1371 set_cc_op(s1, CC_OP_SUBB + ot);
1376 /* if d == OR_TMP0, it means memory operand (address in A0) */
1377 static void gen_inc(DisasContext *s1, TCGMemOp ot, int d, int c)
1380 gen_op_mov_v_reg(ot, cpu_T[0], d);
1382 gen_op_ld_v(s1, ot, cpu_T[0], cpu_A0);
1384 gen_compute_eflags_c(s1, cpu_cc_src);
1386 tcg_gen_addi_tl(cpu_T[0], cpu_T[0], 1);
1387 set_cc_op(s1, CC_OP_INCB + ot);
1389 tcg_gen_addi_tl(cpu_T[0], cpu_T[0], -1);
1390 set_cc_op(s1, CC_OP_DECB + ot);
1392 gen_op_st_rm_T0_A0(s1, ot, d);
1393 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
1396 static void gen_shift_flags(DisasContext *s, TCGMemOp ot, TCGv result,
1397 TCGv shm1, TCGv count, bool is_right)
1399 TCGv_i32 z32, s32, oldop;
1402 /* Store the results into the CC variables. If we know that the
1403 variable must be dead, store unconditionally. Otherwise we'll
1404 need to not disrupt the current contents. */
1405 z_tl = tcg_const_tl(0);
1406 if (cc_op_live[s->cc_op] & USES_CC_DST) {
1407 tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_dst, count, z_tl,
1408 result, cpu_cc_dst);
1410 tcg_gen_mov_tl(cpu_cc_dst, result);
1412 if (cc_op_live[s->cc_op] & USES_CC_SRC) {
1413 tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_src, count, z_tl,
1416 tcg_gen_mov_tl(cpu_cc_src, shm1);
1418 tcg_temp_free(z_tl);
1420 /* Get the two potential CC_OP values into temporaries. */
1421 tcg_gen_movi_i32(cpu_tmp2_i32, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot);
1422 if (s->cc_op == CC_OP_DYNAMIC) {
1425 tcg_gen_movi_i32(cpu_tmp3_i32, s->cc_op);
1426 oldop = cpu_tmp3_i32;
1429 /* Conditionally store the CC_OP value. */
1430 z32 = tcg_const_i32(0);
1431 s32 = tcg_temp_new_i32();
1432 tcg_gen_trunc_tl_i32(s32, count);
1433 tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, s32, z32, cpu_tmp2_i32, oldop);
1434 tcg_temp_free_i32(z32);
1435 tcg_temp_free_i32(s32);
1437 /* The CC_OP value is no longer predictable. */
1438 set_cc_op(s, CC_OP_DYNAMIC);
1441 static void gen_shift_rm_T1(DisasContext *s, TCGMemOp ot, int op1,
1442 int is_right, int is_arith)
1444 target_ulong mask = (ot == MO_64 ? 0x3f : 0x1f);
1447 if (op1 == OR_TMP0) {
1448 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
1450 gen_op_mov_v_reg(ot, cpu_T[0], op1);
1453 tcg_gen_andi_tl(cpu_T[1], cpu_T[1], mask);
1454 tcg_gen_subi_tl(cpu_tmp0, cpu_T[1], 1);
1458 gen_exts(ot, cpu_T[0]);
1459 tcg_gen_sar_tl(cpu_tmp0, cpu_T[0], cpu_tmp0);
1460 tcg_gen_sar_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1462 gen_extu(ot, cpu_T[0]);
1463 tcg_gen_shr_tl(cpu_tmp0, cpu_T[0], cpu_tmp0);
1464 tcg_gen_shr_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1467 tcg_gen_shl_tl(cpu_tmp0, cpu_T[0], cpu_tmp0);
1468 tcg_gen_shl_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1472 gen_op_st_rm_T0_A0(s, ot, op1);
1474 gen_shift_flags(s, ot, cpu_T[0], cpu_tmp0, cpu_T[1], is_right);
1477 static void gen_shift_rm_im(DisasContext *s, TCGMemOp ot, int op1, int op2,
1478 int is_right, int is_arith)
1480 int mask = (ot == MO_64 ? 0x3f : 0x1f);
1484 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
1486 gen_op_mov_v_reg(ot, cpu_T[0], op1);
1492 gen_exts(ot, cpu_T[0]);
1493 tcg_gen_sari_tl(cpu_tmp4, cpu_T[0], op2 - 1);
1494 tcg_gen_sari_tl(cpu_T[0], cpu_T[0], op2);
1496 gen_extu(ot, cpu_T[0]);
1497 tcg_gen_shri_tl(cpu_tmp4, cpu_T[0], op2 - 1);
1498 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], op2);
1501 tcg_gen_shli_tl(cpu_tmp4, cpu_T[0], op2 - 1);
1502 tcg_gen_shli_tl(cpu_T[0], cpu_T[0], op2);
1507 gen_op_st_rm_T0_A0(s, ot, op1);
1509 /* update eflags if non zero shift */
1511 tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
1512 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
1513 set_cc_op(s, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot);
1517 static void gen_rot_rm_T1(DisasContext *s, TCGMemOp ot, int op1, int is_right)
1519 target_ulong mask = (ot == MO_64 ? 0x3f : 0x1f);
1523 if (op1 == OR_TMP0) {
1524 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
1526 gen_op_mov_v_reg(ot, cpu_T[0], op1);
1529 tcg_gen_andi_tl(cpu_T[1], cpu_T[1], mask);
1533 /* Replicate the 8-bit input so that a 32-bit rotate works. */
1534 tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]);
1535 tcg_gen_muli_tl(cpu_T[0], cpu_T[0], 0x01010101);
1538 /* Replicate the 16-bit input so that a 32-bit rotate works. */
1539 tcg_gen_deposit_tl(cpu_T[0], cpu_T[0], cpu_T[0], 16, 16);
1542 #ifdef TARGET_X86_64
1544 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
1545 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
1547 tcg_gen_rotr_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
1549 tcg_gen_rotl_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
1551 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
1556 tcg_gen_rotr_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1558 tcg_gen_rotl_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1564 gen_op_st_rm_T0_A0(s, ot, op1);
1566 /* We'll need the flags computed into CC_SRC. */
1567 gen_compute_eflags(s);
1569 /* The value that was "rotated out" is now present at the other end
1570 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1571 since we've computed the flags into CC_SRC, these variables are
1574 tcg_gen_shri_tl(cpu_cc_src2, cpu_T[0], mask - 1);
1575 tcg_gen_shri_tl(cpu_cc_dst, cpu_T[0], mask);
1576 tcg_gen_andi_tl(cpu_cc_dst, cpu_cc_dst, 1);
1578 tcg_gen_shri_tl(cpu_cc_src2, cpu_T[0], mask);
1579 tcg_gen_andi_tl(cpu_cc_dst, cpu_T[0], 1);
1581 tcg_gen_andi_tl(cpu_cc_src2, cpu_cc_src2, 1);
1582 tcg_gen_xor_tl(cpu_cc_src2, cpu_cc_src2, cpu_cc_dst);
1584 /* Now conditionally store the new CC_OP value. If the shift count
1585 is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1586 Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1587 exactly as we computed above. */
1588 t0 = tcg_const_i32(0);
1589 t1 = tcg_temp_new_i32();
1590 tcg_gen_trunc_tl_i32(t1, cpu_T[1]);
1591 tcg_gen_movi_i32(cpu_tmp2_i32, CC_OP_ADCOX);
1592 tcg_gen_movi_i32(cpu_tmp3_i32, CC_OP_EFLAGS);
1593 tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, t1, t0,
1594 cpu_tmp2_i32, cpu_tmp3_i32);
1595 tcg_temp_free_i32(t0);
1596 tcg_temp_free_i32(t1);
1598 /* The CC_OP value is no longer predictable. */
1599 set_cc_op(s, CC_OP_DYNAMIC);
1602 static void gen_rot_rm_im(DisasContext *s, TCGMemOp ot, int op1, int op2,
1605 int mask = (ot == MO_64 ? 0x3f : 0x1f);
1609 if (op1 == OR_TMP0) {
1610 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
1612 gen_op_mov_v_reg(ot, cpu_T[0], op1);
1618 #ifdef TARGET_X86_64
1620 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
1622 tcg_gen_rotri_i32(cpu_tmp2_i32, cpu_tmp2_i32, op2);
1624 tcg_gen_rotli_i32(cpu_tmp2_i32, cpu_tmp2_i32, op2);
1626 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
1631 tcg_gen_rotri_tl(cpu_T[0], cpu_T[0], op2);
1633 tcg_gen_rotli_tl(cpu_T[0], cpu_T[0], op2);
1644 shift = mask + 1 - shift;
1646 gen_extu(ot, cpu_T[0]);
1647 tcg_gen_shli_tl(cpu_tmp0, cpu_T[0], shift);
1648 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], mask + 1 - shift);
1649 tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
1655 gen_op_st_rm_T0_A0(s, ot, op1);
1658 /* Compute the flags into CC_SRC. */
1659 gen_compute_eflags(s);
1661 /* The value that was "rotated out" is now present at the other end
1662 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1663 since we've computed the flags into CC_SRC, these variables are
1666 tcg_gen_shri_tl(cpu_cc_src2, cpu_T[0], mask - 1);
1667 tcg_gen_shri_tl(cpu_cc_dst, cpu_T[0], mask);
1668 tcg_gen_andi_tl(cpu_cc_dst, cpu_cc_dst, 1);
1670 tcg_gen_shri_tl(cpu_cc_src2, cpu_T[0], mask);
1671 tcg_gen_andi_tl(cpu_cc_dst, cpu_T[0], 1);
1673 tcg_gen_andi_tl(cpu_cc_src2, cpu_cc_src2, 1);
1674 tcg_gen_xor_tl(cpu_cc_src2, cpu_cc_src2, cpu_cc_dst);
1675 set_cc_op(s, CC_OP_ADCOX);
1679 /* XXX: add faster immediate = 1 case */
1680 static void gen_rotc_rm_T1(DisasContext *s, TCGMemOp ot, int op1,
1683 gen_compute_eflags(s);
1684 assert(s->cc_op == CC_OP_EFLAGS);
1688 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
1690 gen_op_mov_v_reg(ot, cpu_T[0], op1);
1695 gen_helper_rcrb(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1698 gen_helper_rcrw(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1701 gen_helper_rcrl(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1703 #ifdef TARGET_X86_64
1705 gen_helper_rcrq(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1714 gen_helper_rclb(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1717 gen_helper_rclw(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1720 gen_helper_rcll(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1722 #ifdef TARGET_X86_64
1724 gen_helper_rclq(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]);
1732 gen_op_st_rm_T0_A0(s, ot, op1);
1735 /* XXX: add faster immediate case */
1736 static void gen_shiftd_rm_T1(DisasContext *s, TCGMemOp ot, int op1,
1737 bool is_right, TCGv count_in)
1739 target_ulong mask = (ot == MO_64 ? 63 : 31);
1743 if (op1 == OR_TMP0) {
1744 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
1746 gen_op_mov_v_reg(ot, cpu_T[0], op1);
1749 count = tcg_temp_new();
1750 tcg_gen_andi_tl(count, count_in, mask);
1754 /* Note: we implement the Intel behaviour for shift count > 16.
1755 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A
1756 portion by constructing it as a 32-bit value. */
1758 tcg_gen_deposit_tl(cpu_tmp0, cpu_T[0], cpu_T[1], 16, 16);
1759 tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
1760 tcg_gen_mov_tl(cpu_T[0], cpu_tmp0);
1762 tcg_gen_deposit_tl(cpu_T[1], cpu_T[0], cpu_T[1], 16, 16);
1765 #ifdef TARGET_X86_64
1767 /* Concatenate the two 32-bit values and use a 64-bit shift. */
1768 tcg_gen_subi_tl(cpu_tmp0, count, 1);
1770 tcg_gen_concat_tl_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
1771 tcg_gen_shr_i64(cpu_tmp0, cpu_T[0], cpu_tmp0);
1772 tcg_gen_shr_i64(cpu_T[0], cpu_T[0], count);
1774 tcg_gen_concat_tl_i64(cpu_T[0], cpu_T[1], cpu_T[0]);
1775 tcg_gen_shl_i64(cpu_tmp0, cpu_T[0], cpu_tmp0);
1776 tcg_gen_shl_i64(cpu_T[0], cpu_T[0], count);
1777 tcg_gen_shri_i64(cpu_tmp0, cpu_tmp0, 32);
1778 tcg_gen_shri_i64(cpu_T[0], cpu_T[0], 32);
1783 tcg_gen_subi_tl(cpu_tmp0, count, 1);
1785 tcg_gen_shr_tl(cpu_tmp0, cpu_T[0], cpu_tmp0);
1787 tcg_gen_subfi_tl(cpu_tmp4, mask + 1, count);
1788 tcg_gen_shr_tl(cpu_T[0], cpu_T[0], count);
1789 tcg_gen_shl_tl(cpu_T[1], cpu_T[1], cpu_tmp4);
1791 tcg_gen_shl_tl(cpu_tmp0, cpu_T[0], cpu_tmp0);
1793 /* Only needed if count > 16, for Intel behaviour. */
1794 tcg_gen_subfi_tl(cpu_tmp4, 33, count);
1795 tcg_gen_shr_tl(cpu_tmp4, cpu_T[1], cpu_tmp4);
1796 tcg_gen_or_tl(cpu_tmp0, cpu_tmp0, cpu_tmp4);
1799 tcg_gen_subfi_tl(cpu_tmp4, mask + 1, count);
1800 tcg_gen_shl_tl(cpu_T[0], cpu_T[0], count);
1801 tcg_gen_shr_tl(cpu_T[1], cpu_T[1], cpu_tmp4);
1803 tcg_gen_movi_tl(cpu_tmp4, 0);
1804 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_T[1], count, cpu_tmp4,
1805 cpu_tmp4, cpu_T[1]);
1806 tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1811 gen_op_st_rm_T0_A0(s, ot, op1);
1813 gen_shift_flags(s, ot, cpu_T[0], cpu_tmp0, count, is_right);
1814 tcg_temp_free(count);
1817 static void gen_shift(DisasContext *s1, int op, TCGMemOp ot, int d, int s)
1820 gen_op_mov_v_reg(ot, cpu_T[1], s);
1823 gen_rot_rm_T1(s1, ot, d, 0);
1826 gen_rot_rm_T1(s1, ot, d, 1);
1830 gen_shift_rm_T1(s1, ot, d, 0, 0);
1833 gen_shift_rm_T1(s1, ot, d, 1, 0);
1836 gen_shift_rm_T1(s1, ot, d, 1, 1);
1839 gen_rotc_rm_T1(s1, ot, d, 0);
1842 gen_rotc_rm_T1(s1, ot, d, 1);
1847 static void gen_shifti(DisasContext *s1, int op, TCGMemOp ot, int d, int c)
1851 gen_rot_rm_im(s1, ot, d, c, 0);
1854 gen_rot_rm_im(s1, ot, d, c, 1);
1858 gen_shift_rm_im(s1, ot, d, c, 0, 0);
1861 gen_shift_rm_im(s1, ot, d, c, 1, 0);
1864 gen_shift_rm_im(s1, ot, d, c, 1, 1);
1867 /* currently not optimized */
1868 tcg_gen_movi_tl(cpu_T[1], c);
1869 gen_shift(s1, op, ot, d, OR_TMP1);
1874 static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm)
1881 int mod, rm, code, override, must_add_seg;
1884 override = s->override;
1885 must_add_seg = s->addseg;
1888 mod = (modrm >> 6) & 3;
1901 code = cpu_ldub_code(env, s->pc++);
1902 scale = (code >> 6) & 3;
1903 index = ((code >> 3) & 7) | REX_X(s);
1905 index = -1; /* no index */
1913 if ((base & 7) == 5) {
1915 disp = (int32_t)cpu_ldl_code(env, s->pc);
1917 if (CODE64(s) && !havesib) {
1918 disp += s->pc + s->rip_offset;
1925 disp = (int8_t)cpu_ldub_code(env, s->pc++);
1929 disp = (int32_t)cpu_ldl_code(env, s->pc);
1934 /* For correct popl handling with esp. */
1935 if (base == R_ESP && s->popl_esp_hack) {
1936 disp += s->popl_esp_hack;
1939 /* Compute the address, with a minimum number of TCG ops. */
1943 sum = cpu_regs[index];
1945 tcg_gen_shli_tl(cpu_A0, cpu_regs[index], scale);
1949 tcg_gen_add_tl(cpu_A0, sum, cpu_regs[base]);
1952 } else if (base >= 0) {
1953 sum = cpu_regs[base];
1955 if (TCGV_IS_UNUSED(sum)) {
1956 tcg_gen_movi_tl(cpu_A0, disp);
1958 tcg_gen_addi_tl(cpu_A0, sum, disp);
1963 if (base == R_EBP || base == R_ESP) {
1970 tcg_gen_ld_tl(cpu_tmp0, cpu_env,
1971 offsetof(CPUX86State, segs[override].base));
1973 if (s->aflag == MO_32) {
1974 tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
1976 tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
1980 tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
1983 if (s->aflag == MO_32) {
1984 tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
1992 disp = cpu_lduw_code(env, s->pc);
1994 tcg_gen_movi_tl(cpu_A0, disp);
1995 rm = 0; /* avoid SS override */
2002 disp = (int8_t)cpu_ldub_code(env, s->pc++);
2006 disp = (int16_t)cpu_lduw_code(env, s->pc);
2014 tcg_gen_add_tl(cpu_A0, cpu_regs[R_EBX], cpu_regs[R_ESI]);
2017 tcg_gen_add_tl(cpu_A0, cpu_regs[R_EBX], cpu_regs[R_EDI]);
2020 tcg_gen_add_tl(cpu_A0, cpu_regs[R_EBP], cpu_regs[R_ESI]);
2023 tcg_gen_add_tl(cpu_A0, cpu_regs[R_EBP], cpu_regs[R_EDI]);
2026 sum = cpu_regs[R_ESI];
2029 sum = cpu_regs[R_EDI];
2032 sum = cpu_regs[R_EBP];
2036 sum = cpu_regs[R_EBX];
2039 tcg_gen_addi_tl(cpu_A0, sum, disp);
2040 tcg_gen_ext16u_tl(cpu_A0, cpu_A0);
2044 if (rm == 2 || rm == 3 || rm == 6) {
2050 gen_op_addl_A0_seg(s, override);
2059 static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm)
2061 int mod, rm, base, code;
2063 mod = (modrm >> 6) & 3;
2074 code = cpu_ldub_code(env, s->pc++);
2116 /* used for LEA and MOV AX, mem */
2117 static void gen_add_A0_ds_seg(DisasContext *s)
2119 int override, must_add_seg;
2120 must_add_seg = s->addseg;
2122 if (s->override >= 0) {
2123 override = s->override;
2127 #ifdef TARGET_X86_64
2129 gen_op_addq_A0_seg(override);
2133 gen_op_addl_A0_seg(s, override);
2138 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2140 static void gen_ldst_modrm(CPUX86State *env, DisasContext *s, int modrm,
2141 TCGMemOp ot, int reg, int is_store)
2145 mod = (modrm >> 6) & 3;
2146 rm = (modrm & 7) | REX_B(s);
2150 gen_op_mov_v_reg(ot, cpu_T[0], reg);
2151 gen_op_mov_reg_v(ot, rm, cpu_T[0]);
2153 gen_op_mov_v_reg(ot, cpu_T[0], rm);
2155 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
2158 gen_lea_modrm(env, s, modrm);
2161 gen_op_mov_v_reg(ot, cpu_T[0], reg);
2162 gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
2164 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
2166 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
2171 static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, TCGMemOp ot)
2177 ret = cpu_ldub_code(env, s->pc);
2181 ret = cpu_lduw_code(env, s->pc);
2185 #ifdef TARGET_X86_64
2188 ret = cpu_ldl_code(env, s->pc);
2197 static inline int insn_const_size(TCGMemOp ot)
2206 static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
2208 TranslationBlock *tb;
2211 pc = s->cs_base + eip;
2213 /* NOTE: we handle the case where the TB spans two pages here */
2214 if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) ||
2215 (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK)) {
2216 /* jump to same page: we can use a direct jump */
2217 tcg_gen_goto_tb(tb_num);
2219 tcg_gen_exit_tb((uintptr_t)tb + tb_num);
2221 /* jump to another page: currently not optimized */
2227 static inline void gen_jcc(DisasContext *s, int b,
2228 target_ulong val, target_ulong next_eip)
2233 l1 = gen_new_label();
2236 gen_goto_tb(s, 0, next_eip);
2239 gen_goto_tb(s, 1, val);
2240 s->is_jmp = DISAS_TB_JUMP;
2242 l1 = gen_new_label();
2243 l2 = gen_new_label();
2246 gen_jmp_im(next_eip);
2256 static void gen_cmovcc1(CPUX86State *env, DisasContext *s, TCGMemOp ot, int b,
2261 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
2263 cc = gen_prepare_cc(s, b, cpu_T[1]);
2264 if (cc.mask != -1) {
2265 TCGv t0 = tcg_temp_new();
2266 tcg_gen_andi_tl(t0, cc.reg, cc.mask);
2270 cc.reg2 = tcg_const_tl(cc.imm);
2273 tcg_gen_movcond_tl(cc.cond, cpu_T[0], cc.reg, cc.reg2,
2274 cpu_T[0], cpu_regs[reg]);
2275 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
2277 if (cc.mask != -1) {
2278 tcg_temp_free(cc.reg);
2281 tcg_temp_free(cc.reg2);
2285 static inline void gen_op_movl_T0_seg(int seg_reg)
2287 tcg_gen_ld32u_tl(cpu_T[0], cpu_env,
2288 offsetof(CPUX86State,segs[seg_reg].selector));
2291 static inline void gen_op_movl_seg_T0_vm(int seg_reg)
2293 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
2294 tcg_gen_st32_tl(cpu_T[0], cpu_env,
2295 offsetof(CPUX86State,segs[seg_reg].selector));
2296 tcg_gen_shli_tl(cpu_T[0], cpu_T[0], 4);
2297 tcg_gen_st_tl(cpu_T[0], cpu_env,
2298 offsetof(CPUX86State,segs[seg_reg].base));
2301 /* move T0 to seg_reg and compute if the CPU state may change. Never
2302 call this function with seg_reg == R_CS */
2303 static void gen_movl_seg_T0(DisasContext *s, int seg_reg, target_ulong cur_eip)
2305 if (s->pe && !s->vm86) {
2306 /* XXX: optimize by finding processor state dynamically */
2307 gen_update_cc_op(s);
2308 gen_jmp_im(cur_eip);
2309 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
2310 gen_helper_load_seg(cpu_env, tcg_const_i32(seg_reg), cpu_tmp2_i32);
2311 /* abort translation because the addseg value may change or
2312 because ss32 may change. For R_SS, translation must always
2313 stop as a special handling must be done to disable hardware
2314 interrupts for the next instruction */
2315 if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS))
2316 s->is_jmp = DISAS_TB_JUMP;
2318 gen_op_movl_seg_T0_vm(seg_reg);
2319 if (seg_reg == R_SS)
2320 s->is_jmp = DISAS_TB_JUMP;
2324 static inline int svm_is_rep(int prefixes)
2326 return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0);
2330 gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
2331 uint32_t type, uint64_t param)
2333 /* no SVM activated; fast case */
2334 if (likely(!(s->flags & HF_SVMI_MASK)))
2336 gen_update_cc_op(s);
2337 gen_jmp_im(pc_start - s->cs_base);
2338 gen_helper_svm_check_intercept_param(cpu_env, tcg_const_i32(type),
2339 tcg_const_i64(param));
2343 gen_svm_check_intercept(DisasContext *s, target_ulong pc_start, uint64_t type)
2345 gen_svm_check_intercept_param(s, pc_start, type, 0);
2348 static inline void gen_stack_update(DisasContext *s, int addend)
2350 #ifdef TARGET_X86_64
2352 gen_op_add_reg_im(MO_64, R_ESP, addend);
2356 gen_op_add_reg_im(MO_32, R_ESP, addend);
2358 gen_op_add_reg_im(MO_16, R_ESP, addend);
2362 /* Generate a push. It depends on ss32, addseg and dflag. */
2363 static void gen_push_v(DisasContext *s, TCGv val)
2365 TCGMemOp a_ot, d_ot = mo_pushpop(s, s->dflag);
2366 int size = 1 << d_ot;
2367 TCGv new_esp = cpu_A0;
2369 tcg_gen_subi_tl(cpu_A0, cpu_regs[R_ESP], size);
2373 } else if (s->ss32) {
2377 tcg_gen_mov_tl(new_esp, cpu_A0);
2378 gen_op_addl_A0_seg(s, R_SS);
2380 tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
2385 tcg_gen_ext16u_tl(cpu_A0, cpu_A0);
2386 tcg_gen_mov_tl(new_esp, cpu_A0);
2387 gen_op_addl_A0_seg(s, R_SS);
2390 gen_op_st_v(s, d_ot, val, cpu_A0);
2391 gen_op_mov_reg_v(a_ot, R_ESP, new_esp);
2394 /* two step pop is necessary for precise exceptions */
2395 static TCGMemOp gen_pop_T0(DisasContext *s)
2397 TCGMemOp d_ot = mo_pushpop(s, s->dflag);
2401 addr = cpu_regs[R_ESP];
2402 } else if (!s->ss32) {
2403 tcg_gen_ext16u_tl(cpu_A0, cpu_regs[R_ESP]);
2404 gen_op_addl_A0_seg(s, R_SS);
2405 } else if (s->addseg) {
2406 tcg_gen_mov_tl(cpu_A0, cpu_regs[R_ESP]);
2407 gen_op_addl_A0_seg(s, R_SS);
2409 tcg_gen_ext32u_tl(cpu_A0, cpu_regs[R_ESP]);
2412 gen_op_ld_v(s, d_ot, cpu_T[0], addr);
2416 static void gen_pop_update(DisasContext *s, TCGMemOp ot)
2418 gen_stack_update(s, 1 << ot);
2421 static void gen_stack_A0(DisasContext *s)
2423 gen_op_movl_A0_reg(R_ESP);
2425 tcg_gen_ext16u_tl(cpu_A0, cpu_A0);
2426 tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2428 gen_op_addl_A0_seg(s, R_SS);
2431 /* NOTE: wrap around in 16 bit not fully handled */
2432 static void gen_pusha(DisasContext *s)
2435 gen_op_movl_A0_reg(R_ESP);
2436 gen_op_addl_A0_im(-8 << s->dflag);
2438 tcg_gen_ext16u_tl(cpu_A0, cpu_A0);
2439 tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2441 gen_op_addl_A0_seg(s, R_SS);
2442 for(i = 0;i < 8; i++) {
2443 gen_op_mov_v_reg(MO_32, cpu_T[0], 7 - i);
2444 gen_op_st_v(s, s->dflag, cpu_T[0], cpu_A0);
2445 gen_op_addl_A0_im(1 << s->dflag);
2447 gen_op_mov_reg_v(MO_16 + s->ss32, R_ESP, cpu_T[1]);
2450 /* NOTE: wrap around in 16 bit not fully handled */
2451 static void gen_popa(DisasContext *s)
2454 gen_op_movl_A0_reg(R_ESP);
2456 tcg_gen_ext16u_tl(cpu_A0, cpu_A0);
2457 tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2458 tcg_gen_addi_tl(cpu_T[1], cpu_T[1], 8 << s->dflag);
2460 gen_op_addl_A0_seg(s, R_SS);
2461 for(i = 0;i < 8; i++) {
2462 /* ESP is not reloaded */
2464 gen_op_ld_v(s, s->dflag, cpu_T[0], cpu_A0);
2465 gen_op_mov_reg_v(s->dflag, 7 - i, cpu_T[0]);
2467 gen_op_addl_A0_im(1 << s->dflag);
2469 gen_op_mov_reg_v(MO_16 + s->ss32, R_ESP, cpu_T[1]);
2472 static void gen_enter(DisasContext *s, int esp_addend, int level)
2474 TCGMemOp ot = mo_pushpop(s, s->dflag);
2475 int opsize = 1 << ot;
2478 #ifdef TARGET_X86_64
2480 gen_op_movl_A0_reg(R_ESP);
2481 gen_op_addq_A0_im(-opsize);
2482 tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2485 gen_op_mov_v_reg(MO_32, cpu_T[0], R_EBP);
2486 gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
2488 /* XXX: must save state */
2489 gen_helper_enter64_level(cpu_env, tcg_const_i32(level),
2490 tcg_const_i32((ot == MO_64)),
2493 gen_op_mov_reg_v(ot, R_EBP, cpu_T[1]);
2494 tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level));
2495 gen_op_mov_reg_v(MO_64, R_ESP, cpu_T[1]);
2499 gen_op_movl_A0_reg(R_ESP);
2500 gen_op_addl_A0_im(-opsize);
2502 tcg_gen_ext16u_tl(cpu_A0, cpu_A0);
2503 tcg_gen_mov_tl(cpu_T[1], cpu_A0);
2505 gen_op_addl_A0_seg(s, R_SS);
2507 gen_op_mov_v_reg(MO_32, cpu_T[0], R_EBP);
2508 gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
2510 /* XXX: must save state */
2511 gen_helper_enter_level(cpu_env, tcg_const_i32(level),
2512 tcg_const_i32(s->dflag - 1),
2515 gen_op_mov_reg_v(ot, R_EBP, cpu_T[1]);
2516 tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level));
2517 gen_op_mov_reg_v(MO_16 + s->ss32, R_ESP, cpu_T[1]);
2521 static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
2523 gen_update_cc_op(s);
2524 gen_jmp_im(cur_eip);
2525 gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno));
2526 s->is_jmp = DISAS_TB_JUMP;
2529 /* an interrupt is different from an exception because of the
2531 static void gen_interrupt(DisasContext *s, int intno,
2532 target_ulong cur_eip, target_ulong next_eip)
2534 gen_update_cc_op(s);
2535 gen_jmp_im(cur_eip);
2536 gen_helper_raise_interrupt(cpu_env, tcg_const_i32(intno),
2537 tcg_const_i32(next_eip - cur_eip));
2538 s->is_jmp = DISAS_TB_JUMP;
2541 static void gen_debug(DisasContext *s, target_ulong cur_eip)
2543 gen_update_cc_op(s);
2544 gen_jmp_im(cur_eip);
2545 gen_helper_debug(cpu_env);
2546 s->is_jmp = DISAS_TB_JUMP;
2549 /* generate a generic end of block. Trace exception is also generated
2551 static void gen_eob(DisasContext *s)
2553 gen_update_cc_op(s);
2554 if (s->tb->flags & HF_INHIBIT_IRQ_MASK) {
2555 gen_helper_reset_inhibit_irq(cpu_env);
2557 if (s->tb->flags & HF_RF_MASK) {
2558 gen_helper_reset_rf(cpu_env);
2560 if (s->singlestep_enabled) {
2561 gen_helper_debug(cpu_env);
2563 gen_helper_single_step(cpu_env);
2567 s->is_jmp = DISAS_TB_JUMP;
2570 /* generate a jump to eip. No segment change must happen before as a
2571 direct call to the next block may occur */
2572 static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
2574 gen_update_cc_op(s);
2575 set_cc_op(s, CC_OP_DYNAMIC);
2577 gen_goto_tb(s, tb_num, eip);
2578 s->is_jmp = DISAS_TB_JUMP;
2585 static void gen_jmp(DisasContext *s, target_ulong eip)
2587 gen_jmp_tb(s, eip, 0);
2590 static inline void gen_ldq_env_A0(DisasContext *s, int offset)
2592 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
2593 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset);
2596 static inline void gen_stq_env_A0(DisasContext *s, int offset)
2598 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset);
2599 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
2602 static inline void gen_ldo_env_A0(DisasContext *s, int offset)
2604 int mem_index = s->mem_index;
2605 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, mem_index, MO_LEQ);
2606 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
2607 tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2608 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_tmp0, mem_index, MO_LEQ);
2609 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
2612 static inline void gen_sto_env_A0(DisasContext *s, int offset)
2614 int mem_index = s->mem_index;
2615 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
2616 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, mem_index, MO_LEQ);
2617 tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2618 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
2619 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_tmp0, mem_index, MO_LEQ);
2622 static inline void gen_op_movo(int d_offset, int s_offset)
2624 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
2625 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2626 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + 8);
2627 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + 8);
2630 static inline void gen_op_movq(int d_offset, int s_offset)
2632 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
2633 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2636 static inline void gen_op_movl(int d_offset, int s_offset)
2638 tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env, s_offset);
2639 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, d_offset);
2642 static inline void gen_op_movq_env_0(int d_offset)
2644 tcg_gen_movi_i64(cpu_tmp1_i64, 0);
2645 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2648 typedef void (*SSEFunc_i_ep)(TCGv_i32 val, TCGv_ptr env, TCGv_ptr reg);
2649 typedef void (*SSEFunc_l_ep)(TCGv_i64 val, TCGv_ptr env, TCGv_ptr reg);
2650 typedef void (*SSEFunc_0_epi)(TCGv_ptr env, TCGv_ptr reg, TCGv_i32 val);
2651 typedef void (*SSEFunc_0_epl)(TCGv_ptr env, TCGv_ptr reg, TCGv_i64 val);
2652 typedef void (*SSEFunc_0_epp)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b);
2653 typedef void (*SSEFunc_0_eppi)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2655 typedef void (*SSEFunc_0_ppi)(TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv_i32 val);
2656 typedef void (*SSEFunc_0_eppt)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2659 #define SSE_SPECIAL ((void *)1)
2660 #define SSE_DUMMY ((void *)2)
2662 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2663 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2664 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2666 static const SSEFunc_0_epp sse_op_table1[256][4] = {
2667 /* 3DNow! extensions */
2668 [0x0e] = { SSE_DUMMY }, /* femms */
2669 [0x0f] = { SSE_DUMMY }, /* pf... */
2670 /* pure SSE operations */
2671 [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2672 [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2673 [0x12] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd, movsldup, movddup */
2674 [0x13] = { SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd */
2675 [0x14] = { gen_helper_punpckldq_xmm, gen_helper_punpcklqdq_xmm },
2676 [0x15] = { gen_helper_punpckhdq_xmm, gen_helper_punpckhqdq_xmm },
2677 [0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movhps, movhpd, movshdup */
2678 [0x17] = { SSE_SPECIAL, SSE_SPECIAL }, /* movhps, movhpd */
2680 [0x28] = { SSE_SPECIAL, SSE_SPECIAL }, /* movaps, movapd */
2681 [0x29] = { SSE_SPECIAL, SSE_SPECIAL }, /* movaps, movapd */
2682 [0x2a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2683 [0x2b] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movntps, movntpd, movntss, movntsd */
2684 [0x2c] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2685 [0x2d] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2686 [0x2e] = { gen_helper_ucomiss, gen_helper_ucomisd },
2687 [0x2f] = { gen_helper_comiss, gen_helper_comisd },
2688 [0x50] = { SSE_SPECIAL, SSE_SPECIAL }, /* movmskps, movmskpd */
2689 [0x51] = SSE_FOP(sqrt),
2690 [0x52] = { gen_helper_rsqrtps, NULL, gen_helper_rsqrtss, NULL },
2691 [0x53] = { gen_helper_rcpps, NULL, gen_helper_rcpss, NULL },
2692 [0x54] = { gen_helper_pand_xmm, gen_helper_pand_xmm }, /* andps, andpd */
2693 [0x55] = { gen_helper_pandn_xmm, gen_helper_pandn_xmm }, /* andnps, andnpd */
2694 [0x56] = { gen_helper_por_xmm, gen_helper_por_xmm }, /* orps, orpd */
2695 [0x57] = { gen_helper_pxor_xmm, gen_helper_pxor_xmm }, /* xorps, xorpd */
2696 [0x58] = SSE_FOP(add),
2697 [0x59] = SSE_FOP(mul),
2698 [0x5a] = { gen_helper_cvtps2pd, gen_helper_cvtpd2ps,
2699 gen_helper_cvtss2sd, gen_helper_cvtsd2ss },
2700 [0x5b] = { gen_helper_cvtdq2ps, gen_helper_cvtps2dq, gen_helper_cvttps2dq },
2701 [0x5c] = SSE_FOP(sub),
2702 [0x5d] = SSE_FOP(min),
2703 [0x5e] = SSE_FOP(div),
2704 [0x5f] = SSE_FOP(max),
2706 [0xc2] = SSE_FOP(cmpeq),
2707 [0xc6] = { (SSEFunc_0_epp)gen_helper_shufps,
2708 (SSEFunc_0_epp)gen_helper_shufpd }, /* XXX: casts */
2710 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */
2711 [0x38] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2712 [0x3a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2714 /* MMX ops and their SSE extensions */
2715 [0x60] = MMX_OP2(punpcklbw),
2716 [0x61] = MMX_OP2(punpcklwd),
2717 [0x62] = MMX_OP2(punpckldq),
2718 [0x63] = MMX_OP2(packsswb),
2719 [0x64] = MMX_OP2(pcmpgtb),
2720 [0x65] = MMX_OP2(pcmpgtw),
2721 [0x66] = MMX_OP2(pcmpgtl),
2722 [0x67] = MMX_OP2(packuswb),
2723 [0x68] = MMX_OP2(punpckhbw),
2724 [0x69] = MMX_OP2(punpckhwd),
2725 [0x6a] = MMX_OP2(punpckhdq),
2726 [0x6b] = MMX_OP2(packssdw),
2727 [0x6c] = { NULL, gen_helper_punpcklqdq_xmm },
2728 [0x6d] = { NULL, gen_helper_punpckhqdq_xmm },
2729 [0x6e] = { SSE_SPECIAL, SSE_SPECIAL }, /* movd mm, ea */
2730 [0x6f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, , movqdu */
2731 [0x70] = { (SSEFunc_0_epp)gen_helper_pshufw_mmx,
2732 (SSEFunc_0_epp)gen_helper_pshufd_xmm,
2733 (SSEFunc_0_epp)gen_helper_pshufhw_xmm,
2734 (SSEFunc_0_epp)gen_helper_pshuflw_xmm }, /* XXX: casts */
2735 [0x71] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftw */
2736 [0x72] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftd */
2737 [0x73] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftq */
2738 [0x74] = MMX_OP2(pcmpeqb),
2739 [0x75] = MMX_OP2(pcmpeqw),
2740 [0x76] = MMX_OP2(pcmpeql),
2741 [0x77] = { SSE_DUMMY }, /* emms */
2742 [0x78] = { NULL, SSE_SPECIAL, NULL, SSE_SPECIAL }, /* extrq_i, insertq_i */
2743 [0x79] = { NULL, gen_helper_extrq_r, NULL, gen_helper_insertq_r },
2744 [0x7c] = { NULL, gen_helper_haddpd, NULL, gen_helper_haddps },
2745 [0x7d] = { NULL, gen_helper_hsubpd, NULL, gen_helper_hsubps },
2746 [0x7e] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movd, movd, , movq */
2747 [0x7f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, movdqu */
2748 [0xc4] = { SSE_SPECIAL, SSE_SPECIAL }, /* pinsrw */
2749 [0xc5] = { SSE_SPECIAL, SSE_SPECIAL }, /* pextrw */
2750 [0xd0] = { NULL, gen_helper_addsubpd, NULL, gen_helper_addsubps },
2751 [0xd1] = MMX_OP2(psrlw),
2752 [0xd2] = MMX_OP2(psrld),
2753 [0xd3] = MMX_OP2(psrlq),
2754 [0xd4] = MMX_OP2(paddq),
2755 [0xd5] = MMX_OP2(pmullw),
2756 [0xd6] = { NULL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2757 [0xd7] = { SSE_SPECIAL, SSE_SPECIAL }, /* pmovmskb */
2758 [0xd8] = MMX_OP2(psubusb),
2759 [0xd9] = MMX_OP2(psubusw),
2760 [0xda] = MMX_OP2(pminub),
2761 [0xdb] = MMX_OP2(pand),
2762 [0xdc] = MMX_OP2(paddusb),
2763 [0xdd] = MMX_OP2(paddusw),
2764 [0xde] = MMX_OP2(pmaxub),
2765 [0xdf] = MMX_OP2(pandn),
2766 [0xe0] = MMX_OP2(pavgb),
2767 [0xe1] = MMX_OP2(psraw),
2768 [0xe2] = MMX_OP2(psrad),
2769 [0xe3] = MMX_OP2(pavgw),
2770 [0xe4] = MMX_OP2(pmulhuw),
2771 [0xe5] = MMX_OP2(pmulhw),
2772 [0xe6] = { NULL, gen_helper_cvttpd2dq, gen_helper_cvtdq2pd, gen_helper_cvtpd2dq },
2773 [0xe7] = { SSE_SPECIAL , SSE_SPECIAL }, /* movntq, movntq */
2774 [0xe8] = MMX_OP2(psubsb),
2775 [0xe9] = MMX_OP2(psubsw),
2776 [0xea] = MMX_OP2(pminsw),
2777 [0xeb] = MMX_OP2(por),
2778 [0xec] = MMX_OP2(paddsb),
2779 [0xed] = MMX_OP2(paddsw),
2780 [0xee] = MMX_OP2(pmaxsw),
2781 [0xef] = MMX_OP2(pxor),
2782 [0xf0] = { NULL, NULL, NULL, SSE_SPECIAL }, /* lddqu */
2783 [0xf1] = MMX_OP2(psllw),
2784 [0xf2] = MMX_OP2(pslld),
2785 [0xf3] = MMX_OP2(psllq),
2786 [0xf4] = MMX_OP2(pmuludq),
2787 [0xf5] = MMX_OP2(pmaddwd),
2788 [0xf6] = MMX_OP2(psadbw),
2789 [0xf7] = { (SSEFunc_0_epp)gen_helper_maskmov_mmx,
2790 (SSEFunc_0_epp)gen_helper_maskmov_xmm }, /* XXX: casts */
2791 [0xf8] = MMX_OP2(psubb),
2792 [0xf9] = MMX_OP2(psubw),
2793 [0xfa] = MMX_OP2(psubl),
2794 [0xfb] = MMX_OP2(psubq),
2795 [0xfc] = MMX_OP2(paddb),
2796 [0xfd] = MMX_OP2(paddw),
2797 [0xfe] = MMX_OP2(paddl),
2800 static const SSEFunc_0_epp sse_op_table2[3 * 8][2] = {
2801 [0 + 2] = MMX_OP2(psrlw),
2802 [0 + 4] = MMX_OP2(psraw),
2803 [0 + 6] = MMX_OP2(psllw),
2804 [8 + 2] = MMX_OP2(psrld),
2805 [8 + 4] = MMX_OP2(psrad),
2806 [8 + 6] = MMX_OP2(pslld),
2807 [16 + 2] = MMX_OP2(psrlq),
2808 [16 + 3] = { NULL, gen_helper_psrldq_xmm },
2809 [16 + 6] = MMX_OP2(psllq),
2810 [16 + 7] = { NULL, gen_helper_pslldq_xmm },
2813 static const SSEFunc_0_epi sse_op_table3ai[] = {
2814 gen_helper_cvtsi2ss,
2818 #ifdef TARGET_X86_64
2819 static const SSEFunc_0_epl sse_op_table3aq[] = {
2820 gen_helper_cvtsq2ss,
2825 static const SSEFunc_i_ep sse_op_table3bi[] = {
2826 gen_helper_cvttss2si,
2827 gen_helper_cvtss2si,
2828 gen_helper_cvttsd2si,
2832 #ifdef TARGET_X86_64
2833 static const SSEFunc_l_ep sse_op_table3bq[] = {
2834 gen_helper_cvttss2sq,
2835 gen_helper_cvtss2sq,
2836 gen_helper_cvttsd2sq,
2841 static const SSEFunc_0_epp sse_op_table4[8][4] = {
2852 static const SSEFunc_0_epp sse_op_table5[256] = {
2853 [0x0c] = gen_helper_pi2fw,
2854 [0x0d] = gen_helper_pi2fd,
2855 [0x1c] = gen_helper_pf2iw,
2856 [0x1d] = gen_helper_pf2id,
2857 [0x8a] = gen_helper_pfnacc,
2858 [0x8e] = gen_helper_pfpnacc,
2859 [0x90] = gen_helper_pfcmpge,
2860 [0x94] = gen_helper_pfmin,
2861 [0x96] = gen_helper_pfrcp,
2862 [0x97] = gen_helper_pfrsqrt,
2863 [0x9a] = gen_helper_pfsub,
2864 [0x9e] = gen_helper_pfadd,
2865 [0xa0] = gen_helper_pfcmpgt,
2866 [0xa4] = gen_helper_pfmax,
2867 [0xa6] = gen_helper_movq, /* pfrcpit1; no need to actually increase precision */
2868 [0xa7] = gen_helper_movq, /* pfrsqit1 */
2869 [0xaa] = gen_helper_pfsubr,
2870 [0xae] = gen_helper_pfacc,
2871 [0xb0] = gen_helper_pfcmpeq,
2872 [0xb4] = gen_helper_pfmul,
2873 [0xb6] = gen_helper_movq, /* pfrcpit2 */
2874 [0xb7] = gen_helper_pmulhrw_mmx,
2875 [0xbb] = gen_helper_pswapd,
2876 [0xbf] = gen_helper_pavgb_mmx /* pavgusb */
2879 struct SSEOpHelper_epp {
2880 SSEFunc_0_epp op[2];
2884 struct SSEOpHelper_eppi {
2885 SSEFunc_0_eppi op[2];
2889 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
2890 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
2891 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
2892 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
2893 #define PCLMULQDQ_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, \
2894 CPUID_EXT_PCLMULQDQ }
2895 #define AESNI_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_AES }
2897 static const struct SSEOpHelper_epp sse_op_table6[256] = {
2898 [0x00] = SSSE3_OP(pshufb),
2899 [0x01] = SSSE3_OP(phaddw),
2900 [0x02] = SSSE3_OP(phaddd),
2901 [0x03] = SSSE3_OP(phaddsw),
2902 [0x04] = SSSE3_OP(pmaddubsw),
2903 [0x05] = SSSE3_OP(phsubw),
2904 [0x06] = SSSE3_OP(phsubd),
2905 [0x07] = SSSE3_OP(phsubsw),
2906 [0x08] = SSSE3_OP(psignb),
2907 [0x09] = SSSE3_OP(psignw),
2908 [0x0a] = SSSE3_OP(psignd),
2909 [0x0b] = SSSE3_OP(pmulhrsw),
2910 [0x10] = SSE41_OP(pblendvb),
2911 [0x14] = SSE41_OP(blendvps),
2912 [0x15] = SSE41_OP(blendvpd),
2913 [0x17] = SSE41_OP(ptest),
2914 [0x1c] = SSSE3_OP(pabsb),
2915 [0x1d] = SSSE3_OP(pabsw),
2916 [0x1e] = SSSE3_OP(pabsd),
2917 [0x20] = SSE41_OP(pmovsxbw),
2918 [0x21] = SSE41_OP(pmovsxbd),
2919 [0x22] = SSE41_OP(pmovsxbq),
2920 [0x23] = SSE41_OP(pmovsxwd),
2921 [0x24] = SSE41_OP(pmovsxwq),
2922 [0x25] = SSE41_OP(pmovsxdq),
2923 [0x28] = SSE41_OP(pmuldq),
2924 [0x29] = SSE41_OP(pcmpeqq),
2925 [0x2a] = SSE41_SPECIAL, /* movntqda */
2926 [0x2b] = SSE41_OP(packusdw),
2927 [0x30] = SSE41_OP(pmovzxbw),
2928 [0x31] = SSE41_OP(pmovzxbd),
2929 [0x32] = SSE41_OP(pmovzxbq),
2930 [0x33] = SSE41_OP(pmovzxwd),
2931 [0x34] = SSE41_OP(pmovzxwq),
2932 [0x35] = SSE41_OP(pmovzxdq),
2933 [0x37] = SSE42_OP(pcmpgtq),
2934 [0x38] = SSE41_OP(pminsb),
2935 [0x39] = SSE41_OP(pminsd),
2936 [0x3a] = SSE41_OP(pminuw),
2937 [0x3b] = SSE41_OP(pminud),
2938 [0x3c] = SSE41_OP(pmaxsb),
2939 [0x3d] = SSE41_OP(pmaxsd),
2940 [0x3e] = SSE41_OP(pmaxuw),
2941 [0x3f] = SSE41_OP(pmaxud),
2942 [0x40] = SSE41_OP(pmulld),
2943 [0x41] = SSE41_OP(phminposuw),
2944 [0xdb] = AESNI_OP(aesimc),
2945 [0xdc] = AESNI_OP(aesenc),
2946 [0xdd] = AESNI_OP(aesenclast),
2947 [0xde] = AESNI_OP(aesdec),
2948 [0xdf] = AESNI_OP(aesdeclast),
2951 static const struct SSEOpHelper_eppi sse_op_table7[256] = {
2952 [0x08] = SSE41_OP(roundps),
2953 [0x09] = SSE41_OP(roundpd),
2954 [0x0a] = SSE41_OP(roundss),
2955 [0x0b] = SSE41_OP(roundsd),
2956 [0x0c] = SSE41_OP(blendps),
2957 [0x0d] = SSE41_OP(blendpd),
2958 [0x0e] = SSE41_OP(pblendw),
2959 [0x0f] = SSSE3_OP(palignr),
2960 [0x14] = SSE41_SPECIAL, /* pextrb */
2961 [0x15] = SSE41_SPECIAL, /* pextrw */
2962 [0x16] = SSE41_SPECIAL, /* pextrd/pextrq */
2963 [0x17] = SSE41_SPECIAL, /* extractps */
2964 [0x20] = SSE41_SPECIAL, /* pinsrb */
2965 [0x21] = SSE41_SPECIAL, /* insertps */
2966 [0x22] = SSE41_SPECIAL, /* pinsrd/pinsrq */
2967 [0x40] = SSE41_OP(dpps),
2968 [0x41] = SSE41_OP(dppd),
2969 [0x42] = SSE41_OP(mpsadbw),
2970 [0x44] = PCLMULQDQ_OP(pclmulqdq),
2971 [0x60] = SSE42_OP(pcmpestrm),
2972 [0x61] = SSE42_OP(pcmpestri),
2973 [0x62] = SSE42_OP(pcmpistrm),
2974 [0x63] = SSE42_OP(pcmpistri),
2975 [0xdf] = AESNI_OP(aeskeygenassist),
2978 static void gen_sse(CPUX86State *env, DisasContext *s, int b,
2979 target_ulong pc_start, int rex_r)
2981 int b1, op1_offset, op2_offset, is_xmm, val;
2982 int modrm, mod, rm, reg;
2983 SSEFunc_0_epp sse_fn_epp;
2984 SSEFunc_0_eppi sse_fn_eppi;
2985 SSEFunc_0_ppi sse_fn_ppi;
2986 SSEFunc_0_eppt sse_fn_eppt;
2990 if (s->prefix & PREFIX_DATA)
2992 else if (s->prefix & PREFIX_REPZ)
2994 else if (s->prefix & PREFIX_REPNZ)
2998 sse_fn_epp = sse_op_table1[b][b1];
3002 if ((b <= 0x5f && b >= 0x10) || b == 0xc6 || b == 0xc2) {
3012 /* simple MMX/SSE operation */
3013 if (s->flags & HF_TS_MASK) {
3014 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
3017 if (s->flags & HF_EM_MASK) {
3019 gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
3022 if (is_xmm && !(s->flags & HF_OSFXSR_MASK))
3023 if ((b != 0x38 && b != 0x3a) || (s->prefix & PREFIX_DATA))
3026 if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW))
3029 gen_helper_emms(cpu_env);
3034 gen_helper_emms(cpu_env);
3037 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3038 the static cpu state) */
3040 gen_helper_enter_mmx(cpu_env);
3043 modrm = cpu_ldub_code(env, s->pc++);
3044 reg = ((modrm >> 3) & 7);
3047 mod = (modrm >> 6) & 3;
3048 if (sse_fn_epp == SSE_SPECIAL) {
3051 case 0x0e7: /* movntq */
3054 gen_lea_modrm(env, s, modrm);
3055 gen_stq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
3057 case 0x1e7: /* movntdq */
3058 case 0x02b: /* movntps */
3059 case 0x12b: /* movntps */
3062 gen_lea_modrm(env, s, modrm);
3063 gen_sto_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3065 case 0x3f0: /* lddqu */
3068 gen_lea_modrm(env, s, modrm);
3069 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3071 case 0x22b: /* movntss */
3072 case 0x32b: /* movntsd */
3075 gen_lea_modrm(env, s, modrm);
3077 gen_stq_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3079 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
3080 xmm_regs[reg].XMM_L(0)));
3081 gen_op_st_v(s, MO_32, cpu_T[0], cpu_A0);
3084 case 0x6e: /* movd mm, ea */
3085 #ifdef TARGET_X86_64
3086 if (s->dflag == MO_64) {
3087 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 0);
3088 tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,fpregs[reg].mmx));
3092 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 0);
3093 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3094 offsetof(CPUX86State,fpregs[reg].mmx));
3095 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
3096 gen_helper_movl_mm_T0_mmx(cpu_ptr0, cpu_tmp2_i32);
3099 case 0x16e: /* movd xmm, ea */
3100 #ifdef TARGET_X86_64
3101 if (s->dflag == MO_64) {
3102 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 0);
3103 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3104 offsetof(CPUX86State,xmm_regs[reg]));
3105 gen_helper_movq_mm_T0_xmm(cpu_ptr0, cpu_T[0]);
3109 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 0);
3110 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3111 offsetof(CPUX86State,xmm_regs[reg]));
3112 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
3113 gen_helper_movl_mm_T0_xmm(cpu_ptr0, cpu_tmp2_i32);
3116 case 0x6f: /* movq mm, ea */
3118 gen_lea_modrm(env, s, modrm);
3119 gen_ldq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
3122 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
3123 offsetof(CPUX86State,fpregs[rm].mmx));
3124 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
3125 offsetof(CPUX86State,fpregs[reg].mmx));
3128 case 0x010: /* movups */
3129 case 0x110: /* movupd */
3130 case 0x028: /* movaps */
3131 case 0x128: /* movapd */
3132 case 0x16f: /* movdqa xmm, ea */
3133 case 0x26f: /* movdqu xmm, ea */
3135 gen_lea_modrm(env, s, modrm);
3136 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3138 rm = (modrm & 7) | REX_B(s);
3139 gen_op_movo(offsetof(CPUX86State,xmm_regs[reg]),
3140 offsetof(CPUX86State,xmm_regs[rm]));
3143 case 0x210: /* movss xmm, ea */
3145 gen_lea_modrm(env, s, modrm);
3146 gen_op_ld_v(s, MO_32, cpu_T[0], cpu_A0);
3147 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
3148 tcg_gen_movi_tl(cpu_T[0], 0);
3149 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)));
3150 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
3151 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
3153 rm = (modrm & 7) | REX_B(s);
3154 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
3155 offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)));
3158 case 0x310: /* movsd xmm, ea */
3160 gen_lea_modrm(env, s, modrm);
3161 gen_ldq_env_A0(s, offsetof(CPUX86State,
3162 xmm_regs[reg].XMM_Q(0)));
3163 tcg_gen_movi_tl(cpu_T[0], 0);
3164 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
3165 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
3167 rm = (modrm & 7) | REX_B(s);
3168 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
3169 offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
3172 case 0x012: /* movlps */
3173 case 0x112: /* movlpd */
3175 gen_lea_modrm(env, s, modrm);
3176 gen_ldq_env_A0(s, offsetof(CPUX86State,
3177 xmm_regs[reg].XMM_Q(0)));
3180 rm = (modrm & 7) | REX_B(s);
3181 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
3182 offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
3185 case 0x212: /* movsldup */
3187 gen_lea_modrm(env, s, modrm);
3188 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3190 rm = (modrm & 7) | REX_B(s);
3191 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
3192 offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)));
3193 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)),
3194 offsetof(CPUX86State,xmm_regs[rm].XMM_L(2)));
3196 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)),
3197 offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
3198 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)),
3199 offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
3201 case 0x312: /* movddup */
3203 gen_lea_modrm(env, s, modrm);
3204 gen_ldq_env_A0(s, offsetof(CPUX86State,
3205 xmm_regs[reg].XMM_Q(0)));
3207 rm = (modrm & 7) | REX_B(s);
3208 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
3209 offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
3211 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)),
3212 offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3214 case 0x016: /* movhps */
3215 case 0x116: /* movhpd */
3217 gen_lea_modrm(env, s, modrm);
3218 gen_ldq_env_A0(s, offsetof(CPUX86State,
3219 xmm_regs[reg].XMM_Q(1)));
3222 rm = (modrm & 7) | REX_B(s);
3223 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)),
3224 offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
3227 case 0x216: /* movshdup */
3229 gen_lea_modrm(env, s, modrm);
3230 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3232 rm = (modrm & 7) | REX_B(s);
3233 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)),
3234 offsetof(CPUX86State,xmm_regs[rm].XMM_L(1)));
3235 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)),
3236 offsetof(CPUX86State,xmm_regs[rm].XMM_L(3)));
3238 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
3239 offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)));
3240 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)),
3241 offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
3246 int bit_index, field_length;
3248 if (b1 == 1 && reg != 0)
3250 field_length = cpu_ldub_code(env, s->pc++) & 0x3F;
3251 bit_index = cpu_ldub_code(env, s->pc++) & 0x3F;
3252 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3253 offsetof(CPUX86State,xmm_regs[reg]));
3255 gen_helper_extrq_i(cpu_env, cpu_ptr0,
3256 tcg_const_i32(bit_index),
3257 tcg_const_i32(field_length));
3259 gen_helper_insertq_i(cpu_env, cpu_ptr0,
3260 tcg_const_i32(bit_index),
3261 tcg_const_i32(field_length));
3264 case 0x7e: /* movd ea, mm */
3265 #ifdef TARGET_X86_64
3266 if (s->dflag == MO_64) {
3267 tcg_gen_ld_i64(cpu_T[0], cpu_env,
3268 offsetof(CPUX86State,fpregs[reg].mmx));
3269 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 1);
3273 tcg_gen_ld32u_tl(cpu_T[0], cpu_env,
3274 offsetof(CPUX86State,fpregs[reg].mmx.MMX_L(0)));
3275 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 1);
3278 case 0x17e: /* movd ea, xmm */
3279 #ifdef TARGET_X86_64
3280 if (s->dflag == MO_64) {
3281 tcg_gen_ld_i64(cpu_T[0], cpu_env,
3282 offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3283 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 1);
3287 tcg_gen_ld32u_tl(cpu_T[0], cpu_env,
3288 offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
3289 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 1);
3292 case 0x27e: /* movq xmm, ea */
3294 gen_lea_modrm(env, s, modrm);
3295 gen_ldq_env_A0(s, offsetof(CPUX86State,
3296 xmm_regs[reg].XMM_Q(0)));
3298 rm = (modrm & 7) | REX_B(s);
3299 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
3300 offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
3302 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
3304 case 0x7f: /* movq ea, mm */
3306 gen_lea_modrm(env, s, modrm);
3307 gen_stq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
3310 gen_op_movq(offsetof(CPUX86State,fpregs[rm].mmx),
3311 offsetof(CPUX86State,fpregs[reg].mmx));
3314 case 0x011: /* movups */
3315 case 0x111: /* movupd */
3316 case 0x029: /* movaps */
3317 case 0x129: /* movapd */
3318 case 0x17f: /* movdqa ea, xmm */
3319 case 0x27f: /* movdqu ea, xmm */
3321 gen_lea_modrm(env, s, modrm);
3322 gen_sto_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3324 rm = (modrm & 7) | REX_B(s);
3325 gen_op_movo(offsetof(CPUX86State,xmm_regs[rm]),
3326 offsetof(CPUX86State,xmm_regs[reg]));
3329 case 0x211: /* movss ea, xmm */
3331 gen_lea_modrm(env, s, modrm);
3332 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
3333 gen_op_st_v(s, MO_32, cpu_T[0], cpu_A0);
3335 rm = (modrm & 7) | REX_B(s);
3336 gen_op_movl(offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)),
3337 offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
3340 case 0x311: /* movsd ea, xmm */
3342 gen_lea_modrm(env, s, modrm);
3343 gen_stq_env_A0(s, offsetof(CPUX86State,
3344 xmm_regs[reg].XMM_Q(0)));
3346 rm = (modrm & 7) | REX_B(s);
3347 gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
3348 offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3351 case 0x013: /* movlps */
3352 case 0x113: /* movlpd */
3354 gen_lea_modrm(env, s, modrm);
3355 gen_stq_env_A0(s, offsetof(CPUX86State,
3356 xmm_regs[reg].XMM_Q(0)));
3361 case 0x017: /* movhps */
3362 case 0x117: /* movhpd */
3364 gen_lea_modrm(env, s, modrm);
3365 gen_stq_env_A0(s, offsetof(CPUX86State,
3366 xmm_regs[reg].XMM_Q(1)));
3371 case 0x71: /* shift mm, im */
3374 case 0x171: /* shift xmm, im */
3380 val = cpu_ldub_code(env, s->pc++);
3382 tcg_gen_movi_tl(cpu_T[0], val);
3383 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0)));
3384 tcg_gen_movi_tl(cpu_T[0], 0);
3385 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(1)));
3386 op1_offset = offsetof(CPUX86State,xmm_t0);
3388 tcg_gen_movi_tl(cpu_T[0], val);
3389 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(0)));
3390 tcg_gen_movi_tl(cpu_T[0], 0);
3391 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(1)));
3392 op1_offset = offsetof(CPUX86State,mmx_t0);
3394 sse_fn_epp = sse_op_table2[((b - 1) & 3) * 8 +
3395 (((modrm >> 3)) & 7)][b1];
3400 rm = (modrm & 7) | REX_B(s);
3401 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3404 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3406 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
3407 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op1_offset);
3408 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
3410 case 0x050: /* movmskps */
3411 rm = (modrm & 7) | REX_B(s);
3412 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3413 offsetof(CPUX86State,xmm_regs[rm]));
3414 gen_helper_movmskps(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3415 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
3417 case 0x150: /* movmskpd */
3418 rm = (modrm & 7) | REX_B(s);
3419 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3420 offsetof(CPUX86State,xmm_regs[rm]));
3421 gen_helper_movmskpd(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3422 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
3424 case 0x02a: /* cvtpi2ps */
3425 case 0x12a: /* cvtpi2pd */
3426 gen_helper_enter_mmx(cpu_env);
3428 gen_lea_modrm(env, s, modrm);
3429 op2_offset = offsetof(CPUX86State,mmx_t0);
3430 gen_ldq_env_A0(s, op2_offset);
3433 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3435 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3436 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3437 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3440 gen_helper_cvtpi2ps(cpu_env, cpu_ptr0, cpu_ptr1);
3444 gen_helper_cvtpi2pd(cpu_env, cpu_ptr0, cpu_ptr1);
3448 case 0x22a: /* cvtsi2ss */
3449 case 0x32a: /* cvtsi2sd */
3450 ot = mo_64_32(s->dflag);
3451 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3452 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3453 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3455 SSEFunc_0_epi sse_fn_epi = sse_op_table3ai[(b >> 8) & 1];
3456 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
3457 sse_fn_epi(cpu_env, cpu_ptr0, cpu_tmp2_i32);
3459 #ifdef TARGET_X86_64
3460 SSEFunc_0_epl sse_fn_epl = sse_op_table3aq[(b >> 8) & 1];
3461 sse_fn_epl(cpu_env, cpu_ptr0, cpu_T[0]);
3467 case 0x02c: /* cvttps2pi */
3468 case 0x12c: /* cvttpd2pi */
3469 case 0x02d: /* cvtps2pi */
3470 case 0x12d: /* cvtpd2pi */
3471 gen_helper_enter_mmx(cpu_env);
3473 gen_lea_modrm(env, s, modrm);
3474 op2_offset = offsetof(CPUX86State,xmm_t0);
3475 gen_ldo_env_A0(s, op2_offset);
3477 rm = (modrm & 7) | REX_B(s);
3478 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3480 op1_offset = offsetof(CPUX86State,fpregs[reg & 7].mmx);
3481 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3482 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3485 gen_helper_cvttps2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3488 gen_helper_cvttpd2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3491 gen_helper_cvtps2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3494 gen_helper_cvtpd2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3498 case 0x22c: /* cvttss2si */
3499 case 0x32c: /* cvttsd2si */
3500 case 0x22d: /* cvtss2si */
3501 case 0x32d: /* cvtsd2si */
3502 ot = mo_64_32(s->dflag);
3504 gen_lea_modrm(env, s, modrm);
3506 gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.XMM_Q(0)));
3508 gen_op_ld_v(s, MO_32, cpu_T[0], cpu_A0);
3509 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0)));
3511 op2_offset = offsetof(CPUX86State,xmm_t0);
3513 rm = (modrm & 7) | REX_B(s);
3514 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3516 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
3518 SSEFunc_i_ep sse_fn_i_ep =
3519 sse_op_table3bi[((b >> 7) & 2) | (b & 1)];
3520 sse_fn_i_ep(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3521 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
3523 #ifdef TARGET_X86_64
3524 SSEFunc_l_ep sse_fn_l_ep =
3525 sse_op_table3bq[((b >> 7) & 2) | (b & 1)];
3526 sse_fn_l_ep(cpu_T[0], cpu_env, cpu_ptr0);
3531 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
3533 case 0xc4: /* pinsrw */
3536 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
3537 val = cpu_ldub_code(env, s->pc++);
3540 tcg_gen_st16_tl(cpu_T[0], cpu_env,
3541 offsetof(CPUX86State,xmm_regs[reg].XMM_W(val)));
3544 tcg_gen_st16_tl(cpu_T[0], cpu_env,
3545 offsetof(CPUX86State,fpregs[reg].mmx.MMX_W(val)));
3548 case 0xc5: /* pextrw */
3552 ot = mo_64_32(s->dflag);
3553 val = cpu_ldub_code(env, s->pc++);
3556 rm = (modrm & 7) | REX_B(s);
3557 tcg_gen_ld16u_tl(cpu_T[0], cpu_env,
3558 offsetof(CPUX86State,xmm_regs[rm].XMM_W(val)));
3562 tcg_gen_ld16u_tl(cpu_T[0], cpu_env,
3563 offsetof(CPUX86State,fpregs[rm].mmx.MMX_W(val)));
3565 reg = ((modrm >> 3) & 7) | rex_r;
3566 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
3568 case 0x1d6: /* movq ea, xmm */
3570 gen_lea_modrm(env, s, modrm);
3571 gen_stq_env_A0(s, offsetof(CPUX86State,
3572 xmm_regs[reg].XMM_Q(0)));
3574 rm = (modrm & 7) | REX_B(s);
3575 gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
3576 offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3577 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
3580 case 0x2d6: /* movq2dq */
3581 gen_helper_enter_mmx(cpu_env);
3583 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
3584 offsetof(CPUX86State,fpregs[rm].mmx));
3585 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
3587 case 0x3d6: /* movdq2q */
3588 gen_helper_enter_mmx(cpu_env);
3589 rm = (modrm & 7) | REX_B(s);
3590 gen_op_movq(offsetof(CPUX86State,fpregs[reg & 7].mmx),
3591 offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
3593 case 0xd7: /* pmovmskb */
3598 rm = (modrm & 7) | REX_B(s);
3599 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[rm]));
3600 gen_helper_pmovmskb_xmm(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3603 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,fpregs[rm].mmx));
3604 gen_helper_pmovmskb_mmx(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3606 reg = ((modrm >> 3) & 7) | rex_r;
3607 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
3613 if ((b & 0xf0) == 0xf0) {
3616 modrm = cpu_ldub_code(env, s->pc++);
3618 reg = ((modrm >> 3) & 7) | rex_r;
3619 mod = (modrm >> 6) & 3;
3624 sse_fn_epp = sse_op_table6[b].op[b1];
3628 if (!(s->cpuid_ext_features & sse_op_table6[b].ext_mask))
3632 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3634 op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
3636 op2_offset = offsetof(CPUX86State,xmm_t0);
3637 gen_lea_modrm(env, s, modrm);
3639 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3640 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3641 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3642 gen_ldq_env_A0(s, op2_offset +
3643 offsetof(XMMReg, XMM_Q(0)));
3645 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3646 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3647 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
3648 s->mem_index, MO_LEUL);
3649 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, op2_offset +
3650 offsetof(XMMReg, XMM_L(0)));
3652 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3653 tcg_gen_qemu_ld_tl(cpu_tmp0, cpu_A0,
3654 s->mem_index, MO_LEUW);
3655 tcg_gen_st16_tl(cpu_tmp0, cpu_env, op2_offset +
3656 offsetof(XMMReg, XMM_W(0)));
3658 case 0x2a: /* movntqda */
3659 gen_ldo_env_A0(s, op1_offset);
3662 gen_ldo_env_A0(s, op2_offset);
3666 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
3668 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3670 op2_offset = offsetof(CPUX86State,mmx_t0);
3671 gen_lea_modrm(env, s, modrm);
3672 gen_ldq_env_A0(s, op2_offset);
3675 if (sse_fn_epp == SSE_SPECIAL) {
3679 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3680 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3681 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
3684 set_cc_op(s, CC_OP_EFLAGS);
3691 /* Various integer extensions at 0f 38 f[0-f]. */
3692 b = modrm | (b1 << 8);
3693 modrm = cpu_ldub_code(env, s->pc++);
3694 reg = ((modrm >> 3) & 7) | rex_r;
3697 case 0x3f0: /* crc32 Gd,Eb */
3698 case 0x3f1: /* crc32 Gd,Ey */
3700 if (!(s->cpuid_ext_features & CPUID_EXT_SSE42)) {
3703 if ((b & 0xff) == 0xf0) {
3705 } else if (s->dflag != MO_64) {
3706 ot = (s->prefix & PREFIX_DATA ? MO_16 : MO_32);
3711 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[reg]);
3712 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3713 gen_helper_crc32(cpu_T[0], cpu_tmp2_i32,
3714 cpu_T[0], tcg_const_i32(8 << ot));
3716 ot = mo_64_32(s->dflag);
3717 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
3720 case 0x1f0: /* crc32 or movbe */
3722 /* For these insns, the f3 prefix is supposed to have priority
3723 over the 66 prefix, but that's not what we implement above
3725 if (s->prefix & PREFIX_REPNZ) {
3729 case 0x0f0: /* movbe Gy,My */
3730 case 0x0f1: /* movbe My,Gy */
3731 if (!(s->cpuid_ext_features & CPUID_EXT_MOVBE)) {
3734 if (s->dflag != MO_64) {
3735 ot = (s->prefix & PREFIX_DATA ? MO_16 : MO_32);
3740 gen_lea_modrm(env, s, modrm);
3742 tcg_gen_qemu_ld_tl(cpu_T[0], cpu_A0,
3743 s->mem_index, ot | MO_BE);
3744 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
3746 tcg_gen_qemu_st_tl(cpu_regs[reg], cpu_A0,
3747 s->mem_index, ot | MO_BE);
3751 case 0x0f2: /* andn Gy, By, Ey */
3752 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
3753 || !(s->prefix & PREFIX_VEX)
3757 ot = mo_64_32(s->dflag);
3758 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3759 tcg_gen_andc_tl(cpu_T[0], cpu_regs[s->vex_v], cpu_T[0]);
3760 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
3761 gen_op_update1_cc();
3762 set_cc_op(s, CC_OP_LOGICB + ot);
3765 case 0x0f7: /* bextr Gy, Ey, By */
3766 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
3767 || !(s->prefix & PREFIX_VEX)
3771 ot = mo_64_32(s->dflag);
3775 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3776 /* Extract START, and shift the operand.
3777 Shifts larger than operand size get zeros. */
3778 tcg_gen_ext8u_tl(cpu_A0, cpu_regs[s->vex_v]);
3779 tcg_gen_shr_tl(cpu_T[0], cpu_T[0], cpu_A0);
3781 bound = tcg_const_tl(ot == MO_64 ? 63 : 31);
3782 zero = tcg_const_tl(0);
3783 tcg_gen_movcond_tl(TCG_COND_LEU, cpu_T[0], cpu_A0, bound,
3785 tcg_temp_free(zero);
3787 /* Extract the LEN into a mask. Lengths larger than
3788 operand size get all ones. */
3789 tcg_gen_shri_tl(cpu_A0, cpu_regs[s->vex_v], 8);
3790 tcg_gen_ext8u_tl(cpu_A0, cpu_A0);
3791 tcg_gen_movcond_tl(TCG_COND_LEU, cpu_A0, cpu_A0, bound,
3793 tcg_temp_free(bound);
3794 tcg_gen_movi_tl(cpu_T[1], 1);
3795 tcg_gen_shl_tl(cpu_T[1], cpu_T[1], cpu_A0);
3796 tcg_gen_subi_tl(cpu_T[1], cpu_T[1], 1);
3797 tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3799 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
3800 gen_op_update1_cc();
3801 set_cc_op(s, CC_OP_LOGICB + ot);
3805 case 0x0f5: /* bzhi Gy, Ey, By */
3806 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3807 || !(s->prefix & PREFIX_VEX)
3811 ot = mo_64_32(s->dflag);
3812 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3813 tcg_gen_ext8u_tl(cpu_T[1], cpu_regs[s->vex_v]);
3815 TCGv bound = tcg_const_tl(ot == MO_64 ? 63 : 31);
3816 /* Note that since we're using BMILG (in order to get O
3817 cleared) we need to store the inverse into C. */
3818 tcg_gen_setcond_tl(TCG_COND_LT, cpu_cc_src,
3820 tcg_gen_movcond_tl(TCG_COND_GT, cpu_T[1], cpu_T[1],
3821 bound, bound, cpu_T[1]);
3822 tcg_temp_free(bound);
3824 tcg_gen_movi_tl(cpu_A0, -1);
3825 tcg_gen_shl_tl(cpu_A0, cpu_A0, cpu_T[1]);
3826 tcg_gen_andc_tl(cpu_T[0], cpu_T[0], cpu_A0);
3827 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
3828 gen_op_update1_cc();
3829 set_cc_op(s, CC_OP_BMILGB + ot);
3832 case 0x3f6: /* mulx By, Gy, rdx, Ey */
3833 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3834 || !(s->prefix & PREFIX_VEX)
3838 ot = mo_64_32(s->dflag);
3839 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3842 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
3843 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_regs[R_EDX]);
3844 tcg_gen_mulu2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
3845 cpu_tmp2_i32, cpu_tmp3_i32);
3846 tcg_gen_extu_i32_tl(cpu_regs[s->vex_v], cpu_tmp2_i32);
3847 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp3_i32);
3849 #ifdef TARGET_X86_64
3851 tcg_gen_mulu2_i64(cpu_regs[s->vex_v], cpu_regs[reg],
3852 cpu_T[0], cpu_regs[R_EDX]);
3858 case 0x3f5: /* pdep Gy, By, Ey */
3859 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3860 || !(s->prefix & PREFIX_VEX)
3864 ot = mo_64_32(s->dflag);
3865 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3866 /* Note that by zero-extending the mask operand, we
3867 automatically handle zero-extending the result. */
3869 tcg_gen_mov_tl(cpu_T[1], cpu_regs[s->vex_v]);
3871 tcg_gen_ext32u_tl(cpu_T[1], cpu_regs[s->vex_v]);
3873 gen_helper_pdep(cpu_regs[reg], cpu_T[0], cpu_T[1]);
3876 case 0x2f5: /* pext Gy, By, Ey */
3877 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3878 || !(s->prefix & PREFIX_VEX)
3882 ot = mo_64_32(s->dflag);
3883 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3884 /* Note that by zero-extending the mask operand, we
3885 automatically handle zero-extending the result. */
3887 tcg_gen_mov_tl(cpu_T[1], cpu_regs[s->vex_v]);
3889 tcg_gen_ext32u_tl(cpu_T[1], cpu_regs[s->vex_v]);
3891 gen_helper_pext(cpu_regs[reg], cpu_T[0], cpu_T[1]);
3894 case 0x1f6: /* adcx Gy, Ey */
3895 case 0x2f6: /* adox Gy, Ey */
3896 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_ADX)) {
3899 TCGv carry_in, carry_out, zero;
3902 ot = mo_64_32(s->dflag);
3903 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3905 /* Re-use the carry-out from a previous round. */
3906 TCGV_UNUSED(carry_in);
3907 carry_out = (b == 0x1f6 ? cpu_cc_dst : cpu_cc_src2);
3911 carry_in = cpu_cc_dst;
3912 end_op = CC_OP_ADCX;
3914 end_op = CC_OP_ADCOX;
3919 end_op = CC_OP_ADCOX;
3921 carry_in = cpu_cc_src2;
3922 end_op = CC_OP_ADOX;
3926 end_op = CC_OP_ADCOX;
3927 carry_in = carry_out;
3930 end_op = (b == 0x1f6 ? CC_OP_ADCX : CC_OP_ADOX);
3933 /* If we can't reuse carry-out, get it out of EFLAGS. */
3934 if (TCGV_IS_UNUSED(carry_in)) {
3935 if (s->cc_op != CC_OP_ADCX && s->cc_op != CC_OP_ADOX) {
3936 gen_compute_eflags(s);
3938 carry_in = cpu_tmp0;
3939 tcg_gen_shri_tl(carry_in, cpu_cc_src,
3940 ctz32(b == 0x1f6 ? CC_C : CC_O));
3941 tcg_gen_andi_tl(carry_in, carry_in, 1);
3945 #ifdef TARGET_X86_64
3947 /* If we know TL is 64-bit, and we want a 32-bit
3948 result, just do everything in 64-bit arithmetic. */
3949 tcg_gen_ext32u_i64(cpu_regs[reg], cpu_regs[reg]);
3950 tcg_gen_ext32u_i64(cpu_T[0], cpu_T[0]);
3951 tcg_gen_add_i64(cpu_T[0], cpu_T[0], cpu_regs[reg]);
3952 tcg_gen_add_i64(cpu_T[0], cpu_T[0], carry_in);
3953 tcg_gen_ext32u_i64(cpu_regs[reg], cpu_T[0]);
3954 tcg_gen_shri_i64(carry_out, cpu_T[0], 32);
3958 /* Otherwise compute the carry-out in two steps. */
3959 zero = tcg_const_tl(0);
3960 tcg_gen_add2_tl(cpu_T[0], carry_out,
3963 tcg_gen_add2_tl(cpu_regs[reg], carry_out,
3964 cpu_regs[reg], carry_out,
3966 tcg_temp_free(zero);
3969 set_cc_op(s, end_op);
3973 case 0x1f7: /* shlx Gy, Ey, By */
3974 case 0x2f7: /* sarx Gy, Ey, By */
3975 case 0x3f7: /* shrx Gy, Ey, By */
3976 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3977 || !(s->prefix & PREFIX_VEX)
3981 ot = mo_64_32(s->dflag);
3982 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3984 tcg_gen_andi_tl(cpu_T[1], cpu_regs[s->vex_v], 63);
3986 tcg_gen_andi_tl(cpu_T[1], cpu_regs[s->vex_v], 31);
3989 tcg_gen_shl_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3990 } else if (b == 0x2f7) {
3992 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
3994 tcg_gen_sar_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3997 tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
3999 tcg_gen_shr_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4001 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
4007 case 0x3f3: /* Group 17 */
4008 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
4009 || !(s->prefix & PREFIX_VEX)
4013 ot = mo_64_32(s->dflag);
4014 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4017 case 1: /* blsr By,Ey */
4018 tcg_gen_neg_tl(cpu_T[1], cpu_T[0]);
4019 tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4020 gen_op_mov_reg_v(ot, s->vex_v, cpu_T[0]);
4021 gen_op_update2_cc();
4022 set_cc_op(s, CC_OP_BMILGB + ot);
4025 case 2: /* blsmsk By,Ey */
4026 tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
4027 tcg_gen_subi_tl(cpu_T[0], cpu_T[0], 1);
4028 tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_cc_src);
4029 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4030 set_cc_op(s, CC_OP_BMILGB + ot);
4033 case 3: /* blsi By, Ey */
4034 tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
4035 tcg_gen_subi_tl(cpu_T[0], cpu_T[0], 1);
4036 tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_cc_src);
4037 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4038 set_cc_op(s, CC_OP_BMILGB + ot);
4054 modrm = cpu_ldub_code(env, s->pc++);
4056 reg = ((modrm >> 3) & 7) | rex_r;
4057 mod = (modrm >> 6) & 3;
4062 sse_fn_eppi = sse_op_table7[b].op[b1];
4066 if (!(s->cpuid_ext_features & sse_op_table7[b].ext_mask))
4069 if (sse_fn_eppi == SSE_SPECIAL) {
4070 ot = mo_64_32(s->dflag);
4071 rm = (modrm & 7) | REX_B(s);
4073 gen_lea_modrm(env, s, modrm);
4074 reg = ((modrm >> 3) & 7) | rex_r;
4075 val = cpu_ldub_code(env, s->pc++);
4077 case 0x14: /* pextrb */
4078 tcg_gen_ld8u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
4079 xmm_regs[reg].XMM_B(val & 15)));
4081 gen_op_mov_reg_v(ot, rm, cpu_T[0]);
4083 tcg_gen_qemu_st_tl(cpu_T[0], cpu_A0,
4084 s->mem_index, MO_UB);
4087 case 0x15: /* pextrw */
4088 tcg_gen_ld16u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
4089 xmm_regs[reg].XMM_W(val & 7)));
4091 gen_op_mov_reg_v(ot, rm, cpu_T[0]);
4093 tcg_gen_qemu_st_tl(cpu_T[0], cpu_A0,
4094 s->mem_index, MO_LEUW);
4098 if (ot == MO_32) { /* pextrd */
4099 tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
4100 offsetof(CPUX86State,
4101 xmm_regs[reg].XMM_L(val & 3)));
4103 tcg_gen_extu_i32_tl(cpu_regs[rm], cpu_tmp2_i32);
4105 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
4106 s->mem_index, MO_LEUL);
4108 } else { /* pextrq */
4109 #ifdef TARGET_X86_64
4110 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
4111 offsetof(CPUX86State,
4112 xmm_regs[reg].XMM_Q(val & 1)));
4114 tcg_gen_mov_i64(cpu_regs[rm], cpu_tmp1_i64);
4116 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0,
4117 s->mem_index, MO_LEQ);
4124 case 0x17: /* extractps */
4125 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
4126 xmm_regs[reg].XMM_L(val & 3)));
4128 gen_op_mov_reg_v(ot, rm, cpu_T[0]);
4130 tcg_gen_qemu_st_tl(cpu_T[0], cpu_A0,
4131 s->mem_index, MO_LEUL);
4134 case 0x20: /* pinsrb */
4136 gen_op_mov_v_reg(MO_32, cpu_T[0], rm);
4138 tcg_gen_qemu_ld_tl(cpu_T[0], cpu_A0,
4139 s->mem_index, MO_UB);
4141 tcg_gen_st8_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
4142 xmm_regs[reg].XMM_B(val & 15)));
4144 case 0x21: /* insertps */
4146 tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
4147 offsetof(CPUX86State,xmm_regs[rm]
4148 .XMM_L((val >> 6) & 3)));
4150 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
4151 s->mem_index, MO_LEUL);
4153 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
4154 offsetof(CPUX86State,xmm_regs[reg]
4155 .XMM_L((val >> 4) & 3)));
4157 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4158 cpu_env, offsetof(CPUX86State,
4159 xmm_regs[reg].XMM_L(0)));
4161 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4162 cpu_env, offsetof(CPUX86State,
4163 xmm_regs[reg].XMM_L(1)));
4165 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4166 cpu_env, offsetof(CPUX86State,
4167 xmm_regs[reg].XMM_L(2)));
4169 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4170 cpu_env, offsetof(CPUX86State,
4171 xmm_regs[reg].XMM_L(3)));
4174 if (ot == MO_32) { /* pinsrd */
4176 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[rm]);
4178 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
4179 s->mem_index, MO_LEUL);
4181 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
4182 offsetof(CPUX86State,
4183 xmm_regs[reg].XMM_L(val & 3)));
4184 } else { /* pinsrq */
4185 #ifdef TARGET_X86_64
4187 gen_op_mov_v_reg(ot, cpu_tmp1_i64, rm);
4189 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0,
4190 s->mem_index, MO_LEQ);
4192 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
4193 offsetof(CPUX86State,
4194 xmm_regs[reg].XMM_Q(val & 1)));
4205 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
4207 op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
4209 op2_offset = offsetof(CPUX86State,xmm_t0);
4210 gen_lea_modrm(env, s, modrm);
4211 gen_ldo_env_A0(s, op2_offset);
4214 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
4216 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
4218 op2_offset = offsetof(CPUX86State,mmx_t0);
4219 gen_lea_modrm(env, s, modrm);
4220 gen_ldq_env_A0(s, op2_offset);
4223 val = cpu_ldub_code(env, s->pc++);
4225 if ((b & 0xfc) == 0x60) { /* pcmpXstrX */
4226 set_cc_op(s, CC_OP_EFLAGS);
4228 if (s->dflag == MO_64) {
4229 /* The helper must use entire 64-bit gp registers */
4234 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4235 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4236 sse_fn_eppi(cpu_env, cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
4240 /* Various integer extensions at 0f 3a f[0-f]. */
4241 b = modrm | (b1 << 8);
4242 modrm = cpu_ldub_code(env, s->pc++);
4243 reg = ((modrm >> 3) & 7) | rex_r;
4246 case 0x3f0: /* rorx Gy,Ey, Ib */
4247 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
4248 || !(s->prefix & PREFIX_VEX)
4252 ot = mo_64_32(s->dflag);
4253 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4254 b = cpu_ldub_code(env, s->pc++);
4256 tcg_gen_rotri_tl(cpu_T[0], cpu_T[0], b & 63);
4258 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4259 tcg_gen_rotri_i32(cpu_tmp2_i32, cpu_tmp2_i32, b & 31);
4260 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
4262 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
4274 /* generic MMX or SSE operation */
4276 case 0x70: /* pshufx insn */
4277 case 0xc6: /* pshufx insn */
4278 case 0xc2: /* compare insns */
4285 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
4289 gen_lea_modrm(env, s, modrm);
4290 op2_offset = offsetof(CPUX86State,xmm_t0);
4296 /* Most sse scalar operations. */
4299 } else if (b1 == 3) {
4304 case 0x2e: /* ucomis[sd] */
4305 case 0x2f: /* comis[sd] */
4317 gen_op_ld_v(s, MO_32, cpu_T[0], cpu_A0);
4318 tcg_gen_st32_tl(cpu_T[0], cpu_env,
4319 offsetof(CPUX86State,xmm_t0.XMM_L(0)));
4323 gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.XMM_D(0)));
4326 /* 128 bit access */
4327 gen_ldo_env_A0(s, op2_offset);
4331 rm = (modrm & 7) | REX_B(s);
4332 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
4335 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
4337 gen_lea_modrm(env, s, modrm);
4338 op2_offset = offsetof(CPUX86State,mmx_t0);
4339 gen_ldq_env_A0(s, op2_offset);
4342 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
4346 case 0x0f: /* 3DNow! data insns */
4347 if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW))
4349 val = cpu_ldub_code(env, s->pc++);
4350 sse_fn_epp = sse_op_table5[val];
4354 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4355 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4356 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4358 case 0x70: /* pshufx insn */
4359 case 0xc6: /* pshufx insn */
4360 val = cpu_ldub_code(env, s->pc++);
4361 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4362 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4363 /* XXX: introduce a new table? */
4364 sse_fn_ppi = (SSEFunc_0_ppi)sse_fn_epp;
4365 sse_fn_ppi(cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
4369 val = cpu_ldub_code(env, s->pc++);
4372 sse_fn_epp = sse_op_table4[val][b1];
4374 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4375 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4376 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4379 /* maskmov : we must prepare A0 */
4382 tcg_gen_mov_tl(cpu_A0, cpu_regs[R_EDI]);
4383 gen_extu(s->aflag, cpu_A0);
4384 gen_add_A0_ds_seg(s);
4386 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4387 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4388 /* XXX: introduce a new table? */
4389 sse_fn_eppt = (SSEFunc_0_eppt)sse_fn_epp;
4390 sse_fn_eppt(cpu_env, cpu_ptr0, cpu_ptr1, cpu_A0);
4393 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4394 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4395 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4398 if (b == 0x2e || b == 0x2f) {
4399 set_cc_op(s, CC_OP_EFLAGS);
4404 /* convert one instruction. s->is_jmp is set if the translation must
4405 be stopped. Return the next pc value */
4406 static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
4407 target_ulong pc_start)
4411 TCGMemOp ot, aflag, dflag;
4412 int modrm, reg, rm, mod, op, opreg, val;
4413 target_ulong next_eip, tval;
4416 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
4417 tcg_gen_debug_insn_start(pc_start);
4424 #ifdef TARGET_X86_64
4429 s->rip_offset = 0; /* for relative ip address */
4433 b = cpu_ldub_code(env, s->pc);
4435 /* Collect prefixes. */
4438 prefixes |= PREFIX_REPZ;
4441 prefixes |= PREFIX_REPNZ;
4444 prefixes |= PREFIX_LOCK;
4465 prefixes |= PREFIX_DATA;
4468 prefixes |= PREFIX_ADR;
4470 #ifdef TARGET_X86_64
4474 rex_w = (b >> 3) & 1;
4475 rex_r = (b & 0x4) << 1;
4476 s->rex_x = (b & 0x2) << 2;
4477 REX_B(s) = (b & 0x1) << 3;
4478 x86_64_hregs = 1; /* select uniform byte register addressing */
4483 case 0xc5: /* 2-byte VEX */
4484 case 0xc4: /* 3-byte VEX */
4485 /* VEX prefixes cannot be used except in 32-bit mode.
4486 Otherwise the instruction is LES or LDS. */
4487 if (s->code32 && !s->vm86) {
4488 static const int pp_prefix[4] = {
4489 0, PREFIX_DATA, PREFIX_REPZ, PREFIX_REPNZ
4491 int vex3, vex2 = cpu_ldub_code(env, s->pc);
4493 if (!CODE64(s) && (vex2 & 0xc0) != 0xc0) {
4494 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4495 otherwise the instruction is LES or LDS. */
4500 /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
4501 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ
4502 | PREFIX_LOCK | PREFIX_DATA)) {
4505 #ifdef TARGET_X86_64
4510 rex_r = (~vex2 >> 4) & 8;
4513 b = cpu_ldub_code(env, s->pc++);
4515 #ifdef TARGET_X86_64
4516 s->rex_x = (~vex2 >> 3) & 8;
4517 s->rex_b = (~vex2 >> 2) & 8;
4519 vex3 = cpu_ldub_code(env, s->pc++);
4520 rex_w = (vex3 >> 7) & 1;
4521 switch (vex2 & 0x1f) {
4522 case 0x01: /* Implied 0f leading opcode bytes. */
4523 b = cpu_ldub_code(env, s->pc++) | 0x100;
4525 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4528 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4531 default: /* Reserved for future use. */
4535 s->vex_v = (~vex3 >> 3) & 0xf;
4536 s->vex_l = (vex3 >> 2) & 1;
4537 prefixes |= pp_prefix[vex3 & 3] | PREFIX_VEX;
4542 /* Post-process prefixes. */
4544 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit
4545 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4546 over 0x66 if both are present. */
4547 dflag = (rex_w > 0 ? MO_64 : prefixes & PREFIX_DATA ? MO_16 : MO_32);
4548 /* In 64-bit mode, 0x67 selects 32-bit addressing. */
4549 aflag = (prefixes & PREFIX_ADR ? MO_32 : MO_64);
4551 /* In 16/32-bit mode, 0x66 selects the opposite data size. */
4552 if (s->code32 ^ ((prefixes & PREFIX_DATA) != 0)) {
4557 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */
4558 if (s->code32 ^ ((prefixes & PREFIX_ADR) != 0)) {
4565 s->prefix = prefixes;
4569 /* lock generation */
4570 if (prefixes & PREFIX_LOCK)
4573 /* now check op code */
4577 /**************************/
4578 /* extended op code */
4579 b = cpu_ldub_code(env, s->pc++) | 0x100;
4582 /**************************/
4597 ot = mo_b_d(b, dflag);
4600 case 0: /* OP Ev, Gv */
4601 modrm = cpu_ldub_code(env, s->pc++);
4602 reg = ((modrm >> 3) & 7) | rex_r;
4603 mod = (modrm >> 6) & 3;
4604 rm = (modrm & 7) | REX_B(s);
4606 gen_lea_modrm(env, s, modrm);
4608 } else if (op == OP_XORL && rm == reg) {
4610 /* xor reg, reg optimisation */
4611 set_cc_op(s, CC_OP_CLR);
4612 tcg_gen_movi_tl(cpu_T[0], 0);
4613 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
4618 gen_op_mov_v_reg(ot, cpu_T[1], reg);
4619 gen_op(s, op, ot, opreg);
4621 case 1: /* OP Gv, Ev */
4622 modrm = cpu_ldub_code(env, s->pc++);
4623 mod = (modrm >> 6) & 3;
4624 reg = ((modrm >> 3) & 7) | rex_r;
4625 rm = (modrm & 7) | REX_B(s);
4627 gen_lea_modrm(env, s, modrm);
4628 gen_op_ld_v(s, ot, cpu_T[1], cpu_A0);
4629 } else if (op == OP_XORL && rm == reg) {
4632 gen_op_mov_v_reg(ot, cpu_T[1], rm);
4634 gen_op(s, op, ot, reg);
4636 case 2: /* OP A, Iv */
4637 val = insn_get(env, s, ot);
4638 tcg_gen_movi_tl(cpu_T[1], val);
4639 gen_op(s, op, ot, OR_EAX);
4648 case 0x80: /* GRP1 */
4654 ot = mo_b_d(b, dflag);
4656 modrm = cpu_ldub_code(env, s->pc++);
4657 mod = (modrm >> 6) & 3;
4658 rm = (modrm & 7) | REX_B(s);
4659 op = (modrm >> 3) & 7;
4665 s->rip_offset = insn_const_size(ot);
4666 gen_lea_modrm(env, s, modrm);
4677 val = insn_get(env, s, ot);
4680 val = (int8_t)insn_get(env, s, MO_8);
4683 tcg_gen_movi_tl(cpu_T[1], val);
4684 gen_op(s, op, ot, opreg);
4688 /**************************/
4689 /* inc, dec, and other misc arith */
4690 case 0x40 ... 0x47: /* inc Gv */
4692 gen_inc(s, ot, OR_EAX + (b & 7), 1);
4694 case 0x48 ... 0x4f: /* dec Gv */
4696 gen_inc(s, ot, OR_EAX + (b & 7), -1);
4698 case 0xf6: /* GRP3 */
4700 ot = mo_b_d(b, dflag);
4702 modrm = cpu_ldub_code(env, s->pc++);
4703 mod = (modrm >> 6) & 3;
4704 rm = (modrm & 7) | REX_B(s);
4705 op = (modrm >> 3) & 7;
4708 s->rip_offset = insn_const_size(ot);
4709 gen_lea_modrm(env, s, modrm);
4710 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
4712 gen_op_mov_v_reg(ot, cpu_T[0], rm);
4717 val = insn_get(env, s, ot);
4718 tcg_gen_movi_tl(cpu_T[1], val);
4719 gen_op_testl_T0_T1_cc();
4720 set_cc_op(s, CC_OP_LOGICB + ot);
4723 tcg_gen_not_tl(cpu_T[0], cpu_T[0]);
4725 gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
4727 gen_op_mov_reg_v(ot, rm, cpu_T[0]);
4731 tcg_gen_neg_tl(cpu_T[0], cpu_T[0]);
4733 gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
4735 gen_op_mov_reg_v(ot, rm, cpu_T[0]);
4737 gen_op_update_neg_cc();
4738 set_cc_op(s, CC_OP_SUBB + ot);
4743 gen_op_mov_v_reg(MO_8, cpu_T[1], R_EAX);
4744 tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]);
4745 tcg_gen_ext8u_tl(cpu_T[1], cpu_T[1]);
4746 /* XXX: use 32 bit mul which could be faster */
4747 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4748 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T[0]);
4749 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4750 tcg_gen_andi_tl(cpu_cc_src, cpu_T[0], 0xff00);
4751 set_cc_op(s, CC_OP_MULB);
4754 gen_op_mov_v_reg(MO_16, cpu_T[1], R_EAX);
4755 tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
4756 tcg_gen_ext16u_tl(cpu_T[1], cpu_T[1]);
4757 /* XXX: use 32 bit mul which could be faster */
4758 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4759 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T[0]);
4760 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4761 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 16);
4762 gen_op_mov_reg_v(MO_16, R_EDX, cpu_T[0]);
4763 tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
4764 set_cc_op(s, CC_OP_MULW);
4768 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4769 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_regs[R_EAX]);
4770 tcg_gen_mulu2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
4771 cpu_tmp2_i32, cpu_tmp3_i32);
4772 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], cpu_tmp2_i32);
4773 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], cpu_tmp3_i32);
4774 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4775 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]);
4776 set_cc_op(s, CC_OP_MULL);
4778 #ifdef TARGET_X86_64
4780 tcg_gen_mulu2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX],
4781 cpu_T[0], cpu_regs[R_EAX]);
4782 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4783 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]);
4784 set_cc_op(s, CC_OP_MULQ);
4792 gen_op_mov_v_reg(MO_8, cpu_T[1], R_EAX);
4793 tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
4794 tcg_gen_ext8s_tl(cpu_T[1], cpu_T[1]);
4795 /* XXX: use 32 bit mul which could be faster */
4796 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4797 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T[0]);
4798 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4799 tcg_gen_ext8s_tl(cpu_tmp0, cpu_T[0]);
4800 tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4801 set_cc_op(s, CC_OP_MULB);
4804 gen_op_mov_v_reg(MO_16, cpu_T[1], R_EAX);
4805 tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4806 tcg_gen_ext16s_tl(cpu_T[1], cpu_T[1]);
4807 /* XXX: use 32 bit mul which could be faster */
4808 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4809 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T[0]);
4810 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
4811 tcg_gen_ext16s_tl(cpu_tmp0, cpu_T[0]);
4812 tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
4813 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 16);
4814 gen_op_mov_reg_v(MO_16, R_EDX, cpu_T[0]);
4815 set_cc_op(s, CC_OP_MULW);
4819 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4820 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_regs[R_EAX]);
4821 tcg_gen_muls2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
4822 cpu_tmp2_i32, cpu_tmp3_i32);
4823 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], cpu_tmp2_i32);
4824 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], cpu_tmp3_i32);
4825 tcg_gen_sari_i32(cpu_tmp2_i32, cpu_tmp2_i32, 31);
4826 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4827 tcg_gen_sub_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
4828 tcg_gen_extu_i32_tl(cpu_cc_src, cpu_tmp2_i32);
4829 set_cc_op(s, CC_OP_MULL);
4831 #ifdef TARGET_X86_64
4833 tcg_gen_muls2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX],
4834 cpu_T[0], cpu_regs[R_EAX]);
4835 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4836 tcg_gen_sari_tl(cpu_cc_src, cpu_regs[R_EAX], 63);
4837 tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, cpu_regs[R_EDX]);
4838 set_cc_op(s, CC_OP_MULQ);
4846 gen_jmp_im(pc_start - s->cs_base);
4847 gen_helper_divb_AL(cpu_env, cpu_T[0]);
4850 gen_jmp_im(pc_start - s->cs_base);
4851 gen_helper_divw_AX(cpu_env, cpu_T[0]);
4855 gen_jmp_im(pc_start - s->cs_base);
4856 gen_helper_divl_EAX(cpu_env, cpu_T[0]);
4858 #ifdef TARGET_X86_64
4860 gen_jmp_im(pc_start - s->cs_base);
4861 gen_helper_divq_EAX(cpu_env, cpu_T[0]);
4869 gen_jmp_im(pc_start - s->cs_base);
4870 gen_helper_idivb_AL(cpu_env, cpu_T[0]);
4873 gen_jmp_im(pc_start - s->cs_base);
4874 gen_helper_idivw_AX(cpu_env, cpu_T[0]);
4878 gen_jmp_im(pc_start - s->cs_base);
4879 gen_helper_idivl_EAX(cpu_env, cpu_T[0]);
4881 #ifdef TARGET_X86_64
4883 gen_jmp_im(pc_start - s->cs_base);
4884 gen_helper_idivq_EAX(cpu_env, cpu_T[0]);
4894 case 0xfe: /* GRP4 */
4895 case 0xff: /* GRP5 */
4896 ot = mo_b_d(b, dflag);
4898 modrm = cpu_ldub_code(env, s->pc++);
4899 mod = (modrm >> 6) & 3;
4900 rm = (modrm & 7) | REX_B(s);
4901 op = (modrm >> 3) & 7;
4902 if (op >= 2 && b == 0xfe) {
4906 if (op == 2 || op == 4) {
4907 /* operand size for jumps is 64 bit */
4909 } else if (op == 3 || op == 5) {
4910 ot = dflag != MO_16 ? MO_32 + (rex_w == 1) : MO_16;
4911 } else if (op == 6) {
4912 /* default push size is 64 bit */
4913 ot = mo_pushpop(s, dflag);
4917 gen_lea_modrm(env, s, modrm);
4918 if (op >= 2 && op != 3 && op != 5)
4919 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
4921 gen_op_mov_v_reg(ot, cpu_T[0], rm);
4925 case 0: /* inc Ev */
4930 gen_inc(s, ot, opreg, 1);
4932 case 1: /* dec Ev */
4937 gen_inc(s, ot, opreg, -1);
4939 case 2: /* call Ev */
4940 /* XXX: optimize if memory (no 'and' is necessary) */
4941 if (dflag == MO_16) {
4942 tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
4944 next_eip = s->pc - s->cs_base;
4945 tcg_gen_movi_tl(cpu_T[1], next_eip);
4946 gen_push_v(s, cpu_T[1]);
4947 gen_op_jmp_v(cpu_T[0]);
4950 case 3: /* lcall Ev */
4951 gen_op_ld_v(s, ot, cpu_T[1], cpu_A0);
4952 gen_add_A0_im(s, 1 << ot);
4953 gen_op_ld_v(s, MO_16, cpu_T[0], cpu_A0);
4955 if (s->pe && !s->vm86) {
4956 gen_update_cc_op(s);
4957 gen_jmp_im(pc_start - s->cs_base);
4958 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4959 gen_helper_lcall_protected(cpu_env, cpu_tmp2_i32, cpu_T[1],
4960 tcg_const_i32(dflag - 1),
4961 tcg_const_i32(s->pc - pc_start));
4963 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4964 gen_helper_lcall_real(cpu_env, cpu_tmp2_i32, cpu_T[1],
4965 tcg_const_i32(dflag - 1),
4966 tcg_const_i32(s->pc - s->cs_base));
4970 case 4: /* jmp Ev */
4971 if (dflag == MO_16) {
4972 tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
4974 gen_op_jmp_v(cpu_T[0]);
4977 case 5: /* ljmp Ev */
4978 gen_op_ld_v(s, ot, cpu_T[1], cpu_A0);
4979 gen_add_A0_im(s, 1 << ot);
4980 gen_op_ld_v(s, MO_16, cpu_T[0], cpu_A0);
4982 if (s->pe && !s->vm86) {
4983 gen_update_cc_op(s);
4984 gen_jmp_im(pc_start - s->cs_base);
4985 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4986 gen_helper_ljmp_protected(cpu_env, cpu_tmp2_i32, cpu_T[1],
4987 tcg_const_i32(s->pc - pc_start));
4989 gen_op_movl_seg_T0_vm(R_CS);
4990 gen_op_jmp_v(cpu_T[1]);
4994 case 6: /* push Ev */
4995 gen_push_v(s, cpu_T[0]);
5002 case 0x84: /* test Ev, Gv */
5004 ot = mo_b_d(b, dflag);
5006 modrm = cpu_ldub_code(env, s->pc++);
5007 reg = ((modrm >> 3) & 7) | rex_r;
5009 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5010 gen_op_mov_v_reg(ot, cpu_T[1], reg);
5011 gen_op_testl_T0_T1_cc();
5012 set_cc_op(s, CC_OP_LOGICB + ot);
5015 case 0xa8: /* test eAX, Iv */
5017 ot = mo_b_d(b, dflag);
5018 val = insn_get(env, s, ot);
5020 gen_op_mov_v_reg(ot, cpu_T[0], OR_EAX);
5021 tcg_gen_movi_tl(cpu_T[1], val);
5022 gen_op_testl_T0_T1_cc();
5023 set_cc_op(s, CC_OP_LOGICB + ot);
5026 case 0x98: /* CWDE/CBW */
5028 #ifdef TARGET_X86_64
5030 gen_op_mov_v_reg(MO_32, cpu_T[0], R_EAX);
5031 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
5032 gen_op_mov_reg_v(MO_64, R_EAX, cpu_T[0]);
5036 gen_op_mov_v_reg(MO_16, cpu_T[0], R_EAX);
5037 tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
5038 gen_op_mov_reg_v(MO_32, R_EAX, cpu_T[0]);
5041 gen_op_mov_v_reg(MO_8, cpu_T[0], R_EAX);
5042 tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
5043 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T[0]);
5049 case 0x99: /* CDQ/CWD */
5051 #ifdef TARGET_X86_64
5053 gen_op_mov_v_reg(MO_64, cpu_T[0], R_EAX);
5054 tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 63);
5055 gen_op_mov_reg_v(MO_64, R_EDX, cpu_T[0]);
5059 gen_op_mov_v_reg(MO_32, cpu_T[0], R_EAX);
5060 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
5061 tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 31);
5062 gen_op_mov_reg_v(MO_32, R_EDX, cpu_T[0]);
5065 gen_op_mov_v_reg(MO_16, cpu_T[0], R_EAX);
5066 tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
5067 tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 15);
5068 gen_op_mov_reg_v(MO_16, R_EDX, cpu_T[0]);
5074 case 0x1af: /* imul Gv, Ev */
5075 case 0x69: /* imul Gv, Ev, I */
5078 modrm = cpu_ldub_code(env, s->pc++);
5079 reg = ((modrm >> 3) & 7) | rex_r;
5081 s->rip_offset = insn_const_size(ot);
5084 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5086 val = insn_get(env, s, ot);
5087 tcg_gen_movi_tl(cpu_T[1], val);
5088 } else if (b == 0x6b) {
5089 val = (int8_t)insn_get(env, s, MO_8);
5090 tcg_gen_movi_tl(cpu_T[1], val);
5092 gen_op_mov_v_reg(ot, cpu_T[1], reg);
5095 #ifdef TARGET_X86_64
5097 tcg_gen_muls2_i64(cpu_regs[reg], cpu_T[1], cpu_T[0], cpu_T[1]);
5098 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]);
5099 tcg_gen_sari_tl(cpu_cc_src, cpu_cc_dst, 63);
5100 tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, cpu_T[1]);
5104 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5105 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
5106 tcg_gen_muls2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
5107 cpu_tmp2_i32, cpu_tmp3_i32);
5108 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
5109 tcg_gen_sari_i32(cpu_tmp2_i32, cpu_tmp2_i32, 31);
5110 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]);
5111 tcg_gen_sub_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
5112 tcg_gen_extu_i32_tl(cpu_cc_src, cpu_tmp2_i32);
5115 tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
5116 tcg_gen_ext16s_tl(cpu_T[1], cpu_T[1]);
5117 /* XXX: use 32 bit mul which could be faster */
5118 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
5119 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
5120 tcg_gen_ext16s_tl(cpu_tmp0, cpu_T[0]);
5121 tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
5122 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
5125 set_cc_op(s, CC_OP_MULB + ot);
5128 case 0x1c1: /* xadd Ev, Gv */
5129 ot = mo_b_d(b, dflag);
5130 modrm = cpu_ldub_code(env, s->pc++);
5131 reg = ((modrm >> 3) & 7) | rex_r;
5132 mod = (modrm >> 6) & 3;
5134 rm = (modrm & 7) | REX_B(s);
5135 gen_op_mov_v_reg(ot, cpu_T[0], reg);
5136 gen_op_mov_v_reg(ot, cpu_T[1], rm);
5137 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
5138 gen_op_mov_reg_v(ot, reg, cpu_T[1]);
5139 gen_op_mov_reg_v(ot, rm, cpu_T[0]);
5141 gen_lea_modrm(env, s, modrm);
5142 gen_op_mov_v_reg(ot, cpu_T[0], reg);
5143 gen_op_ld_v(s, ot, cpu_T[1], cpu_A0);
5144 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
5145 gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
5146 gen_op_mov_reg_v(ot, reg, cpu_T[1]);
5148 gen_op_update2_cc();
5149 set_cc_op(s, CC_OP_ADDB + ot);
5152 case 0x1b1: /* cmpxchg Ev, Gv */
5155 TCGv t0, t1, t2, a0;
5157 ot = mo_b_d(b, dflag);
5158 modrm = cpu_ldub_code(env, s->pc++);
5159 reg = ((modrm >> 3) & 7) | rex_r;
5160 mod = (modrm >> 6) & 3;
5161 t0 = tcg_temp_local_new();
5162 t1 = tcg_temp_local_new();
5163 t2 = tcg_temp_local_new();
5164 a0 = tcg_temp_local_new();
5165 gen_op_mov_v_reg(ot, t1, reg);
5167 rm = (modrm & 7) | REX_B(s);
5168 gen_op_mov_v_reg(ot, t0, rm);
5170 gen_lea_modrm(env, s, modrm);
5171 tcg_gen_mov_tl(a0, cpu_A0);
5172 gen_op_ld_v(s, ot, t0, a0);
5173 rm = 0; /* avoid warning */
5175 label1 = gen_new_label();
5176 tcg_gen_mov_tl(t2, cpu_regs[R_EAX]);
5179 tcg_gen_brcond_tl(TCG_COND_EQ, t2, t0, label1);
5180 label2 = gen_new_label();
5182 gen_op_mov_reg_v(ot, R_EAX, t0);
5184 gen_set_label(label1);
5185 gen_op_mov_reg_v(ot, rm, t1);
5187 /* perform no-op store cycle like physical cpu; must be
5188 before changing accumulator to ensure idempotency if
5189 the store faults and the instruction is restarted */
5190 gen_op_st_v(s, ot, t0, a0);
5191 gen_op_mov_reg_v(ot, R_EAX, t0);
5193 gen_set_label(label1);
5194 gen_op_st_v(s, ot, t1, a0);
5196 gen_set_label(label2);
5197 tcg_gen_mov_tl(cpu_cc_src, t0);
5198 tcg_gen_mov_tl(cpu_cc_srcT, t2);
5199 tcg_gen_sub_tl(cpu_cc_dst, t2, t0);
5200 set_cc_op(s, CC_OP_SUBB + ot);
5207 case 0x1c7: /* cmpxchg8b */
5208 modrm = cpu_ldub_code(env, s->pc++);
5209 mod = (modrm >> 6) & 3;
5210 if ((mod == 3) || ((modrm & 0x38) != 0x8))
5212 #ifdef TARGET_X86_64
5213 if (dflag == MO_64) {
5214 if (!(s->cpuid_ext_features & CPUID_EXT_CX16))
5216 gen_jmp_im(pc_start - s->cs_base);
5217 gen_update_cc_op(s);
5218 gen_lea_modrm(env, s, modrm);
5219 gen_helper_cmpxchg16b(cpu_env, cpu_A0);
5223 if (!(s->cpuid_features & CPUID_CX8))
5225 gen_jmp_im(pc_start - s->cs_base);
5226 gen_update_cc_op(s);
5227 gen_lea_modrm(env, s, modrm);
5228 gen_helper_cmpxchg8b(cpu_env, cpu_A0);
5230 set_cc_op(s, CC_OP_EFLAGS);
5233 /**************************/
5235 case 0x50 ... 0x57: /* push */
5236 gen_op_mov_v_reg(MO_32, cpu_T[0], (b & 7) | REX_B(s));
5237 gen_push_v(s, cpu_T[0]);
5239 case 0x58 ... 0x5f: /* pop */
5241 /* NOTE: order is important for pop %sp */
5242 gen_pop_update(s, ot);
5243 gen_op_mov_reg_v(ot, (b & 7) | REX_B(s), cpu_T[0]);
5245 case 0x60: /* pusha */
5250 case 0x61: /* popa */
5255 case 0x68: /* push Iv */
5257 ot = mo_pushpop(s, dflag);
5259 val = insn_get(env, s, ot);
5261 val = (int8_t)insn_get(env, s, MO_8);
5262 tcg_gen_movi_tl(cpu_T[0], val);
5263 gen_push_v(s, cpu_T[0]);
5265 case 0x8f: /* pop Ev */
5266 modrm = cpu_ldub_code(env, s->pc++);
5267 mod = (modrm >> 6) & 3;
5270 /* NOTE: order is important for pop %sp */
5271 gen_pop_update(s, ot);
5272 rm = (modrm & 7) | REX_B(s);
5273 gen_op_mov_reg_v(ot, rm, cpu_T[0]);
5275 /* NOTE: order is important too for MMU exceptions */
5276 s->popl_esp_hack = 1 << ot;
5277 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5278 s->popl_esp_hack = 0;
5279 gen_pop_update(s, ot);
5282 case 0xc8: /* enter */
5285 val = cpu_lduw_code(env, s->pc);
5287 level = cpu_ldub_code(env, s->pc++);
5288 gen_enter(s, val, level);
5291 case 0xc9: /* leave */
5292 /* XXX: exception not precise (ESP is updated before potential exception) */
5294 gen_op_mov_v_reg(MO_64, cpu_T[0], R_EBP);
5295 gen_op_mov_reg_v(MO_64, R_ESP, cpu_T[0]);
5296 } else if (s->ss32) {
5297 gen_op_mov_v_reg(MO_32, cpu_T[0], R_EBP);
5298 gen_op_mov_reg_v(MO_32, R_ESP, cpu_T[0]);
5300 gen_op_mov_v_reg(MO_16, cpu_T[0], R_EBP);
5301 gen_op_mov_reg_v(MO_16, R_ESP, cpu_T[0]);
5304 gen_op_mov_reg_v(ot, R_EBP, cpu_T[0]);
5305 gen_pop_update(s, ot);
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_T[0]);
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_T[0]);
5321 case 0x07: /* pop es */
5322 case 0x17: /* pop ss */
5323 case 0x1f: /* pop ds */
5328 gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
5329 gen_pop_update(s, ot);
5331 /* if reg == SS, inhibit interrupts/trace. */
5332 /* If several instructions disable interrupts, only the
5334 if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
5335 gen_helper_set_inhibit_irq(cpu_env);
5339 gen_jmp_im(s->pc - s->cs_base);
5343 case 0x1a1: /* pop fs */
5344 case 0x1a9: /* pop gs */
5346 gen_movl_seg_T0(s, (b >> 3) & 7, pc_start - s->cs_base);
5347 gen_pop_update(s, ot);
5349 gen_jmp_im(s->pc - s->cs_base);
5354 /**************************/
5357 case 0x89: /* mov Gv, Ev */
5358 ot = mo_b_d(b, dflag);
5359 modrm = cpu_ldub_code(env, s->pc++);
5360 reg = ((modrm >> 3) & 7) | rex_r;
5362 /* generate a generic store */
5363 gen_ldst_modrm(env, s, modrm, ot, reg, 1);
5366 case 0xc7: /* mov Ev, Iv */
5367 ot = mo_b_d(b, dflag);
5368 modrm = cpu_ldub_code(env, s->pc++);
5369 mod = (modrm >> 6) & 3;
5371 s->rip_offset = insn_const_size(ot);
5372 gen_lea_modrm(env, s, modrm);
5374 val = insn_get(env, s, ot);
5375 tcg_gen_movi_tl(cpu_T[0], val);
5377 gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
5379 gen_op_mov_reg_v(ot, (modrm & 7) | REX_B(s), cpu_T[0]);
5383 case 0x8b: /* mov Ev, Gv */
5384 ot = mo_b_d(b, dflag);
5385 modrm = cpu_ldub_code(env, s->pc++);
5386 reg = ((modrm >> 3) & 7) | rex_r;
5388 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5389 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
5391 case 0x8e: /* mov seg, Gv */
5392 modrm = cpu_ldub_code(env, s->pc++);
5393 reg = (modrm >> 3) & 7;
5394 if (reg >= 6 || reg == R_CS)
5396 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
5397 gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
5399 /* if reg == SS, inhibit interrupts/trace */
5400 /* If several instructions disable interrupts, only the
5402 if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
5403 gen_helper_set_inhibit_irq(cpu_env);
5407 gen_jmp_im(s->pc - s->cs_base);
5411 case 0x8c: /* mov Gv, seg */
5412 modrm = cpu_ldub_code(env, s->pc++);
5413 reg = (modrm >> 3) & 7;
5414 mod = (modrm >> 6) & 3;
5417 gen_op_movl_T0_seg(reg);
5418 ot = mod == 3 ? dflag : MO_16;
5419 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5422 case 0x1b6: /* movzbS Gv, Eb */
5423 case 0x1b7: /* movzwS Gv, Eb */
5424 case 0x1be: /* movsbS Gv, Eb */
5425 case 0x1bf: /* movswS Gv, Eb */
5430 /* d_ot is the size of destination */
5432 /* ot is the size of source */
5433 ot = (b & 1) + MO_8;
5434 /* s_ot is the sign+size of source */
5435 s_ot = b & 8 ? MO_SIGN | ot : ot;
5437 modrm = cpu_ldub_code(env, s->pc++);
5438 reg = ((modrm >> 3) & 7) | rex_r;
5439 mod = (modrm >> 6) & 3;
5440 rm = (modrm & 7) | REX_B(s);
5443 gen_op_mov_v_reg(ot, cpu_T[0], rm);
5446 tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]);
5449 tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
5452 tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
5456 tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
5459 gen_op_mov_reg_v(d_ot, reg, cpu_T[0]);
5461 gen_lea_modrm(env, s, modrm);
5462 gen_op_ld_v(s, s_ot, cpu_T[0], cpu_A0);
5463 gen_op_mov_reg_v(d_ot, reg, cpu_T[0]);
5468 case 0x8d: /* lea */
5470 modrm = cpu_ldub_code(env, s->pc++);
5471 mod = (modrm >> 6) & 3;
5474 reg = ((modrm >> 3) & 7) | rex_r;
5475 /* we must ensure that no segment is added */
5479 gen_lea_modrm(env, s, modrm);
5481 gen_op_mov_reg_v(ot, reg, cpu_A0);
5484 case 0xa0: /* mov EAX, Ov */
5486 case 0xa2: /* mov Ov, EAX */
5489 target_ulong offset_addr;
5491 ot = mo_b_d(b, dflag);
5493 #ifdef TARGET_X86_64
5495 offset_addr = cpu_ldq_code(env, s->pc);
5500 offset_addr = insn_get(env, s, s->aflag);
5503 tcg_gen_movi_tl(cpu_A0, offset_addr);
5504 gen_add_A0_ds_seg(s);
5506 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
5507 gen_op_mov_reg_v(ot, R_EAX, cpu_T[0]);
5509 gen_op_mov_v_reg(ot, cpu_T[0], R_EAX);
5510 gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
5514 case 0xd7: /* xlat */
5515 tcg_gen_mov_tl(cpu_A0, cpu_regs[R_EBX]);
5516 tcg_gen_ext8u_tl(cpu_T[0], cpu_regs[R_EAX]);
5517 tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T[0]);
5518 gen_extu(s->aflag, cpu_A0);
5519 gen_add_A0_ds_seg(s);
5520 gen_op_ld_v(s, MO_8, cpu_T[0], cpu_A0);
5521 gen_op_mov_reg_v(MO_8, R_EAX, cpu_T[0]);
5523 case 0xb0 ... 0xb7: /* mov R, Ib */
5524 val = insn_get(env, s, MO_8);
5525 tcg_gen_movi_tl(cpu_T[0], val);
5526 gen_op_mov_reg_v(MO_8, (b & 7) | REX_B(s), cpu_T[0]);
5528 case 0xb8 ... 0xbf: /* mov R, Iv */
5529 #ifdef TARGET_X86_64
5530 if (dflag == MO_64) {
5533 tmp = cpu_ldq_code(env, s->pc);
5535 reg = (b & 7) | REX_B(s);
5536 tcg_gen_movi_tl(cpu_T[0], tmp);
5537 gen_op_mov_reg_v(MO_64, reg, cpu_T[0]);
5542 val = insn_get(env, s, ot);
5543 reg = (b & 7) | REX_B(s);
5544 tcg_gen_movi_tl(cpu_T[0], val);
5545 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
5549 case 0x91 ... 0x97: /* xchg R, EAX */
5552 reg = (b & 7) | REX_B(s);
5556 case 0x87: /* xchg Ev, Gv */
5557 ot = mo_b_d(b, dflag);
5558 modrm = cpu_ldub_code(env, s->pc++);
5559 reg = ((modrm >> 3) & 7) | rex_r;
5560 mod = (modrm >> 6) & 3;
5562 rm = (modrm & 7) | REX_B(s);
5564 gen_op_mov_v_reg(ot, cpu_T[0], reg);
5565 gen_op_mov_v_reg(ot, cpu_T[1], rm);
5566 gen_op_mov_reg_v(ot, rm, cpu_T[0]);
5567 gen_op_mov_reg_v(ot, reg, cpu_T[1]);
5569 gen_lea_modrm(env, s, modrm);
5570 gen_op_mov_v_reg(ot, cpu_T[0], reg);
5571 /* for xchg, lock is implicit */
5572 if (!(prefixes & PREFIX_LOCK))
5574 gen_op_ld_v(s, ot, cpu_T[1], cpu_A0);
5575 gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
5576 if (!(prefixes & PREFIX_LOCK))
5577 gen_helper_unlock();
5578 gen_op_mov_reg_v(ot, reg, cpu_T[1]);
5581 case 0xc4: /* les Gv */
5582 /* In CODE64 this is VEX3; see above. */
5585 case 0xc5: /* lds Gv */
5586 /* In CODE64 this is VEX2; see above. */
5589 case 0x1b2: /* lss Gv */
5592 case 0x1b4: /* lfs Gv */
5595 case 0x1b5: /* lgs Gv */
5598 ot = dflag != MO_16 ? MO_32 : MO_16;
5599 modrm = cpu_ldub_code(env, s->pc++);
5600 reg = ((modrm >> 3) & 7) | rex_r;
5601 mod = (modrm >> 6) & 3;
5604 gen_lea_modrm(env, s, modrm);
5605 gen_op_ld_v(s, ot, cpu_T[1], cpu_A0);
5606 gen_add_A0_im(s, 1 << ot);
5607 /* load the segment first to handle exceptions properly */
5608 gen_op_ld_v(s, MO_16, cpu_T[0], cpu_A0);
5609 gen_movl_seg_T0(s, op, pc_start - s->cs_base);
5610 /* then put the data */
5611 gen_op_mov_reg_v(ot, reg, cpu_T[1]);
5613 gen_jmp_im(s->pc - s->cs_base);
5618 /************************/
5626 ot = mo_b_d(b, dflag);
5627 modrm = cpu_ldub_code(env, s->pc++);
5628 mod = (modrm >> 6) & 3;
5629 op = (modrm >> 3) & 7;
5635 gen_lea_modrm(env, s, modrm);
5638 opreg = (modrm & 7) | REX_B(s);
5643 gen_shift(s, op, ot, opreg, OR_ECX);
5646 shift = cpu_ldub_code(env, s->pc++);
5648 gen_shifti(s, op, ot, opreg, shift);
5663 case 0x1a4: /* shld imm */
5667 case 0x1a5: /* shld cl */
5671 case 0x1ac: /* shrd imm */
5675 case 0x1ad: /* shrd cl */
5680 modrm = cpu_ldub_code(env, s->pc++);
5681 mod = (modrm >> 6) & 3;
5682 rm = (modrm & 7) | REX_B(s);
5683 reg = ((modrm >> 3) & 7) | rex_r;
5685 gen_lea_modrm(env, s, modrm);
5690 gen_op_mov_v_reg(ot, cpu_T[1], reg);
5693 TCGv imm = tcg_const_tl(cpu_ldub_code(env, s->pc++));
5694 gen_shiftd_rm_T1(s, ot, opreg, op, imm);
5697 gen_shiftd_rm_T1(s, ot, opreg, op, cpu_regs[R_ECX]);
5701 /************************/
5704 if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
5705 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5706 /* XXX: what to do if illegal op ? */
5707 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
5710 modrm = cpu_ldub_code(env, s->pc++);
5711 mod = (modrm >> 6) & 3;
5713 op = ((b & 7) << 3) | ((modrm >> 3) & 7);
5716 gen_lea_modrm(env, s, modrm);
5718 case 0x00 ... 0x07: /* fxxxs */
5719 case 0x10 ... 0x17: /* fixxxl */
5720 case 0x20 ... 0x27: /* fxxxl */
5721 case 0x30 ... 0x37: /* fixxx */
5728 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5729 s->mem_index, MO_LEUL);
5730 gen_helper_flds_FT0(cpu_env, cpu_tmp2_i32);
5733 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5734 s->mem_index, MO_LEUL);
5735 gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32);
5738 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0,
5739 s->mem_index, MO_LEQ);
5740 gen_helper_fldl_FT0(cpu_env, cpu_tmp1_i64);
5744 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5745 s->mem_index, MO_LESW);
5746 gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32);
5750 gen_helper_fp_arith_ST0_FT0(op1);
5752 /* fcomp needs pop */
5753 gen_helper_fpop(cpu_env);
5757 case 0x08: /* flds */
5758 case 0x0a: /* fsts */
5759 case 0x0b: /* fstps */
5760 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5761 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5762 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5767 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5768 s->mem_index, MO_LEUL);
5769 gen_helper_flds_ST0(cpu_env, cpu_tmp2_i32);
5772 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5773 s->mem_index, MO_LEUL);
5774 gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32);
5777 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0,
5778 s->mem_index, MO_LEQ);
5779 gen_helper_fldl_ST0(cpu_env, cpu_tmp1_i64);
5783 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5784 s->mem_index, MO_LESW);
5785 gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32);
5790 /* XXX: the corresponding CPUID bit must be tested ! */
5793 gen_helper_fisttl_ST0(cpu_tmp2_i32, cpu_env);
5794 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5795 s->mem_index, MO_LEUL);
5798 gen_helper_fisttll_ST0(cpu_tmp1_i64, cpu_env);
5799 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0,
5800 s->mem_index, MO_LEQ);
5804 gen_helper_fistt_ST0(cpu_tmp2_i32, cpu_env);
5805 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5806 s->mem_index, MO_LEUW);
5809 gen_helper_fpop(cpu_env);
5814 gen_helper_fsts_ST0(cpu_tmp2_i32, cpu_env);
5815 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5816 s->mem_index, MO_LEUL);
5819 gen_helper_fistl_ST0(cpu_tmp2_i32, cpu_env);
5820 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5821 s->mem_index, MO_LEUL);
5824 gen_helper_fstl_ST0(cpu_tmp1_i64, cpu_env);
5825 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0,
5826 s->mem_index, MO_LEQ);
5830 gen_helper_fist_ST0(cpu_tmp2_i32, cpu_env);
5831 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5832 s->mem_index, MO_LEUW);
5836 gen_helper_fpop(cpu_env);
5840 case 0x0c: /* fldenv mem */
5841 gen_update_cc_op(s);
5842 gen_jmp_im(pc_start - s->cs_base);
5843 gen_helper_fldenv(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5845 case 0x0d: /* fldcw mem */
5846 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5847 s->mem_index, MO_LEUW);
5848 gen_helper_fldcw(cpu_env, cpu_tmp2_i32);
5850 case 0x0e: /* fnstenv mem */
5851 gen_update_cc_op(s);
5852 gen_jmp_im(pc_start - s->cs_base);
5853 gen_helper_fstenv(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5855 case 0x0f: /* fnstcw mem */
5856 gen_helper_fnstcw(cpu_tmp2_i32, cpu_env);
5857 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5858 s->mem_index, MO_LEUW);
5860 case 0x1d: /* fldt mem */
5861 gen_update_cc_op(s);
5862 gen_jmp_im(pc_start - s->cs_base);
5863 gen_helper_fldt_ST0(cpu_env, cpu_A0);
5865 case 0x1f: /* fstpt mem */
5866 gen_update_cc_op(s);
5867 gen_jmp_im(pc_start - s->cs_base);
5868 gen_helper_fstt_ST0(cpu_env, cpu_A0);
5869 gen_helper_fpop(cpu_env);
5871 case 0x2c: /* frstor mem */
5872 gen_update_cc_op(s);
5873 gen_jmp_im(pc_start - s->cs_base);
5874 gen_helper_frstor(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5876 case 0x2e: /* fnsave mem */
5877 gen_update_cc_op(s);
5878 gen_jmp_im(pc_start - s->cs_base);
5879 gen_helper_fsave(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5881 case 0x2f: /* fnstsw mem */
5882 gen_helper_fnstsw(cpu_tmp2_i32, cpu_env);
5883 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5884 s->mem_index, MO_LEUW);
5886 case 0x3c: /* fbld */
5887 gen_update_cc_op(s);
5888 gen_jmp_im(pc_start - s->cs_base);
5889 gen_helper_fbld_ST0(cpu_env, cpu_A0);
5891 case 0x3e: /* fbstp */
5892 gen_update_cc_op(s);
5893 gen_jmp_im(pc_start - s->cs_base);
5894 gen_helper_fbst_ST0(cpu_env, cpu_A0);
5895 gen_helper_fpop(cpu_env);
5897 case 0x3d: /* fildll */
5898 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
5899 gen_helper_fildll_ST0(cpu_env, cpu_tmp1_i64);
5901 case 0x3f: /* fistpll */
5902 gen_helper_fistll_ST0(cpu_tmp1_i64, cpu_env);
5903 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
5904 gen_helper_fpop(cpu_env);
5910 /* register float ops */
5914 case 0x08: /* fld sti */
5915 gen_helper_fpush(cpu_env);
5916 gen_helper_fmov_ST0_STN(cpu_env,
5917 tcg_const_i32((opreg + 1) & 7));
5919 case 0x09: /* fxchg sti */
5920 case 0x29: /* fxchg4 sti, undocumented op */
5921 case 0x39: /* fxchg7 sti, undocumented op */
5922 gen_helper_fxchg_ST0_STN(cpu_env, tcg_const_i32(opreg));
5924 case 0x0a: /* grp d9/2 */
5927 /* check exceptions (FreeBSD FPU probe) */
5928 gen_update_cc_op(s);
5929 gen_jmp_im(pc_start - s->cs_base);
5930 gen_helper_fwait(cpu_env);
5936 case 0x0c: /* grp d9/4 */
5939 gen_helper_fchs_ST0(cpu_env);
5942 gen_helper_fabs_ST0(cpu_env);
5945 gen_helper_fldz_FT0(cpu_env);
5946 gen_helper_fcom_ST0_FT0(cpu_env);
5949 gen_helper_fxam_ST0(cpu_env);
5955 case 0x0d: /* grp d9/5 */
5959 gen_helper_fpush(cpu_env);
5960 gen_helper_fld1_ST0(cpu_env);
5963 gen_helper_fpush(cpu_env);
5964 gen_helper_fldl2t_ST0(cpu_env);
5967 gen_helper_fpush(cpu_env);
5968 gen_helper_fldl2e_ST0(cpu_env);
5971 gen_helper_fpush(cpu_env);
5972 gen_helper_fldpi_ST0(cpu_env);
5975 gen_helper_fpush(cpu_env);
5976 gen_helper_fldlg2_ST0(cpu_env);
5979 gen_helper_fpush(cpu_env);
5980 gen_helper_fldln2_ST0(cpu_env);
5983 gen_helper_fpush(cpu_env);
5984 gen_helper_fldz_ST0(cpu_env);
5991 case 0x0e: /* grp d9/6 */
5994 gen_helper_f2xm1(cpu_env);
5997 gen_helper_fyl2x(cpu_env);
6000 gen_helper_fptan(cpu_env);
6002 case 3: /* fpatan */
6003 gen_helper_fpatan(cpu_env);
6005 case 4: /* fxtract */
6006 gen_helper_fxtract(cpu_env);
6008 case 5: /* fprem1 */
6009 gen_helper_fprem1(cpu_env);
6011 case 6: /* fdecstp */
6012 gen_helper_fdecstp(cpu_env);
6015 case 7: /* fincstp */
6016 gen_helper_fincstp(cpu_env);
6020 case 0x0f: /* grp d9/7 */
6023 gen_helper_fprem(cpu_env);
6025 case 1: /* fyl2xp1 */
6026 gen_helper_fyl2xp1(cpu_env);
6029 gen_helper_fsqrt(cpu_env);
6031 case 3: /* fsincos */
6032 gen_helper_fsincos(cpu_env);
6034 case 5: /* fscale */
6035 gen_helper_fscale(cpu_env);
6037 case 4: /* frndint */
6038 gen_helper_frndint(cpu_env);
6041 gen_helper_fsin(cpu_env);
6045 gen_helper_fcos(cpu_env);
6049 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6050 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6051 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6057 gen_helper_fp_arith_STN_ST0(op1, opreg);
6059 gen_helper_fpop(cpu_env);
6061 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6062 gen_helper_fp_arith_ST0_FT0(op1);
6066 case 0x02: /* fcom */
6067 case 0x22: /* fcom2, undocumented op */
6068 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6069 gen_helper_fcom_ST0_FT0(cpu_env);
6071 case 0x03: /* fcomp */
6072 case 0x23: /* fcomp3, undocumented op */
6073 case 0x32: /* fcomp5, undocumented op */
6074 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6075 gen_helper_fcom_ST0_FT0(cpu_env);
6076 gen_helper_fpop(cpu_env);
6078 case 0x15: /* da/5 */
6080 case 1: /* fucompp */
6081 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
6082 gen_helper_fucom_ST0_FT0(cpu_env);
6083 gen_helper_fpop(cpu_env);
6084 gen_helper_fpop(cpu_env);
6092 case 0: /* feni (287 only, just do nop here) */
6094 case 1: /* fdisi (287 only, just do nop here) */
6097 gen_helper_fclex(cpu_env);
6099 case 3: /* fninit */
6100 gen_helper_fninit(cpu_env);
6102 case 4: /* fsetpm (287 only, just do nop here) */
6108 case 0x1d: /* fucomi */
6109 if (!(s->cpuid_features & CPUID_CMOV)) {
6112 gen_update_cc_op(s);
6113 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6114 gen_helper_fucomi_ST0_FT0(cpu_env);
6115 set_cc_op(s, CC_OP_EFLAGS);
6117 case 0x1e: /* fcomi */
6118 if (!(s->cpuid_features & CPUID_CMOV)) {
6121 gen_update_cc_op(s);
6122 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6123 gen_helper_fcomi_ST0_FT0(cpu_env);
6124 set_cc_op(s, CC_OP_EFLAGS);
6126 case 0x28: /* ffree sti */
6127 gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
6129 case 0x2a: /* fst sti */
6130 gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
6132 case 0x2b: /* fstp sti */
6133 case 0x0b: /* fstp1 sti, undocumented op */
6134 case 0x3a: /* fstp8 sti, undocumented op */
6135 case 0x3b: /* fstp9 sti, undocumented op */
6136 gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
6137 gen_helper_fpop(cpu_env);
6139 case 0x2c: /* fucom st(i) */
6140 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6141 gen_helper_fucom_ST0_FT0(cpu_env);
6143 case 0x2d: /* fucomp st(i) */
6144 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6145 gen_helper_fucom_ST0_FT0(cpu_env);
6146 gen_helper_fpop(cpu_env);
6148 case 0x33: /* de/3 */
6150 case 1: /* fcompp */
6151 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
6152 gen_helper_fcom_ST0_FT0(cpu_env);
6153 gen_helper_fpop(cpu_env);
6154 gen_helper_fpop(cpu_env);
6160 case 0x38: /* ffreep sti, undocumented op */
6161 gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
6162 gen_helper_fpop(cpu_env);
6164 case 0x3c: /* df/4 */
6167 gen_helper_fnstsw(cpu_tmp2_i32, cpu_env);
6168 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
6169 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T[0]);
6175 case 0x3d: /* fucomip */
6176 if (!(s->cpuid_features & CPUID_CMOV)) {
6179 gen_update_cc_op(s);
6180 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6181 gen_helper_fucomi_ST0_FT0(cpu_env);
6182 gen_helper_fpop(cpu_env);
6183 set_cc_op(s, CC_OP_EFLAGS);
6185 case 0x3e: /* fcomip */
6186 if (!(s->cpuid_features & CPUID_CMOV)) {
6189 gen_update_cc_op(s);
6190 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6191 gen_helper_fcomi_ST0_FT0(cpu_env);
6192 gen_helper_fpop(cpu_env);
6193 set_cc_op(s, CC_OP_EFLAGS);
6195 case 0x10 ... 0x13: /* fcmovxx */
6199 static const uint8_t fcmov_cc[8] = {
6206 if (!(s->cpuid_features & CPUID_CMOV)) {
6209 op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1);
6210 l1 = gen_new_label();
6211 gen_jcc1_noeob(s, op1, l1);
6212 gen_helper_fmov_ST0_STN(cpu_env, tcg_const_i32(opreg));
6221 /************************/
6224 case 0xa4: /* movsS */
6226 ot = mo_b_d(b, dflag);
6227 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6228 gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6234 case 0xaa: /* stosS */
6236 ot = mo_b_d(b, dflag);
6237 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6238 gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6243 case 0xac: /* lodsS */
6245 ot = mo_b_d(b, dflag);
6246 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6247 gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6252 case 0xae: /* scasS */
6254 ot = mo_b_d(b, dflag);
6255 if (prefixes & PREFIX_REPNZ) {
6256 gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
6257 } else if (prefixes & PREFIX_REPZ) {
6258 gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
6264 case 0xa6: /* cmpsS */
6266 ot = mo_b_d(b, dflag);
6267 if (prefixes & PREFIX_REPNZ) {
6268 gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
6269 } else if (prefixes & PREFIX_REPZ) {
6270 gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
6275 case 0x6c: /* insS */
6277 ot = mo_b_d32(b, dflag);
6278 tcg_gen_ext16u_tl(cpu_T[0], cpu_regs[R_EDX]);
6279 gen_check_io(s, ot, pc_start - s->cs_base,
6280 SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) | 4);
6281 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6282 gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6285 if (s->tb->cflags & CF_USE_ICOUNT) {
6286 gen_jmp(s, s->pc - s->cs_base);
6290 case 0x6e: /* outsS */
6292 ot = mo_b_d32(b, dflag);
6293 tcg_gen_ext16u_tl(cpu_T[0], cpu_regs[R_EDX]);
6294 gen_check_io(s, ot, pc_start - s->cs_base,
6295 svm_is_rep(prefixes) | 4);
6296 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6297 gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6300 if (s->tb->cflags & CF_USE_ICOUNT) {
6301 gen_jmp(s, s->pc - s->cs_base);
6306 /************************/
6311 ot = mo_b_d32(b, dflag);
6312 val = cpu_ldub_code(env, s->pc++);
6313 tcg_gen_movi_tl(cpu_T[0], val);
6314 gen_check_io(s, ot, pc_start - s->cs_base,
6315 SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6316 if (s->tb->cflags & CF_USE_ICOUNT) {
6319 tcg_gen_movi_i32(cpu_tmp2_i32, val);
6320 gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32);
6321 gen_op_mov_reg_v(ot, R_EAX, cpu_T[1]);
6322 if (s->tb->cflags & CF_USE_ICOUNT) {
6324 gen_jmp(s, s->pc - s->cs_base);
6329 ot = mo_b_d32(b, dflag);
6330 val = cpu_ldub_code(env, s->pc++);
6331 tcg_gen_movi_tl(cpu_T[0], val);
6332 gen_check_io(s, ot, pc_start - s->cs_base,
6333 svm_is_rep(prefixes));
6334 gen_op_mov_v_reg(ot, cpu_T[1], R_EAX);
6336 if (s->tb->cflags & CF_USE_ICOUNT) {
6339 tcg_gen_movi_i32(cpu_tmp2_i32, val);
6340 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
6341 gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6342 if (s->tb->cflags & CF_USE_ICOUNT) {
6344 gen_jmp(s, s->pc - s->cs_base);
6349 ot = mo_b_d32(b, dflag);
6350 tcg_gen_ext16u_tl(cpu_T[0], cpu_regs[R_EDX]);
6351 gen_check_io(s, ot, pc_start - s->cs_base,
6352 SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6353 if (s->tb->cflags & CF_USE_ICOUNT) {
6356 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6357 gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32);
6358 gen_op_mov_reg_v(ot, R_EAX, cpu_T[1]);
6359 if (s->tb->cflags & CF_USE_ICOUNT) {
6361 gen_jmp(s, s->pc - s->cs_base);
6366 ot = mo_b_d32(b, dflag);
6367 tcg_gen_ext16u_tl(cpu_T[0], cpu_regs[R_EDX]);
6368 gen_check_io(s, ot, pc_start - s->cs_base,
6369 svm_is_rep(prefixes));
6370 gen_op_mov_v_reg(ot, cpu_T[1], R_EAX);
6372 if (s->tb->cflags & CF_USE_ICOUNT) {
6375 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6376 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
6377 gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6378 if (s->tb->cflags & CF_USE_ICOUNT) {
6380 gen_jmp(s, s->pc - s->cs_base);
6384 /************************/
6386 case 0xc2: /* ret im */
6387 val = cpu_ldsw_code(env, s->pc);
6390 gen_stack_update(s, val + (1 << ot));
6391 /* Note that gen_pop_T0 uses a zero-extending load. */
6392 gen_op_jmp_v(cpu_T[0]);
6395 case 0xc3: /* ret */
6397 gen_pop_update(s, ot);
6398 /* Note that gen_pop_T0 uses a zero-extending load. */
6399 gen_op_jmp_v(cpu_T[0]);
6402 case 0xca: /* lret im */
6403 val = cpu_ldsw_code(env, s->pc);
6406 if (s->pe && !s->vm86) {
6407 gen_update_cc_op(s);
6408 gen_jmp_im(pc_start - s->cs_base);
6409 gen_helper_lret_protected(cpu_env, tcg_const_i32(dflag - 1),
6410 tcg_const_i32(val));
6414 gen_op_ld_v(s, dflag, cpu_T[0], cpu_A0);
6415 /* NOTE: keeping EIP updated is not a problem in case of
6417 gen_op_jmp_v(cpu_T[0]);
6419 gen_op_addl_A0_im(1 << dflag);
6420 gen_op_ld_v(s, dflag, cpu_T[0], cpu_A0);
6421 gen_op_movl_seg_T0_vm(R_CS);
6422 /* add stack offset */
6423 gen_stack_update(s, val + (2 << dflag));
6427 case 0xcb: /* lret */
6430 case 0xcf: /* iret */
6431 gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET);
6434 gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
6435 set_cc_op(s, CC_OP_EFLAGS);
6436 } else if (s->vm86) {
6438 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6440 gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
6441 set_cc_op(s, CC_OP_EFLAGS);
6444 gen_update_cc_op(s);
6445 gen_jmp_im(pc_start - s->cs_base);
6446 gen_helper_iret_protected(cpu_env, tcg_const_i32(dflag - 1),
6447 tcg_const_i32(s->pc - s->cs_base));
6448 set_cc_op(s, CC_OP_EFLAGS);
6452 case 0xe8: /* call im */
6454 if (dflag != MO_16) {
6455 tval = (int32_t)insn_get(env, s, MO_32);
6457 tval = (int16_t)insn_get(env, s, MO_16);
6459 next_eip = s->pc - s->cs_base;
6461 if (dflag == MO_16) {
6463 } else if (!CODE64(s)) {
6466 tcg_gen_movi_tl(cpu_T[0], next_eip);
6467 gen_push_v(s, cpu_T[0]);
6471 case 0x9a: /* lcall im */
6473 unsigned int selector, offset;
6478 offset = insn_get(env, s, ot);
6479 selector = insn_get(env, s, MO_16);
6481 tcg_gen_movi_tl(cpu_T[0], selector);
6482 tcg_gen_movi_tl(cpu_T[1], offset);
6485 case 0xe9: /* jmp im */
6486 if (dflag != MO_16) {
6487 tval = (int32_t)insn_get(env, s, MO_32);
6489 tval = (int16_t)insn_get(env, s, MO_16);
6491 tval += s->pc - s->cs_base;
6492 if (dflag == MO_16) {
6494 } else if (!CODE64(s)) {
6499 case 0xea: /* ljmp im */
6501 unsigned int selector, offset;
6506 offset = insn_get(env, s, ot);
6507 selector = insn_get(env, s, MO_16);
6509 tcg_gen_movi_tl(cpu_T[0], selector);
6510 tcg_gen_movi_tl(cpu_T[1], offset);
6513 case 0xeb: /* jmp Jb */
6514 tval = (int8_t)insn_get(env, s, MO_8);
6515 tval += s->pc - s->cs_base;
6516 if (dflag == MO_16) {
6521 case 0x70 ... 0x7f: /* jcc Jb */
6522 tval = (int8_t)insn_get(env, s, MO_8);
6524 case 0x180 ... 0x18f: /* jcc Jv */
6525 if (dflag != MO_16) {
6526 tval = (int32_t)insn_get(env, s, MO_32);
6528 tval = (int16_t)insn_get(env, s, MO_16);
6531 next_eip = s->pc - s->cs_base;
6533 if (dflag == MO_16) {
6536 gen_jcc(s, b, tval, next_eip);
6539 case 0x190 ... 0x19f: /* setcc Gv */
6540 modrm = cpu_ldub_code(env, s->pc++);
6541 gen_setcc1(s, b, cpu_T[0]);
6542 gen_ldst_modrm(env, s, modrm, MO_8, OR_TMP0, 1);
6544 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6545 if (!(s->cpuid_features & CPUID_CMOV)) {
6549 modrm = cpu_ldub_code(env, s->pc++);
6550 reg = ((modrm >> 3) & 7) | rex_r;
6551 gen_cmovcc1(env, s, ot, b, modrm, reg);
6554 /************************/
6556 case 0x9c: /* pushf */
6557 gen_svm_check_intercept(s, pc_start, SVM_EXIT_PUSHF);
6558 if (s->vm86 && s->iopl != 3) {
6559 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6561 gen_update_cc_op(s);
6562 gen_helper_read_eflags(cpu_T[0], cpu_env);
6563 gen_push_v(s, cpu_T[0]);
6566 case 0x9d: /* popf */
6567 gen_svm_check_intercept(s, pc_start, SVM_EXIT_POPF);
6568 if (s->vm86 && s->iopl != 3) {
6569 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6573 if (dflag != MO_16) {
6574 gen_helper_write_eflags(cpu_env, cpu_T[0],
6575 tcg_const_i32((TF_MASK | AC_MASK |
6580 gen_helper_write_eflags(cpu_env, cpu_T[0],
6581 tcg_const_i32((TF_MASK | AC_MASK |
6583 IF_MASK | IOPL_MASK)
6587 if (s->cpl <= s->iopl) {
6588 if (dflag != MO_16) {
6589 gen_helper_write_eflags(cpu_env, cpu_T[0],
6590 tcg_const_i32((TF_MASK |
6596 gen_helper_write_eflags(cpu_env, cpu_T[0],
6597 tcg_const_i32((TF_MASK |
6605 if (dflag != MO_16) {
6606 gen_helper_write_eflags(cpu_env, cpu_T[0],
6607 tcg_const_i32((TF_MASK | AC_MASK |
6608 ID_MASK | NT_MASK)));
6610 gen_helper_write_eflags(cpu_env, cpu_T[0],
6611 tcg_const_i32((TF_MASK | AC_MASK |
6617 gen_pop_update(s, ot);
6618 set_cc_op(s, CC_OP_EFLAGS);
6619 /* abort translation because TF/AC flag may change */
6620 gen_jmp_im(s->pc - s->cs_base);
6624 case 0x9e: /* sahf */
6625 if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6627 gen_op_mov_v_reg(MO_8, cpu_T[0], R_AH);
6628 gen_compute_eflags(s);
6629 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O);
6630 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], CC_S | CC_Z | CC_A | CC_P | CC_C);
6631 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_T[0]);
6633 case 0x9f: /* lahf */
6634 if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6636 gen_compute_eflags(s);
6637 /* Note: gen_compute_eflags() only gives the condition codes */
6638 tcg_gen_ori_tl(cpu_T[0], cpu_cc_src, 0x02);
6639 gen_op_mov_reg_v(MO_8, R_AH, cpu_T[0]);
6641 case 0xf5: /* cmc */
6642 gen_compute_eflags(s);
6643 tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6645 case 0xf8: /* clc */
6646 gen_compute_eflags(s);
6647 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C);
6649 case 0xf9: /* stc */
6650 gen_compute_eflags(s);
6651 tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6653 case 0xfc: /* cld */
6654 tcg_gen_movi_i32(cpu_tmp2_i32, 1);
6655 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, df));
6657 case 0xfd: /* std */
6658 tcg_gen_movi_i32(cpu_tmp2_i32, -1);
6659 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, df));
6662 /************************/
6663 /* bit operations */
6664 case 0x1ba: /* bt/bts/btr/btc Gv, im */
6666 modrm = cpu_ldub_code(env, s->pc++);
6667 op = (modrm >> 3) & 7;
6668 mod = (modrm >> 6) & 3;
6669 rm = (modrm & 7) | REX_B(s);
6672 gen_lea_modrm(env, s, modrm);
6673 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
6675 gen_op_mov_v_reg(ot, cpu_T[0], rm);
6678 val = cpu_ldub_code(env, s->pc++);
6679 tcg_gen_movi_tl(cpu_T[1], val);
6684 case 0x1a3: /* bt Gv, Ev */
6687 case 0x1ab: /* bts */
6690 case 0x1b3: /* btr */
6693 case 0x1bb: /* btc */
6697 modrm = cpu_ldub_code(env, s->pc++);
6698 reg = ((modrm >> 3) & 7) | rex_r;
6699 mod = (modrm >> 6) & 3;
6700 rm = (modrm & 7) | REX_B(s);
6701 gen_op_mov_v_reg(MO_32, cpu_T[1], reg);
6703 gen_lea_modrm(env, s, modrm);
6704 /* specific case: we need to add a displacement */
6705 gen_exts(ot, cpu_T[1]);
6706 tcg_gen_sari_tl(cpu_tmp0, cpu_T[1], 3 + ot);
6707 tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, ot);
6708 tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
6709 gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);
6711 gen_op_mov_v_reg(ot, cpu_T[0], rm);
6714 tcg_gen_andi_tl(cpu_T[1], cpu_T[1], (1 << (3 + ot)) - 1);
6715 tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
6720 tcg_gen_movi_tl(cpu_tmp0, 1);
6721 tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
6722 tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
6725 tcg_gen_movi_tl(cpu_tmp0, 1);
6726 tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
6727 tcg_gen_andc_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
6731 tcg_gen_movi_tl(cpu_tmp0, 1);
6732 tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
6733 tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
6738 gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
6740 gen_op_mov_reg_v(ot, rm, cpu_T[0]);
6744 /* Delay all CC updates until after the store above. Note that
6745 C is the result of the test, Z is unchanged, and the others
6746 are all undefined. */
6748 case CC_OP_MULB ... CC_OP_MULQ:
6749 case CC_OP_ADDB ... CC_OP_ADDQ:
6750 case CC_OP_ADCB ... CC_OP_ADCQ:
6751 case CC_OP_SUBB ... CC_OP_SUBQ:
6752 case CC_OP_SBBB ... CC_OP_SBBQ:
6753 case CC_OP_LOGICB ... CC_OP_LOGICQ:
6754 case CC_OP_INCB ... CC_OP_INCQ:
6755 case CC_OP_DECB ... CC_OP_DECQ:
6756 case CC_OP_SHLB ... CC_OP_SHLQ:
6757 case CC_OP_SARB ... CC_OP_SARQ:
6758 case CC_OP_BMILGB ... CC_OP_BMILGQ:
6759 /* Z was going to be computed from the non-zero status of CC_DST.
6760 We can get that same Z value (and the new C value) by leaving
6761 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
6763 tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
6764 set_cc_op(s, ((s->cc_op - CC_OP_MULB) & 3) + CC_OP_SARB);
6767 /* Otherwise, generate EFLAGS and replace the C bit. */
6768 gen_compute_eflags(s);
6769 tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, cpu_tmp4,
6774 case 0x1bc: /* bsf / tzcnt */
6775 case 0x1bd: /* bsr / lzcnt */
6777 modrm = cpu_ldub_code(env, s->pc++);
6778 reg = ((modrm >> 3) & 7) | rex_r;
6779 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
6780 gen_extu(ot, cpu_T[0]);
6782 /* Note that lzcnt and tzcnt are in different extensions. */
6783 if ((prefixes & PREFIX_REPZ)
6785 ? s->cpuid_ext3_features & CPUID_EXT3_ABM
6786 : s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)) {
6788 tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
6790 /* For lzcnt, reduce the target_ulong result by the
6791 number of zeros that we expect to find at the top. */
6792 gen_helper_clz(cpu_T[0], cpu_T[0]);
6793 tcg_gen_subi_tl(cpu_T[0], cpu_T[0], TARGET_LONG_BITS - size);
6795 /* For tzcnt, a zero input must return the operand size:
6796 force all bits outside the operand size to 1. */
6797 target_ulong mask = (target_ulong)-2 << (size - 1);
6798 tcg_gen_ori_tl(cpu_T[0], cpu_T[0], mask);
6799 gen_helper_ctz(cpu_T[0], cpu_T[0]);
6801 /* For lzcnt/tzcnt, C and Z bits are defined and are
6802 related to the result. */
6803 gen_op_update1_cc();
6804 set_cc_op(s, CC_OP_BMILGB + ot);
6806 /* For bsr/bsf, only the Z bit is defined and it is related
6807 to the input and not the result. */
6808 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
6809 set_cc_op(s, CC_OP_LOGICB + ot);
6811 /* For bsr, return the bit index of the first 1 bit,
6812 not the count of leading zeros. */
6813 gen_helper_clz(cpu_T[0], cpu_T[0]);
6814 tcg_gen_xori_tl(cpu_T[0], cpu_T[0], TARGET_LONG_BITS - 1);
6816 gen_helper_ctz(cpu_T[0], cpu_T[0]);
6818 /* ??? The manual says that the output is undefined when the
6819 input is zero, but real hardware leaves it unchanged, and
6820 real programs appear to depend on that. */
6821 tcg_gen_movi_tl(cpu_tmp0, 0);
6822 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_T[0], cpu_cc_dst, cpu_tmp0,
6823 cpu_regs[reg], cpu_T[0]);
6825 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
6827 /************************/
6829 case 0x27: /* daa */
6832 gen_update_cc_op(s);
6833 gen_helper_daa(cpu_env);
6834 set_cc_op(s, CC_OP_EFLAGS);
6836 case 0x2f: /* das */
6839 gen_update_cc_op(s);
6840 gen_helper_das(cpu_env);
6841 set_cc_op(s, CC_OP_EFLAGS);
6843 case 0x37: /* aaa */
6846 gen_update_cc_op(s);
6847 gen_helper_aaa(cpu_env);
6848 set_cc_op(s, CC_OP_EFLAGS);
6850 case 0x3f: /* aas */
6853 gen_update_cc_op(s);
6854 gen_helper_aas(cpu_env);
6855 set_cc_op(s, CC_OP_EFLAGS);
6857 case 0xd4: /* aam */
6860 val = cpu_ldub_code(env, s->pc++);
6862 gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base);
6864 gen_helper_aam(cpu_env, tcg_const_i32(val));
6865 set_cc_op(s, CC_OP_LOGICB);
6868 case 0xd5: /* aad */
6871 val = cpu_ldub_code(env, s->pc++);
6872 gen_helper_aad(cpu_env, tcg_const_i32(val));
6873 set_cc_op(s, CC_OP_LOGICB);
6875 /************************/
6877 case 0x90: /* nop */
6878 /* XXX: correct lock test for all insn */
6879 if (prefixes & PREFIX_LOCK) {
6882 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
6884 goto do_xchg_reg_eax;
6886 if (prefixes & PREFIX_REPZ) {
6887 gen_update_cc_op(s);
6888 gen_jmp_im(pc_start - s->cs_base);
6889 gen_helper_pause(cpu_env, tcg_const_i32(s->pc - pc_start));
6890 s->is_jmp = DISAS_TB_JUMP;
6893 case 0x9b: /* fwait */
6894 if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
6895 (HF_MP_MASK | HF_TS_MASK)) {
6896 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
6898 gen_update_cc_op(s);
6899 gen_jmp_im(pc_start - s->cs_base);
6900 gen_helper_fwait(cpu_env);
6903 case 0xcc: /* int3 */
6904 gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
6906 case 0xcd: /* int N */
6907 val = cpu_ldub_code(env, s->pc++);
6908 if (s->vm86 && s->iopl != 3) {
6909 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6911 gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
6914 case 0xce: /* into */
6917 gen_update_cc_op(s);
6918 gen_jmp_im(pc_start - s->cs_base);
6919 gen_helper_into(cpu_env, tcg_const_i32(s->pc - pc_start));
6922 case 0xf1: /* icebp (undocumented, exits to external debugger) */
6923 gen_svm_check_intercept(s, pc_start, SVM_EXIT_ICEBP);
6925 gen_debug(s, pc_start - s->cs_base);
6929 qemu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM);
6933 case 0xfa: /* cli */
6935 if (s->cpl <= s->iopl) {
6936 gen_helper_cli(cpu_env);
6938 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6942 gen_helper_cli(cpu_env);
6944 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6948 case 0xfb: /* sti */
6950 if (s->cpl <= s->iopl) {
6952 gen_helper_sti(cpu_env);
6953 /* interruptions are enabled only the first insn after sti */
6954 /* If several instructions disable interrupts, only the
6956 if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
6957 gen_helper_set_inhibit_irq(cpu_env);
6958 /* give a chance to handle pending irqs */
6959 gen_jmp_im(s->pc - s->cs_base);
6962 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6968 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6972 case 0x62: /* bound */
6976 modrm = cpu_ldub_code(env, s->pc++);
6977 reg = (modrm >> 3) & 7;
6978 mod = (modrm >> 6) & 3;
6981 gen_op_mov_v_reg(ot, cpu_T[0], reg);
6982 gen_lea_modrm(env, s, modrm);
6983 gen_jmp_im(pc_start - s->cs_base);
6984 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6986 gen_helper_boundw(cpu_env, cpu_A0, cpu_tmp2_i32);
6988 gen_helper_boundl(cpu_env, cpu_A0, cpu_tmp2_i32);
6991 case 0x1c8 ... 0x1cf: /* bswap reg */
6992 reg = (b & 7) | REX_B(s);
6993 #ifdef TARGET_X86_64
6994 if (dflag == MO_64) {
6995 gen_op_mov_v_reg(MO_64, cpu_T[0], reg);
6996 tcg_gen_bswap64_i64(cpu_T[0], cpu_T[0]);
6997 gen_op_mov_reg_v(MO_64, reg, cpu_T[0]);
7001 gen_op_mov_v_reg(MO_32, cpu_T[0], reg);
7002 tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
7003 tcg_gen_bswap32_tl(cpu_T[0], cpu_T[0]);
7004 gen_op_mov_reg_v(MO_32, reg, cpu_T[0]);
7007 case 0xd6: /* salc */
7010 gen_compute_eflags_c(s, cpu_T[0]);
7011 tcg_gen_neg_tl(cpu_T[0], cpu_T[0]);
7012 gen_op_mov_reg_v(MO_8, R_EAX, cpu_T[0]);
7014 case 0xe0: /* loopnz */
7015 case 0xe1: /* loopz */
7016 case 0xe2: /* loop */
7017 case 0xe3: /* jecxz */
7021 tval = (int8_t)insn_get(env, s, MO_8);
7022 next_eip = s->pc - s->cs_base;
7024 if (dflag == MO_16) {
7028 l1 = gen_new_label();
7029 l2 = gen_new_label();
7030 l3 = gen_new_label();
7033 case 0: /* loopnz */
7035 gen_op_add_reg_im(s->aflag, R_ECX, -1);
7036 gen_op_jz_ecx(s->aflag, l3);
7037 gen_jcc1(s, (JCC_Z << 1) | (b ^ 1), l1);
7040 gen_op_add_reg_im(s->aflag, R_ECX, -1);
7041 gen_op_jnz_ecx(s->aflag, l1);
7045 gen_op_jz_ecx(s->aflag, l1);
7050 gen_jmp_im(next_eip);
7059 case 0x130: /* wrmsr */
7060 case 0x132: /* rdmsr */
7062 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7064 gen_update_cc_op(s);
7065 gen_jmp_im(pc_start - s->cs_base);
7067 gen_helper_rdmsr(cpu_env);
7069 gen_helper_wrmsr(cpu_env);
7073 case 0x131: /* rdtsc */
7074 gen_update_cc_op(s);
7075 gen_jmp_im(pc_start - s->cs_base);
7076 if (s->tb->cflags & CF_USE_ICOUNT) {
7079 gen_helper_rdtsc(cpu_env);
7080 if (s->tb->cflags & CF_USE_ICOUNT) {
7082 gen_jmp(s, s->pc - s->cs_base);
7085 case 0x133: /* rdpmc */
7086 gen_update_cc_op(s);
7087 gen_jmp_im(pc_start - s->cs_base);
7088 gen_helper_rdpmc(cpu_env);
7090 case 0x134: /* sysenter */
7091 /* For Intel SYSENTER is valid on 64-bit */
7092 if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
7095 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7097 gen_update_cc_op(s);
7098 gen_jmp_im(pc_start - s->cs_base);
7099 gen_helper_sysenter(cpu_env);
7103 case 0x135: /* sysexit */
7104 /* For Intel SYSEXIT is valid on 64-bit */
7105 if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
7108 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7110 gen_update_cc_op(s);
7111 gen_jmp_im(pc_start - s->cs_base);
7112 gen_helper_sysexit(cpu_env, tcg_const_i32(dflag - 1));
7116 #ifdef TARGET_X86_64
7117 case 0x105: /* syscall */
7118 /* XXX: is it usable in real mode ? */
7119 gen_update_cc_op(s);
7120 gen_jmp_im(pc_start - s->cs_base);
7121 gen_helper_syscall(cpu_env, tcg_const_i32(s->pc - pc_start));
7124 case 0x107: /* sysret */
7126 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7128 gen_update_cc_op(s);
7129 gen_jmp_im(pc_start - s->cs_base);
7130 gen_helper_sysret(cpu_env, tcg_const_i32(dflag - 1));
7131 /* condition codes are modified only in long mode */
7133 set_cc_op(s, CC_OP_EFLAGS);
7139 case 0x1a2: /* cpuid */
7140 gen_update_cc_op(s);
7141 gen_jmp_im(pc_start - s->cs_base);
7142 gen_helper_cpuid(cpu_env);
7144 case 0xf4: /* hlt */
7146 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7148 gen_update_cc_op(s);
7149 gen_jmp_im(pc_start - s->cs_base);
7150 gen_helper_hlt(cpu_env, tcg_const_i32(s->pc - pc_start));
7151 s->is_jmp = DISAS_TB_JUMP;
7155 modrm = cpu_ldub_code(env, s->pc++);
7156 mod = (modrm >> 6) & 3;
7157 op = (modrm >> 3) & 7;
7160 if (!s->pe || s->vm86)
7162 gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_READ);
7163 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,ldt.selector));
7164 ot = mod == 3 ? dflag : MO_16;
7165 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7168 if (!s->pe || s->vm86)
7171 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7173 gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_WRITE);
7174 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7175 gen_jmp_im(pc_start - s->cs_base);
7176 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
7177 gen_helper_lldt(cpu_env, cpu_tmp2_i32);
7181 if (!s->pe || s->vm86)
7183 gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_READ);
7184 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,tr.selector));
7185 ot = mod == 3 ? dflag : MO_16;
7186 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7189 if (!s->pe || s->vm86)
7192 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7194 gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_WRITE);
7195 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7196 gen_jmp_im(pc_start - s->cs_base);
7197 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
7198 gen_helper_ltr(cpu_env, cpu_tmp2_i32);
7203 if (!s->pe || s->vm86)
7205 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7206 gen_update_cc_op(s);
7208 gen_helper_verr(cpu_env, cpu_T[0]);
7210 gen_helper_verw(cpu_env, cpu_T[0]);
7212 set_cc_op(s, CC_OP_EFLAGS);
7219 modrm = cpu_ldub_code(env, s->pc++);
7220 mod = (modrm >> 6) & 3;
7221 op = (modrm >> 3) & 7;
7227 gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_READ);
7228 gen_lea_modrm(env, s, modrm);
7229 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, gdt.limit));
7230 gen_op_st_v(s, MO_16, cpu_T[0], cpu_A0);
7231 gen_add_A0_im(s, 2);
7232 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, gdt.base));
7233 if (dflag == MO_16) {
7234 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffffff);
7236 gen_op_st_v(s, CODE64(s) + MO_32, cpu_T[0], cpu_A0);
7241 case 0: /* monitor */
7242 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) ||
7245 gen_update_cc_op(s);
7246 gen_jmp_im(pc_start - s->cs_base);
7247 tcg_gen_mov_tl(cpu_A0, cpu_regs[R_EAX]);
7248 gen_extu(s->aflag, cpu_A0);
7249 gen_add_A0_ds_seg(s);
7250 gen_helper_monitor(cpu_env, cpu_A0);
7253 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) ||
7256 gen_update_cc_op(s);
7257 gen_jmp_im(pc_start - s->cs_base);
7258 gen_helper_mwait(cpu_env, tcg_const_i32(s->pc - pc_start));
7262 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP) ||
7266 gen_helper_clac(cpu_env);
7267 gen_jmp_im(s->pc - s->cs_base);
7271 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP) ||
7275 gen_helper_stac(cpu_env);
7276 gen_jmp_im(s->pc - s->cs_base);
7283 gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_READ);
7284 gen_lea_modrm(env, s, modrm);
7285 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, idt.limit));
7286 gen_op_st_v(s, MO_16, cpu_T[0], cpu_A0);
7287 gen_add_A0_im(s, 2);
7288 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, idt.base));
7289 if (dflag == MO_16) {
7290 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffffff);
7292 gen_op_st_v(s, CODE64(s) + MO_32, cpu_T[0], cpu_A0);
7298 gen_update_cc_op(s);
7299 gen_jmp_im(pc_start - s->cs_base);
7302 if (!(s->flags & HF_SVME_MASK) || !s->pe)
7305 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7308 gen_helper_vmrun(cpu_env, tcg_const_i32(s->aflag - 1),
7309 tcg_const_i32(s->pc - pc_start));
7311 s->is_jmp = DISAS_TB_JUMP;
7314 case 1: /* VMMCALL */
7315 if (!(s->flags & HF_SVME_MASK))
7317 gen_helper_vmmcall(cpu_env);
7319 case 2: /* VMLOAD */
7320 if (!(s->flags & HF_SVME_MASK) || !s->pe)
7323 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7326 gen_helper_vmload(cpu_env, tcg_const_i32(s->aflag - 1));
7329 case 3: /* VMSAVE */
7330 if (!(s->flags & HF_SVME_MASK) || !s->pe)
7333 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7336 gen_helper_vmsave(cpu_env, tcg_const_i32(s->aflag - 1));
7340 if ((!(s->flags & HF_SVME_MASK) &&
7341 !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) ||
7345 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7348 gen_helper_stgi(cpu_env);
7352 if (!(s->flags & HF_SVME_MASK) || !s->pe)
7355 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7358 gen_helper_clgi(cpu_env);
7361 case 6: /* SKINIT */
7362 if ((!(s->flags & HF_SVME_MASK) &&
7363 !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) ||
7366 gen_helper_skinit(cpu_env);
7368 case 7: /* INVLPGA */
7369 if (!(s->flags & HF_SVME_MASK) || !s->pe)
7372 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7375 gen_helper_invlpga(cpu_env,
7376 tcg_const_i32(s->aflag - 1));
7382 } else if (s->cpl != 0) {
7383 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7385 gen_svm_check_intercept(s, pc_start,
7386 op==2 ? SVM_EXIT_GDTR_WRITE : SVM_EXIT_IDTR_WRITE);
7387 gen_lea_modrm(env, s, modrm);
7388 gen_op_ld_v(s, MO_16, cpu_T[1], cpu_A0);
7389 gen_add_A0_im(s, 2);
7390 gen_op_ld_v(s, CODE64(s) + MO_32, cpu_T[0], cpu_A0);
7391 if (dflag == MO_16) {
7392 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffffff);
7395 tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,gdt.base));
7396 tcg_gen_st32_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,gdt.limit));
7398 tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,idt.base));
7399 tcg_gen_st32_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,idt.limit));
7404 gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0);
7405 #if defined TARGET_X86_64 && defined HOST_WORDS_BIGENDIAN
7406 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,cr[0]) + 4);
7408 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,cr[0]));
7410 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 1);
7414 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7416 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
7417 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7418 gen_helper_lmsw(cpu_env, cpu_T[0]);
7419 gen_jmp_im(s->pc - s->cs_base);
7424 if (mod != 3) { /* invlpg */
7426 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7428 gen_update_cc_op(s);
7429 gen_jmp_im(pc_start - s->cs_base);
7430 gen_lea_modrm(env, s, modrm);
7431 gen_helper_invlpg(cpu_env, cpu_A0);
7432 gen_jmp_im(s->pc - s->cs_base);
7437 case 0: /* swapgs */
7438 #ifdef TARGET_X86_64
7441 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7443 tcg_gen_ld_tl(cpu_T[0], cpu_env,
7444 offsetof(CPUX86State,segs[R_GS].base));
7445 tcg_gen_ld_tl(cpu_T[1], cpu_env,
7446 offsetof(CPUX86State,kernelgsbase));
7447 tcg_gen_st_tl(cpu_T[1], cpu_env,
7448 offsetof(CPUX86State,segs[R_GS].base));
7449 tcg_gen_st_tl(cpu_T[0], cpu_env,
7450 offsetof(CPUX86State,kernelgsbase));
7458 case 1: /* rdtscp */
7459 if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP))
7461 gen_update_cc_op(s);
7462 gen_jmp_im(pc_start - s->cs_base);
7463 if (s->tb->cflags & CF_USE_ICOUNT) {
7466 gen_helper_rdtscp(cpu_env);
7467 if (s->tb->cflags & CF_USE_ICOUNT) {
7469 gen_jmp(s, s->pc - s->cs_base);
7481 case 0x108: /* invd */
7482 case 0x109: /* wbinvd */
7484 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7486 gen_svm_check_intercept(s, pc_start, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD);
7490 case 0x63: /* arpl or movslS (x86_64) */
7491 #ifdef TARGET_X86_64
7494 /* d_ot is the size of destination */
7497 modrm = cpu_ldub_code(env, s->pc++);
7498 reg = ((modrm >> 3) & 7) | rex_r;
7499 mod = (modrm >> 6) & 3;
7500 rm = (modrm & 7) | REX_B(s);
7503 gen_op_mov_v_reg(MO_32, cpu_T[0], rm);
7505 if (d_ot == MO_64) {
7506 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
7508 gen_op_mov_reg_v(d_ot, reg, cpu_T[0]);
7510 gen_lea_modrm(env, s, modrm);
7511 gen_op_ld_v(s, MO_32 | MO_SIGN, cpu_T[0], cpu_A0);
7512 gen_op_mov_reg_v(d_ot, reg, cpu_T[0]);
7518 TCGv t0, t1, t2, a0;
7520 if (!s->pe || s->vm86)
7522 t0 = tcg_temp_local_new();
7523 t1 = tcg_temp_local_new();
7524 t2 = tcg_temp_local_new();
7526 modrm = cpu_ldub_code(env, s->pc++);
7527 reg = (modrm >> 3) & 7;
7528 mod = (modrm >> 6) & 3;
7531 gen_lea_modrm(env, s, modrm);
7532 gen_op_ld_v(s, ot, t0, cpu_A0);
7533 a0 = tcg_temp_local_new();
7534 tcg_gen_mov_tl(a0, cpu_A0);
7536 gen_op_mov_v_reg(ot, t0, rm);
7539 gen_op_mov_v_reg(ot, t1, reg);
7540 tcg_gen_andi_tl(cpu_tmp0, t0, 3);
7541 tcg_gen_andi_tl(t1, t1, 3);
7542 tcg_gen_movi_tl(t2, 0);
7543 label1 = gen_new_label();
7544 tcg_gen_brcond_tl(TCG_COND_GE, cpu_tmp0, t1, label1);
7545 tcg_gen_andi_tl(t0, t0, ~3);
7546 tcg_gen_or_tl(t0, t0, t1);
7547 tcg_gen_movi_tl(t2, CC_Z);
7548 gen_set_label(label1);
7550 gen_op_st_v(s, ot, t0, a0);
7553 gen_op_mov_reg_v(ot, rm, t0);
7555 gen_compute_eflags(s);
7556 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z);
7557 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t2);
7563 case 0x102: /* lar */
7564 case 0x103: /* lsl */
7568 if (!s->pe || s->vm86)
7570 ot = dflag != MO_16 ? MO_32 : MO_16;
7571 modrm = cpu_ldub_code(env, s->pc++);
7572 reg = ((modrm >> 3) & 7) | rex_r;
7573 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7574 t0 = tcg_temp_local_new();
7575 gen_update_cc_op(s);
7577 gen_helper_lar(t0, cpu_env, cpu_T[0]);
7579 gen_helper_lsl(t0, cpu_env, cpu_T[0]);
7581 tcg_gen_andi_tl(cpu_tmp0, cpu_cc_src, CC_Z);
7582 label1 = gen_new_label();
7583 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
7584 gen_op_mov_reg_v(ot, reg, t0);
7585 gen_set_label(label1);
7586 set_cc_op(s, CC_OP_EFLAGS);
7591 modrm = cpu_ldub_code(env, s->pc++);
7592 mod = (modrm >> 6) & 3;
7593 op = (modrm >> 3) & 7;
7595 case 0: /* prefetchnta */
7596 case 1: /* prefetchnt0 */
7597 case 2: /* prefetchnt0 */
7598 case 3: /* prefetchnt0 */
7601 gen_lea_modrm(env, s, modrm);
7602 /* nothing more to do */
7604 default: /* nop (multi byte) */
7605 gen_nop_modrm(env, s, modrm);
7609 case 0x119 ... 0x11f: /* nop (multi byte) */
7610 modrm = cpu_ldub_code(env, s->pc++);
7611 gen_nop_modrm(env, s, modrm);
7613 case 0x120: /* mov reg, crN */
7614 case 0x122: /* mov crN, reg */
7616 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7618 modrm = cpu_ldub_code(env, s->pc++);
7619 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7620 * AMD documentation (24594.pdf) and testing of
7621 * intel 386 and 486 processors all show that the mod bits
7622 * are assumed to be 1's, regardless of actual values.
7624 rm = (modrm & 7) | REX_B(s);
7625 reg = ((modrm >> 3) & 7) | rex_r;
7630 if ((prefixes & PREFIX_LOCK) && (reg == 0) &&
7631 (s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) {
7640 gen_update_cc_op(s);
7641 gen_jmp_im(pc_start - s->cs_base);
7643 gen_op_mov_v_reg(ot, cpu_T[0], rm);
7644 gen_helper_write_crN(cpu_env, tcg_const_i32(reg),
7646 gen_jmp_im(s->pc - s->cs_base);
7649 gen_helper_read_crN(cpu_T[0], cpu_env, tcg_const_i32(reg));
7650 gen_op_mov_reg_v(ot, rm, cpu_T[0]);
7658 case 0x121: /* mov reg, drN */
7659 case 0x123: /* mov drN, reg */
7661 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7663 modrm = cpu_ldub_code(env, s->pc++);
7664 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7665 * AMD documentation (24594.pdf) and testing of
7666 * intel 386 and 486 processors all show that the mod bits
7667 * are assumed to be 1's, regardless of actual values.
7669 rm = (modrm & 7) | REX_B(s);
7670 reg = ((modrm >> 3) & 7) | rex_r;
7675 /* XXX: do it dynamically with CR4.DE bit */
7676 if (reg == 4 || reg == 5 || reg >= 8)
7679 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
7680 gen_op_mov_v_reg(ot, cpu_T[0], rm);
7681 gen_helper_movl_drN_T0(cpu_env, tcg_const_i32(reg), cpu_T[0]);
7682 gen_jmp_im(s->pc - s->cs_base);
7685 gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_DR0 + reg);
7686 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,dr[reg]));
7687 gen_op_mov_reg_v(ot, rm, cpu_T[0]);
7691 case 0x106: /* clts */
7693 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7695 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
7696 gen_helper_clts(cpu_env);
7697 /* abort block because static cpu state changed */
7698 gen_jmp_im(s->pc - s->cs_base);
7702 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
7703 case 0x1c3: /* MOVNTI reg, mem */
7704 if (!(s->cpuid_features & CPUID_SSE2))
7706 ot = mo_64_32(dflag);
7707 modrm = cpu_ldub_code(env, s->pc++);
7708 mod = (modrm >> 6) & 3;
7711 reg = ((modrm >> 3) & 7) | rex_r;
7712 /* generate a generic store */
7713 gen_ldst_modrm(env, s, modrm, ot, reg, 1);
7716 modrm = cpu_ldub_code(env, s->pc++);
7717 mod = (modrm >> 6) & 3;
7718 op = (modrm >> 3) & 7;
7720 case 0: /* fxsave */
7721 if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
7722 (s->prefix & PREFIX_LOCK))
7724 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
7725 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
7728 gen_lea_modrm(env, s, modrm);
7729 gen_update_cc_op(s);
7730 gen_jmp_im(pc_start - s->cs_base);
7731 gen_helper_fxsave(cpu_env, cpu_A0, tcg_const_i32(dflag == MO_64));
7733 case 1: /* fxrstor */
7734 if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
7735 (s->prefix & PREFIX_LOCK))
7737 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
7738 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
7741 gen_lea_modrm(env, s, modrm);
7742 gen_update_cc_op(s);
7743 gen_jmp_im(pc_start - s->cs_base);
7744 gen_helper_fxrstor(cpu_env, cpu_A0, tcg_const_i32(dflag == MO_64));
7746 case 2: /* ldmxcsr */
7747 case 3: /* stmxcsr */
7748 if (s->flags & HF_TS_MASK) {
7749 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
7752 if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK) ||
7755 gen_lea_modrm(env, s, modrm);
7757 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
7758 s->mem_index, MO_LEUL);
7759 gen_helper_ldmxcsr(cpu_env, cpu_tmp2_i32);
7761 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, mxcsr));
7762 gen_op_st_v(s, MO_32, cpu_T[0], cpu_A0);
7765 case 5: /* lfence */
7766 case 6: /* mfence */
7767 if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE2))
7770 case 7: /* sfence / clflush */
7771 if ((modrm & 0xc7) == 0xc0) {
7773 /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX */
7774 if (!(s->cpuid_features & CPUID_SSE))
7778 if (!(s->cpuid_features & CPUID_CLFLUSH))
7780 gen_lea_modrm(env, s, modrm);
7787 case 0x10d: /* 3DNow! prefetch(w) */
7788 modrm = cpu_ldub_code(env, s->pc++);
7789 mod = (modrm >> 6) & 3;
7792 gen_lea_modrm(env, s, modrm);
7793 /* ignore for now */
7795 case 0x1aa: /* rsm */
7796 gen_svm_check_intercept(s, pc_start, SVM_EXIT_RSM);
7797 if (!(s->flags & HF_SMM_MASK))
7799 gen_update_cc_op(s);
7800 gen_jmp_im(s->pc - s->cs_base);
7801 gen_helper_rsm(cpu_env);
7804 case 0x1b8: /* SSE4.2 popcnt */
7805 if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) !=
7808 if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT))
7811 modrm = cpu_ldub_code(env, s->pc++);
7812 reg = ((modrm >> 3) & 7) | rex_r;
7814 if (s->prefix & PREFIX_DATA) {
7817 ot = mo_64_32(dflag);
7820 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
7821 gen_helper_popcnt(cpu_T[0], cpu_env, cpu_T[0], tcg_const_i32(ot));
7822 gen_op_mov_reg_v(ot, reg, cpu_T[0]);
7824 set_cc_op(s, CC_OP_EFLAGS);
7826 case 0x10e ... 0x10f:
7827 /* 3DNow! instructions, ignore prefixes */
7828 s->prefix &= ~(PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA);
7829 case 0x110 ... 0x117:
7830 case 0x128 ... 0x12f:
7831 case 0x138 ... 0x13a:
7832 case 0x150 ... 0x179:
7833 case 0x17c ... 0x17f:
7835 case 0x1c4 ... 0x1c6:
7836 case 0x1d0 ... 0x1fe:
7837 gen_sse(env, s, b, pc_start, rex_r);
7842 /* lock generation */
7843 if (s->prefix & PREFIX_LOCK)
7844 gen_helper_unlock();
7847 if (s->prefix & PREFIX_LOCK)
7848 gen_helper_unlock();
7849 /* XXX: ensure that no lock was generated */
7850 gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
7854 void optimize_flags_init(void)
7856 static const char reg_names[CPU_NB_REGS][4] = {
7857 #ifdef TARGET_X86_64
7887 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
7888 cpu_cc_op = tcg_global_mem_new_i32(TCG_AREG0,
7889 offsetof(CPUX86State, cc_op), "cc_op");
7890 cpu_cc_dst = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_dst),
7892 cpu_cc_src = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_src),
7894 cpu_cc_src2 = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_src2),
7897 for (i = 0; i < CPU_NB_REGS; ++i) {
7898 cpu_regs[i] = tcg_global_mem_new(TCG_AREG0,
7899 offsetof(CPUX86State, regs[i]),
7904 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
7905 basic block 'tb'. If search_pc is TRUE, also generate PC
7906 information for each intermediate instruction. */
7907 static inline void gen_intermediate_code_internal(X86CPU *cpu,
7908 TranslationBlock *tb,
7911 CPUState *cs = CPU(cpu);
7912 CPUX86State *env = &cpu->env;
7913 DisasContext dc1, *dc = &dc1;
7914 target_ulong pc_ptr;
7915 uint16_t *gen_opc_end;
7919 target_ulong pc_start;
7920 target_ulong cs_base;
7924 /* generate intermediate code */
7926 cs_base = tb->cs_base;
7929 dc->pe = (flags >> HF_PE_SHIFT) & 1;
7930 dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
7931 dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
7932 dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
7934 dc->vm86 = (flags >> VM_SHIFT) & 1;
7935 dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
7936 dc->iopl = (flags >> IOPL_SHIFT) & 3;
7937 dc->tf = (flags >> TF_SHIFT) & 1;
7938 dc->singlestep_enabled = cs->singlestep_enabled;
7939 dc->cc_op = CC_OP_DYNAMIC;
7940 dc->cc_op_dirty = false;
7941 dc->cs_base = cs_base;
7943 dc->popl_esp_hack = 0;
7944 /* select memory access functions */
7946 if (flags & HF_SOFTMMU_MASK) {
7947 dc->mem_index = cpu_mmu_index(env);
7949 dc->cpuid_features = env->features[FEAT_1_EDX];
7950 dc->cpuid_ext_features = env->features[FEAT_1_ECX];
7951 dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX];
7952 dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX];
7953 dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX];
7954 #ifdef TARGET_X86_64
7955 dc->lma = (flags >> HF_LMA_SHIFT) & 1;
7956 dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
7959 dc->jmp_opt = !(dc->tf || cs->singlestep_enabled ||
7960 (flags & HF_INHIBIT_IRQ_MASK)
7961 #ifndef CONFIG_SOFTMMU
7962 || (flags & HF_SOFTMMU_MASK)
7965 /* Do not optimize repz jumps at all in icount mode, because
7966 rep movsS instructions are execured with different paths
7967 in !repz_opt and repz_opt modes. The first one was used
7968 always except single step mode. And this setting
7969 disables jumps optimization and control paths become
7970 equivalent in run and single step modes.
7971 Now there will be no jump optimization for repz in
7972 record/replay modes and there will always be an
7973 additional step for ecx=0 when icount is enabled.
7975 dc->repz_opt = !dc->jmp_opt && !(tb->cflags & CF_USE_ICOUNT);
7977 /* check addseg logic */
7978 if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
7979 printf("ERROR addseg\n");
7982 cpu_T[0] = tcg_temp_new();
7983 cpu_T[1] = tcg_temp_new();
7984 cpu_A0 = tcg_temp_new();
7986 cpu_tmp0 = tcg_temp_new();
7987 cpu_tmp1_i64 = tcg_temp_new_i64();
7988 cpu_tmp2_i32 = tcg_temp_new_i32();
7989 cpu_tmp3_i32 = tcg_temp_new_i32();
7990 cpu_tmp4 = tcg_temp_new();
7991 cpu_ptr0 = tcg_temp_new_ptr();
7992 cpu_ptr1 = tcg_temp_new_ptr();
7993 cpu_cc_srcT = tcg_temp_local_new();
7995 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
7997 dc->is_jmp = DISAS_NEXT;
8001 max_insns = tb->cflags & CF_COUNT_MASK;
8003 max_insns = CF_COUNT_MASK;
8007 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
8008 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
8009 if (bp->pc == pc_ptr &&
8010 !((bp->flags & BP_CPU) && (tb->flags & HF_RF_MASK))) {
8011 gen_debug(dc, pc_ptr - dc->cs_base);
8012 goto done_generating;
8017 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
8021 tcg_ctx.gen_opc_instr_start[lj++] = 0;
8023 tcg_ctx.gen_opc_pc[lj] = pc_ptr;
8024 gen_opc_cc_op[lj] = dc->cc_op;
8025 tcg_ctx.gen_opc_instr_start[lj] = 1;
8026 tcg_ctx.gen_opc_icount[lj] = num_insns;
8028 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8031 pc_ptr = disas_insn(env, dc, pc_ptr);
8033 /* stop translation if indicated */
8036 /* if single step mode, we generate only one instruction and
8037 generate an exception */
8038 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
8039 the flag and abort the translation to give the irqs a
8040 change to be happen */
8041 if (dc->tf || dc->singlestep_enabled ||
8042 (flags & HF_INHIBIT_IRQ_MASK)) {
8043 gen_jmp_im(pc_ptr - dc->cs_base);
8047 /* Do not cross the boundary of the pages in icount mode,
8048 it can cause an exception. Do it only when boundary is
8049 crossed by the first instruction in the block.
8050 If current instruction already crossed the bound - it's ok,
8051 because an exception hasn't stopped this code.
8053 if ((tb->cflags & CF_USE_ICOUNT)
8054 && ((pc_ptr & TARGET_PAGE_MASK)
8055 != ((pc_ptr + TARGET_MAX_INSN_SIZE - 1) & TARGET_PAGE_MASK)
8056 || (pc_ptr & ~TARGET_PAGE_MASK) == 0)) {
8057 gen_jmp_im(pc_ptr - dc->cs_base);
8061 /* if too long translation, stop generation too */
8062 if (tcg_ctx.gen_opc_ptr >= gen_opc_end ||
8063 (pc_ptr - pc_start) >= (TARGET_PAGE_SIZE - 32) ||
8064 num_insns >= max_insns) {
8065 gen_jmp_im(pc_ptr - dc->cs_base);
8070 gen_jmp_im(pc_ptr - dc->cs_base);
8075 if (tb->cflags & CF_LAST_IO)
8078 gen_tb_end(tb, num_insns);
8079 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
8080 /* we don't forget to fill the last values */
8082 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
8085 tcg_ctx.gen_opc_instr_start[lj++] = 0;
8089 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
8091 qemu_log("----------------\n");
8092 qemu_log("IN: %s\n", lookup_symbol(pc_start));
8093 #ifdef TARGET_X86_64
8098 disas_flags = !dc->code32;
8099 log_target_disas(env, pc_start, pc_ptr - pc_start, disas_flags);
8105 tb->size = pc_ptr - pc_start;
8106 tb->icount = num_insns;
8110 void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb)
8112 gen_intermediate_code_internal(x86_env_get_cpu(env), tb, false);
8115 void gen_intermediate_code_pc(CPUX86State *env, TranslationBlock *tb)
8117 gen_intermediate_code_internal(x86_env_get_cpu(env), tb, true);
8120 void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb, int pc_pos)
8124 if (qemu_loglevel_mask(CPU_LOG_TB_OP)) {
8126 qemu_log("RESTORE:\n");
8127 for(i = 0;i <= pc_pos; i++) {
8128 if (tcg_ctx.gen_opc_instr_start[i]) {
8129 qemu_log("0x%04x: " TARGET_FMT_lx "\n", i,
8130 tcg_ctx.gen_opc_pc[i]);
8133 qemu_log("pc_pos=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n",
8134 pc_pos, tcg_ctx.gen_opc_pc[pc_pos] - tb->cs_base,
8135 (uint32_t)tb->cs_base);
8138 env->eip = tcg_ctx.gen_opc_pc[pc_pos] - tb->cs_base;
8139 cc_op = gen_opc_cc_op[pc_pos];
8140 if (cc_op != CC_OP_DYNAMIC)