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_T
[0], cpu_T
[1],
3852 cpu_T
[0], cpu_regs
[R_EDX
]);
3853 tcg_gen_mov_i64(cpu_regs
[s
->vex_v
], cpu_T
[0]);
3854 tcg_gen_mov_i64(cpu_regs
[reg
], cpu_T
[1]);
3860 case 0x3f5: /* pdep Gy, By, Ey */
3861 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3862 || !(s
->prefix
& PREFIX_VEX
)
3866 ot
= mo_64_32(s
->dflag
);
3867 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3868 /* Note that by zero-extending the mask operand, we
3869 automatically handle zero-extending the result. */
3871 tcg_gen_mov_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
3873 tcg_gen_ext32u_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
3875 gen_helper_pdep(cpu_regs
[reg
], cpu_T
[0], cpu_T
[1]);
3878 case 0x2f5: /* pext Gy, By, Ey */
3879 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3880 || !(s
->prefix
& PREFIX_VEX
)
3884 ot
= mo_64_32(s
->dflag
);
3885 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3886 /* Note that by zero-extending the mask operand, we
3887 automatically handle zero-extending the result. */
3889 tcg_gen_mov_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
3891 tcg_gen_ext32u_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
3893 gen_helper_pext(cpu_regs
[reg
], cpu_T
[0], cpu_T
[1]);
3896 case 0x1f6: /* adcx Gy, Ey */
3897 case 0x2f6: /* adox Gy, Ey */
3898 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_ADX
)) {
3901 TCGv carry_in
, carry_out
, zero
;
3904 ot
= mo_64_32(s
->dflag
);
3905 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3907 /* Re-use the carry-out from a previous round. */
3908 TCGV_UNUSED(carry_in
);
3909 carry_out
= (b
== 0x1f6 ? cpu_cc_dst
: cpu_cc_src2
);
3913 carry_in
= cpu_cc_dst
;
3914 end_op
= CC_OP_ADCX
;
3916 end_op
= CC_OP_ADCOX
;
3921 end_op
= CC_OP_ADCOX
;
3923 carry_in
= cpu_cc_src2
;
3924 end_op
= CC_OP_ADOX
;
3928 end_op
= CC_OP_ADCOX
;
3929 carry_in
= carry_out
;
3932 end_op
= (b
== 0x1f6 ? CC_OP_ADCX
: CC_OP_ADOX
);
3935 /* If we can't reuse carry-out, get it out of EFLAGS. */
3936 if (TCGV_IS_UNUSED(carry_in
)) {
3937 if (s
->cc_op
!= CC_OP_ADCX
&& s
->cc_op
!= CC_OP_ADOX
) {
3938 gen_compute_eflags(s
);
3940 carry_in
= cpu_tmp0
;
3941 tcg_gen_shri_tl(carry_in
, cpu_cc_src
,
3942 ctz32(b
== 0x1f6 ? CC_C
: CC_O
));
3943 tcg_gen_andi_tl(carry_in
, carry_in
, 1);
3947 #ifdef TARGET_X86_64
3949 /* If we know TL is 64-bit, and we want a 32-bit
3950 result, just do everything in 64-bit arithmetic. */
3951 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_regs
[reg
]);
3952 tcg_gen_ext32u_i64(cpu_T
[0], cpu_T
[0]);
3953 tcg_gen_add_i64(cpu_T
[0], cpu_T
[0], cpu_regs
[reg
]);
3954 tcg_gen_add_i64(cpu_T
[0], cpu_T
[0], carry_in
);
3955 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_T
[0]);
3956 tcg_gen_shri_i64(carry_out
, cpu_T
[0], 32);
3960 /* Otherwise compute the carry-out in two steps. */
3961 zero
= tcg_const_tl(0);
3962 tcg_gen_add2_tl(cpu_T
[0], carry_out
,
3965 tcg_gen_add2_tl(cpu_regs
[reg
], carry_out
,
3966 cpu_regs
[reg
], carry_out
,
3968 tcg_temp_free(zero
);
3971 set_cc_op(s
, end_op
);
3975 case 0x1f7: /* shlx Gy, Ey, By */
3976 case 0x2f7: /* sarx Gy, Ey, By */
3977 case 0x3f7: /* shrx Gy, Ey, By */
3978 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3979 || !(s
->prefix
& PREFIX_VEX
)
3983 ot
= mo_64_32(s
->dflag
);
3984 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3986 tcg_gen_andi_tl(cpu_T
[1], cpu_regs
[s
->vex_v
], 63);
3988 tcg_gen_andi_tl(cpu_T
[1], cpu_regs
[s
->vex_v
], 31);
3991 tcg_gen_shl_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
3992 } else if (b
== 0x2f7) {
3994 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
3996 tcg_gen_sar_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
3999 tcg_gen_ext32u_tl(cpu_T
[0], cpu_T
[0]);
4001 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4003 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
4009 case 0x3f3: /* Group 17 */
4010 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
4011 || !(s
->prefix
& PREFIX_VEX
)
4015 ot
= mo_64_32(s
->dflag
);
4016 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4019 case 1: /* blsr By,Ey */
4020 tcg_gen_neg_tl(cpu_T
[1], cpu_T
[0]);
4021 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4022 gen_op_mov_reg_v(ot
, s
->vex_v
, cpu_T
[0]);
4023 gen_op_update2_cc();
4024 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4027 case 2: /* blsmsk By,Ey */
4028 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
4029 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], 1);
4030 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_cc_src
);
4031 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4032 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4035 case 3: /* blsi By, Ey */
4036 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
4037 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], 1);
4038 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_cc_src
);
4039 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4040 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4056 modrm
= cpu_ldub_code(env
, s
->pc
++);
4058 reg
= ((modrm
>> 3) & 7) | rex_r
;
4059 mod
= (modrm
>> 6) & 3;
4064 sse_fn_eppi
= sse_op_table7
[b
].op
[b1
];
4068 if (!(s
->cpuid_ext_features
& sse_op_table7
[b
].ext_mask
))
4071 if (sse_fn_eppi
== SSE_SPECIAL
) {
4072 ot
= mo_64_32(s
->dflag
);
4073 rm
= (modrm
& 7) | REX_B(s
);
4075 gen_lea_modrm(env
, s
, modrm
);
4076 reg
= ((modrm
>> 3) & 7) | rex_r
;
4077 val
= cpu_ldub_code(env
, s
->pc
++);
4079 case 0x14: /* pextrb */
4080 tcg_gen_ld8u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4081 xmm_regs
[reg
].XMM_B(val
& 15)));
4083 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4085 tcg_gen_qemu_st_tl(cpu_T
[0], cpu_A0
,
4086 s
->mem_index
, MO_UB
);
4089 case 0x15: /* pextrw */
4090 tcg_gen_ld16u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4091 xmm_regs
[reg
].XMM_W(val
& 7)));
4093 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4095 tcg_gen_qemu_st_tl(cpu_T
[0], cpu_A0
,
4096 s
->mem_index
, MO_LEUW
);
4100 if (ot
== MO_32
) { /* pextrd */
4101 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4102 offsetof(CPUX86State
,
4103 xmm_regs
[reg
].XMM_L(val
& 3)));
4105 tcg_gen_extu_i32_tl(cpu_regs
[rm
], cpu_tmp2_i32
);
4107 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
4108 s
->mem_index
, MO_LEUL
);
4110 } else { /* pextrq */
4111 #ifdef TARGET_X86_64
4112 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
4113 offsetof(CPUX86State
,
4114 xmm_regs
[reg
].XMM_Q(val
& 1)));
4116 tcg_gen_mov_i64(cpu_regs
[rm
], cpu_tmp1_i64
);
4118 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
4119 s
->mem_index
, MO_LEQ
);
4126 case 0x17: /* extractps */
4127 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4128 xmm_regs
[reg
].XMM_L(val
& 3)));
4130 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4132 tcg_gen_qemu_st_tl(cpu_T
[0], cpu_A0
,
4133 s
->mem_index
, MO_LEUL
);
4136 case 0x20: /* pinsrb */
4138 gen_op_mov_v_reg(MO_32
, cpu_T
[0], rm
);
4140 tcg_gen_qemu_ld_tl(cpu_T
[0], cpu_A0
,
4141 s
->mem_index
, MO_UB
);
4143 tcg_gen_st8_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4144 xmm_regs
[reg
].XMM_B(val
& 15)));
4146 case 0x21: /* insertps */
4148 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4149 offsetof(CPUX86State
,xmm_regs
[rm
]
4150 .XMM_L((val
>> 6) & 3)));
4152 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
4153 s
->mem_index
, MO_LEUL
);
4155 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4156 offsetof(CPUX86State
,xmm_regs
[reg
]
4157 .XMM_L((val
>> 4) & 3)));
4159 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4160 cpu_env
, offsetof(CPUX86State
,
4161 xmm_regs
[reg
].XMM_L(0)));
4163 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4164 cpu_env
, offsetof(CPUX86State
,
4165 xmm_regs
[reg
].XMM_L(1)));
4167 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4168 cpu_env
, offsetof(CPUX86State
,
4169 xmm_regs
[reg
].XMM_L(2)));
4171 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4172 cpu_env
, offsetof(CPUX86State
,
4173 xmm_regs
[reg
].XMM_L(3)));
4176 if (ot
== MO_32
) { /* pinsrd */
4178 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[rm
]);
4180 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
4181 s
->mem_index
, MO_LEUL
);
4183 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4184 offsetof(CPUX86State
,
4185 xmm_regs
[reg
].XMM_L(val
& 3)));
4186 } else { /* pinsrq */
4187 #ifdef TARGET_X86_64
4189 gen_op_mov_v_reg(ot
, cpu_tmp1_i64
, rm
);
4191 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
4192 s
->mem_index
, MO_LEQ
);
4194 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
4195 offsetof(CPUX86State
,
4196 xmm_regs
[reg
].XMM_Q(val
& 1)));
4207 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4209 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
4211 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4212 gen_lea_modrm(env
, s
, modrm
);
4213 gen_ldo_env_A0(s
, op2_offset
);
4216 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4218 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4220 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4221 gen_lea_modrm(env
, s
, modrm
);
4222 gen_ldq_env_A0(s
, op2_offset
);
4225 val
= cpu_ldub_code(env
, s
->pc
++);
4227 if ((b
& 0xfc) == 0x60) { /* pcmpXstrX */
4228 set_cc_op(s
, CC_OP_EFLAGS
);
4230 if (s
->dflag
== MO_64
) {
4231 /* The helper must use entire 64-bit gp registers */
4236 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4237 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4238 sse_fn_eppi(cpu_env
, cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4242 /* Various integer extensions at 0f 3a f[0-f]. */
4243 b
= modrm
| (b1
<< 8);
4244 modrm
= cpu_ldub_code(env
, s
->pc
++);
4245 reg
= ((modrm
>> 3) & 7) | rex_r
;
4248 case 0x3f0: /* rorx Gy,Ey, Ib */
4249 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4250 || !(s
->prefix
& PREFIX_VEX
)
4254 ot
= mo_64_32(s
->dflag
);
4255 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4256 b
= cpu_ldub_code(env
, s
->pc
++);
4258 tcg_gen_rotri_tl(cpu_T
[0], cpu_T
[0], b
& 63);
4260 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4261 tcg_gen_rotri_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, b
& 31);
4262 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
4264 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
4276 /* generic MMX or SSE operation */
4278 case 0x70: /* pshufx insn */
4279 case 0xc6: /* pshufx insn */
4280 case 0xc2: /* compare insns */
4287 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4291 gen_lea_modrm(env
, s
, modrm
);
4292 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4298 /* Most sse scalar operations. */
4301 } else if (b1
== 3) {
4306 case 0x2e: /* ucomis[sd] */
4307 case 0x2f: /* comis[sd] */
4319 gen_op_ld_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
4320 tcg_gen_st32_tl(cpu_T
[0], cpu_env
,
4321 offsetof(CPUX86State
,xmm_t0
.XMM_L(0)));
4325 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.XMM_D(0)));
4328 /* 128 bit access */
4329 gen_ldo_env_A0(s
, op2_offset
);
4333 rm
= (modrm
& 7) | REX_B(s
);
4334 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
4337 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4339 gen_lea_modrm(env
, s
, modrm
);
4340 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4341 gen_ldq_env_A0(s
, op2_offset
);
4344 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4348 case 0x0f: /* 3DNow! data insns */
4349 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
))
4351 val
= cpu_ldub_code(env
, s
->pc
++);
4352 sse_fn_epp
= sse_op_table5
[val
];
4356 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4357 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4358 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4360 case 0x70: /* pshufx insn */
4361 case 0xc6: /* pshufx insn */
4362 val
= cpu_ldub_code(env
, s
->pc
++);
4363 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4364 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4365 /* XXX: introduce a new table? */
4366 sse_fn_ppi
= (SSEFunc_0_ppi
)sse_fn_epp
;
4367 sse_fn_ppi(cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4371 val
= cpu_ldub_code(env
, s
->pc
++);
4374 sse_fn_epp
= sse_op_table4
[val
][b1
];
4376 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4377 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4378 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4381 /* maskmov : we must prepare A0 */
4384 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EDI
]);
4385 gen_extu(s
->aflag
, cpu_A0
);
4386 gen_add_A0_ds_seg(s
);
4388 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4389 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4390 /* XXX: introduce a new table? */
4391 sse_fn_eppt
= (SSEFunc_0_eppt
)sse_fn_epp
;
4392 sse_fn_eppt(cpu_env
, cpu_ptr0
, cpu_ptr1
, cpu_A0
);
4395 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4396 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4397 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4400 if (b
== 0x2e || b
== 0x2f) {
4401 set_cc_op(s
, CC_OP_EFLAGS
);
4406 /* convert one instruction. s->is_jmp is set if the translation must
4407 be stopped. Return the next pc value */
4408 static target_ulong
disas_insn(CPUX86State
*env
, DisasContext
*s
,
4409 target_ulong pc_start
)
4413 TCGMemOp ot
, aflag
, dflag
;
4414 int modrm
, reg
, rm
, mod
, op
, opreg
, val
;
4415 target_ulong next_eip
, tval
;
4423 #ifdef TARGET_X86_64
4428 s
->rip_offset
= 0; /* for relative ip address */
4432 b
= cpu_ldub_code(env
, s
->pc
);
4434 /* Collect prefixes. */
4437 prefixes
|= PREFIX_REPZ
;
4440 prefixes
|= PREFIX_REPNZ
;
4443 prefixes
|= PREFIX_LOCK
;
4464 prefixes
|= PREFIX_DATA
;
4467 prefixes
|= PREFIX_ADR
;
4469 #ifdef TARGET_X86_64
4473 rex_w
= (b
>> 3) & 1;
4474 rex_r
= (b
& 0x4) << 1;
4475 s
->rex_x
= (b
& 0x2) << 2;
4476 REX_B(s
) = (b
& 0x1) << 3;
4477 x86_64_hregs
= 1; /* select uniform byte register addressing */
4482 case 0xc5: /* 2-byte VEX */
4483 case 0xc4: /* 3-byte VEX */
4484 /* VEX prefixes cannot be used except in 32-bit mode.
4485 Otherwise the instruction is LES or LDS. */
4486 if (s
->code32
&& !s
->vm86
) {
4487 static const int pp_prefix
[4] = {
4488 0, PREFIX_DATA
, PREFIX_REPZ
, PREFIX_REPNZ
4490 int vex3
, vex2
= cpu_ldub_code(env
, s
->pc
);
4492 if (!CODE64(s
) && (vex2
& 0xc0) != 0xc0) {
4493 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4494 otherwise the instruction is LES or LDS. */
4499 /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
4500 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
4501 | PREFIX_LOCK
| PREFIX_DATA
)) {
4504 #ifdef TARGET_X86_64
4509 rex_r
= (~vex2
>> 4) & 8;
4512 b
= cpu_ldub_code(env
, s
->pc
++);
4514 #ifdef TARGET_X86_64
4515 s
->rex_x
= (~vex2
>> 3) & 8;
4516 s
->rex_b
= (~vex2
>> 2) & 8;
4518 vex3
= cpu_ldub_code(env
, s
->pc
++);
4519 rex_w
= (vex3
>> 7) & 1;
4520 switch (vex2
& 0x1f) {
4521 case 0x01: /* Implied 0f leading opcode bytes. */
4522 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4524 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4527 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4530 default: /* Reserved for future use. */
4534 s
->vex_v
= (~vex3
>> 3) & 0xf;
4535 s
->vex_l
= (vex3
>> 2) & 1;
4536 prefixes
|= pp_prefix
[vex3
& 3] | PREFIX_VEX
;
4541 /* Post-process prefixes. */
4543 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit
4544 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4545 over 0x66 if both are present. */
4546 dflag
= (rex_w
> 0 ? MO_64
: prefixes
& PREFIX_DATA
? MO_16
: MO_32
);
4547 /* In 64-bit mode, 0x67 selects 32-bit addressing. */
4548 aflag
= (prefixes
& PREFIX_ADR
? MO_32
: MO_64
);
4550 /* In 16/32-bit mode, 0x66 selects the opposite data size. */
4551 if (s
->code32
^ ((prefixes
& PREFIX_DATA
) != 0)) {
4556 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */
4557 if (s
->code32
^ ((prefixes
& PREFIX_ADR
) != 0)) {
4564 s
->prefix
= prefixes
;
4568 /* lock generation */
4569 if (prefixes
& PREFIX_LOCK
)
4572 /* now check op code */
4576 /**************************/
4577 /* extended op code */
4578 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4581 /**************************/
4596 ot
= mo_b_d(b
, dflag
);
4599 case 0: /* OP Ev, Gv */
4600 modrm
= cpu_ldub_code(env
, s
->pc
++);
4601 reg
= ((modrm
>> 3) & 7) | rex_r
;
4602 mod
= (modrm
>> 6) & 3;
4603 rm
= (modrm
& 7) | REX_B(s
);
4605 gen_lea_modrm(env
, s
, modrm
);
4607 } else if (op
== OP_XORL
&& rm
== reg
) {
4609 /* xor reg, reg optimisation */
4610 set_cc_op(s
, CC_OP_CLR
);
4611 tcg_gen_movi_tl(cpu_T
[0], 0);
4612 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
4617 gen_op_mov_v_reg(ot
, cpu_T
[1], reg
);
4618 gen_op(s
, op
, ot
, opreg
);
4620 case 1: /* OP Gv, Ev */
4621 modrm
= cpu_ldub_code(env
, s
->pc
++);
4622 mod
= (modrm
>> 6) & 3;
4623 reg
= ((modrm
>> 3) & 7) | rex_r
;
4624 rm
= (modrm
& 7) | REX_B(s
);
4626 gen_lea_modrm(env
, s
, modrm
);
4627 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
4628 } else if (op
== OP_XORL
&& rm
== reg
) {
4631 gen_op_mov_v_reg(ot
, cpu_T
[1], rm
);
4633 gen_op(s
, op
, ot
, reg
);
4635 case 2: /* OP A, Iv */
4636 val
= insn_get(env
, s
, ot
);
4637 tcg_gen_movi_tl(cpu_T
[1], val
);
4638 gen_op(s
, op
, ot
, OR_EAX
);
4647 case 0x80: /* GRP1 */
4653 ot
= mo_b_d(b
, dflag
);
4655 modrm
= cpu_ldub_code(env
, s
->pc
++);
4656 mod
= (modrm
>> 6) & 3;
4657 rm
= (modrm
& 7) | REX_B(s
);
4658 op
= (modrm
>> 3) & 7;
4664 s
->rip_offset
= insn_const_size(ot
);
4665 gen_lea_modrm(env
, s
, modrm
);
4676 val
= insn_get(env
, s
, ot
);
4679 val
= (int8_t)insn_get(env
, s
, MO_8
);
4682 tcg_gen_movi_tl(cpu_T
[1], val
);
4683 gen_op(s
, op
, ot
, opreg
);
4687 /**************************/
4688 /* inc, dec, and other misc arith */
4689 case 0x40 ... 0x47: /* inc Gv */
4691 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), 1);
4693 case 0x48 ... 0x4f: /* dec Gv */
4695 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), -1);
4697 case 0xf6: /* GRP3 */
4699 ot
= mo_b_d(b
, dflag
);
4701 modrm
= cpu_ldub_code(env
, s
->pc
++);
4702 mod
= (modrm
>> 6) & 3;
4703 rm
= (modrm
& 7) | REX_B(s
);
4704 op
= (modrm
>> 3) & 7;
4707 s
->rip_offset
= insn_const_size(ot
);
4708 gen_lea_modrm(env
, s
, modrm
);
4709 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
4711 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
4716 val
= insn_get(env
, s
, ot
);
4717 tcg_gen_movi_tl(cpu_T
[1], val
);
4718 gen_op_testl_T0_T1_cc();
4719 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4722 tcg_gen_not_tl(cpu_T
[0], cpu_T
[0]);
4724 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
4726 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4730 tcg_gen_neg_tl(cpu_T
[0], cpu_T
[0]);
4732 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
4734 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4736 gen_op_update_neg_cc();
4737 set_cc_op(s
, CC_OP_SUBB
+ ot
);
4742 gen_op_mov_v_reg(MO_8
, cpu_T
[1], R_EAX
);
4743 tcg_gen_ext8u_tl(cpu_T
[0], cpu_T
[0]);
4744 tcg_gen_ext8u_tl(cpu_T
[1], cpu_T
[1]);
4745 /* XXX: use 32 bit mul which could be faster */
4746 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4747 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
4748 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4749 tcg_gen_andi_tl(cpu_cc_src
, cpu_T
[0], 0xff00);
4750 set_cc_op(s
, CC_OP_MULB
);
4753 gen_op_mov_v_reg(MO_16
, cpu_T
[1], R_EAX
);
4754 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
4755 tcg_gen_ext16u_tl(cpu_T
[1], cpu_T
[1]);
4756 /* XXX: use 32 bit mul which could be faster */
4757 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4758 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
4759 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4760 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], 16);
4761 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T
[0]);
4762 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
4763 set_cc_op(s
, CC_OP_MULW
);
4767 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4768 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
4769 tcg_gen_mulu2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4770 cpu_tmp2_i32
, cpu_tmp3_i32
);
4771 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
4772 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
4773 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4774 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4775 set_cc_op(s
, CC_OP_MULL
);
4777 #ifdef TARGET_X86_64
4779 tcg_gen_mulu2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4780 cpu_T
[0], cpu_regs
[R_EAX
]);
4781 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4782 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4783 set_cc_op(s
, CC_OP_MULQ
);
4791 gen_op_mov_v_reg(MO_8
, cpu_T
[1], R_EAX
);
4792 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
4793 tcg_gen_ext8s_tl(cpu_T
[1], cpu_T
[1]);
4794 /* XXX: use 32 bit mul which could be faster */
4795 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4796 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
4797 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4798 tcg_gen_ext8s_tl(cpu_tmp0
, cpu_T
[0]);
4799 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
4800 set_cc_op(s
, CC_OP_MULB
);
4803 gen_op_mov_v_reg(MO_16
, cpu_T
[1], R_EAX
);
4804 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
4805 tcg_gen_ext16s_tl(cpu_T
[1], cpu_T
[1]);
4806 /* XXX: use 32 bit mul which could be faster */
4807 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4808 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
4809 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4810 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T
[0]);
4811 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
4812 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], 16);
4813 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T
[0]);
4814 set_cc_op(s
, CC_OP_MULW
);
4818 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4819 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
4820 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4821 cpu_tmp2_i32
, cpu_tmp3_i32
);
4822 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
4823 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
4824 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
4825 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4826 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
4827 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
4828 set_cc_op(s
, CC_OP_MULL
);
4830 #ifdef TARGET_X86_64
4832 tcg_gen_muls2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4833 cpu_T
[0], cpu_regs
[R_EAX
]);
4834 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4835 tcg_gen_sari_tl(cpu_cc_src
, cpu_regs
[R_EAX
], 63);
4836 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_regs
[R_EDX
]);
4837 set_cc_op(s
, CC_OP_MULQ
);
4845 gen_helper_divb_AL(cpu_env
, cpu_T
[0]);
4848 gen_helper_divw_AX(cpu_env
, cpu_T
[0]);
4852 gen_helper_divl_EAX(cpu_env
, cpu_T
[0]);
4854 #ifdef TARGET_X86_64
4856 gen_helper_divq_EAX(cpu_env
, cpu_T
[0]);
4864 gen_helper_idivb_AL(cpu_env
, cpu_T
[0]);
4867 gen_helper_idivw_AX(cpu_env
, cpu_T
[0]);
4871 gen_helper_idivl_EAX(cpu_env
, cpu_T
[0]);
4873 #ifdef TARGET_X86_64
4875 gen_helper_idivq_EAX(cpu_env
, cpu_T
[0]);
4885 case 0xfe: /* GRP4 */
4886 case 0xff: /* GRP5 */
4887 ot
= mo_b_d(b
, dflag
);
4889 modrm
= cpu_ldub_code(env
, s
->pc
++);
4890 mod
= (modrm
>> 6) & 3;
4891 rm
= (modrm
& 7) | REX_B(s
);
4892 op
= (modrm
>> 3) & 7;
4893 if (op
>= 2 && b
== 0xfe) {
4897 if (op
== 2 || op
== 4) {
4898 /* operand size for jumps is 64 bit */
4900 } else if (op
== 3 || op
== 5) {
4901 ot
= dflag
!= MO_16
? MO_32
+ (rex_w
== 1) : MO_16
;
4902 } else if (op
== 6) {
4903 /* default push size is 64 bit */
4904 ot
= mo_pushpop(s
, dflag
);
4908 gen_lea_modrm(env
, s
, modrm
);
4909 if (op
>= 2 && op
!= 3 && op
!= 5)
4910 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
4912 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
4916 case 0: /* inc Ev */
4921 gen_inc(s
, ot
, opreg
, 1);
4923 case 1: /* dec Ev */
4928 gen_inc(s
, ot
, opreg
, -1);
4930 case 2: /* call Ev */
4931 /* XXX: optimize if memory (no 'and' is necessary) */
4932 if (dflag
== MO_16
) {
4933 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
4935 next_eip
= s
->pc
- s
->cs_base
;
4936 tcg_gen_movi_tl(cpu_T
[1], next_eip
);
4937 gen_push_v(s
, cpu_T
[1]);
4938 gen_op_jmp_v(cpu_T
[0]);
4941 case 3: /* lcall Ev */
4942 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
4943 gen_add_A0_im(s
, 1 << ot
);
4944 gen_op_ld_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
4946 if (s
->pe
&& !s
->vm86
) {
4947 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4948 gen_helper_lcall_protected(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
4949 tcg_const_i32(dflag
- 1),
4950 tcg_const_tl(s
->pc
- s
->cs_base
));
4952 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4953 gen_helper_lcall_real(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
4954 tcg_const_i32(dflag
- 1),
4955 tcg_const_i32(s
->pc
- s
->cs_base
));
4959 case 4: /* jmp Ev */
4960 if (dflag
== MO_16
) {
4961 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
4963 gen_op_jmp_v(cpu_T
[0]);
4966 case 5: /* ljmp Ev */
4967 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
4968 gen_add_A0_im(s
, 1 << ot
);
4969 gen_op_ld_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
4971 if (s
->pe
&& !s
->vm86
) {
4972 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4973 gen_helper_ljmp_protected(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
4974 tcg_const_tl(s
->pc
- s
->cs_base
));
4976 gen_op_movl_seg_T0_vm(R_CS
);
4977 gen_op_jmp_v(cpu_T
[1]);
4981 case 6: /* push Ev */
4982 gen_push_v(s
, cpu_T
[0]);
4989 case 0x84: /* test Ev, Gv */
4991 ot
= mo_b_d(b
, dflag
);
4993 modrm
= cpu_ldub_code(env
, s
->pc
++);
4994 reg
= ((modrm
>> 3) & 7) | rex_r
;
4996 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4997 gen_op_mov_v_reg(ot
, cpu_T
[1], reg
);
4998 gen_op_testl_T0_T1_cc();
4999 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5002 case 0xa8: /* test eAX, Iv */
5004 ot
= mo_b_d(b
, dflag
);
5005 val
= insn_get(env
, s
, ot
);
5007 gen_op_mov_v_reg(ot
, cpu_T
[0], OR_EAX
);
5008 tcg_gen_movi_tl(cpu_T
[1], val
);
5009 gen_op_testl_T0_T1_cc();
5010 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5013 case 0x98: /* CWDE/CBW */
5015 #ifdef TARGET_X86_64
5017 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EAX
);
5018 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
5019 gen_op_mov_reg_v(MO_64
, R_EAX
, cpu_T
[0]);
5023 gen_op_mov_v_reg(MO_16
, cpu_T
[0], R_EAX
);
5024 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5025 gen_op_mov_reg_v(MO_32
, R_EAX
, cpu_T
[0]);
5028 gen_op_mov_v_reg(MO_8
, cpu_T
[0], R_EAX
);
5029 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
5030 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
5036 case 0x99: /* CDQ/CWD */
5038 #ifdef TARGET_X86_64
5040 gen_op_mov_v_reg(MO_64
, cpu_T
[0], R_EAX
);
5041 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 63);
5042 gen_op_mov_reg_v(MO_64
, R_EDX
, cpu_T
[0]);
5046 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EAX
);
5047 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
5048 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 31);
5049 gen_op_mov_reg_v(MO_32
, R_EDX
, cpu_T
[0]);
5052 gen_op_mov_v_reg(MO_16
, cpu_T
[0], R_EAX
);
5053 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5054 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 15);
5055 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T
[0]);
5061 case 0x1af: /* imul Gv, Ev */
5062 case 0x69: /* imul Gv, Ev, I */
5065 modrm
= cpu_ldub_code(env
, s
->pc
++);
5066 reg
= ((modrm
>> 3) & 7) | rex_r
;
5068 s
->rip_offset
= insn_const_size(ot
);
5071 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5073 val
= insn_get(env
, s
, ot
);
5074 tcg_gen_movi_tl(cpu_T
[1], val
);
5075 } else if (b
== 0x6b) {
5076 val
= (int8_t)insn_get(env
, s
, MO_8
);
5077 tcg_gen_movi_tl(cpu_T
[1], val
);
5079 gen_op_mov_v_reg(ot
, cpu_T
[1], reg
);
5082 #ifdef TARGET_X86_64
5084 tcg_gen_muls2_i64(cpu_regs
[reg
], cpu_T
[1], cpu_T
[0], cpu_T
[1]);
5085 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5086 tcg_gen_sari_tl(cpu_cc_src
, cpu_cc_dst
, 63);
5087 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_T
[1]);
5091 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5092 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
5093 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
5094 cpu_tmp2_i32
, cpu_tmp3_i32
);
5095 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
5096 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
5097 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5098 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
5099 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
5102 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5103 tcg_gen_ext16s_tl(cpu_T
[1], cpu_T
[1]);
5104 /* XXX: use 32 bit mul which could be faster */
5105 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5106 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5107 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T
[0]);
5108 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
5109 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
5112 set_cc_op(s
, CC_OP_MULB
+ ot
);
5115 case 0x1c1: /* xadd Ev, Gv */
5116 ot
= mo_b_d(b
, dflag
);
5117 modrm
= cpu_ldub_code(env
, s
->pc
++);
5118 reg
= ((modrm
>> 3) & 7) | rex_r
;
5119 mod
= (modrm
>> 6) & 3;
5121 rm
= (modrm
& 7) | REX_B(s
);
5122 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
5123 gen_op_mov_v_reg(ot
, cpu_T
[1], rm
);
5124 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5125 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5126 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
5128 gen_lea_modrm(env
, s
, modrm
);
5129 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
5130 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
5131 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5132 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
5133 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5135 gen_op_update2_cc();
5136 set_cc_op(s
, CC_OP_ADDB
+ ot
);
5139 case 0x1b1: /* cmpxchg Ev, Gv */
5141 TCGLabel
*label1
, *label2
;
5142 TCGv t0
, t1
, t2
, a0
;
5144 ot
= mo_b_d(b
, dflag
);
5145 modrm
= cpu_ldub_code(env
, s
->pc
++);
5146 reg
= ((modrm
>> 3) & 7) | rex_r
;
5147 mod
= (modrm
>> 6) & 3;
5148 t0
= tcg_temp_local_new();
5149 t1
= tcg_temp_local_new();
5150 t2
= tcg_temp_local_new();
5151 a0
= tcg_temp_local_new();
5152 gen_op_mov_v_reg(ot
, t1
, reg
);
5154 rm
= (modrm
& 7) | REX_B(s
);
5155 gen_op_mov_v_reg(ot
, t0
, rm
);
5157 gen_lea_modrm(env
, s
, modrm
);
5158 tcg_gen_mov_tl(a0
, cpu_A0
);
5159 gen_op_ld_v(s
, ot
, t0
, a0
);
5160 rm
= 0; /* avoid warning */
5162 label1
= gen_new_label();
5163 tcg_gen_mov_tl(t2
, cpu_regs
[R_EAX
]);
5166 tcg_gen_brcond_tl(TCG_COND_EQ
, t2
, t0
, label1
);
5167 label2
= gen_new_label();
5169 gen_op_mov_reg_v(ot
, R_EAX
, t0
);
5171 gen_set_label(label1
);
5172 gen_op_mov_reg_v(ot
, rm
, t1
);
5174 /* perform no-op store cycle like physical cpu; must be
5175 before changing accumulator to ensure idempotency if
5176 the store faults and the instruction is restarted */
5177 gen_op_st_v(s
, ot
, t0
, a0
);
5178 gen_op_mov_reg_v(ot
, R_EAX
, t0
);
5180 gen_set_label(label1
);
5181 gen_op_st_v(s
, ot
, t1
, a0
);
5183 gen_set_label(label2
);
5184 tcg_gen_mov_tl(cpu_cc_src
, t0
);
5185 tcg_gen_mov_tl(cpu_cc_srcT
, t2
);
5186 tcg_gen_sub_tl(cpu_cc_dst
, t2
, t0
);
5187 set_cc_op(s
, CC_OP_SUBB
+ ot
);
5194 case 0x1c7: /* cmpxchg8b */
5195 modrm
= cpu_ldub_code(env
, s
->pc
++);
5196 mod
= (modrm
>> 6) & 3;
5197 if ((mod
== 3) || ((modrm
& 0x38) != 0x8))
5199 #ifdef TARGET_X86_64
5200 if (dflag
== MO_64
) {
5201 if (!(s
->cpuid_ext_features
& CPUID_EXT_CX16
))
5203 gen_lea_modrm(env
, s
, modrm
);
5204 gen_helper_cmpxchg16b(cpu_env
, cpu_A0
);
5208 if (!(s
->cpuid_features
& CPUID_CX8
))
5210 gen_lea_modrm(env
, s
, modrm
);
5211 gen_helper_cmpxchg8b(cpu_env
, cpu_A0
);
5213 set_cc_op(s
, CC_OP_EFLAGS
);
5216 /**************************/
5218 case 0x50 ... 0x57: /* push */
5219 gen_op_mov_v_reg(MO_32
, cpu_T
[0], (b
& 7) | REX_B(s
));
5220 gen_push_v(s
, cpu_T
[0]);
5222 case 0x58 ... 0x5f: /* pop */
5224 /* NOTE: order is important for pop %sp */
5225 gen_pop_update(s
, ot
);
5226 gen_op_mov_reg_v(ot
, (b
& 7) | REX_B(s
), cpu_T
[0]);
5228 case 0x60: /* pusha */
5233 case 0x61: /* popa */
5238 case 0x68: /* push Iv */
5240 ot
= mo_pushpop(s
, dflag
);
5242 val
= insn_get(env
, s
, ot
);
5244 val
= (int8_t)insn_get(env
, s
, MO_8
);
5245 tcg_gen_movi_tl(cpu_T
[0], val
);
5246 gen_push_v(s
, cpu_T
[0]);
5248 case 0x8f: /* pop Ev */
5249 modrm
= cpu_ldub_code(env
, s
->pc
++);
5250 mod
= (modrm
>> 6) & 3;
5253 /* NOTE: order is important for pop %sp */
5254 gen_pop_update(s
, ot
);
5255 rm
= (modrm
& 7) | REX_B(s
);
5256 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
5258 /* NOTE: order is important too for MMU exceptions */
5259 s
->popl_esp_hack
= 1 << ot
;
5260 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5261 s
->popl_esp_hack
= 0;
5262 gen_pop_update(s
, ot
);
5265 case 0xc8: /* enter */
5268 val
= cpu_lduw_code(env
, s
->pc
);
5270 level
= cpu_ldub_code(env
, s
->pc
++);
5271 gen_enter(s
, val
, level
);
5274 case 0xc9: /* leave */
5275 /* XXX: exception not precise (ESP is updated before potential exception) */
5277 gen_op_mov_v_reg(MO_64
, cpu_T
[0], R_EBP
);
5278 gen_op_mov_reg_v(MO_64
, R_ESP
, cpu_T
[0]);
5279 } else if (s
->ss32
) {
5280 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EBP
);
5281 gen_op_mov_reg_v(MO_32
, R_ESP
, cpu_T
[0]);
5283 gen_op_mov_v_reg(MO_16
, cpu_T
[0], R_EBP
);
5284 gen_op_mov_reg_v(MO_16
, R_ESP
, cpu_T
[0]);
5287 gen_op_mov_reg_v(ot
, R_EBP
, cpu_T
[0]);
5288 gen_pop_update(s
, ot
);
5290 case 0x06: /* push es */
5291 case 0x0e: /* push cs */
5292 case 0x16: /* push ss */
5293 case 0x1e: /* push ds */
5296 gen_op_movl_T0_seg(b
>> 3);
5297 gen_push_v(s
, cpu_T
[0]);
5299 case 0x1a0: /* push fs */
5300 case 0x1a8: /* push gs */
5301 gen_op_movl_T0_seg((b
>> 3) & 7);
5302 gen_push_v(s
, cpu_T
[0]);
5304 case 0x07: /* pop es */
5305 case 0x17: /* pop ss */
5306 case 0x1f: /* pop ds */
5311 gen_movl_seg_T0(s
, reg
);
5312 gen_pop_update(s
, ot
);
5314 /* if reg == SS, inhibit interrupts/trace. */
5315 /* If several instructions disable interrupts, only the
5317 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
5318 gen_helper_set_inhibit_irq(cpu_env
);
5322 gen_jmp_im(s
->pc
- s
->cs_base
);
5326 case 0x1a1: /* pop fs */
5327 case 0x1a9: /* pop gs */
5329 gen_movl_seg_T0(s
, (b
>> 3) & 7);
5330 gen_pop_update(s
, ot
);
5332 gen_jmp_im(s
->pc
- s
->cs_base
);
5337 /**************************/
5340 case 0x89: /* mov Gv, Ev */
5341 ot
= mo_b_d(b
, dflag
);
5342 modrm
= cpu_ldub_code(env
, s
->pc
++);
5343 reg
= ((modrm
>> 3) & 7) | rex_r
;
5345 /* generate a generic store */
5346 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
5349 case 0xc7: /* mov Ev, Iv */
5350 ot
= mo_b_d(b
, dflag
);
5351 modrm
= cpu_ldub_code(env
, s
->pc
++);
5352 mod
= (modrm
>> 6) & 3;
5354 s
->rip_offset
= insn_const_size(ot
);
5355 gen_lea_modrm(env
, s
, modrm
);
5357 val
= insn_get(env
, s
, ot
);
5358 tcg_gen_movi_tl(cpu_T
[0], val
);
5360 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
5362 gen_op_mov_reg_v(ot
, (modrm
& 7) | REX_B(s
), cpu_T
[0]);
5366 case 0x8b: /* mov Ev, Gv */
5367 ot
= mo_b_d(b
, dflag
);
5368 modrm
= cpu_ldub_code(env
, s
->pc
++);
5369 reg
= ((modrm
>> 3) & 7) | rex_r
;
5371 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5372 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
5374 case 0x8e: /* mov seg, Gv */
5375 modrm
= cpu_ldub_code(env
, s
->pc
++);
5376 reg
= (modrm
>> 3) & 7;
5377 if (reg
>= 6 || reg
== R_CS
)
5379 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
5380 gen_movl_seg_T0(s
, reg
);
5382 /* if reg == SS, inhibit interrupts/trace */
5383 /* If several instructions disable interrupts, only the
5385 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
5386 gen_helper_set_inhibit_irq(cpu_env
);
5390 gen_jmp_im(s
->pc
- s
->cs_base
);
5394 case 0x8c: /* mov Gv, seg */
5395 modrm
= cpu_ldub_code(env
, s
->pc
++);
5396 reg
= (modrm
>> 3) & 7;
5397 mod
= (modrm
>> 6) & 3;
5400 gen_op_movl_T0_seg(reg
);
5401 ot
= mod
== 3 ? dflag
: MO_16
;
5402 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5405 case 0x1b6: /* movzbS Gv, Eb */
5406 case 0x1b7: /* movzwS Gv, Eb */
5407 case 0x1be: /* movsbS Gv, Eb */
5408 case 0x1bf: /* movswS Gv, Eb */
5413 /* d_ot is the size of destination */
5415 /* ot is the size of source */
5416 ot
= (b
& 1) + MO_8
;
5417 /* s_ot is the sign+size of source */
5418 s_ot
= b
& 8 ? MO_SIGN
| ot
: ot
;
5420 modrm
= cpu_ldub_code(env
, s
->pc
++);
5421 reg
= ((modrm
>> 3) & 7) | rex_r
;
5422 mod
= (modrm
>> 6) & 3;
5423 rm
= (modrm
& 7) | REX_B(s
);
5426 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
5429 tcg_gen_ext8u_tl(cpu_T
[0], cpu_T
[0]);
5432 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
5435 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
5439 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5442 gen_op_mov_reg_v(d_ot
, reg
, cpu_T
[0]);
5444 gen_lea_modrm(env
, s
, modrm
);
5445 gen_op_ld_v(s
, s_ot
, cpu_T
[0], cpu_A0
);
5446 gen_op_mov_reg_v(d_ot
, reg
, cpu_T
[0]);
5451 case 0x8d: /* lea */
5453 modrm
= cpu_ldub_code(env
, s
->pc
++);
5454 mod
= (modrm
>> 6) & 3;
5457 reg
= ((modrm
>> 3) & 7) | rex_r
;
5458 /* we must ensure that no segment is added */
5462 gen_lea_modrm(env
, s
, modrm
);
5464 gen_op_mov_reg_v(ot
, reg
, cpu_A0
);
5467 case 0xa0: /* mov EAX, Ov */
5469 case 0xa2: /* mov Ov, EAX */
5472 target_ulong offset_addr
;
5474 ot
= mo_b_d(b
, dflag
);
5476 #ifdef TARGET_X86_64
5478 offset_addr
= cpu_ldq_code(env
, s
->pc
);
5483 offset_addr
= insn_get(env
, s
, s
->aflag
);
5486 tcg_gen_movi_tl(cpu_A0
, offset_addr
);
5487 gen_add_A0_ds_seg(s
);
5489 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
5490 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T
[0]);
5492 gen_op_mov_v_reg(ot
, cpu_T
[0], R_EAX
);
5493 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
5497 case 0xd7: /* xlat */
5498 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EBX
]);
5499 tcg_gen_ext8u_tl(cpu_T
[0], cpu_regs
[R_EAX
]);
5500 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_T
[0]);
5501 gen_extu(s
->aflag
, cpu_A0
);
5502 gen_add_A0_ds_seg(s
);
5503 gen_op_ld_v(s
, MO_8
, cpu_T
[0], cpu_A0
);
5504 gen_op_mov_reg_v(MO_8
, R_EAX
, cpu_T
[0]);
5506 case 0xb0 ... 0xb7: /* mov R, Ib */
5507 val
= insn_get(env
, s
, MO_8
);
5508 tcg_gen_movi_tl(cpu_T
[0], val
);
5509 gen_op_mov_reg_v(MO_8
, (b
& 7) | REX_B(s
), cpu_T
[0]);
5511 case 0xb8 ... 0xbf: /* mov R, Iv */
5512 #ifdef TARGET_X86_64
5513 if (dflag
== MO_64
) {
5516 tmp
= cpu_ldq_code(env
, s
->pc
);
5518 reg
= (b
& 7) | REX_B(s
);
5519 tcg_gen_movi_tl(cpu_T
[0], tmp
);
5520 gen_op_mov_reg_v(MO_64
, reg
, cpu_T
[0]);
5525 val
= insn_get(env
, s
, ot
);
5526 reg
= (b
& 7) | REX_B(s
);
5527 tcg_gen_movi_tl(cpu_T
[0], val
);
5528 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
5532 case 0x91 ... 0x97: /* xchg R, EAX */
5535 reg
= (b
& 7) | REX_B(s
);
5539 case 0x87: /* xchg Ev, Gv */
5540 ot
= mo_b_d(b
, dflag
);
5541 modrm
= cpu_ldub_code(env
, s
->pc
++);
5542 reg
= ((modrm
>> 3) & 7) | rex_r
;
5543 mod
= (modrm
>> 6) & 3;
5545 rm
= (modrm
& 7) | REX_B(s
);
5547 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
5548 gen_op_mov_v_reg(ot
, cpu_T
[1], rm
);
5549 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
5550 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5552 gen_lea_modrm(env
, s
, modrm
);
5553 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
5554 /* for xchg, lock is implicit */
5555 if (!(prefixes
& PREFIX_LOCK
))
5557 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
5558 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
5559 if (!(prefixes
& PREFIX_LOCK
))
5560 gen_helper_unlock();
5561 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5564 case 0xc4: /* les Gv */
5565 /* In CODE64 this is VEX3; see above. */
5568 case 0xc5: /* lds Gv */
5569 /* In CODE64 this is VEX2; see above. */
5572 case 0x1b2: /* lss Gv */
5575 case 0x1b4: /* lfs Gv */
5578 case 0x1b5: /* lgs Gv */
5581 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
5582 modrm
= cpu_ldub_code(env
, s
->pc
++);
5583 reg
= ((modrm
>> 3) & 7) | rex_r
;
5584 mod
= (modrm
>> 6) & 3;
5587 gen_lea_modrm(env
, s
, modrm
);
5588 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
5589 gen_add_A0_im(s
, 1 << ot
);
5590 /* load the segment first to handle exceptions properly */
5591 gen_op_ld_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
5592 gen_movl_seg_T0(s
, op
);
5593 /* then put the data */
5594 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5596 gen_jmp_im(s
->pc
- s
->cs_base
);
5601 /************************/
5609 ot
= mo_b_d(b
, dflag
);
5610 modrm
= cpu_ldub_code(env
, s
->pc
++);
5611 mod
= (modrm
>> 6) & 3;
5612 op
= (modrm
>> 3) & 7;
5618 gen_lea_modrm(env
, s
, modrm
);
5621 opreg
= (modrm
& 7) | REX_B(s
);
5626 gen_shift(s
, op
, ot
, opreg
, OR_ECX
);
5629 shift
= cpu_ldub_code(env
, s
->pc
++);
5631 gen_shifti(s
, op
, ot
, opreg
, shift
);
5646 case 0x1a4: /* shld imm */
5650 case 0x1a5: /* shld cl */
5654 case 0x1ac: /* shrd imm */
5658 case 0x1ad: /* shrd cl */
5663 modrm
= cpu_ldub_code(env
, s
->pc
++);
5664 mod
= (modrm
>> 6) & 3;
5665 rm
= (modrm
& 7) | REX_B(s
);
5666 reg
= ((modrm
>> 3) & 7) | rex_r
;
5668 gen_lea_modrm(env
, s
, modrm
);
5673 gen_op_mov_v_reg(ot
, cpu_T
[1], reg
);
5676 TCGv imm
= tcg_const_tl(cpu_ldub_code(env
, s
->pc
++));
5677 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, imm
);
5680 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, cpu_regs
[R_ECX
]);
5684 /************************/
5687 if (s
->flags
& (HF_EM_MASK
| HF_TS_MASK
)) {
5688 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5689 /* XXX: what to do if illegal op ? */
5690 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
5693 modrm
= cpu_ldub_code(env
, s
->pc
++);
5694 mod
= (modrm
>> 6) & 3;
5696 op
= ((b
& 7) << 3) | ((modrm
>> 3) & 7);
5699 gen_lea_modrm(env
, s
, modrm
);
5701 case 0x00 ... 0x07: /* fxxxs */
5702 case 0x10 ... 0x17: /* fixxxl */
5703 case 0x20 ... 0x27: /* fxxxl */
5704 case 0x30 ... 0x37: /* fixxx */
5711 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5712 s
->mem_index
, MO_LEUL
);
5713 gen_helper_flds_FT0(cpu_env
, cpu_tmp2_i32
);
5716 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5717 s
->mem_index
, MO_LEUL
);
5718 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
5721 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
5722 s
->mem_index
, MO_LEQ
);
5723 gen_helper_fldl_FT0(cpu_env
, cpu_tmp1_i64
);
5727 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5728 s
->mem_index
, MO_LESW
);
5729 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
5733 gen_helper_fp_arith_ST0_FT0(op1
);
5735 /* fcomp needs pop */
5736 gen_helper_fpop(cpu_env
);
5740 case 0x08: /* flds */
5741 case 0x0a: /* fsts */
5742 case 0x0b: /* fstps */
5743 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5744 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5745 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5750 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5751 s
->mem_index
, MO_LEUL
);
5752 gen_helper_flds_ST0(cpu_env
, cpu_tmp2_i32
);
5755 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5756 s
->mem_index
, MO_LEUL
);
5757 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
5760 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
5761 s
->mem_index
, MO_LEQ
);
5762 gen_helper_fldl_ST0(cpu_env
, cpu_tmp1_i64
);
5766 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5767 s
->mem_index
, MO_LESW
);
5768 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
5773 /* XXX: the corresponding CPUID bit must be tested ! */
5776 gen_helper_fisttl_ST0(cpu_tmp2_i32
, cpu_env
);
5777 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5778 s
->mem_index
, MO_LEUL
);
5781 gen_helper_fisttll_ST0(cpu_tmp1_i64
, cpu_env
);
5782 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
5783 s
->mem_index
, MO_LEQ
);
5787 gen_helper_fistt_ST0(cpu_tmp2_i32
, cpu_env
);
5788 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5789 s
->mem_index
, MO_LEUW
);
5792 gen_helper_fpop(cpu_env
);
5797 gen_helper_fsts_ST0(cpu_tmp2_i32
, cpu_env
);
5798 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5799 s
->mem_index
, MO_LEUL
);
5802 gen_helper_fistl_ST0(cpu_tmp2_i32
, cpu_env
);
5803 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5804 s
->mem_index
, MO_LEUL
);
5807 gen_helper_fstl_ST0(cpu_tmp1_i64
, cpu_env
);
5808 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
5809 s
->mem_index
, MO_LEQ
);
5813 gen_helper_fist_ST0(cpu_tmp2_i32
, cpu_env
);
5814 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5815 s
->mem_index
, MO_LEUW
);
5819 gen_helper_fpop(cpu_env
);
5823 case 0x0c: /* fldenv mem */
5824 gen_helper_fldenv(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5826 case 0x0d: /* fldcw mem */
5827 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5828 s
->mem_index
, MO_LEUW
);
5829 gen_helper_fldcw(cpu_env
, cpu_tmp2_i32
);
5831 case 0x0e: /* fnstenv mem */
5832 gen_helper_fstenv(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5834 case 0x0f: /* fnstcw mem */
5835 gen_helper_fnstcw(cpu_tmp2_i32
, cpu_env
);
5836 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5837 s
->mem_index
, MO_LEUW
);
5839 case 0x1d: /* fldt mem */
5840 gen_helper_fldt_ST0(cpu_env
, cpu_A0
);
5842 case 0x1f: /* fstpt mem */
5843 gen_helper_fstt_ST0(cpu_env
, cpu_A0
);
5844 gen_helper_fpop(cpu_env
);
5846 case 0x2c: /* frstor mem */
5847 gen_helper_frstor(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5849 case 0x2e: /* fnsave mem */
5850 gen_helper_fsave(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5852 case 0x2f: /* fnstsw mem */
5853 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
5854 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5855 s
->mem_index
, MO_LEUW
);
5857 case 0x3c: /* fbld */
5858 gen_helper_fbld_ST0(cpu_env
, cpu_A0
);
5860 case 0x3e: /* fbstp */
5861 gen_helper_fbst_ST0(cpu_env
, cpu_A0
);
5862 gen_helper_fpop(cpu_env
);
5864 case 0x3d: /* fildll */
5865 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
5866 gen_helper_fildll_ST0(cpu_env
, cpu_tmp1_i64
);
5868 case 0x3f: /* fistpll */
5869 gen_helper_fistll_ST0(cpu_tmp1_i64
, cpu_env
);
5870 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
5871 gen_helper_fpop(cpu_env
);
5877 /* register float ops */
5881 case 0x08: /* fld sti */
5882 gen_helper_fpush(cpu_env
);
5883 gen_helper_fmov_ST0_STN(cpu_env
,
5884 tcg_const_i32((opreg
+ 1) & 7));
5886 case 0x09: /* fxchg sti */
5887 case 0x29: /* fxchg4 sti, undocumented op */
5888 case 0x39: /* fxchg7 sti, undocumented op */
5889 gen_helper_fxchg_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
5891 case 0x0a: /* grp d9/2 */
5894 /* check exceptions (FreeBSD FPU probe) */
5895 gen_helper_fwait(cpu_env
);
5901 case 0x0c: /* grp d9/4 */
5904 gen_helper_fchs_ST0(cpu_env
);
5907 gen_helper_fabs_ST0(cpu_env
);
5910 gen_helper_fldz_FT0(cpu_env
);
5911 gen_helper_fcom_ST0_FT0(cpu_env
);
5914 gen_helper_fxam_ST0(cpu_env
);
5920 case 0x0d: /* grp d9/5 */
5924 gen_helper_fpush(cpu_env
);
5925 gen_helper_fld1_ST0(cpu_env
);
5928 gen_helper_fpush(cpu_env
);
5929 gen_helper_fldl2t_ST0(cpu_env
);
5932 gen_helper_fpush(cpu_env
);
5933 gen_helper_fldl2e_ST0(cpu_env
);
5936 gen_helper_fpush(cpu_env
);
5937 gen_helper_fldpi_ST0(cpu_env
);
5940 gen_helper_fpush(cpu_env
);
5941 gen_helper_fldlg2_ST0(cpu_env
);
5944 gen_helper_fpush(cpu_env
);
5945 gen_helper_fldln2_ST0(cpu_env
);
5948 gen_helper_fpush(cpu_env
);
5949 gen_helper_fldz_ST0(cpu_env
);
5956 case 0x0e: /* grp d9/6 */
5959 gen_helper_f2xm1(cpu_env
);
5962 gen_helper_fyl2x(cpu_env
);
5965 gen_helper_fptan(cpu_env
);
5967 case 3: /* fpatan */
5968 gen_helper_fpatan(cpu_env
);
5970 case 4: /* fxtract */
5971 gen_helper_fxtract(cpu_env
);
5973 case 5: /* fprem1 */
5974 gen_helper_fprem1(cpu_env
);
5976 case 6: /* fdecstp */
5977 gen_helper_fdecstp(cpu_env
);
5980 case 7: /* fincstp */
5981 gen_helper_fincstp(cpu_env
);
5985 case 0x0f: /* grp d9/7 */
5988 gen_helper_fprem(cpu_env
);
5990 case 1: /* fyl2xp1 */
5991 gen_helper_fyl2xp1(cpu_env
);
5994 gen_helper_fsqrt(cpu_env
);
5996 case 3: /* fsincos */
5997 gen_helper_fsincos(cpu_env
);
5999 case 5: /* fscale */
6000 gen_helper_fscale(cpu_env
);
6002 case 4: /* frndint */
6003 gen_helper_frndint(cpu_env
);
6006 gen_helper_fsin(cpu_env
);
6010 gen_helper_fcos(cpu_env
);
6014 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6015 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6016 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6022 gen_helper_fp_arith_STN_ST0(op1
, opreg
);
6024 gen_helper_fpop(cpu_env
);
6026 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6027 gen_helper_fp_arith_ST0_FT0(op1
);
6031 case 0x02: /* fcom */
6032 case 0x22: /* fcom2, undocumented op */
6033 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6034 gen_helper_fcom_ST0_FT0(cpu_env
);
6036 case 0x03: /* fcomp */
6037 case 0x23: /* fcomp3, undocumented op */
6038 case 0x32: /* fcomp5, undocumented op */
6039 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6040 gen_helper_fcom_ST0_FT0(cpu_env
);
6041 gen_helper_fpop(cpu_env
);
6043 case 0x15: /* da/5 */
6045 case 1: /* fucompp */
6046 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6047 gen_helper_fucom_ST0_FT0(cpu_env
);
6048 gen_helper_fpop(cpu_env
);
6049 gen_helper_fpop(cpu_env
);
6057 case 0: /* feni (287 only, just do nop here) */
6059 case 1: /* fdisi (287 only, just do nop here) */
6062 gen_helper_fclex(cpu_env
);
6064 case 3: /* fninit */
6065 gen_helper_fninit(cpu_env
);
6067 case 4: /* fsetpm (287 only, just do nop here) */
6073 case 0x1d: /* fucomi */
6074 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6077 gen_update_cc_op(s
);
6078 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6079 gen_helper_fucomi_ST0_FT0(cpu_env
);
6080 set_cc_op(s
, CC_OP_EFLAGS
);
6082 case 0x1e: /* fcomi */
6083 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6086 gen_update_cc_op(s
);
6087 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6088 gen_helper_fcomi_ST0_FT0(cpu_env
);
6089 set_cc_op(s
, CC_OP_EFLAGS
);
6091 case 0x28: /* ffree sti */
6092 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6094 case 0x2a: /* fst sti */
6095 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6097 case 0x2b: /* fstp sti */
6098 case 0x0b: /* fstp1 sti, undocumented op */
6099 case 0x3a: /* fstp8 sti, undocumented op */
6100 case 0x3b: /* fstp9 sti, undocumented op */
6101 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6102 gen_helper_fpop(cpu_env
);
6104 case 0x2c: /* fucom st(i) */
6105 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6106 gen_helper_fucom_ST0_FT0(cpu_env
);
6108 case 0x2d: /* fucomp st(i) */
6109 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6110 gen_helper_fucom_ST0_FT0(cpu_env
);
6111 gen_helper_fpop(cpu_env
);
6113 case 0x33: /* de/3 */
6115 case 1: /* fcompp */
6116 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6117 gen_helper_fcom_ST0_FT0(cpu_env
);
6118 gen_helper_fpop(cpu_env
);
6119 gen_helper_fpop(cpu_env
);
6125 case 0x38: /* ffreep sti, undocumented op */
6126 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6127 gen_helper_fpop(cpu_env
);
6129 case 0x3c: /* df/4 */
6132 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
6133 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6134 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
6140 case 0x3d: /* fucomip */
6141 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6144 gen_update_cc_op(s
);
6145 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6146 gen_helper_fucomi_ST0_FT0(cpu_env
);
6147 gen_helper_fpop(cpu_env
);
6148 set_cc_op(s
, CC_OP_EFLAGS
);
6150 case 0x3e: /* fcomip */
6151 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6154 gen_update_cc_op(s
);
6155 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6156 gen_helper_fcomi_ST0_FT0(cpu_env
);
6157 gen_helper_fpop(cpu_env
);
6158 set_cc_op(s
, CC_OP_EFLAGS
);
6160 case 0x10 ... 0x13: /* fcmovxx */
6165 static const uint8_t fcmov_cc
[8] = {
6172 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6175 op1
= fcmov_cc
[op
& 3] | (((op
>> 3) & 1) ^ 1);
6176 l1
= gen_new_label();
6177 gen_jcc1_noeob(s
, op1
, l1
);
6178 gen_helper_fmov_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6187 /************************/
6190 case 0xa4: /* movsS */
6192 ot
= mo_b_d(b
, dflag
);
6193 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6194 gen_repz_movs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6200 case 0xaa: /* stosS */
6202 ot
= mo_b_d(b
, dflag
);
6203 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6204 gen_repz_stos(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6209 case 0xac: /* lodsS */
6211 ot
= mo_b_d(b
, dflag
);
6212 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6213 gen_repz_lods(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6218 case 0xae: /* scasS */
6220 ot
= mo_b_d(b
, dflag
);
6221 if (prefixes
& PREFIX_REPNZ
) {
6222 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6223 } else if (prefixes
& PREFIX_REPZ
) {
6224 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6230 case 0xa6: /* cmpsS */
6232 ot
= mo_b_d(b
, dflag
);
6233 if (prefixes
& PREFIX_REPNZ
) {
6234 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6235 } else if (prefixes
& PREFIX_REPZ
) {
6236 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6241 case 0x6c: /* insS */
6243 ot
= mo_b_d32(b
, dflag
);
6244 tcg_gen_ext16u_tl(cpu_T
[0], cpu_regs
[R_EDX
]);
6245 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6246 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
) | 4);
6247 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6248 gen_repz_ins(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6251 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6252 gen_jmp(s
, s
->pc
- s
->cs_base
);
6256 case 0x6e: /* outsS */
6258 ot
= mo_b_d32(b
, dflag
);
6259 tcg_gen_ext16u_tl(cpu_T
[0], cpu_regs
[R_EDX
]);
6260 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6261 svm_is_rep(prefixes
) | 4);
6262 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6263 gen_repz_outs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6266 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6267 gen_jmp(s
, s
->pc
- s
->cs_base
);
6272 /************************/
6277 ot
= mo_b_d32(b
, dflag
);
6278 val
= cpu_ldub_code(env
, s
->pc
++);
6279 tcg_gen_movi_tl(cpu_T
[0], val
);
6280 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6281 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6282 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6285 tcg_gen_movi_i32(cpu_tmp2_i32
, val
);
6286 gen_helper_in_func(ot
, cpu_T
[1], cpu_tmp2_i32
);
6287 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T
[1]);
6288 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6289 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6291 gen_jmp(s
, s
->pc
- s
->cs_base
);
6296 ot
= mo_b_d32(b
, dflag
);
6297 val
= cpu_ldub_code(env
, s
->pc
++);
6298 tcg_gen_movi_tl(cpu_T
[0], val
);
6299 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6300 svm_is_rep(prefixes
));
6301 gen_op_mov_v_reg(ot
, cpu_T
[1], R_EAX
);
6303 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6306 tcg_gen_movi_i32(cpu_tmp2_i32
, val
);
6307 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
6308 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6309 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6310 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6312 gen_jmp(s
, s
->pc
- s
->cs_base
);
6317 ot
= mo_b_d32(b
, dflag
);
6318 tcg_gen_ext16u_tl(cpu_T
[0], cpu_regs
[R_EDX
]);
6319 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6320 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6321 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6324 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6325 gen_helper_in_func(ot
, cpu_T
[1], cpu_tmp2_i32
);
6326 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T
[1]);
6327 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6328 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6330 gen_jmp(s
, s
->pc
- s
->cs_base
);
6335 ot
= mo_b_d32(b
, dflag
);
6336 tcg_gen_ext16u_tl(cpu_T
[0], cpu_regs
[R_EDX
]);
6337 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6338 svm_is_rep(prefixes
));
6339 gen_op_mov_v_reg(ot
, cpu_T
[1], R_EAX
);
6341 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6344 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6345 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
6346 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6347 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6348 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6350 gen_jmp(s
, s
->pc
- s
->cs_base
);
6354 /************************/
6356 case 0xc2: /* ret im */
6357 val
= cpu_ldsw_code(env
, s
->pc
);
6360 gen_stack_update(s
, val
+ (1 << ot
));
6361 /* Note that gen_pop_T0 uses a zero-extending load. */
6362 gen_op_jmp_v(cpu_T
[0]);
6365 case 0xc3: /* ret */
6367 gen_pop_update(s
, ot
);
6368 /* Note that gen_pop_T0 uses a zero-extending load. */
6369 gen_op_jmp_v(cpu_T
[0]);
6372 case 0xca: /* lret im */
6373 val
= cpu_ldsw_code(env
, s
->pc
);
6376 if (s
->pe
&& !s
->vm86
) {
6377 gen_update_cc_op(s
);
6378 gen_jmp_im(pc_start
- s
->cs_base
);
6379 gen_helper_lret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6380 tcg_const_i32(val
));
6384 gen_op_ld_v(s
, dflag
, cpu_T
[0], cpu_A0
);
6385 /* NOTE: keeping EIP updated is not a problem in case of
6387 gen_op_jmp_v(cpu_T
[0]);
6389 gen_op_addl_A0_im(1 << dflag
);
6390 gen_op_ld_v(s
, dflag
, cpu_T
[0], cpu_A0
);
6391 gen_op_movl_seg_T0_vm(R_CS
);
6392 /* add stack offset */
6393 gen_stack_update(s
, val
+ (2 << dflag
));
6397 case 0xcb: /* lret */
6400 case 0xcf: /* iret */
6401 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IRET
);
6404 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6405 set_cc_op(s
, CC_OP_EFLAGS
);
6406 } else if (s
->vm86
) {
6408 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6410 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6411 set_cc_op(s
, CC_OP_EFLAGS
);
6414 gen_helper_iret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6415 tcg_const_i32(s
->pc
- s
->cs_base
));
6416 set_cc_op(s
, CC_OP_EFLAGS
);
6420 case 0xe8: /* call im */
6422 if (dflag
!= MO_16
) {
6423 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6425 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6427 next_eip
= s
->pc
- s
->cs_base
;
6429 if (dflag
== MO_16
) {
6431 } else if (!CODE64(s
)) {
6434 tcg_gen_movi_tl(cpu_T
[0], next_eip
);
6435 gen_push_v(s
, cpu_T
[0]);
6439 case 0x9a: /* lcall im */
6441 unsigned int selector
, offset
;
6446 offset
= insn_get(env
, s
, ot
);
6447 selector
= insn_get(env
, s
, MO_16
);
6449 tcg_gen_movi_tl(cpu_T
[0], selector
);
6450 tcg_gen_movi_tl(cpu_T
[1], offset
);
6453 case 0xe9: /* jmp im */
6454 if (dflag
!= MO_16
) {
6455 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6457 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6459 tval
+= s
->pc
- s
->cs_base
;
6460 if (dflag
== MO_16
) {
6462 } else if (!CODE64(s
)) {
6467 case 0xea: /* ljmp im */
6469 unsigned int selector
, offset
;
6474 offset
= insn_get(env
, s
, ot
);
6475 selector
= insn_get(env
, s
, MO_16
);
6477 tcg_gen_movi_tl(cpu_T
[0], selector
);
6478 tcg_gen_movi_tl(cpu_T
[1], offset
);
6481 case 0xeb: /* jmp Jb */
6482 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6483 tval
+= s
->pc
- s
->cs_base
;
6484 if (dflag
== MO_16
) {
6489 case 0x70 ... 0x7f: /* jcc Jb */
6490 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6492 case 0x180 ... 0x18f: /* jcc Jv */
6493 if (dflag
!= MO_16
) {
6494 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6496 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6499 next_eip
= s
->pc
- s
->cs_base
;
6501 if (dflag
== MO_16
) {
6504 gen_jcc(s
, b
, tval
, next_eip
);
6507 case 0x190 ... 0x19f: /* setcc Gv */
6508 modrm
= cpu_ldub_code(env
, s
->pc
++);
6509 gen_setcc1(s
, b
, cpu_T
[0]);
6510 gen_ldst_modrm(env
, s
, modrm
, MO_8
, OR_TMP0
, 1);
6512 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6513 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6517 modrm
= cpu_ldub_code(env
, s
->pc
++);
6518 reg
= ((modrm
>> 3) & 7) | rex_r
;
6519 gen_cmovcc1(env
, s
, ot
, b
, modrm
, reg
);
6522 /************************/
6524 case 0x9c: /* pushf */
6525 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_PUSHF
);
6526 if (s
->vm86
&& s
->iopl
!= 3) {
6527 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6529 gen_update_cc_op(s
);
6530 gen_helper_read_eflags(cpu_T
[0], cpu_env
);
6531 gen_push_v(s
, cpu_T
[0]);
6534 case 0x9d: /* popf */
6535 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_POPF
);
6536 if (s
->vm86
&& s
->iopl
!= 3) {
6537 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6541 if (dflag
!= MO_16
) {
6542 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6543 tcg_const_i32((TF_MASK
| AC_MASK
|
6548 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6549 tcg_const_i32((TF_MASK
| AC_MASK
|
6551 IF_MASK
| IOPL_MASK
)
6555 if (s
->cpl
<= s
->iopl
) {
6556 if (dflag
!= MO_16
) {
6557 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6558 tcg_const_i32((TF_MASK
|
6564 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6565 tcg_const_i32((TF_MASK
|
6573 if (dflag
!= MO_16
) {
6574 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6575 tcg_const_i32((TF_MASK
| AC_MASK
|
6576 ID_MASK
| NT_MASK
)));
6578 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6579 tcg_const_i32((TF_MASK
| AC_MASK
|
6585 gen_pop_update(s
, ot
);
6586 set_cc_op(s
, CC_OP_EFLAGS
);
6587 /* abort translation because TF/AC flag may change */
6588 gen_jmp_im(s
->pc
- s
->cs_base
);
6592 case 0x9e: /* sahf */
6593 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6595 gen_op_mov_v_reg(MO_8
, cpu_T
[0], R_AH
);
6596 gen_compute_eflags(s
);
6597 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, CC_O
);
6598 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], CC_S
| CC_Z
| CC_A
| CC_P
| CC_C
);
6599 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, cpu_T
[0]);
6601 case 0x9f: /* lahf */
6602 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6604 gen_compute_eflags(s
);
6605 /* Note: gen_compute_eflags() only gives the condition codes */
6606 tcg_gen_ori_tl(cpu_T
[0], cpu_cc_src
, 0x02);
6607 gen_op_mov_reg_v(MO_8
, R_AH
, cpu_T
[0]);
6609 case 0xf5: /* cmc */
6610 gen_compute_eflags(s
);
6611 tcg_gen_xori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6613 case 0xf8: /* clc */
6614 gen_compute_eflags(s
);
6615 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_C
);
6617 case 0xf9: /* stc */
6618 gen_compute_eflags(s
);
6619 tcg_gen_ori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6621 case 0xfc: /* cld */
6622 tcg_gen_movi_i32(cpu_tmp2_i32
, 1);
6623 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6625 case 0xfd: /* std */
6626 tcg_gen_movi_i32(cpu_tmp2_i32
, -1);
6627 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6630 /************************/
6631 /* bit operations */
6632 case 0x1ba: /* bt/bts/btr/btc Gv, im */
6634 modrm
= cpu_ldub_code(env
, s
->pc
++);
6635 op
= (modrm
>> 3) & 7;
6636 mod
= (modrm
>> 6) & 3;
6637 rm
= (modrm
& 7) | REX_B(s
);
6640 gen_lea_modrm(env
, s
, modrm
);
6641 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
6643 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
6646 val
= cpu_ldub_code(env
, s
->pc
++);
6647 tcg_gen_movi_tl(cpu_T
[1], val
);
6652 case 0x1a3: /* bt Gv, Ev */
6655 case 0x1ab: /* bts */
6658 case 0x1b3: /* btr */
6661 case 0x1bb: /* btc */
6665 modrm
= cpu_ldub_code(env
, s
->pc
++);
6666 reg
= ((modrm
>> 3) & 7) | rex_r
;
6667 mod
= (modrm
>> 6) & 3;
6668 rm
= (modrm
& 7) | REX_B(s
);
6669 gen_op_mov_v_reg(MO_32
, cpu_T
[1], reg
);
6671 gen_lea_modrm(env
, s
, modrm
);
6672 /* specific case: we need to add a displacement */
6673 gen_exts(ot
, cpu_T
[1]);
6674 tcg_gen_sari_tl(cpu_tmp0
, cpu_T
[1], 3 + ot
);
6675 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, ot
);
6676 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
6677 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
6679 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
6682 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], (1 << (3 + ot
)) - 1);
6683 tcg_gen_shr_tl(cpu_tmp4
, cpu_T
[0], cpu_T
[1]);
6688 tcg_gen_movi_tl(cpu_tmp0
, 1);
6689 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
6690 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
6693 tcg_gen_movi_tl(cpu_tmp0
, 1);
6694 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
6695 tcg_gen_andc_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
6699 tcg_gen_movi_tl(cpu_tmp0
, 1);
6700 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
6701 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
6706 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
6708 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
6712 /* Delay all CC updates until after the store above. Note that
6713 C is the result of the test, Z is unchanged, and the others
6714 are all undefined. */
6716 case CC_OP_MULB
... CC_OP_MULQ
:
6717 case CC_OP_ADDB
... CC_OP_ADDQ
:
6718 case CC_OP_ADCB
... CC_OP_ADCQ
:
6719 case CC_OP_SUBB
... CC_OP_SUBQ
:
6720 case CC_OP_SBBB
... CC_OP_SBBQ
:
6721 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
6722 case CC_OP_INCB
... CC_OP_INCQ
:
6723 case CC_OP_DECB
... CC_OP_DECQ
:
6724 case CC_OP_SHLB
... CC_OP_SHLQ
:
6725 case CC_OP_SARB
... CC_OP_SARQ
:
6726 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
6727 /* Z was going to be computed from the non-zero status of CC_DST.
6728 We can get that same Z value (and the new C value) by leaving
6729 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
6731 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
6732 set_cc_op(s
, ((s
->cc_op
- CC_OP_MULB
) & 3) + CC_OP_SARB
);
6735 /* Otherwise, generate EFLAGS and replace the C bit. */
6736 gen_compute_eflags(s
);
6737 tcg_gen_deposit_tl(cpu_cc_src
, cpu_cc_src
, cpu_tmp4
,
6742 case 0x1bc: /* bsf / tzcnt */
6743 case 0x1bd: /* bsr / lzcnt */
6745 modrm
= cpu_ldub_code(env
, s
->pc
++);
6746 reg
= ((modrm
>> 3) & 7) | rex_r
;
6747 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
6748 gen_extu(ot
, cpu_T
[0]);
6750 /* Note that lzcnt and tzcnt are in different extensions. */
6751 if ((prefixes
& PREFIX_REPZ
)
6753 ? s
->cpuid_ext3_features
& CPUID_EXT3_ABM
6754 : s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)) {
6756 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
6758 /* For lzcnt, reduce the target_ulong result by the
6759 number of zeros that we expect to find at the top. */
6760 gen_helper_clz(cpu_T
[0], cpu_T
[0]);
6761 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], TARGET_LONG_BITS
- size
);
6763 /* For tzcnt, a zero input must return the operand size:
6764 force all bits outside the operand size to 1. */
6765 target_ulong mask
= (target_ulong
)-2 << (size
- 1);
6766 tcg_gen_ori_tl(cpu_T
[0], cpu_T
[0], mask
);
6767 gen_helper_ctz(cpu_T
[0], cpu_T
[0]);
6769 /* For lzcnt/tzcnt, C and Z bits are defined and are
6770 related to the result. */
6771 gen_op_update1_cc();
6772 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
6774 /* For bsr/bsf, only the Z bit is defined and it is related
6775 to the input and not the result. */
6776 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
6777 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
6779 /* For bsr, return the bit index of the first 1 bit,
6780 not the count of leading zeros. */
6781 gen_helper_clz(cpu_T
[0], cpu_T
[0]);
6782 tcg_gen_xori_tl(cpu_T
[0], cpu_T
[0], TARGET_LONG_BITS
- 1);
6784 gen_helper_ctz(cpu_T
[0], cpu_T
[0]);
6786 /* ??? The manual says that the output is undefined when the
6787 input is zero, but real hardware leaves it unchanged, and
6788 real programs appear to depend on that. */
6789 tcg_gen_movi_tl(cpu_tmp0
, 0);
6790 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_T
[0], cpu_cc_dst
, cpu_tmp0
,
6791 cpu_regs
[reg
], cpu_T
[0]);
6793 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
6795 /************************/
6797 case 0x27: /* daa */
6800 gen_update_cc_op(s
);
6801 gen_helper_daa(cpu_env
);
6802 set_cc_op(s
, CC_OP_EFLAGS
);
6804 case 0x2f: /* das */
6807 gen_update_cc_op(s
);
6808 gen_helper_das(cpu_env
);
6809 set_cc_op(s
, CC_OP_EFLAGS
);
6811 case 0x37: /* aaa */
6814 gen_update_cc_op(s
);
6815 gen_helper_aaa(cpu_env
);
6816 set_cc_op(s
, CC_OP_EFLAGS
);
6818 case 0x3f: /* aas */
6821 gen_update_cc_op(s
);
6822 gen_helper_aas(cpu_env
);
6823 set_cc_op(s
, CC_OP_EFLAGS
);
6825 case 0xd4: /* aam */
6828 val
= cpu_ldub_code(env
, s
->pc
++);
6830 gen_exception(s
, EXCP00_DIVZ
, pc_start
- s
->cs_base
);
6832 gen_helper_aam(cpu_env
, tcg_const_i32(val
));
6833 set_cc_op(s
, CC_OP_LOGICB
);
6836 case 0xd5: /* aad */
6839 val
= cpu_ldub_code(env
, s
->pc
++);
6840 gen_helper_aad(cpu_env
, tcg_const_i32(val
));
6841 set_cc_op(s
, CC_OP_LOGICB
);
6843 /************************/
6845 case 0x90: /* nop */
6846 /* XXX: correct lock test for all insn */
6847 if (prefixes
& PREFIX_LOCK
) {
6850 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
6852 goto do_xchg_reg_eax
;
6854 if (prefixes
& PREFIX_REPZ
) {
6855 gen_update_cc_op(s
);
6856 gen_jmp_im(pc_start
- s
->cs_base
);
6857 gen_helper_pause(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
6858 s
->is_jmp
= DISAS_TB_JUMP
;
6861 case 0x9b: /* fwait */
6862 if ((s
->flags
& (HF_MP_MASK
| HF_TS_MASK
)) ==
6863 (HF_MP_MASK
| HF_TS_MASK
)) {
6864 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
6866 gen_helper_fwait(cpu_env
);
6869 case 0xcc: /* int3 */
6870 gen_interrupt(s
, EXCP03_INT3
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6872 case 0xcd: /* int N */
6873 val
= cpu_ldub_code(env
, s
->pc
++);
6874 if (s
->vm86
&& s
->iopl
!= 3) {
6875 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6877 gen_interrupt(s
, val
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6880 case 0xce: /* into */
6883 gen_update_cc_op(s
);
6884 gen_jmp_im(pc_start
- s
->cs_base
);
6885 gen_helper_into(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
6888 case 0xf1: /* icebp (undocumented, exits to external debugger) */
6889 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_ICEBP
);
6891 gen_debug(s
, pc_start
- s
->cs_base
);
6894 tb_flush(CPU(x86_env_get_cpu(env
)));
6895 qemu_set_log(CPU_LOG_INT
| CPU_LOG_TB_IN_ASM
);
6899 case 0xfa: /* cli */
6901 if (s
->cpl
<= s
->iopl
) {
6902 gen_helper_cli(cpu_env
);
6904 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6908 gen_helper_cli(cpu_env
);
6910 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6914 case 0xfb: /* sti */
6916 if (s
->cpl
<= s
->iopl
) {
6918 gen_helper_sti(cpu_env
);
6919 /* interruptions are enabled only the first insn after sti */
6920 /* If several instructions disable interrupts, only the
6922 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
6923 gen_helper_set_inhibit_irq(cpu_env
);
6924 /* give a chance to handle pending irqs */
6925 gen_jmp_im(s
->pc
- s
->cs_base
);
6928 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6934 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6938 case 0x62: /* bound */
6942 modrm
= cpu_ldub_code(env
, s
->pc
++);
6943 reg
= (modrm
>> 3) & 7;
6944 mod
= (modrm
>> 6) & 3;
6947 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
6948 gen_lea_modrm(env
, s
, modrm
);
6949 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6951 gen_helper_boundw(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
6953 gen_helper_boundl(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
6956 case 0x1c8 ... 0x1cf: /* bswap reg */
6957 reg
= (b
& 7) | REX_B(s
);
6958 #ifdef TARGET_X86_64
6959 if (dflag
== MO_64
) {
6960 gen_op_mov_v_reg(MO_64
, cpu_T
[0], reg
);
6961 tcg_gen_bswap64_i64(cpu_T
[0], cpu_T
[0]);
6962 gen_op_mov_reg_v(MO_64
, reg
, cpu_T
[0]);
6966 gen_op_mov_v_reg(MO_32
, cpu_T
[0], reg
);
6967 tcg_gen_ext32u_tl(cpu_T
[0], cpu_T
[0]);
6968 tcg_gen_bswap32_tl(cpu_T
[0], cpu_T
[0]);
6969 gen_op_mov_reg_v(MO_32
, reg
, cpu_T
[0]);
6972 case 0xd6: /* salc */
6975 gen_compute_eflags_c(s
, cpu_T
[0]);
6976 tcg_gen_neg_tl(cpu_T
[0], cpu_T
[0]);
6977 gen_op_mov_reg_v(MO_8
, R_EAX
, cpu_T
[0]);
6979 case 0xe0: /* loopnz */
6980 case 0xe1: /* loopz */
6981 case 0xe2: /* loop */
6982 case 0xe3: /* jecxz */
6984 TCGLabel
*l1
, *l2
, *l3
;
6986 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6987 next_eip
= s
->pc
- s
->cs_base
;
6989 if (dflag
== MO_16
) {
6993 l1
= gen_new_label();
6994 l2
= gen_new_label();
6995 l3
= gen_new_label();
6998 case 0: /* loopnz */
7000 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
7001 gen_op_jz_ecx(s
->aflag
, l3
);
7002 gen_jcc1(s
, (JCC_Z
<< 1) | (b
^ 1), l1
);
7005 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
7006 gen_op_jnz_ecx(s
->aflag
, l1
);
7010 gen_op_jz_ecx(s
->aflag
, l1
);
7015 gen_jmp_im(next_eip
);
7024 case 0x130: /* wrmsr */
7025 case 0x132: /* rdmsr */
7027 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7029 gen_update_cc_op(s
);
7030 gen_jmp_im(pc_start
- s
->cs_base
);
7032 gen_helper_rdmsr(cpu_env
);
7034 gen_helper_wrmsr(cpu_env
);
7038 case 0x131: /* rdtsc */
7039 gen_update_cc_op(s
);
7040 gen_jmp_im(pc_start
- s
->cs_base
);
7041 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7044 gen_helper_rdtsc(cpu_env
);
7045 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7047 gen_jmp(s
, s
->pc
- s
->cs_base
);
7050 case 0x133: /* rdpmc */
7051 gen_update_cc_op(s
);
7052 gen_jmp_im(pc_start
- s
->cs_base
);
7053 gen_helper_rdpmc(cpu_env
);
7055 case 0x134: /* sysenter */
7056 /* For Intel SYSENTER is valid on 64-bit */
7057 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7060 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7062 gen_helper_sysenter(cpu_env
);
7066 case 0x135: /* sysexit */
7067 /* For Intel SYSEXIT is valid on 64-bit */
7068 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7071 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7073 gen_helper_sysexit(cpu_env
, tcg_const_i32(dflag
- 1));
7077 #ifdef TARGET_X86_64
7078 case 0x105: /* syscall */
7079 /* XXX: is it usable in real mode ? */
7080 gen_update_cc_op(s
);
7081 gen_jmp_im(pc_start
- s
->cs_base
);
7082 gen_helper_syscall(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7085 case 0x107: /* sysret */
7087 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7089 gen_helper_sysret(cpu_env
, tcg_const_i32(dflag
- 1));
7090 /* condition codes are modified only in long mode */
7092 set_cc_op(s
, CC_OP_EFLAGS
);
7098 case 0x1a2: /* cpuid */
7099 gen_update_cc_op(s
);
7100 gen_jmp_im(pc_start
- s
->cs_base
);
7101 gen_helper_cpuid(cpu_env
);
7103 case 0xf4: /* hlt */
7105 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7107 gen_update_cc_op(s
);
7108 gen_jmp_im(pc_start
- s
->cs_base
);
7109 gen_helper_hlt(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7110 s
->is_jmp
= DISAS_TB_JUMP
;
7114 modrm
= cpu_ldub_code(env
, s
->pc
++);
7115 mod
= (modrm
>> 6) & 3;
7116 op
= (modrm
>> 3) & 7;
7119 if (!s
->pe
|| s
->vm86
)
7121 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_READ
);
7122 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,ldt
.selector
));
7123 ot
= mod
== 3 ? dflag
: MO_16
;
7124 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7127 if (!s
->pe
|| s
->vm86
)
7130 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7132 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_WRITE
);
7133 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7134 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
7135 gen_helper_lldt(cpu_env
, cpu_tmp2_i32
);
7139 if (!s
->pe
|| s
->vm86
)
7141 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_READ
);
7142 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,tr
.selector
));
7143 ot
= mod
== 3 ? dflag
: MO_16
;
7144 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7147 if (!s
->pe
|| s
->vm86
)
7150 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7152 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_WRITE
);
7153 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7154 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
7155 gen_helper_ltr(cpu_env
, cpu_tmp2_i32
);
7160 if (!s
->pe
|| s
->vm86
)
7162 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7163 gen_update_cc_op(s
);
7165 gen_helper_verr(cpu_env
, cpu_T
[0]);
7167 gen_helper_verw(cpu_env
, cpu_T
[0]);
7169 set_cc_op(s
, CC_OP_EFLAGS
);
7176 modrm
= cpu_ldub_code(env
, s
->pc
++);
7177 mod
= (modrm
>> 6) & 3;
7178 op
= (modrm
>> 3) & 7;
7184 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_READ
);
7185 gen_lea_modrm(env
, s
, modrm
);
7186 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7187 gen_op_st_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
7188 gen_add_A0_im(s
, 2);
7189 tcg_gen_ld_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7190 if (dflag
== MO_16
) {
7191 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffffff);
7193 gen_op_st_v(s
, CODE64(s
) + MO_32
, cpu_T
[0], cpu_A0
);
7198 case 0: /* monitor */
7199 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) ||
7202 gen_update_cc_op(s
);
7203 gen_jmp_im(pc_start
- s
->cs_base
);
7204 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EAX
]);
7205 gen_extu(s
->aflag
, cpu_A0
);
7206 gen_add_A0_ds_seg(s
);
7207 gen_helper_monitor(cpu_env
, cpu_A0
);
7210 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) ||
7213 gen_update_cc_op(s
);
7214 gen_jmp_im(pc_start
- s
->cs_base
);
7215 gen_helper_mwait(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7219 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
) ||
7223 gen_helper_clac(cpu_env
);
7224 gen_jmp_im(s
->pc
- s
->cs_base
);
7228 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
) ||
7232 gen_helper_stac(cpu_env
);
7233 gen_jmp_im(s
->pc
- s
->cs_base
);
7240 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_READ
);
7241 gen_lea_modrm(env
, s
, modrm
);
7242 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7243 gen_op_st_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
7244 gen_add_A0_im(s
, 2);
7245 tcg_gen_ld_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, idt
.base
));
7246 if (dflag
== MO_16
) {
7247 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffffff);
7249 gen_op_st_v(s
, CODE64(s
) + MO_32
, cpu_T
[0], cpu_A0
);
7255 gen_update_cc_op(s
);
7256 gen_jmp_im(pc_start
- s
->cs_base
);
7259 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7262 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7265 gen_helper_vmrun(cpu_env
, tcg_const_i32(s
->aflag
- 1),
7266 tcg_const_i32(s
->pc
- pc_start
));
7268 s
->is_jmp
= DISAS_TB_JUMP
;
7271 case 1: /* VMMCALL */
7272 if (!(s
->flags
& HF_SVME_MASK
))
7274 gen_helper_vmmcall(cpu_env
);
7276 case 2: /* VMLOAD */
7277 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7280 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7283 gen_helper_vmload(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7286 case 3: /* VMSAVE */
7287 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7290 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7293 gen_helper_vmsave(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7297 if ((!(s
->flags
& HF_SVME_MASK
) &&
7298 !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
)) ||
7302 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7305 gen_helper_stgi(cpu_env
);
7309 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7312 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7315 gen_helper_clgi(cpu_env
);
7318 case 6: /* SKINIT */
7319 if ((!(s
->flags
& HF_SVME_MASK
) &&
7320 !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
)) ||
7323 gen_helper_skinit(cpu_env
);
7325 case 7: /* INVLPGA */
7326 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7329 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7332 gen_helper_invlpga(cpu_env
,
7333 tcg_const_i32(s
->aflag
- 1));
7339 } else if (s
->cpl
!= 0) {
7340 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7342 gen_svm_check_intercept(s
, pc_start
,
7343 op
==2 ? SVM_EXIT_GDTR_WRITE
: SVM_EXIT_IDTR_WRITE
);
7344 gen_lea_modrm(env
, s
, modrm
);
7345 gen_op_ld_v(s
, MO_16
, cpu_T
[1], cpu_A0
);
7346 gen_add_A0_im(s
, 2);
7347 gen_op_ld_v(s
, CODE64(s
) + MO_32
, cpu_T
[0], cpu_A0
);
7348 if (dflag
== MO_16
) {
7349 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffffff);
7352 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,gdt
.base
));
7353 tcg_gen_st32_tl(cpu_T
[1], cpu_env
, offsetof(CPUX86State
,gdt
.limit
));
7355 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,idt
.base
));
7356 tcg_gen_st32_tl(cpu_T
[1], cpu_env
, offsetof(CPUX86State
,idt
.limit
));
7361 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_CR0
);
7362 #if defined TARGET_X86_64 && defined HOST_WORDS_BIGENDIAN
7363 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,cr
[0]) + 4);
7365 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,cr
[0]));
7367 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 1);
7371 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7373 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7374 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7375 gen_helper_lmsw(cpu_env
, cpu_T
[0]);
7376 gen_jmp_im(s
->pc
- s
->cs_base
);
7381 if (mod
!= 3) { /* invlpg */
7383 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7385 gen_update_cc_op(s
);
7386 gen_jmp_im(pc_start
- s
->cs_base
);
7387 gen_lea_modrm(env
, s
, modrm
);
7388 gen_helper_invlpg(cpu_env
, cpu_A0
);
7389 gen_jmp_im(s
->pc
- s
->cs_base
);
7394 case 0: /* swapgs */
7395 #ifdef TARGET_X86_64
7398 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7400 tcg_gen_ld_tl(cpu_T
[0], cpu_env
,
7401 offsetof(CPUX86State
,segs
[R_GS
].base
));
7402 tcg_gen_ld_tl(cpu_T
[1], cpu_env
,
7403 offsetof(CPUX86State
,kernelgsbase
));
7404 tcg_gen_st_tl(cpu_T
[1], cpu_env
,
7405 offsetof(CPUX86State
,segs
[R_GS
].base
));
7406 tcg_gen_st_tl(cpu_T
[0], cpu_env
,
7407 offsetof(CPUX86State
,kernelgsbase
));
7415 case 1: /* rdtscp */
7416 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_RDTSCP
))
7418 gen_update_cc_op(s
);
7419 gen_jmp_im(pc_start
- s
->cs_base
);
7420 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7423 gen_helper_rdtscp(cpu_env
);
7424 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7426 gen_jmp(s
, s
->pc
- s
->cs_base
);
7438 case 0x108: /* invd */
7439 case 0x109: /* wbinvd */
7441 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7443 gen_svm_check_intercept(s
, pc_start
, (b
& 2) ? SVM_EXIT_INVD
: SVM_EXIT_WBINVD
);
7447 case 0x63: /* arpl or movslS (x86_64) */
7448 #ifdef TARGET_X86_64
7451 /* d_ot is the size of destination */
7454 modrm
= cpu_ldub_code(env
, s
->pc
++);
7455 reg
= ((modrm
>> 3) & 7) | rex_r
;
7456 mod
= (modrm
>> 6) & 3;
7457 rm
= (modrm
& 7) | REX_B(s
);
7460 gen_op_mov_v_reg(MO_32
, cpu_T
[0], rm
);
7462 if (d_ot
== MO_64
) {
7463 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
7465 gen_op_mov_reg_v(d_ot
, reg
, cpu_T
[0]);
7467 gen_lea_modrm(env
, s
, modrm
);
7468 gen_op_ld_v(s
, MO_32
| MO_SIGN
, cpu_T
[0], cpu_A0
);
7469 gen_op_mov_reg_v(d_ot
, reg
, cpu_T
[0]);
7475 TCGv t0
, t1
, t2
, a0
;
7477 if (!s
->pe
|| s
->vm86
)
7479 t0
= tcg_temp_local_new();
7480 t1
= tcg_temp_local_new();
7481 t2
= tcg_temp_local_new();
7483 modrm
= cpu_ldub_code(env
, s
->pc
++);
7484 reg
= (modrm
>> 3) & 7;
7485 mod
= (modrm
>> 6) & 3;
7488 gen_lea_modrm(env
, s
, modrm
);
7489 gen_op_ld_v(s
, ot
, t0
, cpu_A0
);
7490 a0
= tcg_temp_local_new();
7491 tcg_gen_mov_tl(a0
, cpu_A0
);
7493 gen_op_mov_v_reg(ot
, t0
, rm
);
7496 gen_op_mov_v_reg(ot
, t1
, reg
);
7497 tcg_gen_andi_tl(cpu_tmp0
, t0
, 3);
7498 tcg_gen_andi_tl(t1
, t1
, 3);
7499 tcg_gen_movi_tl(t2
, 0);
7500 label1
= gen_new_label();
7501 tcg_gen_brcond_tl(TCG_COND_GE
, cpu_tmp0
, t1
, label1
);
7502 tcg_gen_andi_tl(t0
, t0
, ~3);
7503 tcg_gen_or_tl(t0
, t0
, t1
);
7504 tcg_gen_movi_tl(t2
, CC_Z
);
7505 gen_set_label(label1
);
7507 gen_op_st_v(s
, ot
, t0
, a0
);
7510 gen_op_mov_reg_v(ot
, rm
, t0
);
7512 gen_compute_eflags(s
);
7513 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_Z
);
7514 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, t2
);
7520 case 0x102: /* lar */
7521 case 0x103: /* lsl */
7525 if (!s
->pe
|| s
->vm86
)
7527 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
7528 modrm
= cpu_ldub_code(env
, s
->pc
++);
7529 reg
= ((modrm
>> 3) & 7) | rex_r
;
7530 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7531 t0
= tcg_temp_local_new();
7532 gen_update_cc_op(s
);
7534 gen_helper_lar(t0
, cpu_env
, cpu_T
[0]);
7536 gen_helper_lsl(t0
, cpu_env
, cpu_T
[0]);
7538 tcg_gen_andi_tl(cpu_tmp0
, cpu_cc_src
, CC_Z
);
7539 label1
= gen_new_label();
7540 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
7541 gen_op_mov_reg_v(ot
, reg
, t0
);
7542 gen_set_label(label1
);
7543 set_cc_op(s
, CC_OP_EFLAGS
);
7548 modrm
= cpu_ldub_code(env
, s
->pc
++);
7549 mod
= (modrm
>> 6) & 3;
7550 op
= (modrm
>> 3) & 7;
7552 case 0: /* prefetchnta */
7553 case 1: /* prefetchnt0 */
7554 case 2: /* prefetchnt0 */
7555 case 3: /* prefetchnt0 */
7558 gen_lea_modrm(env
, s
, modrm
);
7559 /* nothing more to do */
7561 default: /* nop (multi byte) */
7562 gen_nop_modrm(env
, s
, modrm
);
7566 case 0x119 ... 0x11f: /* nop (multi byte) */
7567 modrm
= cpu_ldub_code(env
, s
->pc
++);
7568 gen_nop_modrm(env
, s
, modrm
);
7570 case 0x120: /* mov reg, crN */
7571 case 0x122: /* mov crN, reg */
7573 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7575 modrm
= cpu_ldub_code(env
, s
->pc
++);
7576 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7577 * AMD documentation (24594.pdf) and testing of
7578 * intel 386 and 486 processors all show that the mod bits
7579 * are assumed to be 1's, regardless of actual values.
7581 rm
= (modrm
& 7) | REX_B(s
);
7582 reg
= ((modrm
>> 3) & 7) | rex_r
;
7587 if ((prefixes
& PREFIX_LOCK
) && (reg
== 0) &&
7588 (s
->cpuid_ext3_features
& CPUID_EXT3_CR8LEG
)) {
7597 gen_update_cc_op(s
);
7598 gen_jmp_im(pc_start
- s
->cs_base
);
7600 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
7601 gen_helper_write_crN(cpu_env
, tcg_const_i32(reg
),
7603 gen_jmp_im(s
->pc
- s
->cs_base
);
7606 gen_helper_read_crN(cpu_T
[0], cpu_env
, tcg_const_i32(reg
));
7607 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
7615 case 0x121: /* mov reg, drN */
7616 case 0x123: /* mov drN, reg */
7618 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7620 modrm
= cpu_ldub_code(env
, s
->pc
++);
7621 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7622 * AMD documentation (24594.pdf) and testing of
7623 * intel 386 and 486 processors all show that the mod bits
7624 * are assumed to be 1's, regardless of actual values.
7626 rm
= (modrm
& 7) | REX_B(s
);
7627 reg
= ((modrm
>> 3) & 7) | rex_r
;
7636 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_DR0
+ reg
);
7637 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
7638 tcg_gen_movi_i32(cpu_tmp2_i32
, reg
);
7639 gen_helper_set_dr(cpu_env
, cpu_tmp2_i32
, cpu_T
[0]);
7640 gen_jmp_im(s
->pc
- s
->cs_base
);
7643 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_DR0
+ reg
);
7644 tcg_gen_movi_i32(cpu_tmp2_i32
, reg
);
7645 gen_helper_get_dr(cpu_T
[0], cpu_env
, cpu_tmp2_i32
);
7646 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
7650 case 0x106: /* clts */
7652 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7654 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7655 gen_helper_clts(cpu_env
);
7656 /* abort block because static cpu state changed */
7657 gen_jmp_im(s
->pc
- s
->cs_base
);
7661 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
7662 case 0x1c3: /* MOVNTI reg, mem */
7663 if (!(s
->cpuid_features
& CPUID_SSE2
))
7665 ot
= mo_64_32(dflag
);
7666 modrm
= cpu_ldub_code(env
, s
->pc
++);
7667 mod
= (modrm
>> 6) & 3;
7670 reg
= ((modrm
>> 3) & 7) | rex_r
;
7671 /* generate a generic store */
7672 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
7675 modrm
= cpu_ldub_code(env
, s
->pc
++);
7676 mod
= (modrm
>> 6) & 3;
7677 op
= (modrm
>> 3) & 7;
7679 case 0: /* fxsave */
7680 if (mod
== 3 || !(s
->cpuid_features
& CPUID_FXSR
) ||
7681 (s
->prefix
& PREFIX_LOCK
))
7683 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
7684 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7687 gen_lea_modrm(env
, s
, modrm
);
7688 gen_helper_fxsave(cpu_env
, cpu_A0
, tcg_const_i32(dflag
== MO_64
));
7690 case 1: /* fxrstor */
7691 if (mod
== 3 || !(s
->cpuid_features
& CPUID_FXSR
) ||
7692 (s
->prefix
& PREFIX_LOCK
))
7694 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
7695 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7698 gen_lea_modrm(env
, s
, modrm
);
7699 gen_helper_fxrstor(cpu_env
, cpu_A0
, tcg_const_i32(dflag
== MO_64
));
7701 case 2: /* ldmxcsr */
7702 case 3: /* stmxcsr */
7703 if (s
->flags
& HF_TS_MASK
) {
7704 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7707 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
) ||
7710 gen_lea_modrm(env
, s
, modrm
);
7712 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
7713 s
->mem_index
, MO_LEUL
);
7714 gen_helper_ldmxcsr(cpu_env
, cpu_tmp2_i32
);
7716 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, mxcsr
));
7717 gen_op_st_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
7720 case 5: /* lfence */
7721 if ((modrm
& 0xc7) != 0xc0 || !(s
->cpuid_features
& CPUID_SSE2
))
7724 case 6: /* mfence/clwb */
7725 if (s
->prefix
& PREFIX_DATA
) {
7727 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLWB
))
7729 gen_nop_modrm(env
, s
, modrm
);
7732 if ((modrm
& 0xc7) != 0xc0 || !(s
->cpuid_features
& CPUID_SSE2
))
7736 case 7: /* sfence / clflush / clflushopt / pcommit */
7737 if ((modrm
& 0xc7) == 0xc0) {
7738 if (s
->prefix
& PREFIX_DATA
) {
7740 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_PCOMMIT
))
7744 /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX */
7745 if (!(s
->cpuid_features
& CPUID_SSE
))
7749 if (s
->prefix
& PREFIX_DATA
) {
7751 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLFLUSHOPT
))
7755 if (!(s
->cpuid_features
& CPUID_CLFLUSH
))
7758 gen_lea_modrm(env
, s
, modrm
);
7765 case 0x10d: /* 3DNow! prefetch(w) */
7766 modrm
= cpu_ldub_code(env
, s
->pc
++);
7767 mod
= (modrm
>> 6) & 3;
7770 gen_lea_modrm(env
, s
, modrm
);
7771 /* ignore for now */
7773 case 0x1aa: /* rsm */
7774 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_RSM
);
7775 if (!(s
->flags
& HF_SMM_MASK
))
7777 gen_update_cc_op(s
);
7778 gen_jmp_im(s
->pc
- s
->cs_base
);
7779 gen_helper_rsm(cpu_env
);
7782 case 0x1b8: /* SSE4.2 popcnt */
7783 if ((prefixes
& (PREFIX_REPZ
| PREFIX_LOCK
| PREFIX_REPNZ
)) !=
7786 if (!(s
->cpuid_ext_features
& CPUID_EXT_POPCNT
))
7789 modrm
= cpu_ldub_code(env
, s
->pc
++);
7790 reg
= ((modrm
>> 3) & 7) | rex_r
;
7792 if (s
->prefix
& PREFIX_DATA
) {
7795 ot
= mo_64_32(dflag
);
7798 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
7799 gen_helper_popcnt(cpu_T
[0], cpu_env
, cpu_T
[0], tcg_const_i32(ot
));
7800 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
7802 set_cc_op(s
, CC_OP_EFLAGS
);
7804 case 0x10e ... 0x10f:
7805 /* 3DNow! instructions, ignore prefixes */
7806 s
->prefix
&= ~(PREFIX_REPZ
| PREFIX_REPNZ
| PREFIX_DATA
);
7807 case 0x110 ... 0x117:
7808 case 0x128 ... 0x12f:
7809 case 0x138 ... 0x13a:
7810 case 0x150 ... 0x179:
7811 case 0x17c ... 0x17f:
7813 case 0x1c4 ... 0x1c6:
7814 case 0x1d0 ... 0x1fe:
7815 gen_sse(env
, s
, b
, pc_start
, rex_r
);
7820 /* lock generation */
7821 if (s
->prefix
& PREFIX_LOCK
)
7822 gen_helper_unlock();
7825 if (s
->prefix
& PREFIX_LOCK
)
7826 gen_helper_unlock();
7827 /* XXX: ensure that no lock was generated */
7828 gen_exception(s
, EXCP06_ILLOP
, pc_start
- s
->cs_base
);
7832 void optimize_flags_init(void)
7834 static const char reg_names
[CPU_NB_REGS
][4] = {
7835 #ifdef TARGET_X86_64
7865 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
7866 cpu_cc_op
= tcg_global_mem_new_i32(TCG_AREG0
,
7867 offsetof(CPUX86State
, cc_op
), "cc_op");
7868 cpu_cc_dst
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_dst
),
7870 cpu_cc_src
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_src
),
7872 cpu_cc_src2
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_src2
),
7875 for (i
= 0; i
< CPU_NB_REGS
; ++i
) {
7876 cpu_regs
[i
] = tcg_global_mem_new(TCG_AREG0
,
7877 offsetof(CPUX86State
, regs
[i
]),
7884 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
7885 basic block 'tb'. */
7886 void gen_intermediate_code(CPUX86State
*env
, TranslationBlock
*tb
)
7888 X86CPU
*cpu
= x86_env_get_cpu(env
);
7889 CPUState
*cs
= CPU(cpu
);
7890 DisasContext dc1
, *dc
= &dc1
;
7891 target_ulong pc_ptr
;
7893 target_ulong pc_start
;
7894 target_ulong cs_base
;
7898 /* generate intermediate code */
7900 cs_base
= tb
->cs_base
;
7903 dc
->pe
= (flags
>> HF_PE_SHIFT
) & 1;
7904 dc
->code32
= (flags
>> HF_CS32_SHIFT
) & 1;
7905 dc
->ss32
= (flags
>> HF_SS32_SHIFT
) & 1;
7906 dc
->addseg
= (flags
>> HF_ADDSEG_SHIFT
) & 1;
7908 dc
->vm86
= (flags
>> VM_SHIFT
) & 1;
7909 dc
->cpl
= (flags
>> HF_CPL_SHIFT
) & 3;
7910 dc
->iopl
= (flags
>> IOPL_SHIFT
) & 3;
7911 dc
->tf
= (flags
>> TF_SHIFT
) & 1;
7912 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
7913 dc
->cc_op
= CC_OP_DYNAMIC
;
7914 dc
->cc_op_dirty
= false;
7915 dc
->cs_base
= cs_base
;
7917 dc
->popl_esp_hack
= 0;
7918 /* select memory access functions */
7920 if (flags
& HF_SOFTMMU_MASK
) {
7921 dc
->mem_index
= cpu_mmu_index(env
, false);
7923 dc
->cpuid_features
= env
->features
[FEAT_1_EDX
];
7924 dc
->cpuid_ext_features
= env
->features
[FEAT_1_ECX
];
7925 dc
->cpuid_ext2_features
= env
->features
[FEAT_8000_0001_EDX
];
7926 dc
->cpuid_ext3_features
= env
->features
[FEAT_8000_0001_ECX
];
7927 dc
->cpuid_7_0_ebx_features
= env
->features
[FEAT_7_0_EBX
];
7928 #ifdef TARGET_X86_64
7929 dc
->lma
= (flags
>> HF_LMA_SHIFT
) & 1;
7930 dc
->code64
= (flags
>> HF_CS64_SHIFT
) & 1;
7933 dc
->jmp_opt
= !(dc
->tf
|| cs
->singlestep_enabled
||
7934 (flags
& HF_INHIBIT_IRQ_MASK
)
7935 #ifndef CONFIG_SOFTMMU
7936 || (flags
& HF_SOFTMMU_MASK
)
7939 /* Do not optimize repz jumps at all in icount mode, because
7940 rep movsS instructions are execured with different paths
7941 in !repz_opt and repz_opt modes. The first one was used
7942 always except single step mode. And this setting
7943 disables jumps optimization and control paths become
7944 equivalent in run and single step modes.
7945 Now there will be no jump optimization for repz in
7946 record/replay modes and there will always be an
7947 additional step for ecx=0 when icount is enabled.
7949 dc
->repz_opt
= !dc
->jmp_opt
&& !(tb
->cflags
& CF_USE_ICOUNT
);
7951 /* check addseg logic */
7952 if (!dc
->addseg
&& (dc
->vm86
|| !dc
->pe
|| !dc
->code32
))
7953 printf("ERROR addseg\n");
7956 cpu_T
[0] = tcg_temp_new();
7957 cpu_T
[1] = tcg_temp_new();
7958 cpu_A0
= tcg_temp_new();
7960 cpu_tmp0
= tcg_temp_new();
7961 cpu_tmp1_i64
= tcg_temp_new_i64();
7962 cpu_tmp2_i32
= tcg_temp_new_i32();
7963 cpu_tmp3_i32
= tcg_temp_new_i32();
7964 cpu_tmp4
= tcg_temp_new();
7965 cpu_ptr0
= tcg_temp_new_ptr();
7966 cpu_ptr1
= tcg_temp_new_ptr();
7967 cpu_cc_srcT
= tcg_temp_local_new();
7969 dc
->is_jmp
= DISAS_NEXT
;
7972 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
7973 if (max_insns
== 0) {
7974 max_insns
= CF_COUNT_MASK
;
7976 if (max_insns
> TCG_MAX_INSNS
) {
7977 max_insns
= TCG_MAX_INSNS
;
7982 tcg_gen_insn_start(pc_ptr
, dc
->cc_op
);
7985 /* If RF is set, suppress an internally generated breakpoint. */
7986 if (unlikely(cpu_breakpoint_test(cs
, pc_ptr
,
7987 tb
->flags
& HF_RF_MASK
7988 ? BP_GDB
: BP_ANY
))) {
7989 gen_debug(dc
, pc_ptr
- dc
->cs_base
);
7990 /* The address covered by the breakpoint must be included in
7991 [tb->pc, tb->pc + tb->size) in order to for it to be
7992 properly cleared -- thus we increment the PC here so that
7993 the logic setting tb->size below does the right thing. */
7995 goto done_generating
;
7997 if (num_insns
== max_insns
&& (tb
->cflags
& CF_LAST_IO
)) {
8001 pc_ptr
= disas_insn(env
, dc
, pc_ptr
);
8002 /* stop translation if indicated */
8005 /* if single step mode, we generate only one instruction and
8006 generate an exception */
8007 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
8008 the flag and abort the translation to give the irqs a
8009 change to be happen */
8010 if (dc
->tf
|| dc
->singlestep_enabled
||
8011 (flags
& HF_INHIBIT_IRQ_MASK
)) {
8012 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8016 /* Do not cross the boundary of the pages in icount mode,
8017 it can cause an exception. Do it only when boundary is
8018 crossed by the first instruction in the block.
8019 If current instruction already crossed the bound - it's ok,
8020 because an exception hasn't stopped this code.
8022 if ((tb
->cflags
& CF_USE_ICOUNT
)
8023 && ((pc_ptr
& TARGET_PAGE_MASK
)
8024 != ((pc_ptr
+ TARGET_MAX_INSN_SIZE
- 1) & TARGET_PAGE_MASK
)
8025 || (pc_ptr
& ~TARGET_PAGE_MASK
) == 0)) {
8026 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8030 /* if too long translation, stop generation too */
8031 if (tcg_op_buf_full() ||
8032 (pc_ptr
- pc_start
) >= (TARGET_PAGE_SIZE
- 32) ||
8033 num_insns
>= max_insns
) {
8034 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8039 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8044 if (tb
->cflags
& CF_LAST_IO
)
8047 gen_tb_end(tb
, num_insns
);
8050 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
8052 qemu_log("----------------\n");
8053 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
8054 #ifdef TARGET_X86_64
8059 disas_flags
= !dc
->code32
;
8060 log_target_disas(cs
, pc_start
, pc_ptr
- pc_start
, disas_flags
);
8065 tb
->size
= pc_ptr
- pc_start
;
8066 tb
->icount
= num_insns
;
8069 void restore_state_to_opc(CPUX86State
*env
, TranslationBlock
*tb
,
8072 int cc_op
= data
[1];
8073 env
->eip
= data
[0] - tb
->cs_base
;
8074 if (cc_op
!= CC_OP_DYNAMIC
) {