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/>.
25 #include "qemu/host-utils.h"
27 #include "disas/disas.h"
29 #include "exec/cpu_ldst.h"
31 #include "exec/helper-proto.h"
32 #include "exec/helper-gen.h"
34 #include "trace-tcg.h"
37 #define PREFIX_REPZ 0x01
38 #define PREFIX_REPNZ 0x02
39 #define PREFIX_LOCK 0x04
40 #define PREFIX_DATA 0x08
41 #define PREFIX_ADR 0x10
42 #define PREFIX_VEX 0x20
45 #define CODE64(s) ((s)->code64)
46 #define REX_X(s) ((s)->rex_x)
47 #define REX_B(s) ((s)->rex_b)
62 //#define MACRO_TEST 1
64 /* global register indexes */
65 static TCGv_ptr cpu_env
;
67 static TCGv cpu_cc_dst
, cpu_cc_src
, cpu_cc_src2
, cpu_cc_srcT
;
68 static TCGv_i32 cpu_cc_op
;
69 static TCGv cpu_regs
[CPU_NB_REGS
];
72 /* local register indexes (only used inside old micro ops) */
73 static TCGv cpu_tmp0
, cpu_tmp4
;
74 static TCGv_ptr cpu_ptr0
, cpu_ptr1
;
75 static TCGv_i32 cpu_tmp2_i32
, cpu_tmp3_i32
;
76 static TCGv_i64 cpu_tmp1_i64
;
78 #include "exec/gen-icount.h"
81 static int x86_64_hregs
;
84 typedef struct DisasContext
{
85 /* current insn context */
86 int override
; /* -1 if no override */
90 target_ulong pc
; /* pc = eip + cs_base */
91 int is_jmp
; /* 1 = means jump (stop translation), 2 means CPU
92 static state change (stop translation) */
93 /* current block context */
94 target_ulong cs_base
; /* base of CS segment */
95 int pe
; /* protected mode */
96 int code32
; /* 32 bit code segment */
98 int lma
; /* long mode active */
99 int code64
; /* 64 bit code segment */
102 int vex_l
; /* vex vector length */
103 int vex_v
; /* vex vvvv register, without 1's compliment. */
104 int ss32
; /* 32 bit stack segment */
105 CCOp cc_op
; /* current CC operation */
107 int addseg
; /* non zero if either DS/ES/SS have a non zero base */
108 int f_st
; /* currently unused */
109 int vm86
; /* vm86 mode */
112 int tf
; /* TF cpu flag */
113 int singlestep_enabled
; /* "hardware" single step enabled */
114 int jmp_opt
; /* use direct block chaining for direct jumps */
115 int repz_opt
; /* optimize jumps within repz instructions */
116 int mem_index
; /* select memory access functions */
117 uint64_t flags
; /* all execution flags */
118 struct TranslationBlock
*tb
;
119 int popl_esp_hack
; /* for correct popl with esp base handling */
120 int rip_offset
; /* only used in x86_64, but left for simplicity */
122 int cpuid_ext_features
;
123 int cpuid_ext2_features
;
124 int cpuid_ext3_features
;
125 int cpuid_7_0_ebx_features
;
128 static void gen_eob(DisasContext
*s
);
129 static void gen_jmp(DisasContext
*s
, target_ulong eip
);
130 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
);
131 static void gen_op(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
);
133 /* i386 arith/logic operations */
153 OP_SHL1
, /* undocumented */
169 /* I386 int registers */
170 OR_EAX
, /* MUST be even numbered */
179 OR_TMP0
= 16, /* temporary operand register */
181 OR_A0
, /* temporary register used when doing address evaluation */
191 /* Bit set if the global variable is live after setting CC_OP to X. */
192 static const uint8_t cc_op_live
[CC_OP_NB
] = {
193 [CC_OP_DYNAMIC
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
194 [CC_OP_EFLAGS
] = USES_CC_SRC
,
195 [CC_OP_MULB
... CC_OP_MULQ
] = USES_CC_DST
| USES_CC_SRC
,
196 [CC_OP_ADDB
... CC_OP_ADDQ
] = USES_CC_DST
| USES_CC_SRC
,
197 [CC_OP_ADCB
... CC_OP_ADCQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
198 [CC_OP_SUBB
... CC_OP_SUBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRCT
,
199 [CC_OP_SBBB
... CC_OP_SBBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
200 [CC_OP_LOGICB
... CC_OP_LOGICQ
] = USES_CC_DST
,
201 [CC_OP_INCB
... CC_OP_INCQ
] = USES_CC_DST
| USES_CC_SRC
,
202 [CC_OP_DECB
... CC_OP_DECQ
] = USES_CC_DST
| USES_CC_SRC
,
203 [CC_OP_SHLB
... CC_OP_SHLQ
] = USES_CC_DST
| USES_CC_SRC
,
204 [CC_OP_SARB
... CC_OP_SARQ
] = USES_CC_DST
| USES_CC_SRC
,
205 [CC_OP_BMILGB
... CC_OP_BMILGQ
] = USES_CC_DST
| USES_CC_SRC
,
206 [CC_OP_ADCX
] = USES_CC_DST
| USES_CC_SRC
,
207 [CC_OP_ADOX
] = USES_CC_SRC
| USES_CC_SRC2
,
208 [CC_OP_ADCOX
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
212 static void set_cc_op(DisasContext
*s
, CCOp op
)
216 if (s
->cc_op
== op
) {
220 /* Discard CC computation that will no longer be used. */
221 dead
= cc_op_live
[s
->cc_op
] & ~cc_op_live
[op
];
222 if (dead
& USES_CC_DST
) {
223 tcg_gen_discard_tl(cpu_cc_dst
);
225 if (dead
& USES_CC_SRC
) {
226 tcg_gen_discard_tl(cpu_cc_src
);
228 if (dead
& USES_CC_SRC2
) {
229 tcg_gen_discard_tl(cpu_cc_src2
);
231 if (dead
& USES_CC_SRCT
) {
232 tcg_gen_discard_tl(cpu_cc_srcT
);
235 if (op
== CC_OP_DYNAMIC
) {
236 /* The DYNAMIC setting is translator only, and should never be
237 stored. Thus we always consider it clean. */
238 s
->cc_op_dirty
= false;
240 /* Discard any computed CC_OP value (see shifts). */
241 if (s
->cc_op
== CC_OP_DYNAMIC
) {
242 tcg_gen_discard_i32(cpu_cc_op
);
244 s
->cc_op_dirty
= true;
249 static void gen_update_cc_op(DisasContext
*s
)
251 if (s
->cc_op_dirty
) {
252 tcg_gen_movi_i32(cpu_cc_op
, s
->cc_op
);
253 s
->cc_op_dirty
= false;
259 #define NB_OP_SIZES 4
261 #else /* !TARGET_X86_64 */
263 #define NB_OP_SIZES 3
265 #endif /* !TARGET_X86_64 */
267 #if defined(HOST_WORDS_BIGENDIAN)
268 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
269 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
270 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
271 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
272 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
274 #define REG_B_OFFSET 0
275 #define REG_H_OFFSET 1
276 #define REG_W_OFFSET 0
277 #define REG_L_OFFSET 0
278 #define REG_LH_OFFSET 4
281 /* In instruction encodings for byte register accesses the
282 * register number usually indicates "low 8 bits of register N";
283 * however there are some special cases where N 4..7 indicates
284 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
285 * true for this special case, false otherwise.
287 static inline bool byte_reg_is_xH(int reg
)
293 if (reg
>= 8 || x86_64_hregs
) {
300 /* Select the size of a push/pop operation. */
301 static inline TCGMemOp
mo_pushpop(DisasContext
*s
, TCGMemOp ot
)
304 return ot
== MO_16
? MO_16
: MO_64
;
310 /* Select only size 64 else 32. Used for SSE operand sizes. */
311 static inline TCGMemOp
mo_64_32(TCGMemOp ot
)
314 return ot
== MO_64
? MO_64
: MO_32
;
320 /* Select size 8 if lsb of B is clear, else OT. Used for decoding
321 byte vs word opcodes. */
322 static inline TCGMemOp
mo_b_d(int b
, TCGMemOp ot
)
324 return b
& 1 ? ot
: MO_8
;
327 /* Select size 8 if lsb of B is clear, else OT capped at 32.
328 Used for decoding operand size of port opcodes. */
329 static inline TCGMemOp
mo_b_d32(int b
, TCGMemOp ot
)
331 return b
& 1 ? (ot
== MO_16
? MO_16
: MO_32
) : MO_8
;
334 static void gen_op_mov_reg_v(TCGMemOp ot
, int reg
, TCGv t0
)
338 if (!byte_reg_is_xH(reg
)) {
339 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 8);
341 tcg_gen_deposit_tl(cpu_regs
[reg
- 4], cpu_regs
[reg
- 4], t0
, 8, 8);
345 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 16);
348 /* For x86_64, this sets the higher half of register to zero.
349 For i386, this is equivalent to a mov. */
350 tcg_gen_ext32u_tl(cpu_regs
[reg
], t0
);
354 tcg_gen_mov_tl(cpu_regs
[reg
], t0
);
362 static inline void gen_op_mov_v_reg(TCGMemOp ot
, TCGv t0
, int reg
)
364 if (ot
== MO_8
&& byte_reg_is_xH(reg
)) {
365 tcg_gen_shri_tl(t0
, cpu_regs
[reg
- 4], 8);
366 tcg_gen_ext8u_tl(t0
, t0
);
368 tcg_gen_mov_tl(t0
, cpu_regs
[reg
]);
372 static inline void gen_op_movl_A0_reg(int reg
)
374 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[reg
]);
377 static inline void gen_op_addl_A0_im(int32_t val
)
379 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, val
);
381 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffffffff);
386 static inline void gen_op_addq_A0_im(int64_t val
)
388 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, val
);
392 static void gen_add_A0_im(DisasContext
*s
, int val
)
396 gen_op_addq_A0_im(val
);
399 gen_op_addl_A0_im(val
);
402 static inline void gen_op_jmp_v(TCGv dest
)
404 tcg_gen_st_tl(dest
, cpu_env
, offsetof(CPUX86State
, eip
));
407 static inline void gen_op_add_reg_im(TCGMemOp size
, int reg
, int32_t val
)
409 tcg_gen_addi_tl(cpu_tmp0
, cpu_regs
[reg
], val
);
410 gen_op_mov_reg_v(size
, reg
, cpu_tmp0
);
413 static inline void gen_op_add_reg_T0(TCGMemOp size
, int reg
)
415 tcg_gen_add_tl(cpu_tmp0
, cpu_regs
[reg
], cpu_T
[0]);
416 gen_op_mov_reg_v(size
, reg
, cpu_tmp0
);
419 static inline void gen_op_addl_A0_reg_sN(int shift
, int reg
)
421 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[reg
]);
423 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, shift
);
424 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
425 /* For x86_64, this sets the higher half of register to zero.
426 For i386, this is equivalent to a nop. */
427 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
430 static inline void gen_op_movl_A0_seg(int reg
)
432 tcg_gen_ld32u_tl(cpu_A0
, cpu_env
, offsetof(CPUX86State
, segs
[reg
].base
) + REG_L_OFFSET
);
435 static inline void gen_op_addl_A0_seg(DisasContext
*s
, int reg
)
437 tcg_gen_ld_tl(cpu_tmp0
, cpu_env
, offsetof(CPUX86State
, segs
[reg
].base
));
440 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffffffff);
441 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
443 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
444 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffffffff);
447 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
452 static inline void gen_op_movq_A0_seg(int reg
)
454 tcg_gen_ld_tl(cpu_A0
, cpu_env
, offsetof(CPUX86State
, segs
[reg
].base
));
457 static inline void gen_op_addq_A0_seg(int reg
)
459 tcg_gen_ld_tl(cpu_tmp0
, cpu_env
, offsetof(CPUX86State
, segs
[reg
].base
));
460 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
463 static inline void gen_op_movq_A0_reg(int reg
)
465 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[reg
]);
468 static inline void gen_op_addq_A0_reg_sN(int shift
, int reg
)
470 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[reg
]);
472 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, shift
);
473 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
477 static inline void gen_op_ld_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
479 tcg_gen_qemu_ld_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
482 static inline void gen_op_st_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
484 tcg_gen_qemu_st_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
487 static inline void gen_op_st_rm_T0_A0(DisasContext
*s
, int idx
, int d
)
490 gen_op_st_v(s
, idx
, cpu_T
[0], cpu_A0
);
492 gen_op_mov_reg_v(idx
, d
, cpu_T
[0]);
496 static inline void gen_jmp_im(target_ulong pc
)
498 tcg_gen_movi_tl(cpu_tmp0
, pc
);
499 gen_op_jmp_v(cpu_tmp0
);
502 static inline void gen_string_movl_A0_ESI(DisasContext
*s
)
506 override
= s
->override
;
511 gen_op_movq_A0_seg(override
);
512 gen_op_addq_A0_reg_sN(0, R_ESI
);
514 gen_op_movq_A0_reg(R_ESI
);
520 if (s
->addseg
&& override
< 0)
523 gen_op_movl_A0_seg(override
);
524 gen_op_addl_A0_reg_sN(0, R_ESI
);
526 gen_op_movl_A0_reg(R_ESI
);
530 /* 16 address, always override */
533 tcg_gen_ext16u_tl(cpu_A0
, cpu_regs
[R_ESI
]);
534 gen_op_addl_A0_seg(s
, override
);
541 static inline void gen_string_movl_A0_EDI(DisasContext
*s
)
546 gen_op_movq_A0_reg(R_EDI
);
551 gen_op_movl_A0_seg(R_ES
);
552 gen_op_addl_A0_reg_sN(0, R_EDI
);
554 gen_op_movl_A0_reg(R_EDI
);
558 tcg_gen_ext16u_tl(cpu_A0
, cpu_regs
[R_EDI
]);
559 gen_op_addl_A0_seg(s
, R_ES
);
566 static inline void gen_op_movl_T0_Dshift(TCGMemOp ot
)
568 tcg_gen_ld32s_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, df
));
569 tcg_gen_shli_tl(cpu_T
[0], cpu_T
[0], ot
);
572 static TCGv
gen_ext_tl(TCGv dst
, TCGv src
, TCGMemOp size
, bool sign
)
577 tcg_gen_ext8s_tl(dst
, src
);
579 tcg_gen_ext8u_tl(dst
, src
);
584 tcg_gen_ext16s_tl(dst
, src
);
586 tcg_gen_ext16u_tl(dst
, src
);
592 tcg_gen_ext32s_tl(dst
, src
);
594 tcg_gen_ext32u_tl(dst
, src
);
603 static void gen_extu(TCGMemOp ot
, TCGv reg
)
605 gen_ext_tl(reg
, reg
, ot
, false);
608 static void gen_exts(TCGMemOp ot
, TCGv reg
)
610 gen_ext_tl(reg
, reg
, ot
, true);
613 static inline void gen_op_jnz_ecx(TCGMemOp size
, TCGLabel
*label1
)
615 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[R_ECX
]);
616 gen_extu(size
, cpu_tmp0
);
617 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_tmp0
, 0, label1
);
620 static inline void gen_op_jz_ecx(TCGMemOp size
, TCGLabel
*label1
)
622 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[R_ECX
]);
623 gen_extu(size
, cpu_tmp0
);
624 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
627 static void gen_helper_in_func(TCGMemOp ot
, TCGv v
, TCGv_i32 n
)
631 gen_helper_inb(v
, cpu_env
, n
);
634 gen_helper_inw(v
, cpu_env
, n
);
637 gen_helper_inl(v
, cpu_env
, n
);
644 static void gen_helper_out_func(TCGMemOp ot
, TCGv_i32 v
, TCGv_i32 n
)
648 gen_helper_outb(cpu_env
, v
, n
);
651 gen_helper_outw(cpu_env
, v
, n
);
654 gen_helper_outl(cpu_env
, v
, n
);
661 static void gen_check_io(DisasContext
*s
, TCGMemOp ot
, target_ulong cur_eip
,
664 target_ulong next_eip
;
666 if (s
->pe
&& (s
->cpl
> s
->iopl
|| s
->vm86
)) {
667 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
670 gen_helper_check_iob(cpu_env
, cpu_tmp2_i32
);
673 gen_helper_check_iow(cpu_env
, cpu_tmp2_i32
);
676 gen_helper_check_iol(cpu_env
, cpu_tmp2_i32
);
682 if(s
->flags
& HF_SVMI_MASK
) {
685 svm_flags
|= (1 << (4 + ot
));
686 next_eip
= s
->pc
- s
->cs_base
;
687 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
688 gen_helper_svm_check_io(cpu_env
, cpu_tmp2_i32
,
689 tcg_const_i32(svm_flags
),
690 tcg_const_i32(next_eip
- cur_eip
));
694 static inline void gen_movs(DisasContext
*s
, TCGMemOp ot
)
696 gen_string_movl_A0_ESI(s
);
697 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
698 gen_string_movl_A0_EDI(s
);
699 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
700 gen_op_movl_T0_Dshift(ot
);
701 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
702 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
705 static void gen_op_update1_cc(void)
707 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
710 static void gen_op_update2_cc(void)
712 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
713 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
716 static void gen_op_update3_cc(TCGv reg
)
718 tcg_gen_mov_tl(cpu_cc_src2
, reg
);
719 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
720 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
723 static inline void gen_op_testl_T0_T1_cc(void)
725 tcg_gen_and_tl(cpu_cc_dst
, cpu_T
[0], cpu_T
[1]);
728 static void gen_op_update_neg_cc(void)
730 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
731 tcg_gen_neg_tl(cpu_cc_src
, cpu_T
[0]);
732 tcg_gen_movi_tl(cpu_cc_srcT
, 0);
735 /* compute all eflags to cc_src */
736 static void gen_compute_eflags(DisasContext
*s
)
738 TCGv zero
, dst
, src1
, src2
;
741 if (s
->cc_op
== CC_OP_EFLAGS
) {
744 if (s
->cc_op
== CC_OP_CLR
) {
745 tcg_gen_movi_tl(cpu_cc_src
, CC_Z
| CC_P
);
746 set_cc_op(s
, CC_OP_EFLAGS
);
755 /* Take care to not read values that are not live. */
756 live
= cc_op_live
[s
->cc_op
] & ~USES_CC_SRCT
;
757 dead
= live
^ (USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
);
759 zero
= tcg_const_tl(0);
760 if (dead
& USES_CC_DST
) {
763 if (dead
& USES_CC_SRC
) {
766 if (dead
& USES_CC_SRC2
) {
772 gen_helper_cc_compute_all(cpu_cc_src
, dst
, src1
, src2
, cpu_cc_op
);
773 set_cc_op(s
, CC_OP_EFLAGS
);
780 typedef struct CCPrepare
{
790 /* compute eflags.C to reg */
791 static CCPrepare
gen_prepare_eflags_c(DisasContext
*s
, TCGv reg
)
797 case CC_OP_SUBB
... CC_OP_SUBQ
:
798 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
799 size
= s
->cc_op
- CC_OP_SUBB
;
800 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
801 /* If no temporary was used, be careful not to alias t1 and t0. */
802 t0
= TCGV_EQUAL(t1
, cpu_cc_src
) ? cpu_tmp0
: reg
;
803 tcg_gen_mov_tl(t0
, cpu_cc_srcT
);
807 case CC_OP_ADDB
... CC_OP_ADDQ
:
808 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
809 size
= s
->cc_op
- CC_OP_ADDB
;
810 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
811 t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
813 return (CCPrepare
) { .cond
= TCG_COND_LTU
, .reg
= t0
,
814 .reg2
= t1
, .mask
= -1, .use_reg2
= true };
816 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
818 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
820 case CC_OP_INCB
... CC_OP_INCQ
:
821 case CC_OP_DECB
... CC_OP_DECQ
:
822 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
823 .mask
= -1, .no_setcond
= true };
825 case CC_OP_SHLB
... CC_OP_SHLQ
:
826 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
827 size
= s
->cc_op
- CC_OP_SHLB
;
828 shift
= (8 << size
) - 1;
829 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
830 .mask
= (target_ulong
)1 << shift
};
832 case CC_OP_MULB
... CC_OP_MULQ
:
833 return (CCPrepare
) { .cond
= TCG_COND_NE
,
834 .reg
= cpu_cc_src
, .mask
= -1 };
836 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
837 size
= s
->cc_op
- CC_OP_BMILGB
;
838 t0
= gen_ext_tl(reg
, cpu_cc_src
, size
, false);
839 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
843 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_dst
,
844 .mask
= -1, .no_setcond
= true };
847 case CC_OP_SARB
... CC_OP_SARQ
:
849 return (CCPrepare
) { .cond
= TCG_COND_NE
,
850 .reg
= cpu_cc_src
, .mask
= CC_C
};
853 /* The need to compute only C from CC_OP_DYNAMIC is important
854 in efficiently implementing e.g. INC at the start of a TB. */
856 gen_helper_cc_compute_c(reg
, cpu_cc_dst
, cpu_cc_src
,
857 cpu_cc_src2
, cpu_cc_op
);
858 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
859 .mask
= -1, .no_setcond
= true };
863 /* compute eflags.P to reg */
864 static CCPrepare
gen_prepare_eflags_p(DisasContext
*s
, TCGv reg
)
866 gen_compute_eflags(s
);
867 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
871 /* compute eflags.S to reg */
872 static CCPrepare
gen_prepare_eflags_s(DisasContext
*s
, TCGv reg
)
876 gen_compute_eflags(s
);
882 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
885 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
888 TCGMemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
889 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, true);
890 return (CCPrepare
) { .cond
= TCG_COND_LT
, .reg
= t0
, .mask
= -1 };
895 /* compute eflags.O to reg */
896 static CCPrepare
gen_prepare_eflags_o(DisasContext
*s
, TCGv reg
)
901 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src2
,
902 .mask
= -1, .no_setcond
= true };
904 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
906 gen_compute_eflags(s
);
907 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
912 /* compute eflags.Z to reg */
913 static CCPrepare
gen_prepare_eflags_z(DisasContext
*s
, TCGv reg
)
917 gen_compute_eflags(s
);
923 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
926 return (CCPrepare
) { .cond
= TCG_COND_ALWAYS
, .mask
= -1 };
929 TCGMemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
930 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
931 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
936 /* perform a conditional store into register 'reg' according to jump opcode
937 value 'b'. In the fast case, T0 is guaranted not to be used. */
938 static CCPrepare
gen_prepare_cc(DisasContext
*s
, int b
, TCGv reg
)
940 int inv
, jcc_op
, cond
;
946 jcc_op
= (b
>> 1) & 7;
949 case CC_OP_SUBB
... CC_OP_SUBQ
:
950 /* We optimize relational operators for the cmp/jcc case. */
951 size
= s
->cc_op
- CC_OP_SUBB
;
954 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
955 gen_extu(size
, cpu_tmp4
);
956 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
957 cc
= (CCPrepare
) { .cond
= TCG_COND_LEU
, .reg
= cpu_tmp4
,
958 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
967 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
968 gen_exts(size
, cpu_tmp4
);
969 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, true);
970 cc
= (CCPrepare
) { .cond
= cond
, .reg
= cpu_tmp4
,
971 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
981 /* This actually generates good code for JC, JZ and JS. */
984 cc
= gen_prepare_eflags_o(s
, reg
);
987 cc
= gen_prepare_eflags_c(s
, reg
);
990 cc
= gen_prepare_eflags_z(s
, reg
);
993 gen_compute_eflags(s
);
994 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
995 .mask
= CC_Z
| CC_C
};
998 cc
= gen_prepare_eflags_s(s
, reg
);
1001 cc
= gen_prepare_eflags_p(s
, reg
);
1004 gen_compute_eflags(s
);
1005 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
1008 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
1009 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
1010 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
1015 gen_compute_eflags(s
);
1016 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
1019 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
1020 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
1021 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
1022 .mask
= CC_S
| CC_Z
};
1029 cc
.cond
= tcg_invert_cond(cc
.cond
);
1034 static void gen_setcc1(DisasContext
*s
, int b
, TCGv reg
)
1036 CCPrepare cc
= gen_prepare_cc(s
, b
, reg
);
1038 if (cc
.no_setcond
) {
1039 if (cc
.cond
== TCG_COND_EQ
) {
1040 tcg_gen_xori_tl(reg
, cc
.reg
, 1);
1042 tcg_gen_mov_tl(reg
, cc
.reg
);
1047 if (cc
.cond
== TCG_COND_NE
&& !cc
.use_reg2
&& cc
.imm
== 0 &&
1048 cc
.mask
!= 0 && (cc
.mask
& (cc
.mask
- 1)) == 0) {
1049 tcg_gen_shri_tl(reg
, cc
.reg
, ctztl(cc
.mask
));
1050 tcg_gen_andi_tl(reg
, reg
, 1);
1053 if (cc
.mask
!= -1) {
1054 tcg_gen_andi_tl(reg
, cc
.reg
, cc
.mask
);
1058 tcg_gen_setcond_tl(cc
.cond
, reg
, cc
.reg
, cc
.reg2
);
1060 tcg_gen_setcondi_tl(cc
.cond
, reg
, cc
.reg
, cc
.imm
);
1064 static inline void gen_compute_eflags_c(DisasContext
*s
, TCGv reg
)
1066 gen_setcc1(s
, JCC_B
<< 1, reg
);
1069 /* generate a conditional jump to label 'l1' according to jump opcode
1070 value 'b'. In the fast case, T0 is guaranted not to be used. */
1071 static inline void gen_jcc1_noeob(DisasContext
*s
, int b
, TCGLabel
*l1
)
1073 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T
[0]);
1075 if (cc
.mask
!= -1) {
1076 tcg_gen_andi_tl(cpu_T
[0], cc
.reg
, cc
.mask
);
1080 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1082 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1086 /* Generate a conditional jump to label 'l1' according to jump opcode
1087 value 'b'. In the fast case, T0 is guaranted not to be used.
1088 A translation block must end soon. */
1089 static inline void gen_jcc1(DisasContext
*s
, int b
, TCGLabel
*l1
)
1091 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T
[0]);
1093 gen_update_cc_op(s
);
1094 if (cc
.mask
!= -1) {
1095 tcg_gen_andi_tl(cpu_T
[0], cc
.reg
, cc
.mask
);
1098 set_cc_op(s
, CC_OP_DYNAMIC
);
1100 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1102 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1106 /* XXX: does not work with gdbstub "ice" single step - not a
1108 static TCGLabel
*gen_jz_ecx_string(DisasContext
*s
, target_ulong next_eip
)
1110 TCGLabel
*l1
= gen_new_label();
1111 TCGLabel
*l2
= gen_new_label();
1112 gen_op_jnz_ecx(s
->aflag
, l1
);
1114 gen_jmp_tb(s
, next_eip
, 1);
1119 static inline void gen_stos(DisasContext
*s
, TCGMemOp ot
)
1121 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EAX
);
1122 gen_string_movl_A0_EDI(s
);
1123 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
1124 gen_op_movl_T0_Dshift(ot
);
1125 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1128 static inline void gen_lods(DisasContext
*s
, TCGMemOp ot
)
1130 gen_string_movl_A0_ESI(s
);
1131 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1132 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T
[0]);
1133 gen_op_movl_T0_Dshift(ot
);
1134 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1137 static inline void gen_scas(DisasContext
*s
, TCGMemOp ot
)
1139 gen_string_movl_A0_EDI(s
);
1140 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
1141 gen_op(s
, OP_CMPL
, ot
, R_EAX
);
1142 gen_op_movl_T0_Dshift(ot
);
1143 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1146 static inline void gen_cmps(DisasContext
*s
, TCGMemOp ot
)
1148 gen_string_movl_A0_EDI(s
);
1149 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
1150 gen_string_movl_A0_ESI(s
);
1151 gen_op(s
, OP_CMPL
, ot
, OR_TMP0
);
1152 gen_op_movl_T0_Dshift(ot
);
1153 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1154 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1157 static void gen_bpt_io(DisasContext
*s
, TCGv_i32 t_port
, int ot
)
1159 if (s
->flags
& HF_IOBPT_MASK
) {
1160 TCGv_i32 t_size
= tcg_const_i32(1 << ot
);
1161 TCGv t_next
= tcg_const_tl(s
->pc
- s
->cs_base
);
1163 gen_helper_bpt_io(cpu_env
, t_port
, t_size
, t_next
);
1164 tcg_temp_free_i32(t_size
);
1165 tcg_temp_free(t_next
);
1170 static inline void gen_ins(DisasContext
*s
, TCGMemOp ot
)
1172 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1175 gen_string_movl_A0_EDI(s
);
1176 /* Note: we must do this dummy write first to be restartable in
1177 case of page fault. */
1178 tcg_gen_movi_tl(cpu_T
[0], 0);
1179 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
1180 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_EDX
]);
1181 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1182 gen_helper_in_func(ot
, cpu_T
[0], cpu_tmp2_i32
);
1183 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
1184 gen_op_movl_T0_Dshift(ot
);
1185 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1186 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
1187 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1192 static inline void gen_outs(DisasContext
*s
, TCGMemOp ot
)
1194 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1197 gen_string_movl_A0_ESI(s
);
1198 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1200 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_EDX
]);
1201 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1202 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[0]);
1203 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1204 gen_op_movl_T0_Dshift(ot
);
1205 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1206 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
1207 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1212 /* same method as Valgrind : we generate jumps to current or next
1214 #define GEN_REPZ(op) \
1215 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1216 target_ulong cur_eip, target_ulong next_eip) \
1219 gen_update_cc_op(s); \
1220 l2 = gen_jz_ecx_string(s, next_eip); \
1221 gen_ ## op(s, ot); \
1222 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1223 /* a loop would cause two single step exceptions if ECX = 1 \
1224 before rep string_insn */ \
1226 gen_op_jz_ecx(s->aflag, l2); \
1227 gen_jmp(s, cur_eip); \
1230 #define GEN_REPZ2(op) \
1231 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1232 target_ulong cur_eip, \
1233 target_ulong next_eip, \
1237 gen_update_cc_op(s); \
1238 l2 = gen_jz_ecx_string(s, next_eip); \
1239 gen_ ## op(s, ot); \
1240 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1241 gen_update_cc_op(s); \
1242 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
1244 gen_op_jz_ecx(s->aflag, l2); \
1245 gen_jmp(s, cur_eip); \
1256 static void gen_helper_fp_arith_ST0_FT0(int op
)
1260 gen_helper_fadd_ST0_FT0(cpu_env
);
1263 gen_helper_fmul_ST0_FT0(cpu_env
);
1266 gen_helper_fcom_ST0_FT0(cpu_env
);
1269 gen_helper_fcom_ST0_FT0(cpu_env
);
1272 gen_helper_fsub_ST0_FT0(cpu_env
);
1275 gen_helper_fsubr_ST0_FT0(cpu_env
);
1278 gen_helper_fdiv_ST0_FT0(cpu_env
);
1281 gen_helper_fdivr_ST0_FT0(cpu_env
);
1286 /* NOTE the exception in "r" op ordering */
1287 static void gen_helper_fp_arith_STN_ST0(int op
, int opreg
)
1289 TCGv_i32 tmp
= tcg_const_i32(opreg
);
1292 gen_helper_fadd_STN_ST0(cpu_env
, tmp
);
1295 gen_helper_fmul_STN_ST0(cpu_env
, tmp
);
1298 gen_helper_fsubr_STN_ST0(cpu_env
, tmp
);
1301 gen_helper_fsub_STN_ST0(cpu_env
, tmp
);
1304 gen_helper_fdivr_STN_ST0(cpu_env
, tmp
);
1307 gen_helper_fdiv_STN_ST0(cpu_env
, tmp
);
1312 /* if d == OR_TMP0, it means memory operand (address in A0) */
1313 static void gen_op(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
)
1316 gen_op_mov_v_reg(ot
, cpu_T
[0], d
);
1318 gen_op_ld_v(s1
, ot
, cpu_T
[0], cpu_A0
);
1322 gen_compute_eflags_c(s1
, cpu_tmp4
);
1323 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1324 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_tmp4
);
1325 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1326 gen_op_update3_cc(cpu_tmp4
);
1327 set_cc_op(s1
, CC_OP_ADCB
+ ot
);
1330 gen_compute_eflags_c(s1
, cpu_tmp4
);
1331 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1332 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_tmp4
);
1333 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1334 gen_op_update3_cc(cpu_tmp4
);
1335 set_cc_op(s1
, CC_OP_SBBB
+ ot
);
1338 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1339 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1340 gen_op_update2_cc();
1341 set_cc_op(s1
, CC_OP_ADDB
+ ot
);
1344 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T
[0]);
1345 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1346 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1347 gen_op_update2_cc();
1348 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1352 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1353 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1354 gen_op_update1_cc();
1355 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1358 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1359 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1360 gen_op_update1_cc();
1361 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1364 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1365 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1366 gen_op_update1_cc();
1367 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1370 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
1371 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T
[0]);
1372 tcg_gen_sub_tl(cpu_cc_dst
, cpu_T
[0], cpu_T
[1]);
1373 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1378 /* if d == OR_TMP0, it means memory operand (address in A0) */
1379 static void gen_inc(DisasContext
*s1
, TCGMemOp ot
, int d
, int c
)
1382 gen_op_mov_v_reg(ot
, cpu_T
[0], d
);
1384 gen_op_ld_v(s1
, ot
, cpu_T
[0], cpu_A0
);
1386 gen_compute_eflags_c(s1
, cpu_cc_src
);
1388 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], 1);
1389 set_cc_op(s1
, CC_OP_INCB
+ ot
);
1391 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], -1);
1392 set_cc_op(s1
, CC_OP_DECB
+ ot
);
1394 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1395 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
1398 static void gen_shift_flags(DisasContext
*s
, TCGMemOp ot
, TCGv result
,
1399 TCGv shm1
, TCGv count
, bool is_right
)
1401 TCGv_i32 z32
, s32
, oldop
;
1404 /* Store the results into the CC variables. If we know that the
1405 variable must be dead, store unconditionally. Otherwise we'll
1406 need to not disrupt the current contents. */
1407 z_tl
= tcg_const_tl(0);
1408 if (cc_op_live
[s
->cc_op
] & USES_CC_DST
) {
1409 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_dst
, count
, z_tl
,
1410 result
, cpu_cc_dst
);
1412 tcg_gen_mov_tl(cpu_cc_dst
, result
);
1414 if (cc_op_live
[s
->cc_op
] & USES_CC_SRC
) {
1415 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_src
, count
, z_tl
,
1418 tcg_gen_mov_tl(cpu_cc_src
, shm1
);
1420 tcg_temp_free(z_tl
);
1422 /* Get the two potential CC_OP values into temporaries. */
1423 tcg_gen_movi_i32(cpu_tmp2_i32
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1424 if (s
->cc_op
== CC_OP_DYNAMIC
) {
1427 tcg_gen_movi_i32(cpu_tmp3_i32
, s
->cc_op
);
1428 oldop
= cpu_tmp3_i32
;
1431 /* Conditionally store the CC_OP value. */
1432 z32
= tcg_const_i32(0);
1433 s32
= tcg_temp_new_i32();
1434 tcg_gen_trunc_tl_i32(s32
, count
);
1435 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, s32
, z32
, cpu_tmp2_i32
, oldop
);
1436 tcg_temp_free_i32(z32
);
1437 tcg_temp_free_i32(s32
);
1439 /* The CC_OP value is no longer predictable. */
1440 set_cc_op(s
, CC_OP_DYNAMIC
);
1443 static void gen_shift_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1444 int is_right
, int is_arith
)
1446 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1449 if (op1
== OR_TMP0
) {
1450 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1452 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1455 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], mask
);
1456 tcg_gen_subi_tl(cpu_tmp0
, cpu_T
[1], 1);
1460 gen_exts(ot
, cpu_T
[0]);
1461 tcg_gen_sar_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1462 tcg_gen_sar_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1464 gen_extu(ot
, cpu_T
[0]);
1465 tcg_gen_shr_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1466 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1469 tcg_gen_shl_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1470 tcg_gen_shl_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1474 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1476 gen_shift_flags(s
, ot
, cpu_T
[0], cpu_tmp0
, cpu_T
[1], is_right
);
1479 static void gen_shift_rm_im(DisasContext
*s
, TCGMemOp ot
, int op1
, int op2
,
1480 int is_right
, int is_arith
)
1482 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1486 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1488 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1494 gen_exts(ot
, cpu_T
[0]);
1495 tcg_gen_sari_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1496 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], op2
);
1498 gen_extu(ot
, cpu_T
[0]);
1499 tcg_gen_shri_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1500 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], op2
);
1503 tcg_gen_shli_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1504 tcg_gen_shli_tl(cpu_T
[0], cpu_T
[0], op2
);
1509 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1511 /* update eflags if non zero shift */
1513 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
1514 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
1515 set_cc_op(s
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1519 static void gen_rot_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
, int is_right
)
1521 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1525 if (op1
== OR_TMP0
) {
1526 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1528 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1531 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], mask
);
1535 /* Replicate the 8-bit input so that a 32-bit rotate works. */
1536 tcg_gen_ext8u_tl(cpu_T
[0], cpu_T
[0]);
1537 tcg_gen_muli_tl(cpu_T
[0], cpu_T
[0], 0x01010101);
1540 /* Replicate the 16-bit input so that a 32-bit rotate works. */
1541 tcg_gen_deposit_tl(cpu_T
[0], cpu_T
[0], cpu_T
[0], 16, 16);
1544 #ifdef TARGET_X86_64
1546 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
1547 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
1549 tcg_gen_rotr_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1551 tcg_gen_rotl_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1553 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
1558 tcg_gen_rotr_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1560 tcg_gen_rotl_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1566 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1568 /* We'll need the flags computed into CC_SRC. */
1569 gen_compute_eflags(s
);
1571 /* The value that was "rotated out" is now present at the other end
1572 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1573 since we've computed the flags into CC_SRC, these variables are
1576 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T
[0], mask
- 1);
1577 tcg_gen_shri_tl(cpu_cc_dst
, cpu_T
[0], mask
);
1578 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1580 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T
[0], mask
);
1581 tcg_gen_andi_tl(cpu_cc_dst
, cpu_T
[0], 1);
1583 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1584 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1586 /* Now conditionally store the new CC_OP value. If the shift count
1587 is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1588 Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1589 exactly as we computed above. */
1590 t0
= tcg_const_i32(0);
1591 t1
= tcg_temp_new_i32();
1592 tcg_gen_trunc_tl_i32(t1
, cpu_T
[1]);
1593 tcg_gen_movi_i32(cpu_tmp2_i32
, CC_OP_ADCOX
);
1594 tcg_gen_movi_i32(cpu_tmp3_i32
, CC_OP_EFLAGS
);
1595 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, t1
, t0
,
1596 cpu_tmp2_i32
, cpu_tmp3_i32
);
1597 tcg_temp_free_i32(t0
);
1598 tcg_temp_free_i32(t1
);
1600 /* The CC_OP value is no longer predictable. */
1601 set_cc_op(s
, CC_OP_DYNAMIC
);
1604 static void gen_rot_rm_im(DisasContext
*s
, TCGMemOp ot
, int op1
, int op2
,
1607 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1611 if (op1
== OR_TMP0
) {
1612 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1614 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1620 #ifdef TARGET_X86_64
1622 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
1624 tcg_gen_rotri_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, op2
);
1626 tcg_gen_rotli_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, op2
);
1628 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
1633 tcg_gen_rotri_tl(cpu_T
[0], cpu_T
[0], op2
);
1635 tcg_gen_rotli_tl(cpu_T
[0], cpu_T
[0], op2
);
1646 shift
= mask
+ 1 - shift
;
1648 gen_extu(ot
, cpu_T
[0]);
1649 tcg_gen_shli_tl(cpu_tmp0
, cpu_T
[0], shift
);
1650 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], mask
+ 1 - shift
);
1651 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
1657 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1660 /* Compute the flags into CC_SRC. */
1661 gen_compute_eflags(s
);
1663 /* The value that was "rotated out" is now present at the other end
1664 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1665 since we've computed the flags into CC_SRC, these variables are
1668 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T
[0], mask
- 1);
1669 tcg_gen_shri_tl(cpu_cc_dst
, cpu_T
[0], mask
);
1670 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1672 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T
[0], mask
);
1673 tcg_gen_andi_tl(cpu_cc_dst
, cpu_T
[0], 1);
1675 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1676 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1677 set_cc_op(s
, CC_OP_ADCOX
);
1681 /* XXX: add faster immediate = 1 case */
1682 static void gen_rotc_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1685 gen_compute_eflags(s
);
1686 assert(s
->cc_op
== CC_OP_EFLAGS
);
1690 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1692 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1697 gen_helper_rcrb(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1700 gen_helper_rcrw(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1703 gen_helper_rcrl(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1705 #ifdef TARGET_X86_64
1707 gen_helper_rcrq(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1716 gen_helper_rclb(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1719 gen_helper_rclw(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1722 gen_helper_rcll(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1724 #ifdef TARGET_X86_64
1726 gen_helper_rclq(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1734 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1737 /* XXX: add faster immediate case */
1738 static void gen_shiftd_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1739 bool is_right
, TCGv count_in
)
1741 target_ulong mask
= (ot
== MO_64
? 63 : 31);
1745 if (op1
== OR_TMP0
) {
1746 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1748 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1751 count
= tcg_temp_new();
1752 tcg_gen_andi_tl(count
, count_in
, mask
);
1756 /* Note: we implement the Intel behaviour for shift count > 16.
1757 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A
1758 portion by constructing it as a 32-bit value. */
1760 tcg_gen_deposit_tl(cpu_tmp0
, cpu_T
[0], cpu_T
[1], 16, 16);
1761 tcg_gen_mov_tl(cpu_T
[1], cpu_T
[0]);
1762 tcg_gen_mov_tl(cpu_T
[0], cpu_tmp0
);
1764 tcg_gen_deposit_tl(cpu_T
[1], cpu_T
[0], cpu_T
[1], 16, 16);
1767 #ifdef TARGET_X86_64
1769 /* Concatenate the two 32-bit values and use a 64-bit shift. */
1770 tcg_gen_subi_tl(cpu_tmp0
, count
, 1);
1772 tcg_gen_concat_tl_i64(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1773 tcg_gen_shr_i64(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1774 tcg_gen_shr_i64(cpu_T
[0], cpu_T
[0], count
);
1776 tcg_gen_concat_tl_i64(cpu_T
[0], cpu_T
[1], cpu_T
[0]);
1777 tcg_gen_shl_i64(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1778 tcg_gen_shl_i64(cpu_T
[0], cpu_T
[0], count
);
1779 tcg_gen_shri_i64(cpu_tmp0
, cpu_tmp0
, 32);
1780 tcg_gen_shri_i64(cpu_T
[0], cpu_T
[0], 32);
1785 tcg_gen_subi_tl(cpu_tmp0
, count
, 1);
1787 tcg_gen_shr_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1789 tcg_gen_subfi_tl(cpu_tmp4
, mask
+ 1, count
);
1790 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], count
);
1791 tcg_gen_shl_tl(cpu_T
[1], cpu_T
[1], cpu_tmp4
);
1793 tcg_gen_shl_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1795 /* Only needed if count > 16, for Intel behaviour. */
1796 tcg_gen_subfi_tl(cpu_tmp4
, 33, count
);
1797 tcg_gen_shr_tl(cpu_tmp4
, cpu_T
[1], cpu_tmp4
);
1798 tcg_gen_or_tl(cpu_tmp0
, cpu_tmp0
, cpu_tmp4
);
1801 tcg_gen_subfi_tl(cpu_tmp4
, mask
+ 1, count
);
1802 tcg_gen_shl_tl(cpu_T
[0], cpu_T
[0], count
);
1803 tcg_gen_shr_tl(cpu_T
[1], cpu_T
[1], cpu_tmp4
);
1805 tcg_gen_movi_tl(cpu_tmp4
, 0);
1806 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_T
[1], count
, cpu_tmp4
,
1807 cpu_tmp4
, cpu_T
[1]);
1808 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1813 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1815 gen_shift_flags(s
, ot
, cpu_T
[0], cpu_tmp0
, count
, is_right
);
1816 tcg_temp_free(count
);
1819 static void gen_shift(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
, int s
)
1822 gen_op_mov_v_reg(ot
, cpu_T
[1], s
);
1825 gen_rot_rm_T1(s1
, ot
, d
, 0);
1828 gen_rot_rm_T1(s1
, ot
, d
, 1);
1832 gen_shift_rm_T1(s1
, ot
, d
, 0, 0);
1835 gen_shift_rm_T1(s1
, ot
, d
, 1, 0);
1838 gen_shift_rm_T1(s1
, ot
, d
, 1, 1);
1841 gen_rotc_rm_T1(s1
, ot
, d
, 0);
1844 gen_rotc_rm_T1(s1
, ot
, d
, 1);
1849 static void gen_shifti(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
, int c
)
1853 gen_rot_rm_im(s1
, ot
, d
, c
, 0);
1856 gen_rot_rm_im(s1
, ot
, d
, c
, 1);
1860 gen_shift_rm_im(s1
, ot
, d
, c
, 0, 0);
1863 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 0);
1866 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 1);
1869 /* currently not optimized */
1870 tcg_gen_movi_tl(cpu_T
[1], c
);
1871 gen_shift(s1
, op
, ot
, d
, OR_TMP1
);
1876 static void gen_lea_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
1883 int mod
, rm
, code
, override
, must_add_seg
;
1886 override
= s
->override
;
1887 must_add_seg
= s
->addseg
;
1890 mod
= (modrm
>> 6) & 3;
1903 code
= cpu_ldub_code(env
, s
->pc
++);
1904 scale
= (code
>> 6) & 3;
1905 index
= ((code
>> 3) & 7) | REX_X(s
);
1907 index
= -1; /* no index */
1915 if ((base
& 7) == 5) {
1917 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
1919 if (CODE64(s
) && !havesib
) {
1920 disp
+= s
->pc
+ s
->rip_offset
;
1927 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
1931 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
1936 /* For correct popl handling with esp. */
1937 if (base
== R_ESP
&& s
->popl_esp_hack
) {
1938 disp
+= s
->popl_esp_hack
;
1941 /* Compute the address, with a minimum number of TCG ops. */
1945 sum
= cpu_regs
[index
];
1947 tcg_gen_shli_tl(cpu_A0
, cpu_regs
[index
], scale
);
1951 tcg_gen_add_tl(cpu_A0
, sum
, cpu_regs
[base
]);
1954 } else if (base
>= 0) {
1955 sum
= cpu_regs
[base
];
1957 if (TCGV_IS_UNUSED(sum
)) {
1958 tcg_gen_movi_tl(cpu_A0
, disp
);
1960 tcg_gen_addi_tl(cpu_A0
, sum
, disp
);
1965 if (base
== R_EBP
|| base
== R_ESP
) {
1972 tcg_gen_ld_tl(cpu_tmp0
, cpu_env
,
1973 offsetof(CPUX86State
, segs
[override
].base
));
1975 if (s
->aflag
== MO_32
) {
1976 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
1978 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
1982 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
1985 if (s
->aflag
== MO_32
) {
1986 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
1994 disp
= cpu_lduw_code(env
, s
->pc
);
1996 tcg_gen_movi_tl(cpu_A0
, disp
);
1997 rm
= 0; /* avoid SS override */
2004 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
2008 disp
= (int16_t)cpu_lduw_code(env
, s
->pc
);
2016 tcg_gen_add_tl(cpu_A0
, cpu_regs
[R_EBX
], cpu_regs
[R_ESI
]);
2019 tcg_gen_add_tl(cpu_A0
, cpu_regs
[R_EBX
], cpu_regs
[R_EDI
]);
2022 tcg_gen_add_tl(cpu_A0
, cpu_regs
[R_EBP
], cpu_regs
[R_ESI
]);
2025 tcg_gen_add_tl(cpu_A0
, cpu_regs
[R_EBP
], cpu_regs
[R_EDI
]);
2028 sum
= cpu_regs
[R_ESI
];
2031 sum
= cpu_regs
[R_EDI
];
2034 sum
= cpu_regs
[R_EBP
];
2038 sum
= cpu_regs
[R_EBX
];
2041 tcg_gen_addi_tl(cpu_A0
, sum
, disp
);
2042 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2046 if (rm
== 2 || rm
== 3 || rm
== 6) {
2052 gen_op_addl_A0_seg(s
, override
);
2061 static void gen_nop_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2063 int mod
, rm
, base
, code
;
2065 mod
= (modrm
>> 6) & 3;
2076 code
= cpu_ldub_code(env
, s
->pc
++);
2118 /* used for LEA and MOV AX, mem */
2119 static void gen_add_A0_ds_seg(DisasContext
*s
)
2121 int override
, must_add_seg
;
2122 must_add_seg
= s
->addseg
;
2124 if (s
->override
>= 0) {
2125 override
= s
->override
;
2129 #ifdef TARGET_X86_64
2131 gen_op_addq_A0_seg(override
);
2135 gen_op_addl_A0_seg(s
, override
);
2140 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2142 static void gen_ldst_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2143 TCGMemOp ot
, int reg
, int is_store
)
2147 mod
= (modrm
>> 6) & 3;
2148 rm
= (modrm
& 7) | REX_B(s
);
2152 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
2153 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
2155 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
2157 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
2160 gen_lea_modrm(env
, s
, modrm
);
2163 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
2164 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
2166 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
2168 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
2173 static inline uint32_t insn_get(CPUX86State
*env
, DisasContext
*s
, TCGMemOp ot
)
2179 ret
= cpu_ldub_code(env
, s
->pc
);
2183 ret
= cpu_lduw_code(env
, s
->pc
);
2187 #ifdef TARGET_X86_64
2190 ret
= cpu_ldl_code(env
, s
->pc
);
2199 static inline int insn_const_size(TCGMemOp ot
)
2208 static inline void gen_goto_tb(DisasContext
*s
, int tb_num
, target_ulong eip
)
2210 TranslationBlock
*tb
;
2213 pc
= s
->cs_base
+ eip
;
2215 /* NOTE: we handle the case where the TB spans two pages here */
2216 if ((pc
& TARGET_PAGE_MASK
) == (tb
->pc
& TARGET_PAGE_MASK
) ||
2217 (pc
& TARGET_PAGE_MASK
) == ((s
->pc
- 1) & TARGET_PAGE_MASK
)) {
2218 /* jump to same page: we can use a direct jump */
2219 tcg_gen_goto_tb(tb_num
);
2221 tcg_gen_exit_tb((uintptr_t)tb
+ tb_num
);
2223 /* jump to another page: currently not optimized */
2229 static inline void gen_jcc(DisasContext
*s
, int b
,
2230 target_ulong val
, target_ulong next_eip
)
2235 l1
= gen_new_label();
2238 gen_goto_tb(s
, 0, next_eip
);
2241 gen_goto_tb(s
, 1, val
);
2242 s
->is_jmp
= DISAS_TB_JUMP
;
2244 l1
= gen_new_label();
2245 l2
= gen_new_label();
2248 gen_jmp_im(next_eip
);
2258 static void gen_cmovcc1(CPUX86State
*env
, DisasContext
*s
, TCGMemOp ot
, int b
,
2263 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
2265 cc
= gen_prepare_cc(s
, b
, cpu_T
[1]);
2266 if (cc
.mask
!= -1) {
2267 TCGv t0
= tcg_temp_new();
2268 tcg_gen_andi_tl(t0
, cc
.reg
, cc
.mask
);
2272 cc
.reg2
= tcg_const_tl(cc
.imm
);
2275 tcg_gen_movcond_tl(cc
.cond
, cpu_T
[0], cc
.reg
, cc
.reg2
,
2276 cpu_T
[0], cpu_regs
[reg
]);
2277 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
2279 if (cc
.mask
!= -1) {
2280 tcg_temp_free(cc
.reg
);
2283 tcg_temp_free(cc
.reg2
);
2287 static inline void gen_op_movl_T0_seg(int seg_reg
)
2289 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
,
2290 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2293 static inline void gen_op_movl_seg_T0_vm(int seg_reg
)
2295 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffff);
2296 tcg_gen_st32_tl(cpu_T
[0], cpu_env
,
2297 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2298 tcg_gen_shli_tl(cpu_T
[0], cpu_T
[0], 4);
2299 tcg_gen_st_tl(cpu_T
[0], cpu_env
,
2300 offsetof(CPUX86State
,segs
[seg_reg
].base
));
2303 /* move T0 to seg_reg and compute if the CPU state may change. Never
2304 call this function with seg_reg == R_CS */
2305 static void gen_movl_seg_T0(DisasContext
*s
, int seg_reg
)
2307 if (s
->pe
&& !s
->vm86
) {
2308 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
2309 gen_helper_load_seg(cpu_env
, tcg_const_i32(seg_reg
), cpu_tmp2_i32
);
2310 /* abort translation because the addseg value may change or
2311 because ss32 may change. For R_SS, translation must always
2312 stop as a special handling must be done to disable hardware
2313 interrupts for the next instruction */
2314 if (seg_reg
== R_SS
|| (s
->code32
&& seg_reg
< R_FS
))
2315 s
->is_jmp
= DISAS_TB_JUMP
;
2317 gen_op_movl_seg_T0_vm(seg_reg
);
2318 if (seg_reg
== R_SS
)
2319 s
->is_jmp
= DISAS_TB_JUMP
;
2323 static inline int svm_is_rep(int prefixes
)
2325 return ((prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) ? 8 : 0);
2329 gen_svm_check_intercept_param(DisasContext
*s
, target_ulong pc_start
,
2330 uint32_t type
, uint64_t param
)
2332 /* no SVM activated; fast case */
2333 if (likely(!(s
->flags
& HF_SVMI_MASK
)))
2335 gen_update_cc_op(s
);
2336 gen_jmp_im(pc_start
- s
->cs_base
);
2337 gen_helper_svm_check_intercept_param(cpu_env
, tcg_const_i32(type
),
2338 tcg_const_i64(param
));
2342 gen_svm_check_intercept(DisasContext
*s
, target_ulong pc_start
, uint64_t type
)
2344 gen_svm_check_intercept_param(s
, pc_start
, type
, 0);
2347 static inline void gen_stack_update(DisasContext
*s
, int addend
)
2349 #ifdef TARGET_X86_64
2351 gen_op_add_reg_im(MO_64
, R_ESP
, addend
);
2355 gen_op_add_reg_im(MO_32
, R_ESP
, addend
);
2357 gen_op_add_reg_im(MO_16
, R_ESP
, addend
);
2361 /* Generate a push. It depends on ss32, addseg and dflag. */
2362 static void gen_push_v(DisasContext
*s
, TCGv val
)
2364 TCGMemOp a_ot
, d_ot
= mo_pushpop(s
, s
->dflag
);
2365 int size
= 1 << d_ot
;
2366 TCGv new_esp
= cpu_A0
;
2368 tcg_gen_subi_tl(cpu_A0
, cpu_regs
[R_ESP
], size
);
2372 } else if (s
->ss32
) {
2376 tcg_gen_mov_tl(new_esp
, cpu_A0
);
2377 gen_op_addl_A0_seg(s
, R_SS
);
2379 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
2384 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2385 tcg_gen_mov_tl(new_esp
, cpu_A0
);
2386 gen_op_addl_A0_seg(s
, R_SS
);
2389 gen_op_st_v(s
, d_ot
, val
, cpu_A0
);
2390 gen_op_mov_reg_v(a_ot
, R_ESP
, new_esp
);
2393 /* two step pop is necessary for precise exceptions */
2394 static TCGMemOp
gen_pop_T0(DisasContext
*s
)
2396 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2400 addr
= cpu_regs
[R_ESP
];
2401 } else if (!s
->ss32
) {
2402 tcg_gen_ext16u_tl(cpu_A0
, cpu_regs
[R_ESP
]);
2403 gen_op_addl_A0_seg(s
, R_SS
);
2404 } else if (s
->addseg
) {
2405 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_ESP
]);
2406 gen_op_addl_A0_seg(s
, R_SS
);
2408 tcg_gen_ext32u_tl(cpu_A0
, cpu_regs
[R_ESP
]);
2411 gen_op_ld_v(s
, d_ot
, cpu_T
[0], addr
);
2415 static void gen_pop_update(DisasContext
*s
, TCGMemOp ot
)
2417 gen_stack_update(s
, 1 << ot
);
2420 static void gen_stack_A0(DisasContext
*s
)
2422 gen_op_movl_A0_reg(R_ESP
);
2424 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2425 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2427 gen_op_addl_A0_seg(s
, R_SS
);
2430 /* NOTE: wrap around in 16 bit not fully handled */
2431 static void gen_pusha(DisasContext
*s
)
2434 gen_op_movl_A0_reg(R_ESP
);
2435 gen_op_addl_A0_im(-(8 << s
->dflag
));
2437 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2438 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2440 gen_op_addl_A0_seg(s
, R_SS
);
2441 for(i
= 0;i
< 8; i
++) {
2442 gen_op_mov_v_reg(MO_32
, cpu_T
[0], 7 - i
);
2443 gen_op_st_v(s
, s
->dflag
, cpu_T
[0], cpu_A0
);
2444 gen_op_addl_A0_im(1 << s
->dflag
);
2446 gen_op_mov_reg_v(MO_16
+ s
->ss32
, R_ESP
, cpu_T
[1]);
2449 /* NOTE: wrap around in 16 bit not fully handled */
2450 static void gen_popa(DisasContext
*s
)
2453 gen_op_movl_A0_reg(R_ESP
);
2455 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2456 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2457 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], 8 << s
->dflag
);
2459 gen_op_addl_A0_seg(s
, R_SS
);
2460 for(i
= 0;i
< 8; i
++) {
2461 /* ESP is not reloaded */
2463 gen_op_ld_v(s
, s
->dflag
, cpu_T
[0], cpu_A0
);
2464 gen_op_mov_reg_v(s
->dflag
, 7 - i
, cpu_T
[0]);
2466 gen_op_addl_A0_im(1 << s
->dflag
);
2468 gen_op_mov_reg_v(MO_16
+ s
->ss32
, R_ESP
, cpu_T
[1]);
2471 static void gen_enter(DisasContext
*s
, int esp_addend
, int level
)
2473 TCGMemOp ot
= mo_pushpop(s
, s
->dflag
);
2474 int opsize
= 1 << ot
;
2477 #ifdef TARGET_X86_64
2479 gen_op_movl_A0_reg(R_ESP
);
2480 gen_op_addq_A0_im(-opsize
);
2481 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2484 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EBP
);
2485 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
2487 /* XXX: must save state */
2488 gen_helper_enter64_level(cpu_env
, tcg_const_i32(level
),
2489 tcg_const_i32((ot
== MO_64
)),
2492 gen_op_mov_reg_v(ot
, R_EBP
, cpu_T
[1]);
2493 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], -esp_addend
+ (-opsize
* level
));
2494 gen_op_mov_reg_v(MO_64
, R_ESP
, cpu_T
[1]);
2498 gen_op_movl_A0_reg(R_ESP
);
2499 gen_op_addl_A0_im(-opsize
);
2501 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2502 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2504 gen_op_addl_A0_seg(s
, R_SS
);
2506 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EBP
);
2507 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
2509 /* XXX: must save state */
2510 gen_helper_enter_level(cpu_env
, tcg_const_i32(level
),
2511 tcg_const_i32(s
->dflag
- 1),
2514 gen_op_mov_reg_v(ot
, R_EBP
, cpu_T
[1]);
2515 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], -esp_addend
+ (-opsize
* level
));
2516 gen_op_mov_reg_v(MO_16
+ s
->ss32
, R_ESP
, cpu_T
[1]);
2520 static void gen_exception(DisasContext
*s
, int trapno
, target_ulong cur_eip
)
2522 gen_update_cc_op(s
);
2523 gen_jmp_im(cur_eip
);
2524 gen_helper_raise_exception(cpu_env
, tcg_const_i32(trapno
));
2525 s
->is_jmp
= DISAS_TB_JUMP
;
2528 /* an interrupt is different from an exception because of the
2530 static void gen_interrupt(DisasContext
*s
, int intno
,
2531 target_ulong cur_eip
, target_ulong next_eip
)
2533 gen_update_cc_op(s
);
2534 gen_jmp_im(cur_eip
);
2535 gen_helper_raise_interrupt(cpu_env
, tcg_const_i32(intno
),
2536 tcg_const_i32(next_eip
- cur_eip
));
2537 s
->is_jmp
= DISAS_TB_JUMP
;
2540 static void gen_debug(DisasContext
*s
, target_ulong cur_eip
)
2542 gen_update_cc_op(s
);
2543 gen_jmp_im(cur_eip
);
2544 gen_helper_debug(cpu_env
);
2545 s
->is_jmp
= DISAS_TB_JUMP
;
2548 /* generate a generic end of block. Trace exception is also generated
2550 static void gen_eob(DisasContext
*s
)
2552 gen_update_cc_op(s
);
2553 if (s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
) {
2554 gen_helper_reset_inhibit_irq(cpu_env
);
2556 if (s
->tb
->flags
& HF_RF_MASK
) {
2557 gen_helper_reset_rf(cpu_env
);
2559 if (s
->singlestep_enabled
) {
2560 gen_helper_debug(cpu_env
);
2562 gen_helper_single_step(cpu_env
);
2566 s
->is_jmp
= DISAS_TB_JUMP
;
2569 /* generate a jump to eip. No segment change must happen before as a
2570 direct call to the next block may occur */
2571 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
)
2573 gen_update_cc_op(s
);
2574 set_cc_op(s
, CC_OP_DYNAMIC
);
2576 gen_goto_tb(s
, tb_num
, eip
);
2577 s
->is_jmp
= DISAS_TB_JUMP
;
2584 static void gen_jmp(DisasContext
*s
, target_ulong eip
)
2586 gen_jmp_tb(s
, eip
, 0);
2589 static inline void gen_ldq_env_A0(DisasContext
*s
, int offset
)
2591 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
2592 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2595 static inline void gen_stq_env_A0(DisasContext
*s
, int offset
)
2597 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2598 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
2601 static inline void gen_ldo_env_A0(DisasContext
*s
, int offset
)
2603 int mem_index
= s
->mem_index
;
2604 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, mem_index
, MO_LEQ
);
2605 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(0)));
2606 tcg_gen_addi_tl(cpu_tmp0
, cpu_A0
, 8);
2607 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
, MO_LEQ
);
2608 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(1)));
2611 static inline void gen_sto_env_A0(DisasContext
*s
, int offset
)
2613 int mem_index
= s
->mem_index
;
2614 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(0)));
2615 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, mem_index
, MO_LEQ
);
2616 tcg_gen_addi_tl(cpu_tmp0
, cpu_A0
, 8);
2617 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(1)));
2618 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
, MO_LEQ
);
2621 static inline void gen_op_movo(int d_offset
, int s_offset
)
2623 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
+ offsetof(XMMReg
, XMM_Q(0)));
2624 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
+ offsetof(XMMReg
, XMM_Q(0)));
2625 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
+ offsetof(XMMReg
, XMM_Q(1)));
2626 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
+ offsetof(XMMReg
, XMM_Q(1)));
2629 static inline void gen_op_movq(int d_offset
, int s_offset
)
2631 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
);
2632 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2635 static inline void gen_op_movl(int d_offset
, int s_offset
)
2637 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
, s_offset
);
2638 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, d_offset
);
2641 static inline void gen_op_movq_env_0(int d_offset
)
2643 tcg_gen_movi_i64(cpu_tmp1_i64
, 0);
2644 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2647 typedef void (*SSEFunc_i_ep
)(TCGv_i32 val
, TCGv_ptr env
, TCGv_ptr reg
);
2648 typedef void (*SSEFunc_l_ep
)(TCGv_i64 val
, TCGv_ptr env
, TCGv_ptr reg
);
2649 typedef void (*SSEFunc_0_epi
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i32 val
);
2650 typedef void (*SSEFunc_0_epl
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i64 val
);
2651 typedef void (*SSEFunc_0_epp
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
);
2652 typedef void (*SSEFunc_0_eppi
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2654 typedef void (*SSEFunc_0_ppi
)(TCGv_ptr reg_a
, TCGv_ptr reg_b
, TCGv_i32 val
);
2655 typedef void (*SSEFunc_0_eppt
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2658 #define SSE_SPECIAL ((void *)1)
2659 #define SSE_DUMMY ((void *)2)
2661 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2662 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2663 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2665 static const SSEFunc_0_epp sse_op_table1
[256][4] = {
2666 /* 3DNow! extensions */
2667 [0x0e] = { SSE_DUMMY
}, /* femms */
2668 [0x0f] = { SSE_DUMMY
}, /* pf... */
2669 /* pure SSE operations */
2670 [0x10] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2671 [0x11] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2672 [0x12] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd, movsldup, movddup */
2673 [0x13] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd */
2674 [0x14] = { gen_helper_punpckldq_xmm
, gen_helper_punpcklqdq_xmm
},
2675 [0x15] = { gen_helper_punpckhdq_xmm
, gen_helper_punpckhqdq_xmm
},
2676 [0x16] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd, movshdup */
2677 [0x17] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd */
2679 [0x28] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2680 [0x29] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2681 [0x2a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2682 [0x2b] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movntps, movntpd, movntss, movntsd */
2683 [0x2c] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2684 [0x2d] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2685 [0x2e] = { gen_helper_ucomiss
, gen_helper_ucomisd
},
2686 [0x2f] = { gen_helper_comiss
, gen_helper_comisd
},
2687 [0x50] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movmskps, movmskpd */
2688 [0x51] = SSE_FOP(sqrt
),
2689 [0x52] = { gen_helper_rsqrtps
, NULL
, gen_helper_rsqrtss
, NULL
},
2690 [0x53] = { gen_helper_rcpps
, NULL
, gen_helper_rcpss
, NULL
},
2691 [0x54] = { gen_helper_pand_xmm
, gen_helper_pand_xmm
}, /* andps, andpd */
2692 [0x55] = { gen_helper_pandn_xmm
, gen_helper_pandn_xmm
}, /* andnps, andnpd */
2693 [0x56] = { gen_helper_por_xmm
, gen_helper_por_xmm
}, /* orps, orpd */
2694 [0x57] = { gen_helper_pxor_xmm
, gen_helper_pxor_xmm
}, /* xorps, xorpd */
2695 [0x58] = SSE_FOP(add
),
2696 [0x59] = SSE_FOP(mul
),
2697 [0x5a] = { gen_helper_cvtps2pd
, gen_helper_cvtpd2ps
,
2698 gen_helper_cvtss2sd
, gen_helper_cvtsd2ss
},
2699 [0x5b] = { gen_helper_cvtdq2ps
, gen_helper_cvtps2dq
, gen_helper_cvttps2dq
},
2700 [0x5c] = SSE_FOP(sub
),
2701 [0x5d] = SSE_FOP(min
),
2702 [0x5e] = SSE_FOP(div
),
2703 [0x5f] = SSE_FOP(max
),
2705 [0xc2] = SSE_FOP(cmpeq
),
2706 [0xc6] = { (SSEFunc_0_epp
)gen_helper_shufps
,
2707 (SSEFunc_0_epp
)gen_helper_shufpd
}, /* XXX: casts */
2709 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */
2710 [0x38] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2711 [0x3a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2713 /* MMX ops and their SSE extensions */
2714 [0x60] = MMX_OP2(punpcklbw
),
2715 [0x61] = MMX_OP2(punpcklwd
),
2716 [0x62] = MMX_OP2(punpckldq
),
2717 [0x63] = MMX_OP2(packsswb
),
2718 [0x64] = MMX_OP2(pcmpgtb
),
2719 [0x65] = MMX_OP2(pcmpgtw
),
2720 [0x66] = MMX_OP2(pcmpgtl
),
2721 [0x67] = MMX_OP2(packuswb
),
2722 [0x68] = MMX_OP2(punpckhbw
),
2723 [0x69] = MMX_OP2(punpckhwd
),
2724 [0x6a] = MMX_OP2(punpckhdq
),
2725 [0x6b] = MMX_OP2(packssdw
),
2726 [0x6c] = { NULL
, gen_helper_punpcklqdq_xmm
},
2727 [0x6d] = { NULL
, gen_helper_punpckhqdq_xmm
},
2728 [0x6e] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movd mm, ea */
2729 [0x6f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, , movqdu */
2730 [0x70] = { (SSEFunc_0_epp
)gen_helper_pshufw_mmx
,
2731 (SSEFunc_0_epp
)gen_helper_pshufd_xmm
,
2732 (SSEFunc_0_epp
)gen_helper_pshufhw_xmm
,
2733 (SSEFunc_0_epp
)gen_helper_pshuflw_xmm
}, /* XXX: casts */
2734 [0x71] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftw */
2735 [0x72] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftd */
2736 [0x73] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftq */
2737 [0x74] = MMX_OP2(pcmpeqb
),
2738 [0x75] = MMX_OP2(pcmpeqw
),
2739 [0x76] = MMX_OP2(pcmpeql
),
2740 [0x77] = { SSE_DUMMY
}, /* emms */
2741 [0x78] = { NULL
, SSE_SPECIAL
, NULL
, SSE_SPECIAL
}, /* extrq_i, insertq_i */
2742 [0x79] = { NULL
, gen_helper_extrq_r
, NULL
, gen_helper_insertq_r
},
2743 [0x7c] = { NULL
, gen_helper_haddpd
, NULL
, gen_helper_haddps
},
2744 [0x7d] = { NULL
, gen_helper_hsubpd
, NULL
, gen_helper_hsubps
},
2745 [0x7e] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movd, movd, , movq */
2746 [0x7f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, movdqu */
2747 [0xc4] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pinsrw */
2748 [0xc5] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pextrw */
2749 [0xd0] = { NULL
, gen_helper_addsubpd
, NULL
, gen_helper_addsubps
},
2750 [0xd1] = MMX_OP2(psrlw
),
2751 [0xd2] = MMX_OP2(psrld
),
2752 [0xd3] = MMX_OP2(psrlq
),
2753 [0xd4] = MMX_OP2(paddq
),
2754 [0xd5] = MMX_OP2(pmullw
),
2755 [0xd6] = { NULL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2756 [0xd7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pmovmskb */
2757 [0xd8] = MMX_OP2(psubusb
),
2758 [0xd9] = MMX_OP2(psubusw
),
2759 [0xda] = MMX_OP2(pminub
),
2760 [0xdb] = MMX_OP2(pand
),
2761 [0xdc] = MMX_OP2(paddusb
),
2762 [0xdd] = MMX_OP2(paddusw
),
2763 [0xde] = MMX_OP2(pmaxub
),
2764 [0xdf] = MMX_OP2(pandn
),
2765 [0xe0] = MMX_OP2(pavgb
),
2766 [0xe1] = MMX_OP2(psraw
),
2767 [0xe2] = MMX_OP2(psrad
),
2768 [0xe3] = MMX_OP2(pavgw
),
2769 [0xe4] = MMX_OP2(pmulhuw
),
2770 [0xe5] = MMX_OP2(pmulhw
),
2771 [0xe6] = { NULL
, gen_helper_cvttpd2dq
, gen_helper_cvtdq2pd
, gen_helper_cvtpd2dq
},
2772 [0xe7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movntq, movntq */
2773 [0xe8] = MMX_OP2(psubsb
),
2774 [0xe9] = MMX_OP2(psubsw
),
2775 [0xea] = MMX_OP2(pminsw
),
2776 [0xeb] = MMX_OP2(por
),
2777 [0xec] = MMX_OP2(paddsb
),
2778 [0xed] = MMX_OP2(paddsw
),
2779 [0xee] = MMX_OP2(pmaxsw
),
2780 [0xef] = MMX_OP2(pxor
),
2781 [0xf0] = { NULL
, NULL
, NULL
, SSE_SPECIAL
}, /* lddqu */
2782 [0xf1] = MMX_OP2(psllw
),
2783 [0xf2] = MMX_OP2(pslld
),
2784 [0xf3] = MMX_OP2(psllq
),
2785 [0xf4] = MMX_OP2(pmuludq
),
2786 [0xf5] = MMX_OP2(pmaddwd
),
2787 [0xf6] = MMX_OP2(psadbw
),
2788 [0xf7] = { (SSEFunc_0_epp
)gen_helper_maskmov_mmx
,
2789 (SSEFunc_0_epp
)gen_helper_maskmov_xmm
}, /* XXX: casts */
2790 [0xf8] = MMX_OP2(psubb
),
2791 [0xf9] = MMX_OP2(psubw
),
2792 [0xfa] = MMX_OP2(psubl
),
2793 [0xfb] = MMX_OP2(psubq
),
2794 [0xfc] = MMX_OP2(paddb
),
2795 [0xfd] = MMX_OP2(paddw
),
2796 [0xfe] = MMX_OP2(paddl
),
2799 static const SSEFunc_0_epp sse_op_table2
[3 * 8][2] = {
2800 [0 + 2] = MMX_OP2(psrlw
),
2801 [0 + 4] = MMX_OP2(psraw
),
2802 [0 + 6] = MMX_OP2(psllw
),
2803 [8 + 2] = MMX_OP2(psrld
),
2804 [8 + 4] = MMX_OP2(psrad
),
2805 [8 + 6] = MMX_OP2(pslld
),
2806 [16 + 2] = MMX_OP2(psrlq
),
2807 [16 + 3] = { NULL
, gen_helper_psrldq_xmm
},
2808 [16 + 6] = MMX_OP2(psllq
),
2809 [16 + 7] = { NULL
, gen_helper_pslldq_xmm
},
2812 static const SSEFunc_0_epi sse_op_table3ai
[] = {
2813 gen_helper_cvtsi2ss
,
2817 #ifdef TARGET_X86_64
2818 static const SSEFunc_0_epl sse_op_table3aq
[] = {
2819 gen_helper_cvtsq2ss
,
2824 static const SSEFunc_i_ep sse_op_table3bi
[] = {
2825 gen_helper_cvttss2si
,
2826 gen_helper_cvtss2si
,
2827 gen_helper_cvttsd2si
,
2831 #ifdef TARGET_X86_64
2832 static const SSEFunc_l_ep sse_op_table3bq
[] = {
2833 gen_helper_cvttss2sq
,
2834 gen_helper_cvtss2sq
,
2835 gen_helper_cvttsd2sq
,
2840 static const SSEFunc_0_epp sse_op_table4
[8][4] = {
2851 static const SSEFunc_0_epp sse_op_table5
[256] = {
2852 [0x0c] = gen_helper_pi2fw
,
2853 [0x0d] = gen_helper_pi2fd
,
2854 [0x1c] = gen_helper_pf2iw
,
2855 [0x1d] = gen_helper_pf2id
,
2856 [0x8a] = gen_helper_pfnacc
,
2857 [0x8e] = gen_helper_pfpnacc
,
2858 [0x90] = gen_helper_pfcmpge
,
2859 [0x94] = gen_helper_pfmin
,
2860 [0x96] = gen_helper_pfrcp
,
2861 [0x97] = gen_helper_pfrsqrt
,
2862 [0x9a] = gen_helper_pfsub
,
2863 [0x9e] = gen_helper_pfadd
,
2864 [0xa0] = gen_helper_pfcmpgt
,
2865 [0xa4] = gen_helper_pfmax
,
2866 [0xa6] = gen_helper_movq
, /* pfrcpit1; no need to actually increase precision */
2867 [0xa7] = gen_helper_movq
, /* pfrsqit1 */
2868 [0xaa] = gen_helper_pfsubr
,
2869 [0xae] = gen_helper_pfacc
,
2870 [0xb0] = gen_helper_pfcmpeq
,
2871 [0xb4] = gen_helper_pfmul
,
2872 [0xb6] = gen_helper_movq
, /* pfrcpit2 */
2873 [0xb7] = gen_helper_pmulhrw_mmx
,
2874 [0xbb] = gen_helper_pswapd
,
2875 [0xbf] = gen_helper_pavgb_mmx
/* pavgusb */
2878 struct SSEOpHelper_epp
{
2879 SSEFunc_0_epp op
[2];
2883 struct SSEOpHelper_eppi
{
2884 SSEFunc_0_eppi op
[2];
2888 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
2889 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
2890 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
2891 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
2892 #define PCLMULQDQ_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, \
2893 CPUID_EXT_PCLMULQDQ }
2894 #define AESNI_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_AES }
2896 static const struct SSEOpHelper_epp sse_op_table6
[256] = {
2897 [0x00] = SSSE3_OP(pshufb
),
2898 [0x01] = SSSE3_OP(phaddw
),
2899 [0x02] = SSSE3_OP(phaddd
),
2900 [0x03] = SSSE3_OP(phaddsw
),
2901 [0x04] = SSSE3_OP(pmaddubsw
),
2902 [0x05] = SSSE3_OP(phsubw
),
2903 [0x06] = SSSE3_OP(phsubd
),
2904 [0x07] = SSSE3_OP(phsubsw
),
2905 [0x08] = SSSE3_OP(psignb
),
2906 [0x09] = SSSE3_OP(psignw
),
2907 [0x0a] = SSSE3_OP(psignd
),
2908 [0x0b] = SSSE3_OP(pmulhrsw
),
2909 [0x10] = SSE41_OP(pblendvb
),
2910 [0x14] = SSE41_OP(blendvps
),
2911 [0x15] = SSE41_OP(blendvpd
),
2912 [0x17] = SSE41_OP(ptest
),
2913 [0x1c] = SSSE3_OP(pabsb
),
2914 [0x1d] = SSSE3_OP(pabsw
),
2915 [0x1e] = SSSE3_OP(pabsd
),
2916 [0x20] = SSE41_OP(pmovsxbw
),
2917 [0x21] = SSE41_OP(pmovsxbd
),
2918 [0x22] = SSE41_OP(pmovsxbq
),
2919 [0x23] = SSE41_OP(pmovsxwd
),
2920 [0x24] = SSE41_OP(pmovsxwq
),
2921 [0x25] = SSE41_OP(pmovsxdq
),
2922 [0x28] = SSE41_OP(pmuldq
),
2923 [0x29] = SSE41_OP(pcmpeqq
),
2924 [0x2a] = SSE41_SPECIAL
, /* movntqda */
2925 [0x2b] = SSE41_OP(packusdw
),
2926 [0x30] = SSE41_OP(pmovzxbw
),
2927 [0x31] = SSE41_OP(pmovzxbd
),
2928 [0x32] = SSE41_OP(pmovzxbq
),
2929 [0x33] = SSE41_OP(pmovzxwd
),
2930 [0x34] = SSE41_OP(pmovzxwq
),
2931 [0x35] = SSE41_OP(pmovzxdq
),
2932 [0x37] = SSE42_OP(pcmpgtq
),
2933 [0x38] = SSE41_OP(pminsb
),
2934 [0x39] = SSE41_OP(pminsd
),
2935 [0x3a] = SSE41_OP(pminuw
),
2936 [0x3b] = SSE41_OP(pminud
),
2937 [0x3c] = SSE41_OP(pmaxsb
),
2938 [0x3d] = SSE41_OP(pmaxsd
),
2939 [0x3e] = SSE41_OP(pmaxuw
),
2940 [0x3f] = SSE41_OP(pmaxud
),
2941 [0x40] = SSE41_OP(pmulld
),
2942 [0x41] = SSE41_OP(phminposuw
),
2943 [0xdb] = AESNI_OP(aesimc
),
2944 [0xdc] = AESNI_OP(aesenc
),
2945 [0xdd] = AESNI_OP(aesenclast
),
2946 [0xde] = AESNI_OP(aesdec
),
2947 [0xdf] = AESNI_OP(aesdeclast
),
2950 static const struct SSEOpHelper_eppi sse_op_table7
[256] = {
2951 [0x08] = SSE41_OP(roundps
),
2952 [0x09] = SSE41_OP(roundpd
),
2953 [0x0a] = SSE41_OP(roundss
),
2954 [0x0b] = SSE41_OP(roundsd
),
2955 [0x0c] = SSE41_OP(blendps
),
2956 [0x0d] = SSE41_OP(blendpd
),
2957 [0x0e] = SSE41_OP(pblendw
),
2958 [0x0f] = SSSE3_OP(palignr
),
2959 [0x14] = SSE41_SPECIAL
, /* pextrb */
2960 [0x15] = SSE41_SPECIAL
, /* pextrw */
2961 [0x16] = SSE41_SPECIAL
, /* pextrd/pextrq */
2962 [0x17] = SSE41_SPECIAL
, /* extractps */
2963 [0x20] = SSE41_SPECIAL
, /* pinsrb */
2964 [0x21] = SSE41_SPECIAL
, /* insertps */
2965 [0x22] = SSE41_SPECIAL
, /* pinsrd/pinsrq */
2966 [0x40] = SSE41_OP(dpps
),
2967 [0x41] = SSE41_OP(dppd
),
2968 [0x42] = SSE41_OP(mpsadbw
),
2969 [0x44] = PCLMULQDQ_OP(pclmulqdq
),
2970 [0x60] = SSE42_OP(pcmpestrm
),
2971 [0x61] = SSE42_OP(pcmpestri
),
2972 [0x62] = SSE42_OP(pcmpistrm
),
2973 [0x63] = SSE42_OP(pcmpistri
),
2974 [0xdf] = AESNI_OP(aeskeygenassist
),
2977 static void gen_sse(CPUX86State
*env
, DisasContext
*s
, int b
,
2978 target_ulong pc_start
, int rex_r
)
2980 int b1
, op1_offset
, op2_offset
, is_xmm
, val
;
2981 int modrm
, mod
, rm
, reg
;
2982 SSEFunc_0_epp sse_fn_epp
;
2983 SSEFunc_0_eppi sse_fn_eppi
;
2984 SSEFunc_0_ppi sse_fn_ppi
;
2985 SSEFunc_0_eppt sse_fn_eppt
;
2989 if (s
->prefix
& PREFIX_DATA
)
2991 else if (s
->prefix
& PREFIX_REPZ
)
2993 else if (s
->prefix
& PREFIX_REPNZ
)
2997 sse_fn_epp
= sse_op_table1
[b
][b1
];
3001 if ((b
<= 0x5f && b
>= 0x10) || b
== 0xc6 || b
== 0xc2) {
3011 /* simple MMX/SSE operation */
3012 if (s
->flags
& HF_TS_MASK
) {
3013 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
3016 if (s
->flags
& HF_EM_MASK
) {
3018 gen_exception(s
, EXCP06_ILLOP
, pc_start
- s
->cs_base
);
3021 if (is_xmm
&& !(s
->flags
& HF_OSFXSR_MASK
))
3022 if ((b
!= 0x38 && b
!= 0x3a) || (s
->prefix
& PREFIX_DATA
))
3025 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
))
3028 gen_helper_emms(cpu_env
);
3033 gen_helper_emms(cpu_env
);
3036 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3037 the static cpu state) */
3039 gen_helper_enter_mmx(cpu_env
);
3042 modrm
= cpu_ldub_code(env
, s
->pc
++);
3043 reg
= ((modrm
>> 3) & 7);
3046 mod
= (modrm
>> 6) & 3;
3047 if (sse_fn_epp
== SSE_SPECIAL
) {
3050 case 0x0e7: /* movntq */
3053 gen_lea_modrm(env
, s
, modrm
);
3054 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3056 case 0x1e7: /* movntdq */
3057 case 0x02b: /* movntps */
3058 case 0x12b: /* movntps */
3061 gen_lea_modrm(env
, s
, modrm
);
3062 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3064 case 0x3f0: /* lddqu */
3067 gen_lea_modrm(env
, s
, modrm
);
3068 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3070 case 0x22b: /* movntss */
3071 case 0x32b: /* movntsd */
3074 gen_lea_modrm(env
, s
, modrm
);
3076 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3077 xmm_regs
[reg
].XMM_Q(0)));
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
;
4421 #ifdef TARGET_X86_64
4426 s
->rip_offset
= 0; /* for relative ip address */
4430 b
= cpu_ldub_code(env
, s
->pc
);
4432 /* Collect prefixes. */
4435 prefixes
|= PREFIX_REPZ
;
4438 prefixes
|= PREFIX_REPNZ
;
4441 prefixes
|= PREFIX_LOCK
;
4462 prefixes
|= PREFIX_DATA
;
4465 prefixes
|= PREFIX_ADR
;
4467 #ifdef TARGET_X86_64
4471 rex_w
= (b
>> 3) & 1;
4472 rex_r
= (b
& 0x4) << 1;
4473 s
->rex_x
= (b
& 0x2) << 2;
4474 REX_B(s
) = (b
& 0x1) << 3;
4475 x86_64_hregs
= 1; /* select uniform byte register addressing */
4480 case 0xc5: /* 2-byte VEX */
4481 case 0xc4: /* 3-byte VEX */
4482 /* VEX prefixes cannot be used except in 32-bit mode.
4483 Otherwise the instruction is LES or LDS. */
4484 if (s
->code32
&& !s
->vm86
) {
4485 static const int pp_prefix
[4] = {
4486 0, PREFIX_DATA
, PREFIX_REPZ
, PREFIX_REPNZ
4488 int vex3
, vex2
= cpu_ldub_code(env
, s
->pc
);
4490 if (!CODE64(s
) && (vex2
& 0xc0) != 0xc0) {
4491 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4492 otherwise the instruction is LES or LDS. */
4497 /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
4498 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
4499 | PREFIX_LOCK
| PREFIX_DATA
)) {
4502 #ifdef TARGET_X86_64
4507 rex_r
= (~vex2
>> 4) & 8;
4510 b
= cpu_ldub_code(env
, s
->pc
++);
4512 #ifdef TARGET_X86_64
4513 s
->rex_x
= (~vex2
>> 3) & 8;
4514 s
->rex_b
= (~vex2
>> 2) & 8;
4516 vex3
= cpu_ldub_code(env
, s
->pc
++);
4517 rex_w
= (vex3
>> 7) & 1;
4518 switch (vex2
& 0x1f) {
4519 case 0x01: /* Implied 0f leading opcode bytes. */
4520 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4522 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4525 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4528 default: /* Reserved for future use. */
4532 s
->vex_v
= (~vex3
>> 3) & 0xf;
4533 s
->vex_l
= (vex3
>> 2) & 1;
4534 prefixes
|= pp_prefix
[vex3
& 3] | PREFIX_VEX
;
4539 /* Post-process prefixes. */
4541 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit
4542 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4543 over 0x66 if both are present. */
4544 dflag
= (rex_w
> 0 ? MO_64
: prefixes
& PREFIX_DATA
? MO_16
: MO_32
);
4545 /* In 64-bit mode, 0x67 selects 32-bit addressing. */
4546 aflag
= (prefixes
& PREFIX_ADR
? MO_32
: MO_64
);
4548 /* In 16/32-bit mode, 0x66 selects the opposite data size. */
4549 if (s
->code32
^ ((prefixes
& PREFIX_DATA
) != 0)) {
4554 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */
4555 if (s
->code32
^ ((prefixes
& PREFIX_ADR
) != 0)) {
4562 s
->prefix
= prefixes
;
4566 /* lock generation */
4567 if (prefixes
& PREFIX_LOCK
)
4570 /* now check op code */
4574 /**************************/
4575 /* extended op code */
4576 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4579 /**************************/
4594 ot
= mo_b_d(b
, dflag
);
4597 case 0: /* OP Ev, Gv */
4598 modrm
= cpu_ldub_code(env
, s
->pc
++);
4599 reg
= ((modrm
>> 3) & 7) | rex_r
;
4600 mod
= (modrm
>> 6) & 3;
4601 rm
= (modrm
& 7) | REX_B(s
);
4603 gen_lea_modrm(env
, s
, modrm
);
4605 } else if (op
== OP_XORL
&& rm
== reg
) {
4607 /* xor reg, reg optimisation */
4608 set_cc_op(s
, CC_OP_CLR
);
4609 tcg_gen_movi_tl(cpu_T
[0], 0);
4610 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
4615 gen_op_mov_v_reg(ot
, cpu_T
[1], reg
);
4616 gen_op(s
, op
, ot
, opreg
);
4618 case 1: /* OP Gv, Ev */
4619 modrm
= cpu_ldub_code(env
, s
->pc
++);
4620 mod
= (modrm
>> 6) & 3;
4621 reg
= ((modrm
>> 3) & 7) | rex_r
;
4622 rm
= (modrm
& 7) | REX_B(s
);
4624 gen_lea_modrm(env
, s
, modrm
);
4625 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
4626 } else if (op
== OP_XORL
&& rm
== reg
) {
4629 gen_op_mov_v_reg(ot
, cpu_T
[1], rm
);
4631 gen_op(s
, op
, ot
, reg
);
4633 case 2: /* OP A, Iv */
4634 val
= insn_get(env
, s
, ot
);
4635 tcg_gen_movi_tl(cpu_T
[1], val
);
4636 gen_op(s
, op
, ot
, OR_EAX
);
4645 case 0x80: /* GRP1 */
4651 ot
= mo_b_d(b
, dflag
);
4653 modrm
= cpu_ldub_code(env
, s
->pc
++);
4654 mod
= (modrm
>> 6) & 3;
4655 rm
= (modrm
& 7) | REX_B(s
);
4656 op
= (modrm
>> 3) & 7;
4662 s
->rip_offset
= insn_const_size(ot
);
4663 gen_lea_modrm(env
, s
, modrm
);
4674 val
= insn_get(env
, s
, ot
);
4677 val
= (int8_t)insn_get(env
, s
, MO_8
);
4680 tcg_gen_movi_tl(cpu_T
[1], val
);
4681 gen_op(s
, op
, ot
, opreg
);
4685 /**************************/
4686 /* inc, dec, and other misc arith */
4687 case 0x40 ... 0x47: /* inc Gv */
4689 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), 1);
4691 case 0x48 ... 0x4f: /* dec Gv */
4693 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), -1);
4695 case 0xf6: /* GRP3 */
4697 ot
= mo_b_d(b
, dflag
);
4699 modrm
= cpu_ldub_code(env
, s
->pc
++);
4700 mod
= (modrm
>> 6) & 3;
4701 rm
= (modrm
& 7) | REX_B(s
);
4702 op
= (modrm
>> 3) & 7;
4705 s
->rip_offset
= insn_const_size(ot
);
4706 gen_lea_modrm(env
, s
, modrm
);
4707 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
4709 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
4714 val
= insn_get(env
, s
, ot
);
4715 tcg_gen_movi_tl(cpu_T
[1], val
);
4716 gen_op_testl_T0_T1_cc();
4717 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4720 tcg_gen_not_tl(cpu_T
[0], cpu_T
[0]);
4722 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
4724 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4728 tcg_gen_neg_tl(cpu_T
[0], cpu_T
[0]);
4730 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
4732 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4734 gen_op_update_neg_cc();
4735 set_cc_op(s
, CC_OP_SUBB
+ ot
);
4740 gen_op_mov_v_reg(MO_8
, cpu_T
[1], R_EAX
);
4741 tcg_gen_ext8u_tl(cpu_T
[0], cpu_T
[0]);
4742 tcg_gen_ext8u_tl(cpu_T
[1], cpu_T
[1]);
4743 /* XXX: use 32 bit mul which could be faster */
4744 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4745 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
4746 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4747 tcg_gen_andi_tl(cpu_cc_src
, cpu_T
[0], 0xff00);
4748 set_cc_op(s
, CC_OP_MULB
);
4751 gen_op_mov_v_reg(MO_16
, cpu_T
[1], R_EAX
);
4752 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
4753 tcg_gen_ext16u_tl(cpu_T
[1], cpu_T
[1]);
4754 /* XXX: use 32 bit mul which could be faster */
4755 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4756 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
4757 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4758 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], 16);
4759 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T
[0]);
4760 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
4761 set_cc_op(s
, CC_OP_MULW
);
4765 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4766 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
4767 tcg_gen_mulu2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4768 cpu_tmp2_i32
, cpu_tmp3_i32
);
4769 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
4770 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
4771 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4772 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4773 set_cc_op(s
, CC_OP_MULL
);
4775 #ifdef TARGET_X86_64
4777 tcg_gen_mulu2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4778 cpu_T
[0], cpu_regs
[R_EAX
]);
4779 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4780 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4781 set_cc_op(s
, CC_OP_MULQ
);
4789 gen_op_mov_v_reg(MO_8
, cpu_T
[1], R_EAX
);
4790 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
4791 tcg_gen_ext8s_tl(cpu_T
[1], cpu_T
[1]);
4792 /* XXX: use 32 bit mul which could be faster */
4793 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4794 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
4795 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4796 tcg_gen_ext8s_tl(cpu_tmp0
, cpu_T
[0]);
4797 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
4798 set_cc_op(s
, CC_OP_MULB
);
4801 gen_op_mov_v_reg(MO_16
, cpu_T
[1], R_EAX
);
4802 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
4803 tcg_gen_ext16s_tl(cpu_T
[1], cpu_T
[1]);
4804 /* XXX: use 32 bit mul which could be faster */
4805 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4806 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
4807 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4808 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T
[0]);
4809 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
4810 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], 16);
4811 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T
[0]);
4812 set_cc_op(s
, CC_OP_MULW
);
4816 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4817 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
4818 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4819 cpu_tmp2_i32
, cpu_tmp3_i32
);
4820 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
4821 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
4822 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
4823 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4824 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
4825 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
4826 set_cc_op(s
, CC_OP_MULL
);
4828 #ifdef TARGET_X86_64
4830 tcg_gen_muls2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4831 cpu_T
[0], cpu_regs
[R_EAX
]);
4832 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4833 tcg_gen_sari_tl(cpu_cc_src
, cpu_regs
[R_EAX
], 63);
4834 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_regs
[R_EDX
]);
4835 set_cc_op(s
, CC_OP_MULQ
);
4843 gen_helper_divb_AL(cpu_env
, cpu_T
[0]);
4846 gen_helper_divw_AX(cpu_env
, cpu_T
[0]);
4850 gen_helper_divl_EAX(cpu_env
, cpu_T
[0]);
4852 #ifdef TARGET_X86_64
4854 gen_helper_divq_EAX(cpu_env
, cpu_T
[0]);
4862 gen_helper_idivb_AL(cpu_env
, cpu_T
[0]);
4865 gen_helper_idivw_AX(cpu_env
, cpu_T
[0]);
4869 gen_helper_idivl_EAX(cpu_env
, cpu_T
[0]);
4871 #ifdef TARGET_X86_64
4873 gen_helper_idivq_EAX(cpu_env
, cpu_T
[0]);
4883 case 0xfe: /* GRP4 */
4884 case 0xff: /* GRP5 */
4885 ot
= mo_b_d(b
, dflag
);
4887 modrm
= cpu_ldub_code(env
, s
->pc
++);
4888 mod
= (modrm
>> 6) & 3;
4889 rm
= (modrm
& 7) | REX_B(s
);
4890 op
= (modrm
>> 3) & 7;
4891 if (op
>= 2 && b
== 0xfe) {
4895 if (op
== 2 || op
== 4) {
4896 /* operand size for jumps is 64 bit */
4898 } else if (op
== 3 || op
== 5) {
4899 ot
= dflag
!= MO_16
? MO_32
+ (rex_w
== 1) : MO_16
;
4900 } else if (op
== 6) {
4901 /* default push size is 64 bit */
4902 ot
= mo_pushpop(s
, dflag
);
4906 gen_lea_modrm(env
, s
, modrm
);
4907 if (op
>= 2 && op
!= 3 && op
!= 5)
4908 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
4910 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
4914 case 0: /* inc Ev */
4919 gen_inc(s
, ot
, opreg
, 1);
4921 case 1: /* dec Ev */
4926 gen_inc(s
, ot
, opreg
, -1);
4928 case 2: /* call Ev */
4929 /* XXX: optimize if memory (no 'and' is necessary) */
4930 if (dflag
== MO_16
) {
4931 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
4933 next_eip
= s
->pc
- s
->cs_base
;
4934 tcg_gen_movi_tl(cpu_T
[1], next_eip
);
4935 gen_push_v(s
, cpu_T
[1]);
4936 gen_op_jmp_v(cpu_T
[0]);
4939 case 3: /* lcall Ev */
4940 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
4941 gen_add_A0_im(s
, 1 << ot
);
4942 gen_op_ld_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
4944 if (s
->pe
&& !s
->vm86
) {
4945 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4946 gen_helper_lcall_protected(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
4947 tcg_const_i32(dflag
- 1),
4948 tcg_const_tl(s
->pc
- s
->cs_base
));
4950 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4951 gen_helper_lcall_real(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
4952 tcg_const_i32(dflag
- 1),
4953 tcg_const_i32(s
->pc
- s
->cs_base
));
4957 case 4: /* jmp Ev */
4958 if (dflag
== MO_16
) {
4959 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
4961 gen_op_jmp_v(cpu_T
[0]);
4964 case 5: /* ljmp Ev */
4965 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
4966 gen_add_A0_im(s
, 1 << ot
);
4967 gen_op_ld_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
4969 if (s
->pe
&& !s
->vm86
) {
4970 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4971 gen_helper_ljmp_protected(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
4972 tcg_const_tl(s
->pc
- s
->cs_base
));
4974 gen_op_movl_seg_T0_vm(R_CS
);
4975 gen_op_jmp_v(cpu_T
[1]);
4979 case 6: /* push Ev */
4980 gen_push_v(s
, cpu_T
[0]);
4987 case 0x84: /* test Ev, Gv */
4989 ot
= mo_b_d(b
, dflag
);
4991 modrm
= cpu_ldub_code(env
, s
->pc
++);
4992 reg
= ((modrm
>> 3) & 7) | rex_r
;
4994 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4995 gen_op_mov_v_reg(ot
, cpu_T
[1], reg
);
4996 gen_op_testl_T0_T1_cc();
4997 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5000 case 0xa8: /* test eAX, Iv */
5002 ot
= mo_b_d(b
, dflag
);
5003 val
= insn_get(env
, s
, ot
);
5005 gen_op_mov_v_reg(ot
, cpu_T
[0], OR_EAX
);
5006 tcg_gen_movi_tl(cpu_T
[1], val
);
5007 gen_op_testl_T0_T1_cc();
5008 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5011 case 0x98: /* CWDE/CBW */
5013 #ifdef TARGET_X86_64
5015 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EAX
);
5016 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
5017 gen_op_mov_reg_v(MO_64
, R_EAX
, cpu_T
[0]);
5021 gen_op_mov_v_reg(MO_16
, cpu_T
[0], R_EAX
);
5022 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5023 gen_op_mov_reg_v(MO_32
, R_EAX
, cpu_T
[0]);
5026 gen_op_mov_v_reg(MO_8
, cpu_T
[0], R_EAX
);
5027 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
5028 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
5034 case 0x99: /* CDQ/CWD */
5036 #ifdef TARGET_X86_64
5038 gen_op_mov_v_reg(MO_64
, cpu_T
[0], R_EAX
);
5039 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 63);
5040 gen_op_mov_reg_v(MO_64
, R_EDX
, cpu_T
[0]);
5044 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EAX
);
5045 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
5046 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 31);
5047 gen_op_mov_reg_v(MO_32
, R_EDX
, cpu_T
[0]);
5050 gen_op_mov_v_reg(MO_16
, cpu_T
[0], R_EAX
);
5051 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5052 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 15);
5053 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T
[0]);
5059 case 0x1af: /* imul Gv, Ev */
5060 case 0x69: /* imul Gv, Ev, I */
5063 modrm
= cpu_ldub_code(env
, s
->pc
++);
5064 reg
= ((modrm
>> 3) & 7) | rex_r
;
5066 s
->rip_offset
= insn_const_size(ot
);
5069 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5071 val
= insn_get(env
, s
, ot
);
5072 tcg_gen_movi_tl(cpu_T
[1], val
);
5073 } else if (b
== 0x6b) {
5074 val
= (int8_t)insn_get(env
, s
, MO_8
);
5075 tcg_gen_movi_tl(cpu_T
[1], val
);
5077 gen_op_mov_v_reg(ot
, cpu_T
[1], reg
);
5080 #ifdef TARGET_X86_64
5082 tcg_gen_muls2_i64(cpu_regs
[reg
], cpu_T
[1], cpu_T
[0], cpu_T
[1]);
5083 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5084 tcg_gen_sari_tl(cpu_cc_src
, cpu_cc_dst
, 63);
5085 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_T
[1]);
5089 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5090 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
5091 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
5092 cpu_tmp2_i32
, cpu_tmp3_i32
);
5093 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
5094 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
5095 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5096 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
5097 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
5100 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5101 tcg_gen_ext16s_tl(cpu_T
[1], cpu_T
[1]);
5102 /* XXX: use 32 bit mul which could be faster */
5103 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5104 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5105 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T
[0]);
5106 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
5107 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
5110 set_cc_op(s
, CC_OP_MULB
+ ot
);
5113 case 0x1c1: /* xadd Ev, Gv */
5114 ot
= mo_b_d(b
, dflag
);
5115 modrm
= cpu_ldub_code(env
, s
->pc
++);
5116 reg
= ((modrm
>> 3) & 7) | rex_r
;
5117 mod
= (modrm
>> 6) & 3;
5119 rm
= (modrm
& 7) | REX_B(s
);
5120 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
5121 gen_op_mov_v_reg(ot
, cpu_T
[1], rm
);
5122 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5123 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5124 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
5126 gen_lea_modrm(env
, s
, modrm
);
5127 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
5128 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
5129 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5130 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
5131 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5133 gen_op_update2_cc();
5134 set_cc_op(s
, CC_OP_ADDB
+ ot
);
5137 case 0x1b1: /* cmpxchg Ev, Gv */
5139 TCGLabel
*label1
, *label2
;
5140 TCGv t0
, t1
, t2
, a0
;
5142 ot
= mo_b_d(b
, dflag
);
5143 modrm
= cpu_ldub_code(env
, s
->pc
++);
5144 reg
= ((modrm
>> 3) & 7) | rex_r
;
5145 mod
= (modrm
>> 6) & 3;
5146 t0
= tcg_temp_local_new();
5147 t1
= tcg_temp_local_new();
5148 t2
= tcg_temp_local_new();
5149 a0
= tcg_temp_local_new();
5150 gen_op_mov_v_reg(ot
, t1
, reg
);
5152 rm
= (modrm
& 7) | REX_B(s
);
5153 gen_op_mov_v_reg(ot
, t0
, rm
);
5155 gen_lea_modrm(env
, s
, modrm
);
5156 tcg_gen_mov_tl(a0
, cpu_A0
);
5157 gen_op_ld_v(s
, ot
, t0
, a0
);
5158 rm
= 0; /* avoid warning */
5160 label1
= gen_new_label();
5161 tcg_gen_mov_tl(t2
, cpu_regs
[R_EAX
]);
5164 tcg_gen_brcond_tl(TCG_COND_EQ
, t2
, t0
, label1
);
5165 label2
= gen_new_label();
5167 gen_op_mov_reg_v(ot
, R_EAX
, t0
);
5169 gen_set_label(label1
);
5170 gen_op_mov_reg_v(ot
, rm
, t1
);
5172 /* perform no-op store cycle like physical cpu; must be
5173 before changing accumulator to ensure idempotency if
5174 the store faults and the instruction is restarted */
5175 gen_op_st_v(s
, ot
, t0
, a0
);
5176 gen_op_mov_reg_v(ot
, R_EAX
, t0
);
5178 gen_set_label(label1
);
5179 gen_op_st_v(s
, ot
, t1
, a0
);
5181 gen_set_label(label2
);
5182 tcg_gen_mov_tl(cpu_cc_src
, t0
);
5183 tcg_gen_mov_tl(cpu_cc_srcT
, t2
);
5184 tcg_gen_sub_tl(cpu_cc_dst
, t2
, t0
);
5185 set_cc_op(s
, CC_OP_SUBB
+ ot
);
5192 case 0x1c7: /* cmpxchg8b */
5193 modrm
= cpu_ldub_code(env
, s
->pc
++);
5194 mod
= (modrm
>> 6) & 3;
5195 if ((mod
== 3) || ((modrm
& 0x38) != 0x8))
5197 #ifdef TARGET_X86_64
5198 if (dflag
== MO_64
) {
5199 if (!(s
->cpuid_ext_features
& CPUID_EXT_CX16
))
5201 gen_lea_modrm(env
, s
, modrm
);
5202 gen_helper_cmpxchg16b(cpu_env
, cpu_A0
);
5206 if (!(s
->cpuid_features
& CPUID_CX8
))
5208 gen_lea_modrm(env
, s
, modrm
);
5209 gen_helper_cmpxchg8b(cpu_env
, cpu_A0
);
5211 set_cc_op(s
, CC_OP_EFLAGS
);
5214 /**************************/
5216 case 0x50 ... 0x57: /* push */
5217 gen_op_mov_v_reg(MO_32
, cpu_T
[0], (b
& 7) | REX_B(s
));
5218 gen_push_v(s
, cpu_T
[0]);
5220 case 0x58 ... 0x5f: /* pop */
5222 /* NOTE: order is important for pop %sp */
5223 gen_pop_update(s
, ot
);
5224 gen_op_mov_reg_v(ot
, (b
& 7) | REX_B(s
), cpu_T
[0]);
5226 case 0x60: /* pusha */
5231 case 0x61: /* popa */
5236 case 0x68: /* push Iv */
5238 ot
= mo_pushpop(s
, dflag
);
5240 val
= insn_get(env
, s
, ot
);
5242 val
= (int8_t)insn_get(env
, s
, MO_8
);
5243 tcg_gen_movi_tl(cpu_T
[0], val
);
5244 gen_push_v(s
, cpu_T
[0]);
5246 case 0x8f: /* pop Ev */
5247 modrm
= cpu_ldub_code(env
, s
->pc
++);
5248 mod
= (modrm
>> 6) & 3;
5251 /* NOTE: order is important for pop %sp */
5252 gen_pop_update(s
, ot
);
5253 rm
= (modrm
& 7) | REX_B(s
);
5254 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
5256 /* NOTE: order is important too for MMU exceptions */
5257 s
->popl_esp_hack
= 1 << ot
;
5258 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5259 s
->popl_esp_hack
= 0;
5260 gen_pop_update(s
, ot
);
5263 case 0xc8: /* enter */
5266 val
= cpu_lduw_code(env
, s
->pc
);
5268 level
= cpu_ldub_code(env
, s
->pc
++);
5269 gen_enter(s
, val
, level
);
5272 case 0xc9: /* leave */
5273 /* XXX: exception not precise (ESP is updated before potential exception) */
5275 gen_op_mov_v_reg(MO_64
, cpu_T
[0], R_EBP
);
5276 gen_op_mov_reg_v(MO_64
, R_ESP
, cpu_T
[0]);
5277 } else if (s
->ss32
) {
5278 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EBP
);
5279 gen_op_mov_reg_v(MO_32
, R_ESP
, cpu_T
[0]);
5281 gen_op_mov_v_reg(MO_16
, cpu_T
[0], R_EBP
);
5282 gen_op_mov_reg_v(MO_16
, R_ESP
, cpu_T
[0]);
5285 gen_op_mov_reg_v(ot
, R_EBP
, cpu_T
[0]);
5286 gen_pop_update(s
, ot
);
5288 case 0x06: /* push es */
5289 case 0x0e: /* push cs */
5290 case 0x16: /* push ss */
5291 case 0x1e: /* push ds */
5294 gen_op_movl_T0_seg(b
>> 3);
5295 gen_push_v(s
, cpu_T
[0]);
5297 case 0x1a0: /* push fs */
5298 case 0x1a8: /* push gs */
5299 gen_op_movl_T0_seg((b
>> 3) & 7);
5300 gen_push_v(s
, cpu_T
[0]);
5302 case 0x07: /* pop es */
5303 case 0x17: /* pop ss */
5304 case 0x1f: /* pop ds */
5309 gen_movl_seg_T0(s
, reg
);
5310 gen_pop_update(s
, ot
);
5312 /* if reg == SS, inhibit interrupts/trace. */
5313 /* If several instructions disable interrupts, only the
5315 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
5316 gen_helper_set_inhibit_irq(cpu_env
);
5320 gen_jmp_im(s
->pc
- s
->cs_base
);
5324 case 0x1a1: /* pop fs */
5325 case 0x1a9: /* pop gs */
5327 gen_movl_seg_T0(s
, (b
>> 3) & 7);
5328 gen_pop_update(s
, ot
);
5330 gen_jmp_im(s
->pc
- s
->cs_base
);
5335 /**************************/
5338 case 0x89: /* mov Gv, Ev */
5339 ot
= mo_b_d(b
, dflag
);
5340 modrm
= cpu_ldub_code(env
, s
->pc
++);
5341 reg
= ((modrm
>> 3) & 7) | rex_r
;
5343 /* generate a generic store */
5344 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
5347 case 0xc7: /* mov Ev, Iv */
5348 ot
= mo_b_d(b
, dflag
);
5349 modrm
= cpu_ldub_code(env
, s
->pc
++);
5350 mod
= (modrm
>> 6) & 3;
5352 s
->rip_offset
= insn_const_size(ot
);
5353 gen_lea_modrm(env
, s
, modrm
);
5355 val
= insn_get(env
, s
, ot
);
5356 tcg_gen_movi_tl(cpu_T
[0], val
);
5358 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
5360 gen_op_mov_reg_v(ot
, (modrm
& 7) | REX_B(s
), cpu_T
[0]);
5364 case 0x8b: /* mov Ev, Gv */
5365 ot
= mo_b_d(b
, dflag
);
5366 modrm
= cpu_ldub_code(env
, s
->pc
++);
5367 reg
= ((modrm
>> 3) & 7) | rex_r
;
5369 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5370 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
5372 case 0x8e: /* mov seg, Gv */
5373 modrm
= cpu_ldub_code(env
, s
->pc
++);
5374 reg
= (modrm
>> 3) & 7;
5375 if (reg
>= 6 || reg
== R_CS
)
5377 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
5378 gen_movl_seg_T0(s
, reg
);
5380 /* if reg == SS, inhibit interrupts/trace */
5381 /* If several instructions disable interrupts, only the
5383 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
5384 gen_helper_set_inhibit_irq(cpu_env
);
5388 gen_jmp_im(s
->pc
- s
->cs_base
);
5392 case 0x8c: /* mov Gv, seg */
5393 modrm
= cpu_ldub_code(env
, s
->pc
++);
5394 reg
= (modrm
>> 3) & 7;
5395 mod
= (modrm
>> 6) & 3;
5398 gen_op_movl_T0_seg(reg
);
5399 ot
= mod
== 3 ? dflag
: MO_16
;
5400 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5403 case 0x1b6: /* movzbS Gv, Eb */
5404 case 0x1b7: /* movzwS Gv, Eb */
5405 case 0x1be: /* movsbS Gv, Eb */
5406 case 0x1bf: /* movswS Gv, Eb */
5411 /* d_ot is the size of destination */
5413 /* ot is the size of source */
5414 ot
= (b
& 1) + MO_8
;
5415 /* s_ot is the sign+size of source */
5416 s_ot
= b
& 8 ? MO_SIGN
| ot
: ot
;
5418 modrm
= cpu_ldub_code(env
, s
->pc
++);
5419 reg
= ((modrm
>> 3) & 7) | rex_r
;
5420 mod
= (modrm
>> 6) & 3;
5421 rm
= (modrm
& 7) | REX_B(s
);
5424 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
5427 tcg_gen_ext8u_tl(cpu_T
[0], cpu_T
[0]);
5430 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
5433 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
5437 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5440 gen_op_mov_reg_v(d_ot
, reg
, cpu_T
[0]);
5442 gen_lea_modrm(env
, s
, modrm
);
5443 gen_op_ld_v(s
, s_ot
, cpu_T
[0], cpu_A0
);
5444 gen_op_mov_reg_v(d_ot
, reg
, cpu_T
[0]);
5449 case 0x8d: /* lea */
5451 modrm
= cpu_ldub_code(env
, s
->pc
++);
5452 mod
= (modrm
>> 6) & 3;
5455 reg
= ((modrm
>> 3) & 7) | rex_r
;
5456 /* we must ensure that no segment is added */
5460 gen_lea_modrm(env
, s
, modrm
);
5462 gen_op_mov_reg_v(ot
, reg
, cpu_A0
);
5465 case 0xa0: /* mov EAX, Ov */
5467 case 0xa2: /* mov Ov, EAX */
5470 target_ulong offset_addr
;
5472 ot
= mo_b_d(b
, dflag
);
5474 #ifdef TARGET_X86_64
5476 offset_addr
= cpu_ldq_code(env
, s
->pc
);
5481 offset_addr
= insn_get(env
, s
, s
->aflag
);
5484 tcg_gen_movi_tl(cpu_A0
, offset_addr
);
5485 gen_add_A0_ds_seg(s
);
5487 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
5488 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T
[0]);
5490 gen_op_mov_v_reg(ot
, cpu_T
[0], R_EAX
);
5491 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
5495 case 0xd7: /* xlat */
5496 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EBX
]);
5497 tcg_gen_ext8u_tl(cpu_T
[0], cpu_regs
[R_EAX
]);
5498 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_T
[0]);
5499 gen_extu(s
->aflag
, cpu_A0
);
5500 gen_add_A0_ds_seg(s
);
5501 gen_op_ld_v(s
, MO_8
, cpu_T
[0], cpu_A0
);
5502 gen_op_mov_reg_v(MO_8
, R_EAX
, cpu_T
[0]);
5504 case 0xb0 ... 0xb7: /* mov R, Ib */
5505 val
= insn_get(env
, s
, MO_8
);
5506 tcg_gen_movi_tl(cpu_T
[0], val
);
5507 gen_op_mov_reg_v(MO_8
, (b
& 7) | REX_B(s
), cpu_T
[0]);
5509 case 0xb8 ... 0xbf: /* mov R, Iv */
5510 #ifdef TARGET_X86_64
5511 if (dflag
== MO_64
) {
5514 tmp
= cpu_ldq_code(env
, s
->pc
);
5516 reg
= (b
& 7) | REX_B(s
);
5517 tcg_gen_movi_tl(cpu_T
[0], tmp
);
5518 gen_op_mov_reg_v(MO_64
, reg
, cpu_T
[0]);
5523 val
= insn_get(env
, s
, ot
);
5524 reg
= (b
& 7) | REX_B(s
);
5525 tcg_gen_movi_tl(cpu_T
[0], val
);
5526 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
5530 case 0x91 ... 0x97: /* xchg R, EAX */
5533 reg
= (b
& 7) | REX_B(s
);
5537 case 0x87: /* xchg Ev, Gv */
5538 ot
= mo_b_d(b
, dflag
);
5539 modrm
= cpu_ldub_code(env
, s
->pc
++);
5540 reg
= ((modrm
>> 3) & 7) | rex_r
;
5541 mod
= (modrm
>> 6) & 3;
5543 rm
= (modrm
& 7) | REX_B(s
);
5545 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
5546 gen_op_mov_v_reg(ot
, cpu_T
[1], rm
);
5547 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
5548 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5550 gen_lea_modrm(env
, s
, modrm
);
5551 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
5552 /* for xchg, lock is implicit */
5553 if (!(prefixes
& PREFIX_LOCK
))
5555 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
5556 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
5557 if (!(prefixes
& PREFIX_LOCK
))
5558 gen_helper_unlock();
5559 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5562 case 0xc4: /* les Gv */
5563 /* In CODE64 this is VEX3; see above. */
5566 case 0xc5: /* lds Gv */
5567 /* In CODE64 this is VEX2; see above. */
5570 case 0x1b2: /* lss Gv */
5573 case 0x1b4: /* lfs Gv */
5576 case 0x1b5: /* lgs Gv */
5579 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
5580 modrm
= cpu_ldub_code(env
, s
->pc
++);
5581 reg
= ((modrm
>> 3) & 7) | rex_r
;
5582 mod
= (modrm
>> 6) & 3;
5585 gen_lea_modrm(env
, s
, modrm
);
5586 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
5587 gen_add_A0_im(s
, 1 << ot
);
5588 /* load the segment first to handle exceptions properly */
5589 gen_op_ld_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
5590 gen_movl_seg_T0(s
, op
);
5591 /* then put the data */
5592 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5594 gen_jmp_im(s
->pc
- s
->cs_base
);
5599 /************************/
5607 ot
= mo_b_d(b
, dflag
);
5608 modrm
= cpu_ldub_code(env
, s
->pc
++);
5609 mod
= (modrm
>> 6) & 3;
5610 op
= (modrm
>> 3) & 7;
5616 gen_lea_modrm(env
, s
, modrm
);
5619 opreg
= (modrm
& 7) | REX_B(s
);
5624 gen_shift(s
, op
, ot
, opreg
, OR_ECX
);
5627 shift
= cpu_ldub_code(env
, s
->pc
++);
5629 gen_shifti(s
, op
, ot
, opreg
, shift
);
5644 case 0x1a4: /* shld imm */
5648 case 0x1a5: /* shld cl */
5652 case 0x1ac: /* shrd imm */
5656 case 0x1ad: /* shrd cl */
5661 modrm
= cpu_ldub_code(env
, s
->pc
++);
5662 mod
= (modrm
>> 6) & 3;
5663 rm
= (modrm
& 7) | REX_B(s
);
5664 reg
= ((modrm
>> 3) & 7) | rex_r
;
5666 gen_lea_modrm(env
, s
, modrm
);
5671 gen_op_mov_v_reg(ot
, cpu_T
[1], reg
);
5674 TCGv imm
= tcg_const_tl(cpu_ldub_code(env
, s
->pc
++));
5675 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, imm
);
5678 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, cpu_regs
[R_ECX
]);
5682 /************************/
5685 if (s
->flags
& (HF_EM_MASK
| HF_TS_MASK
)) {
5686 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5687 /* XXX: what to do if illegal op ? */
5688 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
5691 modrm
= cpu_ldub_code(env
, s
->pc
++);
5692 mod
= (modrm
>> 6) & 3;
5694 op
= ((b
& 7) << 3) | ((modrm
>> 3) & 7);
5697 gen_lea_modrm(env
, s
, modrm
);
5699 case 0x00 ... 0x07: /* fxxxs */
5700 case 0x10 ... 0x17: /* fixxxl */
5701 case 0x20 ... 0x27: /* fxxxl */
5702 case 0x30 ... 0x37: /* fixxx */
5709 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5710 s
->mem_index
, MO_LEUL
);
5711 gen_helper_flds_FT0(cpu_env
, cpu_tmp2_i32
);
5714 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5715 s
->mem_index
, MO_LEUL
);
5716 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
5719 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
5720 s
->mem_index
, MO_LEQ
);
5721 gen_helper_fldl_FT0(cpu_env
, cpu_tmp1_i64
);
5725 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5726 s
->mem_index
, MO_LESW
);
5727 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
5731 gen_helper_fp_arith_ST0_FT0(op1
);
5733 /* fcomp needs pop */
5734 gen_helper_fpop(cpu_env
);
5738 case 0x08: /* flds */
5739 case 0x0a: /* fsts */
5740 case 0x0b: /* fstps */
5741 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5742 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5743 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5748 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5749 s
->mem_index
, MO_LEUL
);
5750 gen_helper_flds_ST0(cpu_env
, cpu_tmp2_i32
);
5753 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5754 s
->mem_index
, MO_LEUL
);
5755 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
5758 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
5759 s
->mem_index
, MO_LEQ
);
5760 gen_helper_fldl_ST0(cpu_env
, cpu_tmp1_i64
);
5764 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5765 s
->mem_index
, MO_LESW
);
5766 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
5771 /* XXX: the corresponding CPUID bit must be tested ! */
5774 gen_helper_fisttl_ST0(cpu_tmp2_i32
, cpu_env
);
5775 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5776 s
->mem_index
, MO_LEUL
);
5779 gen_helper_fisttll_ST0(cpu_tmp1_i64
, cpu_env
);
5780 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
5781 s
->mem_index
, MO_LEQ
);
5785 gen_helper_fistt_ST0(cpu_tmp2_i32
, cpu_env
);
5786 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5787 s
->mem_index
, MO_LEUW
);
5790 gen_helper_fpop(cpu_env
);
5795 gen_helper_fsts_ST0(cpu_tmp2_i32
, cpu_env
);
5796 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5797 s
->mem_index
, MO_LEUL
);
5800 gen_helper_fistl_ST0(cpu_tmp2_i32
, cpu_env
);
5801 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5802 s
->mem_index
, MO_LEUL
);
5805 gen_helper_fstl_ST0(cpu_tmp1_i64
, cpu_env
);
5806 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
5807 s
->mem_index
, MO_LEQ
);
5811 gen_helper_fist_ST0(cpu_tmp2_i32
, cpu_env
);
5812 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5813 s
->mem_index
, MO_LEUW
);
5817 gen_helper_fpop(cpu_env
);
5821 case 0x0c: /* fldenv mem */
5822 gen_helper_fldenv(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5824 case 0x0d: /* fldcw mem */
5825 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5826 s
->mem_index
, MO_LEUW
);
5827 gen_helper_fldcw(cpu_env
, cpu_tmp2_i32
);
5829 case 0x0e: /* fnstenv mem */
5830 gen_helper_fstenv(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5832 case 0x0f: /* fnstcw mem */
5833 gen_helper_fnstcw(cpu_tmp2_i32
, cpu_env
);
5834 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5835 s
->mem_index
, MO_LEUW
);
5837 case 0x1d: /* fldt mem */
5838 gen_helper_fldt_ST0(cpu_env
, cpu_A0
);
5840 case 0x1f: /* fstpt mem */
5841 gen_helper_fstt_ST0(cpu_env
, cpu_A0
);
5842 gen_helper_fpop(cpu_env
);
5844 case 0x2c: /* frstor mem */
5845 gen_helper_frstor(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5847 case 0x2e: /* fnsave mem */
5848 gen_helper_fsave(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5850 case 0x2f: /* fnstsw mem */
5851 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
5852 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5853 s
->mem_index
, MO_LEUW
);
5855 case 0x3c: /* fbld */
5856 gen_helper_fbld_ST0(cpu_env
, cpu_A0
);
5858 case 0x3e: /* fbstp */
5859 gen_helper_fbst_ST0(cpu_env
, cpu_A0
);
5860 gen_helper_fpop(cpu_env
);
5862 case 0x3d: /* fildll */
5863 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
5864 gen_helper_fildll_ST0(cpu_env
, cpu_tmp1_i64
);
5866 case 0x3f: /* fistpll */
5867 gen_helper_fistll_ST0(cpu_tmp1_i64
, cpu_env
);
5868 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
5869 gen_helper_fpop(cpu_env
);
5875 /* register float ops */
5879 case 0x08: /* fld sti */
5880 gen_helper_fpush(cpu_env
);
5881 gen_helper_fmov_ST0_STN(cpu_env
,
5882 tcg_const_i32((opreg
+ 1) & 7));
5884 case 0x09: /* fxchg sti */
5885 case 0x29: /* fxchg4 sti, undocumented op */
5886 case 0x39: /* fxchg7 sti, undocumented op */
5887 gen_helper_fxchg_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
5889 case 0x0a: /* grp d9/2 */
5892 /* check exceptions (FreeBSD FPU probe) */
5893 gen_helper_fwait(cpu_env
);
5899 case 0x0c: /* grp d9/4 */
5902 gen_helper_fchs_ST0(cpu_env
);
5905 gen_helper_fabs_ST0(cpu_env
);
5908 gen_helper_fldz_FT0(cpu_env
);
5909 gen_helper_fcom_ST0_FT0(cpu_env
);
5912 gen_helper_fxam_ST0(cpu_env
);
5918 case 0x0d: /* grp d9/5 */
5922 gen_helper_fpush(cpu_env
);
5923 gen_helper_fld1_ST0(cpu_env
);
5926 gen_helper_fpush(cpu_env
);
5927 gen_helper_fldl2t_ST0(cpu_env
);
5930 gen_helper_fpush(cpu_env
);
5931 gen_helper_fldl2e_ST0(cpu_env
);
5934 gen_helper_fpush(cpu_env
);
5935 gen_helper_fldpi_ST0(cpu_env
);
5938 gen_helper_fpush(cpu_env
);
5939 gen_helper_fldlg2_ST0(cpu_env
);
5942 gen_helper_fpush(cpu_env
);
5943 gen_helper_fldln2_ST0(cpu_env
);
5946 gen_helper_fpush(cpu_env
);
5947 gen_helper_fldz_ST0(cpu_env
);
5954 case 0x0e: /* grp d9/6 */
5957 gen_helper_f2xm1(cpu_env
);
5960 gen_helper_fyl2x(cpu_env
);
5963 gen_helper_fptan(cpu_env
);
5965 case 3: /* fpatan */
5966 gen_helper_fpatan(cpu_env
);
5968 case 4: /* fxtract */
5969 gen_helper_fxtract(cpu_env
);
5971 case 5: /* fprem1 */
5972 gen_helper_fprem1(cpu_env
);
5974 case 6: /* fdecstp */
5975 gen_helper_fdecstp(cpu_env
);
5978 case 7: /* fincstp */
5979 gen_helper_fincstp(cpu_env
);
5983 case 0x0f: /* grp d9/7 */
5986 gen_helper_fprem(cpu_env
);
5988 case 1: /* fyl2xp1 */
5989 gen_helper_fyl2xp1(cpu_env
);
5992 gen_helper_fsqrt(cpu_env
);
5994 case 3: /* fsincos */
5995 gen_helper_fsincos(cpu_env
);
5997 case 5: /* fscale */
5998 gen_helper_fscale(cpu_env
);
6000 case 4: /* frndint */
6001 gen_helper_frndint(cpu_env
);
6004 gen_helper_fsin(cpu_env
);
6008 gen_helper_fcos(cpu_env
);
6012 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6013 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6014 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6020 gen_helper_fp_arith_STN_ST0(op1
, opreg
);
6022 gen_helper_fpop(cpu_env
);
6024 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6025 gen_helper_fp_arith_ST0_FT0(op1
);
6029 case 0x02: /* fcom */
6030 case 0x22: /* fcom2, undocumented op */
6031 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6032 gen_helper_fcom_ST0_FT0(cpu_env
);
6034 case 0x03: /* fcomp */
6035 case 0x23: /* fcomp3, undocumented op */
6036 case 0x32: /* fcomp5, undocumented op */
6037 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6038 gen_helper_fcom_ST0_FT0(cpu_env
);
6039 gen_helper_fpop(cpu_env
);
6041 case 0x15: /* da/5 */
6043 case 1: /* fucompp */
6044 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6045 gen_helper_fucom_ST0_FT0(cpu_env
);
6046 gen_helper_fpop(cpu_env
);
6047 gen_helper_fpop(cpu_env
);
6055 case 0: /* feni (287 only, just do nop here) */
6057 case 1: /* fdisi (287 only, just do nop here) */
6060 gen_helper_fclex(cpu_env
);
6062 case 3: /* fninit */
6063 gen_helper_fninit(cpu_env
);
6065 case 4: /* fsetpm (287 only, just do nop here) */
6071 case 0x1d: /* fucomi */
6072 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6075 gen_update_cc_op(s
);
6076 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6077 gen_helper_fucomi_ST0_FT0(cpu_env
);
6078 set_cc_op(s
, CC_OP_EFLAGS
);
6080 case 0x1e: /* fcomi */
6081 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6084 gen_update_cc_op(s
);
6085 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6086 gen_helper_fcomi_ST0_FT0(cpu_env
);
6087 set_cc_op(s
, CC_OP_EFLAGS
);
6089 case 0x28: /* ffree sti */
6090 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6092 case 0x2a: /* fst sti */
6093 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6095 case 0x2b: /* fstp sti */
6096 case 0x0b: /* fstp1 sti, undocumented op */
6097 case 0x3a: /* fstp8 sti, undocumented op */
6098 case 0x3b: /* fstp9 sti, undocumented op */
6099 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6100 gen_helper_fpop(cpu_env
);
6102 case 0x2c: /* fucom st(i) */
6103 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6104 gen_helper_fucom_ST0_FT0(cpu_env
);
6106 case 0x2d: /* fucomp st(i) */
6107 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6108 gen_helper_fucom_ST0_FT0(cpu_env
);
6109 gen_helper_fpop(cpu_env
);
6111 case 0x33: /* de/3 */
6113 case 1: /* fcompp */
6114 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6115 gen_helper_fcom_ST0_FT0(cpu_env
);
6116 gen_helper_fpop(cpu_env
);
6117 gen_helper_fpop(cpu_env
);
6123 case 0x38: /* ffreep sti, undocumented op */
6124 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6125 gen_helper_fpop(cpu_env
);
6127 case 0x3c: /* df/4 */
6130 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
6131 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6132 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
6138 case 0x3d: /* fucomip */
6139 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6142 gen_update_cc_op(s
);
6143 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6144 gen_helper_fucomi_ST0_FT0(cpu_env
);
6145 gen_helper_fpop(cpu_env
);
6146 set_cc_op(s
, CC_OP_EFLAGS
);
6148 case 0x3e: /* fcomip */
6149 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6152 gen_update_cc_op(s
);
6153 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6154 gen_helper_fcomi_ST0_FT0(cpu_env
);
6155 gen_helper_fpop(cpu_env
);
6156 set_cc_op(s
, CC_OP_EFLAGS
);
6158 case 0x10 ... 0x13: /* fcmovxx */
6163 static const uint8_t fcmov_cc
[8] = {
6170 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6173 op1
= fcmov_cc
[op
& 3] | (((op
>> 3) & 1) ^ 1);
6174 l1
= gen_new_label();
6175 gen_jcc1_noeob(s
, op1
, l1
);
6176 gen_helper_fmov_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6185 /************************/
6188 case 0xa4: /* movsS */
6190 ot
= mo_b_d(b
, dflag
);
6191 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6192 gen_repz_movs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6198 case 0xaa: /* stosS */
6200 ot
= mo_b_d(b
, dflag
);
6201 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6202 gen_repz_stos(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6207 case 0xac: /* lodsS */
6209 ot
= mo_b_d(b
, dflag
);
6210 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6211 gen_repz_lods(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6216 case 0xae: /* scasS */
6218 ot
= mo_b_d(b
, dflag
);
6219 if (prefixes
& PREFIX_REPNZ
) {
6220 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6221 } else if (prefixes
& PREFIX_REPZ
) {
6222 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6228 case 0xa6: /* cmpsS */
6230 ot
= mo_b_d(b
, dflag
);
6231 if (prefixes
& PREFIX_REPNZ
) {
6232 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6233 } else if (prefixes
& PREFIX_REPZ
) {
6234 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6239 case 0x6c: /* insS */
6241 ot
= mo_b_d32(b
, dflag
);
6242 tcg_gen_ext16u_tl(cpu_T
[0], cpu_regs
[R_EDX
]);
6243 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6244 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
) | 4);
6245 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6246 gen_repz_ins(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6249 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6250 gen_jmp(s
, s
->pc
- s
->cs_base
);
6254 case 0x6e: /* outsS */
6256 ot
= mo_b_d32(b
, dflag
);
6257 tcg_gen_ext16u_tl(cpu_T
[0], cpu_regs
[R_EDX
]);
6258 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6259 svm_is_rep(prefixes
) | 4);
6260 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6261 gen_repz_outs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6264 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6265 gen_jmp(s
, s
->pc
- s
->cs_base
);
6270 /************************/
6275 ot
= mo_b_d32(b
, dflag
);
6276 val
= cpu_ldub_code(env
, s
->pc
++);
6277 tcg_gen_movi_tl(cpu_T
[0], val
);
6278 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6279 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6280 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6283 tcg_gen_movi_i32(cpu_tmp2_i32
, val
);
6284 gen_helper_in_func(ot
, cpu_T
[1], cpu_tmp2_i32
);
6285 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T
[1]);
6286 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6287 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6289 gen_jmp(s
, s
->pc
- s
->cs_base
);
6294 ot
= mo_b_d32(b
, dflag
);
6295 val
= cpu_ldub_code(env
, s
->pc
++);
6296 tcg_gen_movi_tl(cpu_T
[0], val
);
6297 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6298 svm_is_rep(prefixes
));
6299 gen_op_mov_v_reg(ot
, cpu_T
[1], R_EAX
);
6301 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6304 tcg_gen_movi_i32(cpu_tmp2_i32
, val
);
6305 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
6306 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6307 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6308 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6310 gen_jmp(s
, s
->pc
- s
->cs_base
);
6315 ot
= mo_b_d32(b
, dflag
);
6316 tcg_gen_ext16u_tl(cpu_T
[0], cpu_regs
[R_EDX
]);
6317 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6318 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6319 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6322 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6323 gen_helper_in_func(ot
, cpu_T
[1], cpu_tmp2_i32
);
6324 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T
[1]);
6325 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6326 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6328 gen_jmp(s
, s
->pc
- s
->cs_base
);
6333 ot
= mo_b_d32(b
, dflag
);
6334 tcg_gen_ext16u_tl(cpu_T
[0], cpu_regs
[R_EDX
]);
6335 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6336 svm_is_rep(prefixes
));
6337 gen_op_mov_v_reg(ot
, cpu_T
[1], R_EAX
);
6339 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6342 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6343 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
6344 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6345 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6346 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6348 gen_jmp(s
, s
->pc
- s
->cs_base
);
6352 /************************/
6354 case 0xc2: /* ret im */
6355 val
= cpu_ldsw_code(env
, s
->pc
);
6358 gen_stack_update(s
, val
+ (1 << ot
));
6359 /* Note that gen_pop_T0 uses a zero-extending load. */
6360 gen_op_jmp_v(cpu_T
[0]);
6363 case 0xc3: /* ret */
6365 gen_pop_update(s
, ot
);
6366 /* Note that gen_pop_T0 uses a zero-extending load. */
6367 gen_op_jmp_v(cpu_T
[0]);
6370 case 0xca: /* lret im */
6371 val
= cpu_ldsw_code(env
, s
->pc
);
6374 if (s
->pe
&& !s
->vm86
) {
6375 gen_update_cc_op(s
);
6376 gen_jmp_im(pc_start
- s
->cs_base
);
6377 gen_helper_lret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6378 tcg_const_i32(val
));
6382 gen_op_ld_v(s
, dflag
, cpu_T
[0], cpu_A0
);
6383 /* NOTE: keeping EIP updated is not a problem in case of
6385 gen_op_jmp_v(cpu_T
[0]);
6387 gen_op_addl_A0_im(1 << dflag
);
6388 gen_op_ld_v(s
, dflag
, cpu_T
[0], cpu_A0
);
6389 gen_op_movl_seg_T0_vm(R_CS
);
6390 /* add stack offset */
6391 gen_stack_update(s
, val
+ (2 << dflag
));
6395 case 0xcb: /* lret */
6398 case 0xcf: /* iret */
6399 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IRET
);
6402 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6403 set_cc_op(s
, CC_OP_EFLAGS
);
6404 } else if (s
->vm86
) {
6406 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6408 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6409 set_cc_op(s
, CC_OP_EFLAGS
);
6412 gen_helper_iret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6413 tcg_const_i32(s
->pc
- s
->cs_base
));
6414 set_cc_op(s
, CC_OP_EFLAGS
);
6418 case 0xe8: /* call im */
6420 if (dflag
!= MO_16
) {
6421 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6423 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6425 next_eip
= s
->pc
- s
->cs_base
;
6427 if (dflag
== MO_16
) {
6429 } else if (!CODE64(s
)) {
6432 tcg_gen_movi_tl(cpu_T
[0], next_eip
);
6433 gen_push_v(s
, cpu_T
[0]);
6437 case 0x9a: /* lcall im */
6439 unsigned int selector
, offset
;
6444 offset
= insn_get(env
, s
, ot
);
6445 selector
= insn_get(env
, s
, MO_16
);
6447 tcg_gen_movi_tl(cpu_T
[0], selector
);
6448 tcg_gen_movi_tl(cpu_T
[1], offset
);
6451 case 0xe9: /* jmp im */
6452 if (dflag
!= MO_16
) {
6453 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6455 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6457 tval
+= s
->pc
- s
->cs_base
;
6458 if (dflag
== MO_16
) {
6460 } else if (!CODE64(s
)) {
6465 case 0xea: /* ljmp im */
6467 unsigned int selector
, offset
;
6472 offset
= insn_get(env
, s
, ot
);
6473 selector
= insn_get(env
, s
, MO_16
);
6475 tcg_gen_movi_tl(cpu_T
[0], selector
);
6476 tcg_gen_movi_tl(cpu_T
[1], offset
);
6479 case 0xeb: /* jmp Jb */
6480 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6481 tval
+= s
->pc
- s
->cs_base
;
6482 if (dflag
== MO_16
) {
6487 case 0x70 ... 0x7f: /* jcc Jb */
6488 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6490 case 0x180 ... 0x18f: /* jcc Jv */
6491 if (dflag
!= MO_16
) {
6492 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6494 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6497 next_eip
= s
->pc
- s
->cs_base
;
6499 if (dflag
== MO_16
) {
6502 gen_jcc(s
, b
, tval
, next_eip
);
6505 case 0x190 ... 0x19f: /* setcc Gv */
6506 modrm
= cpu_ldub_code(env
, s
->pc
++);
6507 gen_setcc1(s
, b
, cpu_T
[0]);
6508 gen_ldst_modrm(env
, s
, modrm
, MO_8
, OR_TMP0
, 1);
6510 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6511 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6515 modrm
= cpu_ldub_code(env
, s
->pc
++);
6516 reg
= ((modrm
>> 3) & 7) | rex_r
;
6517 gen_cmovcc1(env
, s
, ot
, b
, modrm
, reg
);
6520 /************************/
6522 case 0x9c: /* pushf */
6523 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_PUSHF
);
6524 if (s
->vm86
&& s
->iopl
!= 3) {
6525 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6527 gen_update_cc_op(s
);
6528 gen_helper_read_eflags(cpu_T
[0], cpu_env
);
6529 gen_push_v(s
, cpu_T
[0]);
6532 case 0x9d: /* popf */
6533 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_POPF
);
6534 if (s
->vm86
&& s
->iopl
!= 3) {
6535 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6539 if (dflag
!= MO_16
) {
6540 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6541 tcg_const_i32((TF_MASK
| AC_MASK
|
6546 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6547 tcg_const_i32((TF_MASK
| AC_MASK
|
6549 IF_MASK
| IOPL_MASK
)
6553 if (s
->cpl
<= s
->iopl
) {
6554 if (dflag
!= MO_16
) {
6555 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6556 tcg_const_i32((TF_MASK
|
6562 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6563 tcg_const_i32((TF_MASK
|
6571 if (dflag
!= MO_16
) {
6572 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6573 tcg_const_i32((TF_MASK
| AC_MASK
|
6574 ID_MASK
| NT_MASK
)));
6576 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6577 tcg_const_i32((TF_MASK
| AC_MASK
|
6583 gen_pop_update(s
, ot
);
6584 set_cc_op(s
, CC_OP_EFLAGS
);
6585 /* abort translation because TF/AC flag may change */
6586 gen_jmp_im(s
->pc
- s
->cs_base
);
6590 case 0x9e: /* sahf */
6591 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6593 gen_op_mov_v_reg(MO_8
, cpu_T
[0], R_AH
);
6594 gen_compute_eflags(s
);
6595 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, CC_O
);
6596 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], CC_S
| CC_Z
| CC_A
| CC_P
| CC_C
);
6597 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, cpu_T
[0]);
6599 case 0x9f: /* lahf */
6600 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6602 gen_compute_eflags(s
);
6603 /* Note: gen_compute_eflags() only gives the condition codes */
6604 tcg_gen_ori_tl(cpu_T
[0], cpu_cc_src
, 0x02);
6605 gen_op_mov_reg_v(MO_8
, R_AH
, cpu_T
[0]);
6607 case 0xf5: /* cmc */
6608 gen_compute_eflags(s
);
6609 tcg_gen_xori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6611 case 0xf8: /* clc */
6612 gen_compute_eflags(s
);
6613 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_C
);
6615 case 0xf9: /* stc */
6616 gen_compute_eflags(s
);
6617 tcg_gen_ori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6619 case 0xfc: /* cld */
6620 tcg_gen_movi_i32(cpu_tmp2_i32
, 1);
6621 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6623 case 0xfd: /* std */
6624 tcg_gen_movi_i32(cpu_tmp2_i32
, -1);
6625 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6628 /************************/
6629 /* bit operations */
6630 case 0x1ba: /* bt/bts/btr/btc Gv, im */
6632 modrm
= cpu_ldub_code(env
, s
->pc
++);
6633 op
= (modrm
>> 3) & 7;
6634 mod
= (modrm
>> 6) & 3;
6635 rm
= (modrm
& 7) | REX_B(s
);
6638 gen_lea_modrm(env
, s
, modrm
);
6639 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
6641 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
6644 val
= cpu_ldub_code(env
, s
->pc
++);
6645 tcg_gen_movi_tl(cpu_T
[1], val
);
6650 case 0x1a3: /* bt Gv, Ev */
6653 case 0x1ab: /* bts */
6656 case 0x1b3: /* btr */
6659 case 0x1bb: /* btc */
6663 modrm
= cpu_ldub_code(env
, s
->pc
++);
6664 reg
= ((modrm
>> 3) & 7) | rex_r
;
6665 mod
= (modrm
>> 6) & 3;
6666 rm
= (modrm
& 7) | REX_B(s
);
6667 gen_op_mov_v_reg(MO_32
, cpu_T
[1], reg
);
6669 gen_lea_modrm(env
, s
, modrm
);
6670 /* specific case: we need to add a displacement */
6671 gen_exts(ot
, cpu_T
[1]);
6672 tcg_gen_sari_tl(cpu_tmp0
, cpu_T
[1], 3 + ot
);
6673 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, ot
);
6674 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
6675 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
6677 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
6680 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], (1 << (3 + ot
)) - 1);
6681 tcg_gen_shr_tl(cpu_tmp4
, cpu_T
[0], cpu_T
[1]);
6686 tcg_gen_movi_tl(cpu_tmp0
, 1);
6687 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
6688 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
6691 tcg_gen_movi_tl(cpu_tmp0
, 1);
6692 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
6693 tcg_gen_andc_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
6697 tcg_gen_movi_tl(cpu_tmp0
, 1);
6698 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
6699 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
6704 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
6706 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
6710 /* Delay all CC updates until after the store above. Note that
6711 C is the result of the test, Z is unchanged, and the others
6712 are all undefined. */
6714 case CC_OP_MULB
... CC_OP_MULQ
:
6715 case CC_OP_ADDB
... CC_OP_ADDQ
:
6716 case CC_OP_ADCB
... CC_OP_ADCQ
:
6717 case CC_OP_SUBB
... CC_OP_SUBQ
:
6718 case CC_OP_SBBB
... CC_OP_SBBQ
:
6719 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
6720 case CC_OP_INCB
... CC_OP_INCQ
:
6721 case CC_OP_DECB
... CC_OP_DECQ
:
6722 case CC_OP_SHLB
... CC_OP_SHLQ
:
6723 case CC_OP_SARB
... CC_OP_SARQ
:
6724 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
6725 /* Z was going to be computed from the non-zero status of CC_DST.
6726 We can get that same Z value (and the new C value) by leaving
6727 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
6729 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
6730 set_cc_op(s
, ((s
->cc_op
- CC_OP_MULB
) & 3) + CC_OP_SARB
);
6733 /* Otherwise, generate EFLAGS and replace the C bit. */
6734 gen_compute_eflags(s
);
6735 tcg_gen_deposit_tl(cpu_cc_src
, cpu_cc_src
, cpu_tmp4
,
6740 case 0x1bc: /* bsf / tzcnt */
6741 case 0x1bd: /* bsr / lzcnt */
6743 modrm
= cpu_ldub_code(env
, s
->pc
++);
6744 reg
= ((modrm
>> 3) & 7) | rex_r
;
6745 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
6746 gen_extu(ot
, cpu_T
[0]);
6748 /* Note that lzcnt and tzcnt are in different extensions. */
6749 if ((prefixes
& PREFIX_REPZ
)
6751 ? s
->cpuid_ext3_features
& CPUID_EXT3_ABM
6752 : s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)) {
6754 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
6756 /* For lzcnt, reduce the target_ulong result by the
6757 number of zeros that we expect to find at the top. */
6758 gen_helper_clz(cpu_T
[0], cpu_T
[0]);
6759 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], TARGET_LONG_BITS
- size
);
6761 /* For tzcnt, a zero input must return the operand size:
6762 force all bits outside the operand size to 1. */
6763 target_ulong mask
= (target_ulong
)-2 << (size
- 1);
6764 tcg_gen_ori_tl(cpu_T
[0], cpu_T
[0], mask
);
6765 gen_helper_ctz(cpu_T
[0], cpu_T
[0]);
6767 /* For lzcnt/tzcnt, C and Z bits are defined and are
6768 related to the result. */
6769 gen_op_update1_cc();
6770 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
6772 /* For bsr/bsf, only the Z bit is defined and it is related
6773 to the input and not the result. */
6774 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
6775 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
6777 /* For bsr, return the bit index of the first 1 bit,
6778 not the count of leading zeros. */
6779 gen_helper_clz(cpu_T
[0], cpu_T
[0]);
6780 tcg_gen_xori_tl(cpu_T
[0], cpu_T
[0], TARGET_LONG_BITS
- 1);
6782 gen_helper_ctz(cpu_T
[0], cpu_T
[0]);
6784 /* ??? The manual says that the output is undefined when the
6785 input is zero, but real hardware leaves it unchanged, and
6786 real programs appear to depend on that. */
6787 tcg_gen_movi_tl(cpu_tmp0
, 0);
6788 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_T
[0], cpu_cc_dst
, cpu_tmp0
,
6789 cpu_regs
[reg
], cpu_T
[0]);
6791 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
6793 /************************/
6795 case 0x27: /* daa */
6798 gen_update_cc_op(s
);
6799 gen_helper_daa(cpu_env
);
6800 set_cc_op(s
, CC_OP_EFLAGS
);
6802 case 0x2f: /* das */
6805 gen_update_cc_op(s
);
6806 gen_helper_das(cpu_env
);
6807 set_cc_op(s
, CC_OP_EFLAGS
);
6809 case 0x37: /* aaa */
6812 gen_update_cc_op(s
);
6813 gen_helper_aaa(cpu_env
);
6814 set_cc_op(s
, CC_OP_EFLAGS
);
6816 case 0x3f: /* aas */
6819 gen_update_cc_op(s
);
6820 gen_helper_aas(cpu_env
);
6821 set_cc_op(s
, CC_OP_EFLAGS
);
6823 case 0xd4: /* aam */
6826 val
= cpu_ldub_code(env
, s
->pc
++);
6828 gen_exception(s
, EXCP00_DIVZ
, pc_start
- s
->cs_base
);
6830 gen_helper_aam(cpu_env
, tcg_const_i32(val
));
6831 set_cc_op(s
, CC_OP_LOGICB
);
6834 case 0xd5: /* aad */
6837 val
= cpu_ldub_code(env
, s
->pc
++);
6838 gen_helper_aad(cpu_env
, tcg_const_i32(val
));
6839 set_cc_op(s
, CC_OP_LOGICB
);
6841 /************************/
6843 case 0x90: /* nop */
6844 /* XXX: correct lock test for all insn */
6845 if (prefixes
& PREFIX_LOCK
) {
6848 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
6850 goto do_xchg_reg_eax
;
6852 if (prefixes
& PREFIX_REPZ
) {
6853 gen_update_cc_op(s
);
6854 gen_jmp_im(pc_start
- s
->cs_base
);
6855 gen_helper_pause(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
6856 s
->is_jmp
= DISAS_TB_JUMP
;
6859 case 0x9b: /* fwait */
6860 if ((s
->flags
& (HF_MP_MASK
| HF_TS_MASK
)) ==
6861 (HF_MP_MASK
| HF_TS_MASK
)) {
6862 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
6864 gen_helper_fwait(cpu_env
);
6867 case 0xcc: /* int3 */
6868 gen_interrupt(s
, EXCP03_INT3
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6870 case 0xcd: /* int N */
6871 val
= cpu_ldub_code(env
, s
->pc
++);
6872 if (s
->vm86
&& s
->iopl
!= 3) {
6873 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6875 gen_interrupt(s
, val
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6878 case 0xce: /* into */
6881 gen_update_cc_op(s
);
6882 gen_jmp_im(pc_start
- s
->cs_base
);
6883 gen_helper_into(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
6886 case 0xf1: /* icebp (undocumented, exits to external debugger) */
6887 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_ICEBP
);
6889 gen_debug(s
, pc_start
- s
->cs_base
);
6892 tb_flush(CPU(x86_env_get_cpu(env
)));
6893 qemu_set_log(CPU_LOG_INT
| CPU_LOG_TB_IN_ASM
);
6897 case 0xfa: /* cli */
6899 if (s
->cpl
<= s
->iopl
) {
6900 gen_helper_cli(cpu_env
);
6902 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6906 gen_helper_cli(cpu_env
);
6908 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6912 case 0xfb: /* sti */
6914 if (s
->cpl
<= s
->iopl
) {
6916 gen_helper_sti(cpu_env
);
6917 /* interruptions are enabled only the first insn after sti */
6918 /* If several instructions disable interrupts, only the
6920 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
6921 gen_helper_set_inhibit_irq(cpu_env
);
6922 /* give a chance to handle pending irqs */
6923 gen_jmp_im(s
->pc
- s
->cs_base
);
6926 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6932 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6936 case 0x62: /* bound */
6940 modrm
= cpu_ldub_code(env
, s
->pc
++);
6941 reg
= (modrm
>> 3) & 7;
6942 mod
= (modrm
>> 6) & 3;
6945 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
6946 gen_lea_modrm(env
, s
, modrm
);
6947 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6949 gen_helper_boundw(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
6951 gen_helper_boundl(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
6954 case 0x1c8 ... 0x1cf: /* bswap reg */
6955 reg
= (b
& 7) | REX_B(s
);
6956 #ifdef TARGET_X86_64
6957 if (dflag
== MO_64
) {
6958 gen_op_mov_v_reg(MO_64
, cpu_T
[0], reg
);
6959 tcg_gen_bswap64_i64(cpu_T
[0], cpu_T
[0]);
6960 gen_op_mov_reg_v(MO_64
, reg
, cpu_T
[0]);
6964 gen_op_mov_v_reg(MO_32
, cpu_T
[0], reg
);
6965 tcg_gen_ext32u_tl(cpu_T
[0], cpu_T
[0]);
6966 tcg_gen_bswap32_tl(cpu_T
[0], cpu_T
[0]);
6967 gen_op_mov_reg_v(MO_32
, reg
, cpu_T
[0]);
6970 case 0xd6: /* salc */
6973 gen_compute_eflags_c(s
, cpu_T
[0]);
6974 tcg_gen_neg_tl(cpu_T
[0], cpu_T
[0]);
6975 gen_op_mov_reg_v(MO_8
, R_EAX
, cpu_T
[0]);
6977 case 0xe0: /* loopnz */
6978 case 0xe1: /* loopz */
6979 case 0xe2: /* loop */
6980 case 0xe3: /* jecxz */
6982 TCGLabel
*l1
, *l2
, *l3
;
6984 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6985 next_eip
= s
->pc
- s
->cs_base
;
6987 if (dflag
== MO_16
) {
6991 l1
= gen_new_label();
6992 l2
= gen_new_label();
6993 l3
= gen_new_label();
6996 case 0: /* loopnz */
6998 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
6999 gen_op_jz_ecx(s
->aflag
, l3
);
7000 gen_jcc1(s
, (JCC_Z
<< 1) | (b
^ 1), l1
);
7003 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
7004 gen_op_jnz_ecx(s
->aflag
, l1
);
7008 gen_op_jz_ecx(s
->aflag
, l1
);
7013 gen_jmp_im(next_eip
);
7022 case 0x130: /* wrmsr */
7023 case 0x132: /* rdmsr */
7025 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7027 gen_update_cc_op(s
);
7028 gen_jmp_im(pc_start
- s
->cs_base
);
7030 gen_helper_rdmsr(cpu_env
);
7032 gen_helper_wrmsr(cpu_env
);
7036 case 0x131: /* rdtsc */
7037 gen_update_cc_op(s
);
7038 gen_jmp_im(pc_start
- s
->cs_base
);
7039 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7042 gen_helper_rdtsc(cpu_env
);
7043 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7045 gen_jmp(s
, s
->pc
- s
->cs_base
);
7048 case 0x133: /* rdpmc */
7049 gen_update_cc_op(s
);
7050 gen_jmp_im(pc_start
- s
->cs_base
);
7051 gen_helper_rdpmc(cpu_env
);
7053 case 0x134: /* sysenter */
7054 /* For Intel SYSENTER is valid on 64-bit */
7055 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7058 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7060 gen_helper_sysenter(cpu_env
);
7064 case 0x135: /* sysexit */
7065 /* For Intel SYSEXIT is valid on 64-bit */
7066 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7069 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7071 gen_helper_sysexit(cpu_env
, tcg_const_i32(dflag
- 1));
7075 #ifdef TARGET_X86_64
7076 case 0x105: /* syscall */
7077 /* XXX: is it usable in real mode ? */
7078 gen_update_cc_op(s
);
7079 gen_jmp_im(pc_start
- s
->cs_base
);
7080 gen_helper_syscall(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7083 case 0x107: /* sysret */
7085 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7087 gen_helper_sysret(cpu_env
, tcg_const_i32(dflag
- 1));
7088 /* condition codes are modified only in long mode */
7090 set_cc_op(s
, CC_OP_EFLAGS
);
7096 case 0x1a2: /* cpuid */
7097 gen_update_cc_op(s
);
7098 gen_jmp_im(pc_start
- s
->cs_base
);
7099 gen_helper_cpuid(cpu_env
);
7101 case 0xf4: /* hlt */
7103 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7105 gen_update_cc_op(s
);
7106 gen_jmp_im(pc_start
- s
->cs_base
);
7107 gen_helper_hlt(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7108 s
->is_jmp
= DISAS_TB_JUMP
;
7112 modrm
= cpu_ldub_code(env
, s
->pc
++);
7113 mod
= (modrm
>> 6) & 3;
7114 op
= (modrm
>> 3) & 7;
7117 if (!s
->pe
|| s
->vm86
)
7119 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_READ
);
7120 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,ldt
.selector
));
7121 ot
= mod
== 3 ? dflag
: MO_16
;
7122 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7125 if (!s
->pe
|| s
->vm86
)
7128 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7130 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_WRITE
);
7131 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7132 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
7133 gen_helper_lldt(cpu_env
, cpu_tmp2_i32
);
7137 if (!s
->pe
|| s
->vm86
)
7139 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_READ
);
7140 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,tr
.selector
));
7141 ot
= mod
== 3 ? dflag
: MO_16
;
7142 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7145 if (!s
->pe
|| s
->vm86
)
7148 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7150 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_WRITE
);
7151 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7152 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
7153 gen_helper_ltr(cpu_env
, cpu_tmp2_i32
);
7158 if (!s
->pe
|| s
->vm86
)
7160 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7161 gen_update_cc_op(s
);
7163 gen_helper_verr(cpu_env
, cpu_T
[0]);
7165 gen_helper_verw(cpu_env
, cpu_T
[0]);
7167 set_cc_op(s
, CC_OP_EFLAGS
);
7174 modrm
= cpu_ldub_code(env
, s
->pc
++);
7175 mod
= (modrm
>> 6) & 3;
7176 op
= (modrm
>> 3) & 7;
7182 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_READ
);
7183 gen_lea_modrm(env
, s
, modrm
);
7184 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7185 gen_op_st_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
7186 gen_add_A0_im(s
, 2);
7187 tcg_gen_ld_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7188 if (dflag
== MO_16
) {
7189 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffffff);
7191 gen_op_st_v(s
, CODE64(s
) + MO_32
, cpu_T
[0], cpu_A0
);
7196 case 0: /* monitor */
7197 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) ||
7200 gen_update_cc_op(s
);
7201 gen_jmp_im(pc_start
- s
->cs_base
);
7202 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EAX
]);
7203 gen_extu(s
->aflag
, cpu_A0
);
7204 gen_add_A0_ds_seg(s
);
7205 gen_helper_monitor(cpu_env
, cpu_A0
);
7208 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) ||
7211 gen_update_cc_op(s
);
7212 gen_jmp_im(pc_start
- s
->cs_base
);
7213 gen_helper_mwait(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7217 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
) ||
7221 gen_helper_clac(cpu_env
);
7222 gen_jmp_im(s
->pc
- s
->cs_base
);
7226 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
) ||
7230 gen_helper_stac(cpu_env
);
7231 gen_jmp_im(s
->pc
- s
->cs_base
);
7238 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_READ
);
7239 gen_lea_modrm(env
, s
, modrm
);
7240 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7241 gen_op_st_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
7242 gen_add_A0_im(s
, 2);
7243 tcg_gen_ld_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, idt
.base
));
7244 if (dflag
== MO_16
) {
7245 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffffff);
7247 gen_op_st_v(s
, CODE64(s
) + MO_32
, cpu_T
[0], cpu_A0
);
7253 gen_update_cc_op(s
);
7254 gen_jmp_im(pc_start
- s
->cs_base
);
7257 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7260 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7263 gen_helper_vmrun(cpu_env
, tcg_const_i32(s
->aflag
- 1),
7264 tcg_const_i32(s
->pc
- pc_start
));
7266 s
->is_jmp
= DISAS_TB_JUMP
;
7269 case 1: /* VMMCALL */
7270 if (!(s
->flags
& HF_SVME_MASK
))
7272 gen_helper_vmmcall(cpu_env
);
7274 case 2: /* VMLOAD */
7275 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7278 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7281 gen_helper_vmload(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7284 case 3: /* VMSAVE */
7285 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7288 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7291 gen_helper_vmsave(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7295 if ((!(s
->flags
& HF_SVME_MASK
) &&
7296 !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
)) ||
7300 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7303 gen_helper_stgi(cpu_env
);
7307 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7310 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7313 gen_helper_clgi(cpu_env
);
7316 case 6: /* SKINIT */
7317 if ((!(s
->flags
& HF_SVME_MASK
) &&
7318 !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
)) ||
7321 gen_helper_skinit(cpu_env
);
7323 case 7: /* INVLPGA */
7324 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7327 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7330 gen_helper_invlpga(cpu_env
,
7331 tcg_const_i32(s
->aflag
- 1));
7337 } else if (s
->cpl
!= 0) {
7338 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7340 gen_svm_check_intercept(s
, pc_start
,
7341 op
==2 ? SVM_EXIT_GDTR_WRITE
: SVM_EXIT_IDTR_WRITE
);
7342 gen_lea_modrm(env
, s
, modrm
);
7343 gen_op_ld_v(s
, MO_16
, cpu_T
[1], cpu_A0
);
7344 gen_add_A0_im(s
, 2);
7345 gen_op_ld_v(s
, CODE64(s
) + MO_32
, cpu_T
[0], cpu_A0
);
7346 if (dflag
== MO_16
) {
7347 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffffff);
7350 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,gdt
.base
));
7351 tcg_gen_st32_tl(cpu_T
[1], cpu_env
, offsetof(CPUX86State
,gdt
.limit
));
7353 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,idt
.base
));
7354 tcg_gen_st32_tl(cpu_T
[1], cpu_env
, offsetof(CPUX86State
,idt
.limit
));
7359 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_CR0
);
7360 #if defined TARGET_X86_64 && defined HOST_WORDS_BIGENDIAN
7361 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,cr
[0]) + 4);
7363 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,cr
[0]));
7365 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 1);
7369 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7371 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7372 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7373 gen_helper_lmsw(cpu_env
, cpu_T
[0]);
7374 gen_jmp_im(s
->pc
- s
->cs_base
);
7379 if (mod
!= 3) { /* invlpg */
7381 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7383 gen_update_cc_op(s
);
7384 gen_jmp_im(pc_start
- s
->cs_base
);
7385 gen_lea_modrm(env
, s
, modrm
);
7386 gen_helper_invlpg(cpu_env
, cpu_A0
);
7387 gen_jmp_im(s
->pc
- s
->cs_base
);
7392 case 0: /* swapgs */
7393 #ifdef TARGET_X86_64
7396 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7398 tcg_gen_ld_tl(cpu_T
[0], cpu_env
,
7399 offsetof(CPUX86State
,segs
[R_GS
].base
));
7400 tcg_gen_ld_tl(cpu_T
[1], cpu_env
,
7401 offsetof(CPUX86State
,kernelgsbase
));
7402 tcg_gen_st_tl(cpu_T
[1], cpu_env
,
7403 offsetof(CPUX86State
,segs
[R_GS
].base
));
7404 tcg_gen_st_tl(cpu_T
[0], cpu_env
,
7405 offsetof(CPUX86State
,kernelgsbase
));
7413 case 1: /* rdtscp */
7414 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_RDTSCP
))
7416 gen_update_cc_op(s
);
7417 gen_jmp_im(pc_start
- s
->cs_base
);
7418 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7421 gen_helper_rdtscp(cpu_env
);
7422 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7424 gen_jmp(s
, s
->pc
- s
->cs_base
);
7436 case 0x108: /* invd */
7437 case 0x109: /* wbinvd */
7439 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7441 gen_svm_check_intercept(s
, pc_start
, (b
& 2) ? SVM_EXIT_INVD
: SVM_EXIT_WBINVD
);
7445 case 0x63: /* arpl or movslS (x86_64) */
7446 #ifdef TARGET_X86_64
7449 /* d_ot is the size of destination */
7452 modrm
= cpu_ldub_code(env
, s
->pc
++);
7453 reg
= ((modrm
>> 3) & 7) | rex_r
;
7454 mod
= (modrm
>> 6) & 3;
7455 rm
= (modrm
& 7) | REX_B(s
);
7458 gen_op_mov_v_reg(MO_32
, cpu_T
[0], rm
);
7460 if (d_ot
== MO_64
) {
7461 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
7463 gen_op_mov_reg_v(d_ot
, reg
, cpu_T
[0]);
7465 gen_lea_modrm(env
, s
, modrm
);
7466 gen_op_ld_v(s
, MO_32
| MO_SIGN
, cpu_T
[0], cpu_A0
);
7467 gen_op_mov_reg_v(d_ot
, reg
, cpu_T
[0]);
7473 TCGv t0
, t1
, t2
, a0
;
7475 if (!s
->pe
|| s
->vm86
)
7477 t0
= tcg_temp_local_new();
7478 t1
= tcg_temp_local_new();
7479 t2
= tcg_temp_local_new();
7481 modrm
= cpu_ldub_code(env
, s
->pc
++);
7482 reg
= (modrm
>> 3) & 7;
7483 mod
= (modrm
>> 6) & 3;
7486 gen_lea_modrm(env
, s
, modrm
);
7487 gen_op_ld_v(s
, ot
, t0
, cpu_A0
);
7488 a0
= tcg_temp_local_new();
7489 tcg_gen_mov_tl(a0
, cpu_A0
);
7491 gen_op_mov_v_reg(ot
, t0
, rm
);
7494 gen_op_mov_v_reg(ot
, t1
, reg
);
7495 tcg_gen_andi_tl(cpu_tmp0
, t0
, 3);
7496 tcg_gen_andi_tl(t1
, t1
, 3);
7497 tcg_gen_movi_tl(t2
, 0);
7498 label1
= gen_new_label();
7499 tcg_gen_brcond_tl(TCG_COND_GE
, cpu_tmp0
, t1
, label1
);
7500 tcg_gen_andi_tl(t0
, t0
, ~3);
7501 tcg_gen_or_tl(t0
, t0
, t1
);
7502 tcg_gen_movi_tl(t2
, CC_Z
);
7503 gen_set_label(label1
);
7505 gen_op_st_v(s
, ot
, t0
, a0
);
7508 gen_op_mov_reg_v(ot
, rm
, t0
);
7510 gen_compute_eflags(s
);
7511 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_Z
);
7512 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, t2
);
7518 case 0x102: /* lar */
7519 case 0x103: /* lsl */
7523 if (!s
->pe
|| s
->vm86
)
7525 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
7526 modrm
= cpu_ldub_code(env
, s
->pc
++);
7527 reg
= ((modrm
>> 3) & 7) | rex_r
;
7528 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7529 t0
= tcg_temp_local_new();
7530 gen_update_cc_op(s
);
7532 gen_helper_lar(t0
, cpu_env
, cpu_T
[0]);
7534 gen_helper_lsl(t0
, cpu_env
, cpu_T
[0]);
7536 tcg_gen_andi_tl(cpu_tmp0
, cpu_cc_src
, CC_Z
);
7537 label1
= gen_new_label();
7538 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
7539 gen_op_mov_reg_v(ot
, reg
, t0
);
7540 gen_set_label(label1
);
7541 set_cc_op(s
, CC_OP_EFLAGS
);
7546 modrm
= cpu_ldub_code(env
, s
->pc
++);
7547 mod
= (modrm
>> 6) & 3;
7548 op
= (modrm
>> 3) & 7;
7550 case 0: /* prefetchnta */
7551 case 1: /* prefetchnt0 */
7552 case 2: /* prefetchnt0 */
7553 case 3: /* prefetchnt0 */
7556 gen_lea_modrm(env
, s
, modrm
);
7557 /* nothing more to do */
7559 default: /* nop (multi byte) */
7560 gen_nop_modrm(env
, s
, modrm
);
7564 case 0x119 ... 0x11f: /* nop (multi byte) */
7565 modrm
= cpu_ldub_code(env
, s
->pc
++);
7566 gen_nop_modrm(env
, s
, modrm
);
7568 case 0x120: /* mov reg, crN */
7569 case 0x122: /* mov crN, reg */
7571 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7573 modrm
= cpu_ldub_code(env
, s
->pc
++);
7574 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7575 * AMD documentation (24594.pdf) and testing of
7576 * intel 386 and 486 processors all show that the mod bits
7577 * are assumed to be 1's, regardless of actual values.
7579 rm
= (modrm
& 7) | REX_B(s
);
7580 reg
= ((modrm
>> 3) & 7) | rex_r
;
7585 if ((prefixes
& PREFIX_LOCK
) && (reg
== 0) &&
7586 (s
->cpuid_ext3_features
& CPUID_EXT3_CR8LEG
)) {
7595 gen_update_cc_op(s
);
7596 gen_jmp_im(pc_start
- s
->cs_base
);
7598 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
7599 gen_helper_write_crN(cpu_env
, tcg_const_i32(reg
),
7601 gen_jmp_im(s
->pc
- s
->cs_base
);
7604 gen_helper_read_crN(cpu_T
[0], cpu_env
, tcg_const_i32(reg
));
7605 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
7613 case 0x121: /* mov reg, drN */
7614 case 0x123: /* mov drN, 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
;
7634 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_DR0
+ reg
);
7635 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
7636 tcg_gen_movi_i32(cpu_tmp2_i32
, reg
);
7637 gen_helper_set_dr(cpu_env
, cpu_tmp2_i32
, cpu_T
[0]);
7638 gen_jmp_im(s
->pc
- s
->cs_base
);
7641 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_DR0
+ reg
);
7642 tcg_gen_movi_i32(cpu_tmp2_i32
, reg
);
7643 gen_helper_get_dr(cpu_T
[0], cpu_env
, cpu_tmp2_i32
);
7644 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
7648 case 0x106: /* clts */
7650 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7652 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7653 gen_helper_clts(cpu_env
);
7654 /* abort block because static cpu state changed */
7655 gen_jmp_im(s
->pc
- s
->cs_base
);
7659 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
7660 case 0x1c3: /* MOVNTI reg, mem */
7661 if (!(s
->cpuid_features
& CPUID_SSE2
))
7663 ot
= mo_64_32(dflag
);
7664 modrm
= cpu_ldub_code(env
, s
->pc
++);
7665 mod
= (modrm
>> 6) & 3;
7668 reg
= ((modrm
>> 3) & 7) | rex_r
;
7669 /* generate a generic store */
7670 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
7673 modrm
= cpu_ldub_code(env
, s
->pc
++);
7674 mod
= (modrm
>> 6) & 3;
7675 op
= (modrm
>> 3) & 7;
7677 case 0: /* fxsave */
7678 if (mod
== 3 || !(s
->cpuid_features
& CPUID_FXSR
) ||
7679 (s
->prefix
& PREFIX_LOCK
))
7681 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
7682 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7685 gen_lea_modrm(env
, s
, modrm
);
7686 gen_helper_fxsave(cpu_env
, cpu_A0
, tcg_const_i32(dflag
== MO_64
));
7688 case 1: /* fxrstor */
7689 if (mod
== 3 || !(s
->cpuid_features
& CPUID_FXSR
) ||
7690 (s
->prefix
& PREFIX_LOCK
))
7692 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
7693 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7696 gen_lea_modrm(env
, s
, modrm
);
7697 gen_helper_fxrstor(cpu_env
, cpu_A0
, tcg_const_i32(dflag
== MO_64
));
7699 case 2: /* ldmxcsr */
7700 case 3: /* stmxcsr */
7701 if (s
->flags
& HF_TS_MASK
) {
7702 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7705 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
) ||
7708 gen_lea_modrm(env
, s
, modrm
);
7710 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
7711 s
->mem_index
, MO_LEUL
);
7712 gen_helper_ldmxcsr(cpu_env
, cpu_tmp2_i32
);
7714 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, mxcsr
));
7715 gen_op_st_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
7718 case 5: /* lfence */
7719 if ((modrm
& 0xc7) != 0xc0 || !(s
->cpuid_features
& CPUID_SSE2
))
7722 case 6: /* mfence/clwb */
7723 if (s
->prefix
& PREFIX_DATA
) {
7725 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLWB
))
7727 gen_nop_modrm(env
, s
, modrm
);
7730 if ((modrm
& 0xc7) != 0xc0 || !(s
->cpuid_features
& CPUID_SSE2
))
7734 case 7: /* sfence / clflush */
7735 if ((modrm
& 0xc7) == 0xc0) {
7737 /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX */
7738 if (!(s
->cpuid_features
& CPUID_SSE
))
7742 if (!(s
->cpuid_features
& CPUID_CLFLUSH
))
7744 gen_lea_modrm(env
, s
, modrm
);
7751 case 0x10d: /* 3DNow! prefetch(w) */
7752 modrm
= cpu_ldub_code(env
, s
->pc
++);
7753 mod
= (modrm
>> 6) & 3;
7756 gen_lea_modrm(env
, s
, modrm
);
7757 /* ignore for now */
7759 case 0x1aa: /* rsm */
7760 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_RSM
);
7761 if (!(s
->flags
& HF_SMM_MASK
))
7763 gen_update_cc_op(s
);
7764 gen_jmp_im(s
->pc
- s
->cs_base
);
7765 gen_helper_rsm(cpu_env
);
7768 case 0x1b8: /* SSE4.2 popcnt */
7769 if ((prefixes
& (PREFIX_REPZ
| PREFIX_LOCK
| PREFIX_REPNZ
)) !=
7772 if (!(s
->cpuid_ext_features
& CPUID_EXT_POPCNT
))
7775 modrm
= cpu_ldub_code(env
, s
->pc
++);
7776 reg
= ((modrm
>> 3) & 7) | rex_r
;
7778 if (s
->prefix
& PREFIX_DATA
) {
7781 ot
= mo_64_32(dflag
);
7784 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
7785 gen_helper_popcnt(cpu_T
[0], cpu_env
, cpu_T
[0], tcg_const_i32(ot
));
7786 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
7788 set_cc_op(s
, CC_OP_EFLAGS
);
7790 case 0x10e ... 0x10f:
7791 /* 3DNow! instructions, ignore prefixes */
7792 s
->prefix
&= ~(PREFIX_REPZ
| PREFIX_REPNZ
| PREFIX_DATA
);
7793 case 0x110 ... 0x117:
7794 case 0x128 ... 0x12f:
7795 case 0x138 ... 0x13a:
7796 case 0x150 ... 0x179:
7797 case 0x17c ... 0x17f:
7799 case 0x1c4 ... 0x1c6:
7800 case 0x1d0 ... 0x1fe:
7801 gen_sse(env
, s
, b
, pc_start
, rex_r
);
7806 /* lock generation */
7807 if (s
->prefix
& PREFIX_LOCK
)
7808 gen_helper_unlock();
7811 if (s
->prefix
& PREFIX_LOCK
)
7812 gen_helper_unlock();
7813 /* XXX: ensure that no lock was generated */
7814 gen_exception(s
, EXCP06_ILLOP
, pc_start
- s
->cs_base
);
7818 void optimize_flags_init(void)
7820 static const char reg_names
[CPU_NB_REGS
][4] = {
7821 #ifdef TARGET_X86_64
7851 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
7852 cpu_cc_op
= tcg_global_mem_new_i32(TCG_AREG0
,
7853 offsetof(CPUX86State
, cc_op
), "cc_op");
7854 cpu_cc_dst
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_dst
),
7856 cpu_cc_src
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_src
),
7858 cpu_cc_src2
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_src2
),
7861 for (i
= 0; i
< CPU_NB_REGS
; ++i
) {
7862 cpu_regs
[i
] = tcg_global_mem_new(TCG_AREG0
,
7863 offsetof(CPUX86State
, regs
[i
]),
7870 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
7871 basic block 'tb'. */
7872 void gen_intermediate_code(CPUX86State
*env
, TranslationBlock
*tb
)
7874 X86CPU
*cpu
= x86_env_get_cpu(env
);
7875 CPUState
*cs
= CPU(cpu
);
7876 DisasContext dc1
, *dc
= &dc1
;
7877 target_ulong pc_ptr
;
7879 target_ulong pc_start
;
7880 target_ulong cs_base
;
7884 /* generate intermediate code */
7886 cs_base
= tb
->cs_base
;
7889 dc
->pe
= (flags
>> HF_PE_SHIFT
) & 1;
7890 dc
->code32
= (flags
>> HF_CS32_SHIFT
) & 1;
7891 dc
->ss32
= (flags
>> HF_SS32_SHIFT
) & 1;
7892 dc
->addseg
= (flags
>> HF_ADDSEG_SHIFT
) & 1;
7894 dc
->vm86
= (flags
>> VM_SHIFT
) & 1;
7895 dc
->cpl
= (flags
>> HF_CPL_SHIFT
) & 3;
7896 dc
->iopl
= (flags
>> IOPL_SHIFT
) & 3;
7897 dc
->tf
= (flags
>> TF_SHIFT
) & 1;
7898 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
7899 dc
->cc_op
= CC_OP_DYNAMIC
;
7900 dc
->cc_op_dirty
= false;
7901 dc
->cs_base
= cs_base
;
7903 dc
->popl_esp_hack
= 0;
7904 /* select memory access functions */
7906 if (flags
& HF_SOFTMMU_MASK
) {
7907 dc
->mem_index
= cpu_mmu_index(env
, false);
7909 dc
->cpuid_features
= env
->features
[FEAT_1_EDX
];
7910 dc
->cpuid_ext_features
= env
->features
[FEAT_1_ECX
];
7911 dc
->cpuid_ext2_features
= env
->features
[FEAT_8000_0001_EDX
];
7912 dc
->cpuid_ext3_features
= env
->features
[FEAT_8000_0001_ECX
];
7913 dc
->cpuid_7_0_ebx_features
= env
->features
[FEAT_7_0_EBX
];
7914 #ifdef TARGET_X86_64
7915 dc
->lma
= (flags
>> HF_LMA_SHIFT
) & 1;
7916 dc
->code64
= (flags
>> HF_CS64_SHIFT
) & 1;
7919 dc
->jmp_opt
= !(dc
->tf
|| cs
->singlestep_enabled
||
7920 (flags
& HF_INHIBIT_IRQ_MASK
)
7921 #ifndef CONFIG_SOFTMMU
7922 || (flags
& HF_SOFTMMU_MASK
)
7925 /* Do not optimize repz jumps at all in icount mode, because
7926 rep movsS instructions are execured with different paths
7927 in !repz_opt and repz_opt modes. The first one was used
7928 always except single step mode. And this setting
7929 disables jumps optimization and control paths become
7930 equivalent in run and single step modes.
7931 Now there will be no jump optimization for repz in
7932 record/replay modes and there will always be an
7933 additional step for ecx=0 when icount is enabled.
7935 dc
->repz_opt
= !dc
->jmp_opt
&& !(tb
->cflags
& CF_USE_ICOUNT
);
7937 /* check addseg logic */
7938 if (!dc
->addseg
&& (dc
->vm86
|| !dc
->pe
|| !dc
->code32
))
7939 printf("ERROR addseg\n");
7942 cpu_T
[0] = tcg_temp_new();
7943 cpu_T
[1] = tcg_temp_new();
7944 cpu_A0
= tcg_temp_new();
7946 cpu_tmp0
= tcg_temp_new();
7947 cpu_tmp1_i64
= tcg_temp_new_i64();
7948 cpu_tmp2_i32
= tcg_temp_new_i32();
7949 cpu_tmp3_i32
= tcg_temp_new_i32();
7950 cpu_tmp4
= tcg_temp_new();
7951 cpu_ptr0
= tcg_temp_new_ptr();
7952 cpu_ptr1
= tcg_temp_new_ptr();
7953 cpu_cc_srcT
= tcg_temp_local_new();
7955 dc
->is_jmp
= DISAS_NEXT
;
7958 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
7959 if (max_insns
== 0) {
7960 max_insns
= CF_COUNT_MASK
;
7962 if (max_insns
> TCG_MAX_INSNS
) {
7963 max_insns
= TCG_MAX_INSNS
;
7968 tcg_gen_insn_start(pc_ptr
, dc
->cc_op
);
7971 /* If RF is set, suppress an internally generated breakpoint. */
7972 if (unlikely(cpu_breakpoint_test(cs
, pc_ptr
,
7973 tb
->flags
& HF_RF_MASK
7974 ? BP_GDB
: BP_ANY
))) {
7975 gen_debug(dc
, pc_ptr
- dc
->cs_base
);
7976 /* The address covered by the breakpoint must be included in
7977 [tb->pc, tb->pc + tb->size) in order to for it to be
7978 properly cleared -- thus we increment the PC here so that
7979 the logic setting tb->size below does the right thing. */
7981 goto done_generating
;
7983 if (num_insns
== max_insns
&& (tb
->cflags
& CF_LAST_IO
)) {
7987 pc_ptr
= disas_insn(env
, dc
, pc_ptr
);
7988 /* stop translation if indicated */
7991 /* if single step mode, we generate only one instruction and
7992 generate an exception */
7993 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
7994 the flag and abort the translation to give the irqs a
7995 change to be happen */
7996 if (dc
->tf
|| dc
->singlestep_enabled
||
7997 (flags
& HF_INHIBIT_IRQ_MASK
)) {
7998 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8002 /* Do not cross the boundary of the pages in icount mode,
8003 it can cause an exception. Do it only when boundary is
8004 crossed by the first instruction in the block.
8005 If current instruction already crossed the bound - it's ok,
8006 because an exception hasn't stopped this code.
8008 if ((tb
->cflags
& CF_USE_ICOUNT
)
8009 && ((pc_ptr
& TARGET_PAGE_MASK
)
8010 != ((pc_ptr
+ TARGET_MAX_INSN_SIZE
- 1) & TARGET_PAGE_MASK
)
8011 || (pc_ptr
& ~TARGET_PAGE_MASK
) == 0)) {
8012 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8016 /* if too long translation, stop generation too */
8017 if (tcg_op_buf_full() ||
8018 (pc_ptr
- pc_start
) >= (TARGET_PAGE_SIZE
- 32) ||
8019 num_insns
>= max_insns
) {
8020 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8025 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8030 if (tb
->cflags
& CF_LAST_IO
)
8033 gen_tb_end(tb
, num_insns
);
8036 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
8038 qemu_log("----------------\n");
8039 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
8040 #ifdef TARGET_X86_64
8045 disas_flags
= !dc
->code32
;
8046 log_target_disas(cs
, pc_start
, pc_ptr
- pc_start
, disas_flags
);
8051 tb
->size
= pc_ptr
- pc_start
;
8052 tb
->icount
= num_insns
;
8055 void restore_state_to_opc(CPUX86State
*env
, TranslationBlock
*tb
,
8058 int cc_op
= data
[1];
8059 env
->eip
= data
[0] - tb
->cs_base
;
8060 if (cc_op
!= CC_OP_DYNAMIC
) {