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.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 #include "qemu/osdep.h"
21 #include "qemu/host-utils.h"
23 #include "disas/disas.h"
24 #include "exec/exec-all.h"
25 #include "tcg/tcg-op.h"
26 #include "exec/cpu_ldst.h"
27 #include "exec/translator.h"
29 #include "exec/helper-proto.h"
30 #include "exec/helper-gen.h"
31 #include "helper-tcg.h"
33 #include "trace-tcg.h"
36 #define PREFIX_REPZ 0x01
37 #define PREFIX_REPNZ 0x02
38 #define PREFIX_LOCK 0x04
39 #define PREFIX_DATA 0x08
40 #define PREFIX_ADR 0x10
41 #define PREFIX_VEX 0x20
42 #define PREFIX_REX 0x40
52 /* For a switch indexed by MODRM, match all memory operands for a given OP. */
53 #define CASE_MODRM_MEM_OP(OP) \
54 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
55 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
56 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7
58 #define CASE_MODRM_OP(OP) \
59 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
60 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
61 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7: \
62 case (3 << 6) | (OP << 3) | 0 ... (3 << 6) | (OP << 3) | 7
64 //#define MACRO_TEST 1
66 /* global register indexes */
67 static TCGv cpu_cc_dst
, cpu_cc_src
, cpu_cc_src2
;
68 static TCGv_i32 cpu_cc_op
;
69 static TCGv cpu_regs
[CPU_NB_REGS
];
70 static TCGv cpu_seg_base
[6];
71 static TCGv_i64 cpu_bndl
[4];
72 static TCGv_i64 cpu_bndu
[4];
74 #include "exec/gen-icount.h"
76 typedef struct DisasContext
{
77 DisasContextBase base
;
79 /* current insn context */
80 int override
; /* -1 if no override */
84 target_ulong pc_start
;
85 target_ulong pc
; /* pc = eip + cs_base */
86 /* current block context */
87 target_ulong cs_base
; /* base of CS segment */
89 #ifndef CONFIG_USER_ONLY
90 uint8_t cpl
; /* code priv level */
91 uint8_t iopl
; /* i/o priv level */
100 int vex_l
; /* vex vector length */
101 int vex_v
; /* vex vvvv register, without 1's complement. */
102 CCOp cc_op
; /* current CC operation */
104 int tf
; /* TF cpu flag */
105 int jmp_opt
; /* use direct block chaining for direct jumps */
106 int repz_opt
; /* optimize jumps within repz instructions */
107 int mem_index
; /* select memory access functions */
108 uint32_t flags
; /* all execution flags */
109 int popl_esp_hack
; /* for correct popl with esp base handling */
110 int rip_offset
; /* only used in x86_64, but left for simplicity */
112 int cpuid_ext_features
;
113 int cpuid_ext2_features
;
114 int cpuid_ext3_features
;
115 int cpuid_7_0_ebx_features
;
116 int cpuid_xsave_features
;
118 /* TCG local temps */
124 /* TCG local register indexes (only used inside old micro ops) */
136 /* The environment in which user-only runs is constrained. */
137 #ifdef CONFIG_USER_ONLY
142 #define PE(S) (((S)->flags & HF_PE_MASK) != 0)
143 #define CPL(S) ((S)->cpl)
144 #define IOPL(S) ((S)->iopl)
146 #if defined(CONFIG_USER_ONLY) && defined(TARGET_X86_64)
147 #define VM86(S) false
148 #define CODE32(S) true
150 #define ADDSEG(S) false
152 #define VM86(S) (((S)->flags & HF_VM_MASK) != 0)
153 #define CODE32(S) (((S)->flags & HF_CS32_MASK) != 0)
154 #define SS32(S) (((S)->flags & HF_SS32_MASK) != 0)
155 #define ADDSEG(S) (((S)->flags & HF_ADDSEG_MASK) != 0)
157 #if !defined(TARGET_X86_64)
158 #define CODE64(S) false
160 #elif defined(CONFIG_USER_ONLY)
161 #define CODE64(S) true
164 #define CODE64(S) (((S)->flags & HF_CS64_MASK) != 0)
165 #define LMA(S) (((S)->flags & HF_LMA_MASK) != 0)
169 #define REX_PREFIX(S) (((S)->prefix & PREFIX_REX) != 0)
170 #define REX_W(S) ((S)->rex_w)
171 #define REX_R(S) ((S)->rex_r + 0)
172 #define REX_X(S) ((S)->rex_x + 0)
173 #define REX_B(S) ((S)->rex_b + 0)
175 #define REX_PREFIX(S) false
176 #define REX_W(S) false
182 static void gen_eob(DisasContext
*s
);
183 static void gen_jr(DisasContext
*s
, TCGv dest
);
184 static void gen_jmp(DisasContext
*s
, target_ulong eip
);
185 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
);
186 static void gen_op(DisasContext
*s1
, int op
, MemOp ot
, int d
);
188 /* i386 arith/logic operations */
208 OP_SHL1
, /* undocumented */
224 /* I386 int registers */
225 OR_EAX
, /* MUST be even numbered */
234 OR_TMP0
= 16, /* temporary operand register */
236 OR_A0
, /* temporary register used when doing address evaluation */
246 /* Bit set if the global variable is live after setting CC_OP to X. */
247 static const uint8_t cc_op_live
[CC_OP_NB
] = {
248 [CC_OP_DYNAMIC
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
249 [CC_OP_EFLAGS
] = USES_CC_SRC
,
250 [CC_OP_MULB
... CC_OP_MULQ
] = USES_CC_DST
| USES_CC_SRC
,
251 [CC_OP_ADDB
... CC_OP_ADDQ
] = USES_CC_DST
| USES_CC_SRC
,
252 [CC_OP_ADCB
... CC_OP_ADCQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
253 [CC_OP_SUBB
... CC_OP_SUBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRCT
,
254 [CC_OP_SBBB
... CC_OP_SBBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
255 [CC_OP_LOGICB
... CC_OP_LOGICQ
] = USES_CC_DST
,
256 [CC_OP_INCB
... CC_OP_INCQ
] = USES_CC_DST
| USES_CC_SRC
,
257 [CC_OP_DECB
... CC_OP_DECQ
] = USES_CC_DST
| USES_CC_SRC
,
258 [CC_OP_SHLB
... CC_OP_SHLQ
] = USES_CC_DST
| USES_CC_SRC
,
259 [CC_OP_SARB
... CC_OP_SARQ
] = USES_CC_DST
| USES_CC_SRC
,
260 [CC_OP_BMILGB
... CC_OP_BMILGQ
] = USES_CC_DST
| USES_CC_SRC
,
261 [CC_OP_ADCX
] = USES_CC_DST
| USES_CC_SRC
,
262 [CC_OP_ADOX
] = USES_CC_SRC
| USES_CC_SRC2
,
263 [CC_OP_ADCOX
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
265 [CC_OP_POPCNT
] = USES_CC_SRC
,
268 static void set_cc_op(DisasContext
*s
, CCOp op
)
272 if (s
->cc_op
== op
) {
276 /* Discard CC computation that will no longer be used. */
277 dead
= cc_op_live
[s
->cc_op
] & ~cc_op_live
[op
];
278 if (dead
& USES_CC_DST
) {
279 tcg_gen_discard_tl(cpu_cc_dst
);
281 if (dead
& USES_CC_SRC
) {
282 tcg_gen_discard_tl(cpu_cc_src
);
284 if (dead
& USES_CC_SRC2
) {
285 tcg_gen_discard_tl(cpu_cc_src2
);
287 if (dead
& USES_CC_SRCT
) {
288 tcg_gen_discard_tl(s
->cc_srcT
);
291 if (op
== CC_OP_DYNAMIC
) {
292 /* The DYNAMIC setting is translator only, and should never be
293 stored. Thus we always consider it clean. */
294 s
->cc_op_dirty
= false;
296 /* Discard any computed CC_OP value (see shifts). */
297 if (s
->cc_op
== CC_OP_DYNAMIC
) {
298 tcg_gen_discard_i32(cpu_cc_op
);
300 s
->cc_op_dirty
= true;
305 static void gen_update_cc_op(DisasContext
*s
)
307 if (s
->cc_op_dirty
) {
308 tcg_gen_movi_i32(cpu_cc_op
, s
->cc_op
);
309 s
->cc_op_dirty
= false;
315 #define NB_OP_SIZES 4
317 #else /* !TARGET_X86_64 */
319 #define NB_OP_SIZES 3
321 #endif /* !TARGET_X86_64 */
323 #if defined(HOST_WORDS_BIGENDIAN)
324 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
325 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
326 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
327 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
328 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
330 #define REG_B_OFFSET 0
331 #define REG_H_OFFSET 1
332 #define REG_W_OFFSET 0
333 #define REG_L_OFFSET 0
334 #define REG_LH_OFFSET 4
337 /* In instruction encodings for byte register accesses the
338 * register number usually indicates "low 8 bits of register N";
339 * however there are some special cases where N 4..7 indicates
340 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
341 * true for this special case, false otherwise.
343 static inline bool byte_reg_is_xH(DisasContext
*s
, int reg
)
345 /* Any time the REX prefix is present, byte registers are uniform */
346 if (reg
< 4 || REX_PREFIX(s
)) {
352 /* Select the size of a push/pop operation. */
353 static inline MemOp
mo_pushpop(DisasContext
*s
, MemOp ot
)
356 return ot
== MO_16
? MO_16
: MO_64
;
362 /* Select the size of the stack pointer. */
363 static inline MemOp
mo_stacksize(DisasContext
*s
)
365 return CODE64(s
) ? MO_64
: SS32(s
) ? MO_32
: MO_16
;
368 /* Select only size 64 else 32. Used for SSE operand sizes. */
369 static inline MemOp
mo_64_32(MemOp ot
)
372 return ot
== MO_64
? MO_64
: MO_32
;
378 /* Select size 8 if lsb of B is clear, else OT. Used for decoding
379 byte vs word opcodes. */
380 static inline MemOp
mo_b_d(int b
, MemOp ot
)
382 return b
& 1 ? ot
: MO_8
;
385 /* Select size 8 if lsb of B is clear, else OT capped at 32.
386 Used for decoding operand size of port opcodes. */
387 static inline MemOp
mo_b_d32(int b
, MemOp ot
)
389 return b
& 1 ? (ot
== MO_16
? MO_16
: MO_32
) : MO_8
;
392 static void gen_op_mov_reg_v(DisasContext
*s
, MemOp ot
, int reg
, TCGv t0
)
396 if (!byte_reg_is_xH(s
, reg
)) {
397 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 8);
399 tcg_gen_deposit_tl(cpu_regs
[reg
- 4], cpu_regs
[reg
- 4], t0
, 8, 8);
403 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 16);
406 /* For x86_64, this sets the higher half of register to zero.
407 For i386, this is equivalent to a mov. */
408 tcg_gen_ext32u_tl(cpu_regs
[reg
], t0
);
412 tcg_gen_mov_tl(cpu_regs
[reg
], t0
);
421 void gen_op_mov_v_reg(DisasContext
*s
, MemOp ot
, TCGv t0
, int reg
)
423 if (ot
== MO_8
&& byte_reg_is_xH(s
, reg
)) {
424 tcg_gen_extract_tl(t0
, cpu_regs
[reg
- 4], 8, 8);
426 tcg_gen_mov_tl(t0
, cpu_regs
[reg
]);
430 static void gen_add_A0_im(DisasContext
*s
, int val
)
432 tcg_gen_addi_tl(s
->A0
, s
->A0
, val
);
434 tcg_gen_ext32u_tl(s
->A0
, s
->A0
);
438 static inline void gen_op_jmp_v(TCGv dest
)
440 tcg_gen_st_tl(dest
, cpu_env
, offsetof(CPUX86State
, eip
));
444 void gen_op_add_reg_im(DisasContext
*s
, MemOp size
, int reg
, int32_t val
)
446 tcg_gen_addi_tl(s
->tmp0
, cpu_regs
[reg
], val
);
447 gen_op_mov_reg_v(s
, size
, reg
, s
->tmp0
);
450 static inline void gen_op_add_reg_T0(DisasContext
*s
, MemOp size
, int reg
)
452 tcg_gen_add_tl(s
->tmp0
, cpu_regs
[reg
], s
->T0
);
453 gen_op_mov_reg_v(s
, size
, reg
, s
->tmp0
);
456 static inline void gen_op_ld_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
458 tcg_gen_qemu_ld_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
461 static inline void gen_op_st_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
463 tcg_gen_qemu_st_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
466 static inline void gen_op_st_rm_T0_A0(DisasContext
*s
, int idx
, int d
)
469 gen_op_st_v(s
, idx
, s
->T0
, s
->A0
);
471 gen_op_mov_reg_v(s
, idx
, d
, s
->T0
);
475 static inline void gen_jmp_im(DisasContext
*s
, target_ulong pc
)
477 tcg_gen_movi_tl(s
->tmp0
, pc
);
478 gen_op_jmp_v(s
->tmp0
);
481 /* Compute SEG:REG into A0. SEG is selected from the override segment
482 (OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to
483 indicate no override. */
484 static void gen_lea_v_seg(DisasContext
*s
, MemOp aflag
, TCGv a0
,
485 int def_seg
, int ovr_seg
)
491 tcg_gen_mov_tl(s
->A0
, a0
);
498 if (ovr_seg
< 0 && ADDSEG(s
)) {
502 tcg_gen_ext32u_tl(s
->A0
, a0
);
508 tcg_gen_ext16u_tl(s
->A0
, a0
);
523 TCGv seg
= cpu_seg_base
[ovr_seg
];
525 if (aflag
== MO_64
) {
526 tcg_gen_add_tl(s
->A0
, a0
, seg
);
527 } else if (CODE64(s
)) {
528 tcg_gen_ext32u_tl(s
->A0
, a0
);
529 tcg_gen_add_tl(s
->A0
, s
->A0
, seg
);
531 tcg_gen_add_tl(s
->A0
, a0
, seg
);
532 tcg_gen_ext32u_tl(s
->A0
, s
->A0
);
537 static inline void gen_string_movl_A0_ESI(DisasContext
*s
)
539 gen_lea_v_seg(s
, s
->aflag
, cpu_regs
[R_ESI
], R_DS
, s
->override
);
542 static inline void gen_string_movl_A0_EDI(DisasContext
*s
)
544 gen_lea_v_seg(s
, s
->aflag
, cpu_regs
[R_EDI
], R_ES
, -1);
547 static inline void gen_op_movl_T0_Dshift(DisasContext
*s
, MemOp ot
)
549 tcg_gen_ld32s_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, df
));
550 tcg_gen_shli_tl(s
->T0
, s
->T0
, ot
);
553 static TCGv
gen_ext_tl(TCGv dst
, TCGv src
, MemOp size
, bool sign
)
558 tcg_gen_ext8s_tl(dst
, src
);
560 tcg_gen_ext8u_tl(dst
, src
);
565 tcg_gen_ext16s_tl(dst
, src
);
567 tcg_gen_ext16u_tl(dst
, src
);
573 tcg_gen_ext32s_tl(dst
, src
);
575 tcg_gen_ext32u_tl(dst
, src
);
584 static void gen_extu(MemOp ot
, TCGv reg
)
586 gen_ext_tl(reg
, reg
, ot
, false);
589 static void gen_exts(MemOp ot
, TCGv reg
)
591 gen_ext_tl(reg
, reg
, ot
, true);
595 void gen_op_jnz_ecx(DisasContext
*s
, MemOp size
, TCGLabel
*label1
)
597 tcg_gen_mov_tl(s
->tmp0
, cpu_regs
[R_ECX
]);
598 gen_extu(size
, s
->tmp0
);
599 tcg_gen_brcondi_tl(TCG_COND_NE
, s
->tmp0
, 0, label1
);
603 void gen_op_jz_ecx(DisasContext
*s
, MemOp size
, TCGLabel
*label1
)
605 tcg_gen_mov_tl(s
->tmp0
, cpu_regs
[R_ECX
]);
606 gen_extu(size
, s
->tmp0
);
607 tcg_gen_brcondi_tl(TCG_COND_EQ
, s
->tmp0
, 0, label1
);
610 static void gen_helper_in_func(MemOp ot
, TCGv v
, TCGv_i32 n
)
614 gen_helper_inb(v
, cpu_env
, n
);
617 gen_helper_inw(v
, cpu_env
, n
);
620 gen_helper_inl(v
, cpu_env
, n
);
627 static void gen_helper_out_func(MemOp ot
, TCGv_i32 v
, TCGv_i32 n
)
631 gen_helper_outb(cpu_env
, v
, n
);
634 gen_helper_outw(cpu_env
, v
, n
);
637 gen_helper_outl(cpu_env
, v
, n
);
644 static void gen_check_io(DisasContext
*s
, MemOp ot
, target_ulong cur_eip
,
647 target_ulong next_eip
;
649 if (PE(s
) && (CPL(s
) > IOPL(s
) || VM86(s
))) {
650 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
653 gen_helper_check_iob(cpu_env
, s
->tmp2_i32
);
656 gen_helper_check_iow(cpu_env
, s
->tmp2_i32
);
659 gen_helper_check_iol(cpu_env
, s
->tmp2_i32
);
665 if(s
->flags
& HF_GUEST_MASK
) {
667 gen_jmp_im(s
, cur_eip
);
668 svm_flags
|= (1 << (4 + ot
));
669 next_eip
= s
->pc
- s
->cs_base
;
670 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
671 gen_helper_svm_check_io(cpu_env
, s
->tmp2_i32
,
672 tcg_const_i32(svm_flags
),
673 tcg_const_i32(next_eip
- cur_eip
));
677 static inline void gen_movs(DisasContext
*s
, MemOp ot
)
679 gen_string_movl_A0_ESI(s
);
680 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
681 gen_string_movl_A0_EDI(s
);
682 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
683 gen_op_movl_T0_Dshift(s
, ot
);
684 gen_op_add_reg_T0(s
, s
->aflag
, R_ESI
);
685 gen_op_add_reg_T0(s
, s
->aflag
, R_EDI
);
688 static void gen_op_update1_cc(DisasContext
*s
)
690 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
693 static void gen_op_update2_cc(DisasContext
*s
)
695 tcg_gen_mov_tl(cpu_cc_src
, s
->T1
);
696 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
699 static void gen_op_update3_cc(DisasContext
*s
, TCGv reg
)
701 tcg_gen_mov_tl(cpu_cc_src2
, reg
);
702 tcg_gen_mov_tl(cpu_cc_src
, s
->T1
);
703 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
706 static inline void gen_op_testl_T0_T1_cc(DisasContext
*s
)
708 tcg_gen_and_tl(cpu_cc_dst
, s
->T0
, s
->T1
);
711 static void gen_op_update_neg_cc(DisasContext
*s
)
713 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
714 tcg_gen_neg_tl(cpu_cc_src
, s
->T0
);
715 tcg_gen_movi_tl(s
->cc_srcT
, 0);
718 /* compute all eflags to cc_src */
719 static void gen_compute_eflags(DisasContext
*s
)
721 TCGv zero
, dst
, src1
, src2
;
724 if (s
->cc_op
== CC_OP_EFLAGS
) {
727 if (s
->cc_op
== CC_OP_CLR
) {
728 tcg_gen_movi_tl(cpu_cc_src
, CC_Z
| CC_P
);
729 set_cc_op(s
, CC_OP_EFLAGS
);
738 /* Take care to not read values that are not live. */
739 live
= cc_op_live
[s
->cc_op
] & ~USES_CC_SRCT
;
740 dead
= live
^ (USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
);
742 zero
= tcg_const_tl(0);
743 if (dead
& USES_CC_DST
) {
746 if (dead
& USES_CC_SRC
) {
749 if (dead
& USES_CC_SRC2
) {
755 gen_helper_cc_compute_all(cpu_cc_src
, dst
, src1
, src2
, cpu_cc_op
);
756 set_cc_op(s
, CC_OP_EFLAGS
);
763 typedef struct CCPrepare
{
773 /* compute eflags.C to reg */
774 static CCPrepare
gen_prepare_eflags_c(DisasContext
*s
, TCGv reg
)
780 case CC_OP_SUBB
... CC_OP_SUBQ
:
781 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
782 size
= s
->cc_op
- CC_OP_SUBB
;
783 t1
= gen_ext_tl(s
->tmp0
, cpu_cc_src
, size
, false);
784 /* If no temporary was used, be careful not to alias t1 and t0. */
785 t0
= t1
== cpu_cc_src
? s
->tmp0
: reg
;
786 tcg_gen_mov_tl(t0
, s
->cc_srcT
);
790 case CC_OP_ADDB
... CC_OP_ADDQ
:
791 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
792 size
= s
->cc_op
- CC_OP_ADDB
;
793 t1
= gen_ext_tl(s
->tmp0
, cpu_cc_src
, size
, false);
794 t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
796 return (CCPrepare
) { .cond
= TCG_COND_LTU
, .reg
= t0
,
797 .reg2
= t1
, .mask
= -1, .use_reg2
= true };
799 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
802 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
804 case CC_OP_INCB
... CC_OP_INCQ
:
805 case CC_OP_DECB
... CC_OP_DECQ
:
806 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
807 .mask
= -1, .no_setcond
= true };
809 case CC_OP_SHLB
... CC_OP_SHLQ
:
810 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
811 size
= s
->cc_op
- CC_OP_SHLB
;
812 shift
= (8 << size
) - 1;
813 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
814 .mask
= (target_ulong
)1 << shift
};
816 case CC_OP_MULB
... CC_OP_MULQ
:
817 return (CCPrepare
) { .cond
= TCG_COND_NE
,
818 .reg
= cpu_cc_src
, .mask
= -1 };
820 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
821 size
= s
->cc_op
- CC_OP_BMILGB
;
822 t0
= gen_ext_tl(reg
, cpu_cc_src
, size
, false);
823 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
827 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_dst
,
828 .mask
= -1, .no_setcond
= true };
831 case CC_OP_SARB
... CC_OP_SARQ
:
833 return (CCPrepare
) { .cond
= TCG_COND_NE
,
834 .reg
= cpu_cc_src
, .mask
= CC_C
};
837 /* The need to compute only C from CC_OP_DYNAMIC is important
838 in efficiently implementing e.g. INC at the start of a TB. */
840 gen_helper_cc_compute_c(reg
, cpu_cc_dst
, cpu_cc_src
,
841 cpu_cc_src2
, cpu_cc_op
);
842 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
843 .mask
= -1, .no_setcond
= true };
847 /* compute eflags.P to reg */
848 static CCPrepare
gen_prepare_eflags_p(DisasContext
*s
, TCGv reg
)
850 gen_compute_eflags(s
);
851 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
855 /* compute eflags.S to reg */
856 static CCPrepare
gen_prepare_eflags_s(DisasContext
*s
, TCGv reg
)
860 gen_compute_eflags(s
);
866 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
870 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
873 MemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
874 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, true);
875 return (CCPrepare
) { .cond
= TCG_COND_LT
, .reg
= t0
, .mask
= -1 };
880 /* compute eflags.O to reg */
881 static CCPrepare
gen_prepare_eflags_o(DisasContext
*s
, TCGv reg
)
886 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src2
,
887 .mask
= -1, .no_setcond
= true };
890 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
892 gen_compute_eflags(s
);
893 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
898 /* compute eflags.Z to reg */
899 static CCPrepare
gen_prepare_eflags_z(DisasContext
*s
, TCGv reg
)
903 gen_compute_eflags(s
);
909 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
912 return (CCPrepare
) { .cond
= TCG_COND_ALWAYS
, .mask
= -1 };
914 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= cpu_cc_src
,
918 MemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
919 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
920 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
925 /* perform a conditional store into register 'reg' according to jump opcode
926 value 'b'. In the fast case, T0 is guaranted not to be used. */
927 static CCPrepare
gen_prepare_cc(DisasContext
*s
, int b
, TCGv reg
)
929 int inv
, jcc_op
, cond
;
935 jcc_op
= (b
>> 1) & 7;
938 case CC_OP_SUBB
... CC_OP_SUBQ
:
939 /* We optimize relational operators for the cmp/jcc case. */
940 size
= s
->cc_op
- CC_OP_SUBB
;
943 tcg_gen_mov_tl(s
->tmp4
, s
->cc_srcT
);
944 gen_extu(size
, s
->tmp4
);
945 t0
= gen_ext_tl(s
->tmp0
, cpu_cc_src
, size
, false);
946 cc
= (CCPrepare
) { .cond
= TCG_COND_LEU
, .reg
= s
->tmp4
,
947 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
956 tcg_gen_mov_tl(s
->tmp4
, s
->cc_srcT
);
957 gen_exts(size
, s
->tmp4
);
958 t0
= gen_ext_tl(s
->tmp0
, cpu_cc_src
, size
, true);
959 cc
= (CCPrepare
) { .cond
= cond
, .reg
= s
->tmp4
,
960 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
970 /* This actually generates good code for JC, JZ and JS. */
973 cc
= gen_prepare_eflags_o(s
, reg
);
976 cc
= gen_prepare_eflags_c(s
, reg
);
979 cc
= gen_prepare_eflags_z(s
, reg
);
982 gen_compute_eflags(s
);
983 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
984 .mask
= CC_Z
| CC_C
};
987 cc
= gen_prepare_eflags_s(s
, reg
);
990 cc
= gen_prepare_eflags_p(s
, reg
);
993 gen_compute_eflags(s
);
994 if (reg
== cpu_cc_src
) {
997 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
998 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
999 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
1004 gen_compute_eflags(s
);
1005 if (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
,
1011 .mask
= CC_S
| CC_Z
};
1018 cc
.cond
= tcg_invert_cond(cc
.cond
);
1023 static void gen_setcc1(DisasContext
*s
, int b
, TCGv reg
)
1025 CCPrepare cc
= gen_prepare_cc(s
, b
, reg
);
1027 if (cc
.no_setcond
) {
1028 if (cc
.cond
== TCG_COND_EQ
) {
1029 tcg_gen_xori_tl(reg
, cc
.reg
, 1);
1031 tcg_gen_mov_tl(reg
, cc
.reg
);
1036 if (cc
.cond
== TCG_COND_NE
&& !cc
.use_reg2
&& cc
.imm
== 0 &&
1037 cc
.mask
!= 0 && (cc
.mask
& (cc
.mask
- 1)) == 0) {
1038 tcg_gen_shri_tl(reg
, cc
.reg
, ctztl(cc
.mask
));
1039 tcg_gen_andi_tl(reg
, reg
, 1);
1042 if (cc
.mask
!= -1) {
1043 tcg_gen_andi_tl(reg
, cc
.reg
, cc
.mask
);
1047 tcg_gen_setcond_tl(cc
.cond
, reg
, cc
.reg
, cc
.reg2
);
1049 tcg_gen_setcondi_tl(cc
.cond
, reg
, cc
.reg
, cc
.imm
);
1053 static inline void gen_compute_eflags_c(DisasContext
*s
, TCGv reg
)
1055 gen_setcc1(s
, JCC_B
<< 1, reg
);
1058 /* generate a conditional jump to label 'l1' according to jump opcode
1059 value 'b'. In the fast case, T0 is guaranted not to be used. */
1060 static inline void gen_jcc1_noeob(DisasContext
*s
, int b
, TCGLabel
*l1
)
1062 CCPrepare cc
= gen_prepare_cc(s
, b
, s
->T0
);
1064 if (cc
.mask
!= -1) {
1065 tcg_gen_andi_tl(s
->T0
, cc
.reg
, cc
.mask
);
1069 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1071 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1075 /* Generate a conditional jump to label 'l1' according to jump opcode
1076 value 'b'. In the fast case, T0 is guaranted not to be used.
1077 A translation block must end soon. */
1078 static inline void gen_jcc1(DisasContext
*s
, int b
, TCGLabel
*l1
)
1080 CCPrepare cc
= gen_prepare_cc(s
, b
, s
->T0
);
1082 gen_update_cc_op(s
);
1083 if (cc
.mask
!= -1) {
1084 tcg_gen_andi_tl(s
->T0
, cc
.reg
, cc
.mask
);
1087 set_cc_op(s
, CC_OP_DYNAMIC
);
1089 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1091 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1095 /* XXX: does not work with gdbstub "ice" single step - not a
1097 static TCGLabel
*gen_jz_ecx_string(DisasContext
*s
, target_ulong next_eip
)
1099 TCGLabel
*l1
= gen_new_label();
1100 TCGLabel
*l2
= gen_new_label();
1101 gen_op_jnz_ecx(s
, s
->aflag
, l1
);
1103 gen_jmp_tb(s
, next_eip
, 1);
1108 static inline void gen_stos(DisasContext
*s
, MemOp ot
)
1110 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, R_EAX
);
1111 gen_string_movl_A0_EDI(s
);
1112 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
1113 gen_op_movl_T0_Dshift(s
, ot
);
1114 gen_op_add_reg_T0(s
, s
->aflag
, R_EDI
);
1117 static inline void gen_lods(DisasContext
*s
, MemOp ot
)
1119 gen_string_movl_A0_ESI(s
);
1120 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1121 gen_op_mov_reg_v(s
, ot
, R_EAX
, s
->T0
);
1122 gen_op_movl_T0_Dshift(s
, ot
);
1123 gen_op_add_reg_T0(s
, s
->aflag
, R_ESI
);
1126 static inline void gen_scas(DisasContext
*s
, MemOp ot
)
1128 gen_string_movl_A0_EDI(s
);
1129 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
1130 gen_op(s
, OP_CMPL
, ot
, R_EAX
);
1131 gen_op_movl_T0_Dshift(s
, ot
);
1132 gen_op_add_reg_T0(s
, s
->aflag
, R_EDI
);
1135 static inline void gen_cmps(DisasContext
*s
, MemOp ot
)
1137 gen_string_movl_A0_EDI(s
);
1138 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
1139 gen_string_movl_A0_ESI(s
);
1140 gen_op(s
, OP_CMPL
, ot
, OR_TMP0
);
1141 gen_op_movl_T0_Dshift(s
, ot
);
1142 gen_op_add_reg_T0(s
, s
->aflag
, R_ESI
);
1143 gen_op_add_reg_T0(s
, s
->aflag
, R_EDI
);
1146 static void gen_bpt_io(DisasContext
*s
, TCGv_i32 t_port
, int ot
)
1148 if (s
->flags
& HF_IOBPT_MASK
) {
1149 #ifdef CONFIG_USER_ONLY
1150 /* user-mode cpu should not be in IOBPT mode */
1151 g_assert_not_reached();
1153 TCGv_i32 t_size
= tcg_const_i32(1 << ot
);
1154 TCGv t_next
= tcg_const_tl(s
->pc
- s
->cs_base
);
1156 gen_helper_bpt_io(cpu_env
, t_port
, t_size
, t_next
);
1157 tcg_temp_free_i32(t_size
);
1158 tcg_temp_free(t_next
);
1159 #endif /* CONFIG_USER_ONLY */
1163 static inline void gen_ins(DisasContext
*s
, MemOp ot
)
1165 gen_string_movl_A0_EDI(s
);
1166 /* Note: we must do this dummy write first to be restartable in
1167 case of page fault. */
1168 tcg_gen_movi_tl(s
->T0
, 0);
1169 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
1170 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_EDX
]);
1171 tcg_gen_andi_i32(s
->tmp2_i32
, s
->tmp2_i32
, 0xffff);
1172 gen_helper_in_func(ot
, s
->T0
, s
->tmp2_i32
);
1173 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
1174 gen_op_movl_T0_Dshift(s
, ot
);
1175 gen_op_add_reg_T0(s
, s
->aflag
, R_EDI
);
1176 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
1179 static inline void gen_outs(DisasContext
*s
, MemOp ot
)
1181 gen_string_movl_A0_ESI(s
);
1182 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1184 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_EDX
]);
1185 tcg_gen_andi_i32(s
->tmp2_i32
, s
->tmp2_i32
, 0xffff);
1186 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, s
->T0
);
1187 gen_helper_out_func(ot
, s
->tmp2_i32
, s
->tmp3_i32
);
1188 gen_op_movl_T0_Dshift(s
, ot
);
1189 gen_op_add_reg_T0(s
, s
->aflag
, R_ESI
);
1190 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
1193 /* same method as Valgrind : we generate jumps to current or next
1195 #define GEN_REPZ(op) \
1196 static inline void gen_repz_ ## op(DisasContext *s, MemOp ot, \
1197 target_ulong cur_eip, target_ulong next_eip) \
1200 gen_update_cc_op(s); \
1201 l2 = gen_jz_ecx_string(s, next_eip); \
1202 gen_ ## op(s, ot); \
1203 gen_op_add_reg_im(s, s->aflag, R_ECX, -1); \
1204 /* a loop would cause two single step exceptions if ECX = 1 \
1205 before rep string_insn */ \
1207 gen_op_jz_ecx(s, s->aflag, l2); \
1208 gen_jmp(s, cur_eip); \
1211 #define GEN_REPZ2(op) \
1212 static inline void gen_repz_ ## op(DisasContext *s, MemOp ot, \
1213 target_ulong cur_eip, \
1214 target_ulong next_eip, \
1218 gen_update_cc_op(s); \
1219 l2 = gen_jz_ecx_string(s, next_eip); \
1220 gen_ ## op(s, ot); \
1221 gen_op_add_reg_im(s, s->aflag, R_ECX, -1); \
1222 gen_update_cc_op(s); \
1223 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
1225 gen_op_jz_ecx(s, s->aflag, l2); \
1226 gen_jmp(s, cur_eip); \
1237 static void gen_helper_fp_arith_ST0_FT0(int op
)
1241 gen_helper_fadd_ST0_FT0(cpu_env
);
1244 gen_helper_fmul_ST0_FT0(cpu_env
);
1247 gen_helper_fcom_ST0_FT0(cpu_env
);
1250 gen_helper_fcom_ST0_FT0(cpu_env
);
1253 gen_helper_fsub_ST0_FT0(cpu_env
);
1256 gen_helper_fsubr_ST0_FT0(cpu_env
);
1259 gen_helper_fdiv_ST0_FT0(cpu_env
);
1262 gen_helper_fdivr_ST0_FT0(cpu_env
);
1267 /* NOTE the exception in "r" op ordering */
1268 static void gen_helper_fp_arith_STN_ST0(int op
, int opreg
)
1270 TCGv_i32 tmp
= tcg_const_i32(opreg
);
1273 gen_helper_fadd_STN_ST0(cpu_env
, tmp
);
1276 gen_helper_fmul_STN_ST0(cpu_env
, tmp
);
1279 gen_helper_fsubr_STN_ST0(cpu_env
, tmp
);
1282 gen_helper_fsub_STN_ST0(cpu_env
, tmp
);
1285 gen_helper_fdivr_STN_ST0(cpu_env
, tmp
);
1288 gen_helper_fdiv_STN_ST0(cpu_env
, tmp
);
1293 static void gen_exception(DisasContext
*s
, int trapno
, target_ulong cur_eip
)
1295 gen_update_cc_op(s
);
1296 gen_jmp_im(s
, cur_eip
);
1297 gen_helper_raise_exception(cpu_env
, tcg_const_i32(trapno
));
1298 s
->base
.is_jmp
= DISAS_NORETURN
;
1301 /* Generate #UD for the current instruction. The assumption here is that
1302 the instruction is known, but it isn't allowed in the current cpu mode. */
1303 static void gen_illegal_opcode(DisasContext
*s
)
1305 gen_exception(s
, EXCP06_ILLOP
, s
->pc_start
- s
->cs_base
);
1308 /* Generate #GP for the current instruction. */
1309 static void gen_exception_gpf(DisasContext
*s
)
1311 gen_exception(s
, EXCP0D_GPF
, s
->pc_start
- s
->cs_base
);
1314 /* Check for cpl == 0; if not, raise #GP and return false. */
1315 static bool check_cpl0(DisasContext
*s
)
1320 gen_exception_gpf(s
);
1324 /* If vm86, check for iopl == 3; if not, raise #GP and return false. */
1325 static bool check_vm86_iopl(DisasContext
*s
)
1327 if (!VM86(s
) || IOPL(s
) == 3) {
1330 gen_exception_gpf(s
);
1334 /* Check for iopl allowing access; if not, raise #GP and return false. */
1335 static bool check_iopl(DisasContext
*s
)
1337 if (VM86(s
) ? IOPL(s
) == 3 : CPL(s
) <= IOPL(s
)) {
1340 gen_exception_gpf(s
);
1344 /* if d == OR_TMP0, it means memory operand (address in A0) */
1345 static void gen_op(DisasContext
*s1
, int op
, MemOp ot
, int d
)
1348 if (s1
->prefix
& PREFIX_LOCK
) {
1349 /* Lock prefix when destination is not memory. */
1350 gen_illegal_opcode(s1
);
1353 gen_op_mov_v_reg(s1
, ot
, s1
->T0
, d
);
1354 } else if (!(s1
->prefix
& PREFIX_LOCK
)) {
1355 gen_op_ld_v(s1
, ot
, s1
->T0
, s1
->A0
);
1359 gen_compute_eflags_c(s1
, s1
->tmp4
);
1360 if (s1
->prefix
& PREFIX_LOCK
) {
1361 tcg_gen_add_tl(s1
->T0
, s1
->tmp4
, s1
->T1
);
1362 tcg_gen_atomic_add_fetch_tl(s1
->T0
, s1
->A0
, s1
->T0
,
1363 s1
->mem_index
, ot
| MO_LE
);
1365 tcg_gen_add_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1366 tcg_gen_add_tl(s1
->T0
, s1
->T0
, s1
->tmp4
);
1367 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1369 gen_op_update3_cc(s1
, s1
->tmp4
);
1370 set_cc_op(s1
, CC_OP_ADCB
+ ot
);
1373 gen_compute_eflags_c(s1
, s1
->tmp4
);
1374 if (s1
->prefix
& PREFIX_LOCK
) {
1375 tcg_gen_add_tl(s1
->T0
, s1
->T1
, s1
->tmp4
);
1376 tcg_gen_neg_tl(s1
->T0
, s1
->T0
);
1377 tcg_gen_atomic_add_fetch_tl(s1
->T0
, s1
->A0
, s1
->T0
,
1378 s1
->mem_index
, ot
| MO_LE
);
1380 tcg_gen_sub_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1381 tcg_gen_sub_tl(s1
->T0
, s1
->T0
, s1
->tmp4
);
1382 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1384 gen_op_update3_cc(s1
, s1
->tmp4
);
1385 set_cc_op(s1
, CC_OP_SBBB
+ ot
);
1388 if (s1
->prefix
& PREFIX_LOCK
) {
1389 tcg_gen_atomic_add_fetch_tl(s1
->T0
, s1
->A0
, s1
->T1
,
1390 s1
->mem_index
, ot
| MO_LE
);
1392 tcg_gen_add_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1393 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1395 gen_op_update2_cc(s1
);
1396 set_cc_op(s1
, CC_OP_ADDB
+ ot
);
1399 if (s1
->prefix
& PREFIX_LOCK
) {
1400 tcg_gen_neg_tl(s1
->T0
, s1
->T1
);
1401 tcg_gen_atomic_fetch_add_tl(s1
->cc_srcT
, s1
->A0
, s1
->T0
,
1402 s1
->mem_index
, ot
| MO_LE
);
1403 tcg_gen_sub_tl(s1
->T0
, s1
->cc_srcT
, s1
->T1
);
1405 tcg_gen_mov_tl(s1
->cc_srcT
, s1
->T0
);
1406 tcg_gen_sub_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1407 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1409 gen_op_update2_cc(s1
);
1410 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1414 if (s1
->prefix
& PREFIX_LOCK
) {
1415 tcg_gen_atomic_and_fetch_tl(s1
->T0
, s1
->A0
, s1
->T1
,
1416 s1
->mem_index
, ot
| MO_LE
);
1418 tcg_gen_and_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1419 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1421 gen_op_update1_cc(s1
);
1422 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1425 if (s1
->prefix
& PREFIX_LOCK
) {
1426 tcg_gen_atomic_or_fetch_tl(s1
->T0
, s1
->A0
, s1
->T1
,
1427 s1
->mem_index
, ot
| MO_LE
);
1429 tcg_gen_or_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1430 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1432 gen_op_update1_cc(s1
);
1433 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1436 if (s1
->prefix
& PREFIX_LOCK
) {
1437 tcg_gen_atomic_xor_fetch_tl(s1
->T0
, s1
->A0
, s1
->T1
,
1438 s1
->mem_index
, ot
| MO_LE
);
1440 tcg_gen_xor_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1441 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1443 gen_op_update1_cc(s1
);
1444 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1447 tcg_gen_mov_tl(cpu_cc_src
, s1
->T1
);
1448 tcg_gen_mov_tl(s1
->cc_srcT
, s1
->T0
);
1449 tcg_gen_sub_tl(cpu_cc_dst
, s1
->T0
, s1
->T1
);
1450 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1455 /* if d == OR_TMP0, it means memory operand (address in A0) */
1456 static void gen_inc(DisasContext
*s1
, MemOp ot
, int d
, int c
)
1458 if (s1
->prefix
& PREFIX_LOCK
) {
1460 /* Lock prefix when destination is not memory */
1461 gen_illegal_opcode(s1
);
1464 tcg_gen_movi_tl(s1
->T0
, c
> 0 ? 1 : -1);
1465 tcg_gen_atomic_add_fetch_tl(s1
->T0
, s1
->A0
, s1
->T0
,
1466 s1
->mem_index
, ot
| MO_LE
);
1469 gen_op_mov_v_reg(s1
, ot
, s1
->T0
, d
);
1471 gen_op_ld_v(s1
, ot
, s1
->T0
, s1
->A0
);
1473 tcg_gen_addi_tl(s1
->T0
, s1
->T0
, (c
> 0 ? 1 : -1));
1474 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1477 gen_compute_eflags_c(s1
, cpu_cc_src
);
1478 tcg_gen_mov_tl(cpu_cc_dst
, s1
->T0
);
1479 set_cc_op(s1
, (c
> 0 ? CC_OP_INCB
: CC_OP_DECB
) + ot
);
1482 static void gen_shift_flags(DisasContext
*s
, MemOp ot
, TCGv result
,
1483 TCGv shm1
, TCGv count
, bool is_right
)
1485 TCGv_i32 z32
, s32
, oldop
;
1488 /* Store the results into the CC variables. If we know that the
1489 variable must be dead, store unconditionally. Otherwise we'll
1490 need to not disrupt the current contents. */
1491 z_tl
= tcg_const_tl(0);
1492 if (cc_op_live
[s
->cc_op
] & USES_CC_DST
) {
1493 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_dst
, count
, z_tl
,
1494 result
, cpu_cc_dst
);
1496 tcg_gen_mov_tl(cpu_cc_dst
, result
);
1498 if (cc_op_live
[s
->cc_op
] & USES_CC_SRC
) {
1499 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_src
, count
, z_tl
,
1502 tcg_gen_mov_tl(cpu_cc_src
, shm1
);
1504 tcg_temp_free(z_tl
);
1506 /* Get the two potential CC_OP values into temporaries. */
1507 tcg_gen_movi_i32(s
->tmp2_i32
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1508 if (s
->cc_op
== CC_OP_DYNAMIC
) {
1511 tcg_gen_movi_i32(s
->tmp3_i32
, s
->cc_op
);
1512 oldop
= s
->tmp3_i32
;
1515 /* Conditionally store the CC_OP value. */
1516 z32
= tcg_const_i32(0);
1517 s32
= tcg_temp_new_i32();
1518 tcg_gen_trunc_tl_i32(s32
, count
);
1519 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, s32
, z32
, s
->tmp2_i32
, oldop
);
1520 tcg_temp_free_i32(z32
);
1521 tcg_temp_free_i32(s32
);
1523 /* The CC_OP value is no longer predictable. */
1524 set_cc_op(s
, CC_OP_DYNAMIC
);
1527 static void gen_shift_rm_T1(DisasContext
*s
, MemOp ot
, int op1
,
1528 int is_right
, int is_arith
)
1530 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1533 if (op1
== OR_TMP0
) {
1534 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1536 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1539 tcg_gen_andi_tl(s
->T1
, s
->T1
, mask
);
1540 tcg_gen_subi_tl(s
->tmp0
, s
->T1
, 1);
1544 gen_exts(ot
, s
->T0
);
1545 tcg_gen_sar_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1546 tcg_gen_sar_tl(s
->T0
, s
->T0
, s
->T1
);
1548 gen_extu(ot
, s
->T0
);
1549 tcg_gen_shr_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1550 tcg_gen_shr_tl(s
->T0
, s
->T0
, s
->T1
);
1553 tcg_gen_shl_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1554 tcg_gen_shl_tl(s
->T0
, s
->T0
, s
->T1
);
1558 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1560 gen_shift_flags(s
, ot
, s
->T0
, s
->tmp0
, s
->T1
, is_right
);
1563 static void gen_shift_rm_im(DisasContext
*s
, MemOp ot
, int op1
, int op2
,
1564 int is_right
, int is_arith
)
1566 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1570 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1572 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1578 gen_exts(ot
, s
->T0
);
1579 tcg_gen_sari_tl(s
->tmp4
, s
->T0
, op2
- 1);
1580 tcg_gen_sari_tl(s
->T0
, s
->T0
, op2
);
1582 gen_extu(ot
, s
->T0
);
1583 tcg_gen_shri_tl(s
->tmp4
, s
->T0
, op2
- 1);
1584 tcg_gen_shri_tl(s
->T0
, s
->T0
, op2
);
1587 tcg_gen_shli_tl(s
->tmp4
, s
->T0
, op2
- 1);
1588 tcg_gen_shli_tl(s
->T0
, s
->T0
, op2
);
1593 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1595 /* update eflags if non zero shift */
1597 tcg_gen_mov_tl(cpu_cc_src
, s
->tmp4
);
1598 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
1599 set_cc_op(s
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1603 static void gen_rot_rm_T1(DisasContext
*s
, MemOp ot
, int op1
, int is_right
)
1605 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1609 if (op1
== OR_TMP0
) {
1610 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1612 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1615 tcg_gen_andi_tl(s
->T1
, s
->T1
, mask
);
1619 /* Replicate the 8-bit input so that a 32-bit rotate works. */
1620 tcg_gen_ext8u_tl(s
->T0
, s
->T0
);
1621 tcg_gen_muli_tl(s
->T0
, s
->T0
, 0x01010101);
1624 /* Replicate the 16-bit input so that a 32-bit rotate works. */
1625 tcg_gen_deposit_tl(s
->T0
, s
->T0
, s
->T0
, 16, 16);
1628 #ifdef TARGET_X86_64
1630 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
1631 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, s
->T1
);
1633 tcg_gen_rotr_i32(s
->tmp2_i32
, s
->tmp2_i32
, s
->tmp3_i32
);
1635 tcg_gen_rotl_i32(s
->tmp2_i32
, s
->tmp2_i32
, s
->tmp3_i32
);
1637 tcg_gen_extu_i32_tl(s
->T0
, s
->tmp2_i32
);
1642 tcg_gen_rotr_tl(s
->T0
, s
->T0
, s
->T1
);
1644 tcg_gen_rotl_tl(s
->T0
, s
->T0
, s
->T1
);
1650 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1652 /* We'll need the flags computed into CC_SRC. */
1653 gen_compute_eflags(s
);
1655 /* The value that was "rotated out" is now present at the other end
1656 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1657 since we've computed the flags into CC_SRC, these variables are
1660 tcg_gen_shri_tl(cpu_cc_src2
, s
->T0
, mask
- 1);
1661 tcg_gen_shri_tl(cpu_cc_dst
, s
->T0
, mask
);
1662 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1664 tcg_gen_shri_tl(cpu_cc_src2
, s
->T0
, mask
);
1665 tcg_gen_andi_tl(cpu_cc_dst
, s
->T0
, 1);
1667 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1668 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1670 /* Now conditionally store the new CC_OP value. If the shift count
1671 is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1672 Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1673 exactly as we computed above. */
1674 t0
= tcg_const_i32(0);
1675 t1
= tcg_temp_new_i32();
1676 tcg_gen_trunc_tl_i32(t1
, s
->T1
);
1677 tcg_gen_movi_i32(s
->tmp2_i32
, CC_OP_ADCOX
);
1678 tcg_gen_movi_i32(s
->tmp3_i32
, CC_OP_EFLAGS
);
1679 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, t1
, t0
,
1680 s
->tmp2_i32
, s
->tmp3_i32
);
1681 tcg_temp_free_i32(t0
);
1682 tcg_temp_free_i32(t1
);
1684 /* The CC_OP value is no longer predictable. */
1685 set_cc_op(s
, CC_OP_DYNAMIC
);
1688 static void gen_rot_rm_im(DisasContext
*s
, MemOp ot
, int op1
, int op2
,
1691 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1695 if (op1
== OR_TMP0
) {
1696 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1698 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1704 #ifdef TARGET_X86_64
1706 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
1708 tcg_gen_rotri_i32(s
->tmp2_i32
, s
->tmp2_i32
, op2
);
1710 tcg_gen_rotli_i32(s
->tmp2_i32
, s
->tmp2_i32
, op2
);
1712 tcg_gen_extu_i32_tl(s
->T0
, s
->tmp2_i32
);
1717 tcg_gen_rotri_tl(s
->T0
, s
->T0
, op2
);
1719 tcg_gen_rotli_tl(s
->T0
, s
->T0
, op2
);
1730 shift
= mask
+ 1 - shift
;
1732 gen_extu(ot
, s
->T0
);
1733 tcg_gen_shli_tl(s
->tmp0
, s
->T0
, shift
);
1734 tcg_gen_shri_tl(s
->T0
, s
->T0
, mask
+ 1 - shift
);
1735 tcg_gen_or_tl(s
->T0
, s
->T0
, s
->tmp0
);
1741 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1744 /* Compute the flags into CC_SRC. */
1745 gen_compute_eflags(s
);
1747 /* The value that was "rotated out" is now present at the other end
1748 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1749 since we've computed the flags into CC_SRC, these variables are
1752 tcg_gen_shri_tl(cpu_cc_src2
, s
->T0
, mask
- 1);
1753 tcg_gen_shri_tl(cpu_cc_dst
, s
->T0
, mask
);
1754 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1756 tcg_gen_shri_tl(cpu_cc_src2
, s
->T0
, mask
);
1757 tcg_gen_andi_tl(cpu_cc_dst
, s
->T0
, 1);
1759 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1760 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1761 set_cc_op(s
, CC_OP_ADCOX
);
1765 /* XXX: add faster immediate = 1 case */
1766 static void gen_rotc_rm_T1(DisasContext
*s
, MemOp ot
, int op1
,
1769 gen_compute_eflags(s
);
1770 assert(s
->cc_op
== CC_OP_EFLAGS
);
1774 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1776 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1781 gen_helper_rcrb(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1784 gen_helper_rcrw(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1787 gen_helper_rcrl(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1789 #ifdef TARGET_X86_64
1791 gen_helper_rcrq(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1800 gen_helper_rclb(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1803 gen_helper_rclw(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1806 gen_helper_rcll(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1808 #ifdef TARGET_X86_64
1810 gen_helper_rclq(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1818 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1821 /* XXX: add faster immediate case */
1822 static void gen_shiftd_rm_T1(DisasContext
*s
, MemOp ot
, int op1
,
1823 bool is_right
, TCGv count_in
)
1825 target_ulong mask
= (ot
== MO_64
? 63 : 31);
1829 if (op1
== OR_TMP0
) {
1830 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1832 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1835 count
= tcg_temp_new();
1836 tcg_gen_andi_tl(count
, count_in
, mask
);
1840 /* Note: we implement the Intel behaviour for shift count > 16.
1841 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A
1842 portion by constructing it as a 32-bit value. */
1844 tcg_gen_deposit_tl(s
->tmp0
, s
->T0
, s
->T1
, 16, 16);
1845 tcg_gen_mov_tl(s
->T1
, s
->T0
);
1846 tcg_gen_mov_tl(s
->T0
, s
->tmp0
);
1848 tcg_gen_deposit_tl(s
->T1
, s
->T0
, s
->T1
, 16, 16);
1851 * If TARGET_X86_64 defined then fall through into MO_32 case,
1852 * otherwise fall through default case.
1855 #ifdef TARGET_X86_64
1856 /* Concatenate the two 32-bit values and use a 64-bit shift. */
1857 tcg_gen_subi_tl(s
->tmp0
, count
, 1);
1859 tcg_gen_concat_tl_i64(s
->T0
, s
->T0
, s
->T1
);
1860 tcg_gen_shr_i64(s
->tmp0
, s
->T0
, s
->tmp0
);
1861 tcg_gen_shr_i64(s
->T0
, s
->T0
, count
);
1863 tcg_gen_concat_tl_i64(s
->T0
, s
->T1
, s
->T0
);
1864 tcg_gen_shl_i64(s
->tmp0
, s
->T0
, s
->tmp0
);
1865 tcg_gen_shl_i64(s
->T0
, s
->T0
, count
);
1866 tcg_gen_shri_i64(s
->tmp0
, s
->tmp0
, 32);
1867 tcg_gen_shri_i64(s
->T0
, s
->T0
, 32);
1872 tcg_gen_subi_tl(s
->tmp0
, count
, 1);
1874 tcg_gen_shr_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1876 tcg_gen_subfi_tl(s
->tmp4
, mask
+ 1, count
);
1877 tcg_gen_shr_tl(s
->T0
, s
->T0
, count
);
1878 tcg_gen_shl_tl(s
->T1
, s
->T1
, s
->tmp4
);
1880 tcg_gen_shl_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1882 /* Only needed if count > 16, for Intel behaviour. */
1883 tcg_gen_subfi_tl(s
->tmp4
, 33, count
);
1884 tcg_gen_shr_tl(s
->tmp4
, s
->T1
, s
->tmp4
);
1885 tcg_gen_or_tl(s
->tmp0
, s
->tmp0
, s
->tmp4
);
1888 tcg_gen_subfi_tl(s
->tmp4
, mask
+ 1, count
);
1889 tcg_gen_shl_tl(s
->T0
, s
->T0
, count
);
1890 tcg_gen_shr_tl(s
->T1
, s
->T1
, s
->tmp4
);
1892 tcg_gen_movi_tl(s
->tmp4
, 0);
1893 tcg_gen_movcond_tl(TCG_COND_EQ
, s
->T1
, count
, s
->tmp4
,
1895 tcg_gen_or_tl(s
->T0
, s
->T0
, s
->T1
);
1900 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1902 gen_shift_flags(s
, ot
, s
->T0
, s
->tmp0
, count
, is_right
);
1903 tcg_temp_free(count
);
1906 static void gen_shift(DisasContext
*s1
, int op
, MemOp ot
, int d
, int s
)
1909 gen_op_mov_v_reg(s1
, ot
, s1
->T1
, s
);
1912 gen_rot_rm_T1(s1
, ot
, d
, 0);
1915 gen_rot_rm_T1(s1
, ot
, d
, 1);
1919 gen_shift_rm_T1(s1
, ot
, d
, 0, 0);
1922 gen_shift_rm_T1(s1
, ot
, d
, 1, 0);
1925 gen_shift_rm_T1(s1
, ot
, d
, 1, 1);
1928 gen_rotc_rm_T1(s1
, ot
, d
, 0);
1931 gen_rotc_rm_T1(s1
, ot
, d
, 1);
1936 static void gen_shifti(DisasContext
*s1
, int op
, MemOp ot
, int d
, int c
)
1940 gen_rot_rm_im(s1
, ot
, d
, c
, 0);
1943 gen_rot_rm_im(s1
, ot
, d
, c
, 1);
1947 gen_shift_rm_im(s1
, ot
, d
, c
, 0, 0);
1950 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 0);
1953 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 1);
1956 /* currently not optimized */
1957 tcg_gen_movi_tl(s1
->T1
, c
);
1958 gen_shift(s1
, op
, ot
, d
, OR_TMP1
);
1963 #define X86_MAX_INSN_LENGTH 15
1965 static uint64_t advance_pc(CPUX86State
*env
, DisasContext
*s
, int num_bytes
)
1967 uint64_t pc
= s
->pc
;
1970 if (unlikely(s
->pc
- s
->pc_start
> X86_MAX_INSN_LENGTH
)) {
1971 /* If the instruction's 16th byte is on a different page than the 1st, a
1972 * page fault on the second page wins over the general protection fault
1973 * caused by the instruction being too long.
1974 * This can happen even if the operand is only one byte long!
1976 if (((s
->pc
- 1) ^ (pc
- 1)) & TARGET_PAGE_MASK
) {
1977 volatile uint8_t unused
=
1978 cpu_ldub_code(env
, (s
->pc
- 1) & TARGET_PAGE_MASK
);
1981 siglongjmp(s
->jmpbuf
, 1);
1987 static inline uint8_t x86_ldub_code(CPUX86State
*env
, DisasContext
*s
)
1989 return translator_ldub(env
, advance_pc(env
, s
, 1));
1992 static inline int16_t x86_ldsw_code(CPUX86State
*env
, DisasContext
*s
)
1994 return translator_ldsw(env
, advance_pc(env
, s
, 2));
1997 static inline uint16_t x86_lduw_code(CPUX86State
*env
, DisasContext
*s
)
1999 return translator_lduw(env
, advance_pc(env
, s
, 2));
2002 static inline uint32_t x86_ldl_code(CPUX86State
*env
, DisasContext
*s
)
2004 return translator_ldl(env
, advance_pc(env
, s
, 4));
2007 #ifdef TARGET_X86_64
2008 static inline uint64_t x86_ldq_code(CPUX86State
*env
, DisasContext
*s
)
2010 return translator_ldq(env
, advance_pc(env
, s
, 8));
2014 /* Decompose an address. */
2016 typedef struct AddressParts
{
2024 static AddressParts
gen_lea_modrm_0(CPUX86State
*env
, DisasContext
*s
,
2027 int def_seg
, base
, index
, scale
, mod
, rm
;
2036 mod
= (modrm
>> 6) & 3;
2038 base
= rm
| REX_B(s
);
2041 /* Normally filtered out earlier, but including this path
2042 simplifies multi-byte nop, as well as bndcl, bndcu, bndcn. */
2051 int code
= x86_ldub_code(env
, s
);
2052 scale
= (code
>> 6) & 3;
2053 index
= ((code
>> 3) & 7) | REX_X(s
);
2055 index
= -1; /* no index */
2057 base
= (code
& 7) | REX_B(s
);
2063 if ((base
& 7) == 5) {
2065 disp
= (int32_t)x86_ldl_code(env
, s
);
2066 if (CODE64(s
) && !havesib
) {
2068 disp
+= s
->pc
+ s
->rip_offset
;
2073 disp
= (int8_t)x86_ldub_code(env
, s
);
2077 disp
= (int32_t)x86_ldl_code(env
, s
);
2081 /* For correct popl handling with esp. */
2082 if (base
== R_ESP
&& s
->popl_esp_hack
) {
2083 disp
+= s
->popl_esp_hack
;
2085 if (base
== R_EBP
|| base
== R_ESP
) {
2094 disp
= x86_lduw_code(env
, s
);
2097 } else if (mod
== 1) {
2098 disp
= (int8_t)x86_ldub_code(env
, s
);
2100 disp
= (int16_t)x86_lduw_code(env
, s
);
2144 return (AddressParts
){ def_seg
, base
, index
, scale
, disp
};
2147 /* Compute the address, with a minimum number of TCG ops. */
2148 static TCGv
gen_lea_modrm_1(DisasContext
*s
, AddressParts a
)
2154 ea
= cpu_regs
[a
.index
];
2156 tcg_gen_shli_tl(s
->A0
, cpu_regs
[a
.index
], a
.scale
);
2160 tcg_gen_add_tl(s
->A0
, ea
, cpu_regs
[a
.base
]);
2163 } else if (a
.base
>= 0) {
2164 ea
= cpu_regs
[a
.base
];
2167 tcg_gen_movi_tl(s
->A0
, a
.disp
);
2169 } else if (a
.disp
!= 0) {
2170 tcg_gen_addi_tl(s
->A0
, ea
, a
.disp
);
2177 static void gen_lea_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2179 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
2180 TCGv ea
= gen_lea_modrm_1(s
, a
);
2181 gen_lea_v_seg(s
, s
->aflag
, ea
, a
.def_seg
, s
->override
);
2184 static void gen_nop_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2186 (void)gen_lea_modrm_0(env
, s
, modrm
);
2189 /* Used for BNDCL, BNDCU, BNDCN. */
2190 static void gen_bndck(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2191 TCGCond cond
, TCGv_i64 bndv
)
2193 TCGv ea
= gen_lea_modrm_1(s
, gen_lea_modrm_0(env
, s
, modrm
));
2195 tcg_gen_extu_tl_i64(s
->tmp1_i64
, ea
);
2197 tcg_gen_ext32u_i64(s
->tmp1_i64
, s
->tmp1_i64
);
2199 tcg_gen_setcond_i64(cond
, s
->tmp1_i64
, s
->tmp1_i64
, bndv
);
2200 tcg_gen_extrl_i64_i32(s
->tmp2_i32
, s
->tmp1_i64
);
2201 gen_helper_bndck(cpu_env
, s
->tmp2_i32
);
2204 /* used for LEA and MOV AX, mem */
2205 static void gen_add_A0_ds_seg(DisasContext
*s
)
2207 gen_lea_v_seg(s
, s
->aflag
, s
->A0
, R_DS
, s
->override
);
2210 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2212 static void gen_ldst_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2213 MemOp ot
, int reg
, int is_store
)
2217 mod
= (modrm
>> 6) & 3;
2218 rm
= (modrm
& 7) | REX_B(s
);
2222 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
2223 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
2225 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
2227 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
2230 gen_lea_modrm(env
, s
, modrm
);
2233 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
2234 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
2236 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
2238 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
2243 static inline uint32_t insn_get(CPUX86State
*env
, DisasContext
*s
, MemOp ot
)
2249 ret
= x86_ldub_code(env
, s
);
2252 ret
= x86_lduw_code(env
, s
);
2255 #ifdef TARGET_X86_64
2258 ret
= x86_ldl_code(env
, s
);
2266 static inline int insn_const_size(MemOp ot
)
2275 static inline bool use_goto_tb(DisasContext
*s
, target_ulong pc
)
2277 #ifndef CONFIG_USER_ONLY
2278 return (pc
& TARGET_PAGE_MASK
) == (s
->base
.tb
->pc
& TARGET_PAGE_MASK
) ||
2279 (pc
& TARGET_PAGE_MASK
) == (s
->pc_start
& TARGET_PAGE_MASK
);
2285 static inline void gen_goto_tb(DisasContext
*s
, int tb_num
, target_ulong eip
)
2287 target_ulong pc
= s
->cs_base
+ eip
;
2289 if (use_goto_tb(s
, pc
)) {
2290 /* jump to same page: we can use a direct jump */
2291 tcg_gen_goto_tb(tb_num
);
2293 tcg_gen_exit_tb(s
->base
.tb
, tb_num
);
2294 s
->base
.is_jmp
= DISAS_NORETURN
;
2296 /* jump to another page */
2302 static inline void gen_jcc(DisasContext
*s
, int b
,
2303 target_ulong val
, target_ulong next_eip
)
2308 l1
= gen_new_label();
2311 gen_goto_tb(s
, 0, next_eip
);
2314 gen_goto_tb(s
, 1, val
);
2316 l1
= gen_new_label();
2317 l2
= gen_new_label();
2320 gen_jmp_im(s
, next_eip
);
2330 static void gen_cmovcc1(CPUX86State
*env
, DisasContext
*s
, MemOp ot
, int b
,
2335 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
2337 cc
= gen_prepare_cc(s
, b
, s
->T1
);
2338 if (cc
.mask
!= -1) {
2339 TCGv t0
= tcg_temp_new();
2340 tcg_gen_andi_tl(t0
, cc
.reg
, cc
.mask
);
2344 cc
.reg2
= tcg_const_tl(cc
.imm
);
2347 tcg_gen_movcond_tl(cc
.cond
, s
->T0
, cc
.reg
, cc
.reg2
,
2348 s
->T0
, cpu_regs
[reg
]);
2349 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
2351 if (cc
.mask
!= -1) {
2352 tcg_temp_free(cc
.reg
);
2355 tcg_temp_free(cc
.reg2
);
2359 static inline void gen_op_movl_T0_seg(DisasContext
*s
, X86Seg seg_reg
)
2361 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
2362 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2365 static inline void gen_op_movl_seg_T0_vm(DisasContext
*s
, X86Seg seg_reg
)
2367 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
2368 tcg_gen_st32_tl(s
->T0
, cpu_env
,
2369 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2370 tcg_gen_shli_tl(cpu_seg_base
[seg_reg
], s
->T0
, 4);
2373 /* move T0 to seg_reg and compute if the CPU state may change. Never
2374 call this function with seg_reg == R_CS */
2375 static void gen_movl_seg_T0(DisasContext
*s
, X86Seg seg_reg
)
2377 if (PE(s
) && !VM86(s
)) {
2378 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
2379 gen_helper_load_seg(cpu_env
, tcg_const_i32(seg_reg
), s
->tmp2_i32
);
2380 /* abort translation because the addseg value may change or
2381 because ss32 may change. For R_SS, translation must always
2382 stop as a special handling must be done to disable hardware
2383 interrupts for the next instruction */
2384 if (seg_reg
== R_SS
|| (CODE32(s
) && seg_reg
< R_FS
)) {
2385 s
->base
.is_jmp
= DISAS_TOO_MANY
;
2388 gen_op_movl_seg_T0_vm(s
, seg_reg
);
2389 if (seg_reg
== R_SS
) {
2390 s
->base
.is_jmp
= DISAS_TOO_MANY
;
2395 static inline int svm_is_rep(int prefixes
)
2397 return ((prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) ? 8 : 0);
2401 gen_svm_check_intercept_param(DisasContext
*s
, target_ulong pc_start
,
2402 uint32_t type
, uint64_t param
)
2404 /* no SVM activated; fast case */
2405 if (likely(!(s
->flags
& HF_GUEST_MASK
)))
2407 gen_update_cc_op(s
);
2408 gen_jmp_im(s
, pc_start
- s
->cs_base
);
2409 gen_helper_svm_check_intercept_param(cpu_env
, tcg_const_i32(type
),
2410 tcg_const_i64(param
));
2414 gen_svm_check_intercept(DisasContext
*s
, target_ulong pc_start
, uint64_t type
)
2416 gen_svm_check_intercept_param(s
, pc_start
, type
, 0);
2419 static inline void gen_stack_update(DisasContext
*s
, int addend
)
2421 gen_op_add_reg_im(s
, mo_stacksize(s
), R_ESP
, addend
);
2424 /* Generate a push. It depends on ss32, addseg and dflag. */
2425 static void gen_push_v(DisasContext
*s
, TCGv val
)
2427 MemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2428 MemOp a_ot
= mo_stacksize(s
);
2429 int size
= 1 << d_ot
;
2430 TCGv new_esp
= s
->A0
;
2432 tcg_gen_subi_tl(s
->A0
, cpu_regs
[R_ESP
], size
);
2437 tcg_gen_mov_tl(new_esp
, s
->A0
);
2439 gen_lea_v_seg(s
, a_ot
, s
->A0
, R_SS
, -1);
2442 gen_op_st_v(s
, d_ot
, val
, s
->A0
);
2443 gen_op_mov_reg_v(s
, a_ot
, R_ESP
, new_esp
);
2446 /* two step pop is necessary for precise exceptions */
2447 static MemOp
gen_pop_T0(DisasContext
*s
)
2449 MemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2451 gen_lea_v_seg(s
, mo_stacksize(s
), cpu_regs
[R_ESP
], R_SS
, -1);
2452 gen_op_ld_v(s
, d_ot
, s
->T0
, s
->A0
);
2457 static inline void gen_pop_update(DisasContext
*s
, MemOp ot
)
2459 gen_stack_update(s
, 1 << ot
);
2462 static inline void gen_stack_A0(DisasContext
*s
)
2464 gen_lea_v_seg(s
, SS32(s
) ? MO_32
: MO_16
, cpu_regs
[R_ESP
], R_SS
, -1);
2467 static void gen_pusha(DisasContext
*s
)
2469 MemOp s_ot
= SS32(s
) ? MO_32
: MO_16
;
2470 MemOp d_ot
= s
->dflag
;
2471 int size
= 1 << d_ot
;
2474 for (i
= 0; i
< 8; i
++) {
2475 tcg_gen_addi_tl(s
->A0
, cpu_regs
[R_ESP
], (i
- 8) * size
);
2476 gen_lea_v_seg(s
, s_ot
, s
->A0
, R_SS
, -1);
2477 gen_op_st_v(s
, d_ot
, cpu_regs
[7 - i
], s
->A0
);
2480 gen_stack_update(s
, -8 * size
);
2483 static void gen_popa(DisasContext
*s
)
2485 MemOp s_ot
= SS32(s
) ? MO_32
: MO_16
;
2486 MemOp d_ot
= s
->dflag
;
2487 int size
= 1 << d_ot
;
2490 for (i
= 0; i
< 8; i
++) {
2491 /* ESP is not reloaded */
2492 if (7 - i
== R_ESP
) {
2495 tcg_gen_addi_tl(s
->A0
, cpu_regs
[R_ESP
], i
* size
);
2496 gen_lea_v_seg(s
, s_ot
, s
->A0
, R_SS
, -1);
2497 gen_op_ld_v(s
, d_ot
, s
->T0
, s
->A0
);
2498 gen_op_mov_reg_v(s
, d_ot
, 7 - i
, s
->T0
);
2501 gen_stack_update(s
, 8 * size
);
2504 static void gen_enter(DisasContext
*s
, int esp_addend
, int level
)
2506 MemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2507 MemOp a_ot
= CODE64(s
) ? MO_64
: SS32(s
) ? MO_32
: MO_16
;
2508 int size
= 1 << d_ot
;
2510 /* Push BP; compute FrameTemp into T1. */
2511 tcg_gen_subi_tl(s
->T1
, cpu_regs
[R_ESP
], size
);
2512 gen_lea_v_seg(s
, a_ot
, s
->T1
, R_SS
, -1);
2513 gen_op_st_v(s
, d_ot
, cpu_regs
[R_EBP
], s
->A0
);
2519 /* Copy level-1 pointers from the previous frame. */
2520 for (i
= 1; i
< level
; ++i
) {
2521 tcg_gen_subi_tl(s
->A0
, cpu_regs
[R_EBP
], size
* i
);
2522 gen_lea_v_seg(s
, a_ot
, s
->A0
, R_SS
, -1);
2523 gen_op_ld_v(s
, d_ot
, s
->tmp0
, s
->A0
);
2525 tcg_gen_subi_tl(s
->A0
, s
->T1
, size
* i
);
2526 gen_lea_v_seg(s
, a_ot
, s
->A0
, R_SS
, -1);
2527 gen_op_st_v(s
, d_ot
, s
->tmp0
, s
->A0
);
2530 /* Push the current FrameTemp as the last level. */
2531 tcg_gen_subi_tl(s
->A0
, s
->T1
, size
* level
);
2532 gen_lea_v_seg(s
, a_ot
, s
->A0
, R_SS
, -1);
2533 gen_op_st_v(s
, d_ot
, s
->T1
, s
->A0
);
2536 /* Copy the FrameTemp value to EBP. */
2537 gen_op_mov_reg_v(s
, a_ot
, R_EBP
, s
->T1
);
2539 /* Compute the final value of ESP. */
2540 tcg_gen_subi_tl(s
->T1
, s
->T1
, esp_addend
+ size
* level
);
2541 gen_op_mov_reg_v(s
, a_ot
, R_ESP
, s
->T1
);
2544 static void gen_leave(DisasContext
*s
)
2546 MemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2547 MemOp a_ot
= mo_stacksize(s
);
2549 gen_lea_v_seg(s
, a_ot
, cpu_regs
[R_EBP
], R_SS
, -1);
2550 gen_op_ld_v(s
, d_ot
, s
->T0
, s
->A0
);
2552 tcg_gen_addi_tl(s
->T1
, cpu_regs
[R_EBP
], 1 << d_ot
);
2554 gen_op_mov_reg_v(s
, d_ot
, R_EBP
, s
->T0
);
2555 gen_op_mov_reg_v(s
, a_ot
, R_ESP
, s
->T1
);
2558 /* Similarly, except that the assumption here is that we don't decode
2559 the instruction at all -- either a missing opcode, an unimplemented
2560 feature, or just a bogus instruction stream. */
2561 static void gen_unknown_opcode(CPUX86State
*env
, DisasContext
*s
)
2563 gen_illegal_opcode(s
);
2565 if (qemu_loglevel_mask(LOG_UNIMP
)) {
2566 FILE *logfile
= qemu_log_lock();
2567 target_ulong pc
= s
->pc_start
, end
= s
->pc
;
2569 qemu_log("ILLOPC: " TARGET_FMT_lx
":", pc
);
2570 for (; pc
< end
; ++pc
) {
2571 qemu_log(" %02x", cpu_ldub_code(env
, pc
));
2574 qemu_log_unlock(logfile
);
2578 /* an interrupt is different from an exception because of the
2580 static void gen_interrupt(DisasContext
*s
, int intno
,
2581 target_ulong cur_eip
, target_ulong next_eip
)
2583 gen_update_cc_op(s
);
2584 gen_jmp_im(s
, cur_eip
);
2585 gen_helper_raise_interrupt(cpu_env
, tcg_const_i32(intno
),
2586 tcg_const_i32(next_eip
- cur_eip
));
2587 s
->base
.is_jmp
= DISAS_NORETURN
;
2590 static void gen_debug(DisasContext
*s
, target_ulong cur_eip
)
2592 gen_update_cc_op(s
);
2593 gen_jmp_im(s
, cur_eip
);
2594 gen_helper_debug(cpu_env
);
2595 s
->base
.is_jmp
= DISAS_NORETURN
;
2598 static void gen_set_hflag(DisasContext
*s
, uint32_t mask
)
2600 if ((s
->flags
& mask
) == 0) {
2601 TCGv_i32 t
= tcg_temp_new_i32();
2602 tcg_gen_ld_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2603 tcg_gen_ori_i32(t
, t
, mask
);
2604 tcg_gen_st_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2605 tcg_temp_free_i32(t
);
2610 static void gen_reset_hflag(DisasContext
*s
, uint32_t mask
)
2612 if (s
->flags
& mask
) {
2613 TCGv_i32 t
= tcg_temp_new_i32();
2614 tcg_gen_ld_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2615 tcg_gen_andi_i32(t
, t
, ~mask
);
2616 tcg_gen_st_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2617 tcg_temp_free_i32(t
);
2622 /* Clear BND registers during legacy branches. */
2623 static void gen_bnd_jmp(DisasContext
*s
)
2625 /* Clear the registers only if BND prefix is missing, MPX is enabled,
2626 and if the BNDREGs are known to be in use (non-zero) already.
2627 The helper itself will check BNDPRESERVE at runtime. */
2628 if ((s
->prefix
& PREFIX_REPNZ
) == 0
2629 && (s
->flags
& HF_MPX_EN_MASK
) != 0
2630 && (s
->flags
& HF_MPX_IU_MASK
) != 0) {
2631 gen_helper_bnd_jmp(cpu_env
);
2635 /* Generate an end of block. Trace exception is also generated if needed.
2636 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set.
2637 If RECHECK_TF, emit a rechecking helper for #DB, ignoring the state of
2638 S->TF. This is used by the syscall/sysret insns. */
2640 do_gen_eob_worker(DisasContext
*s
, bool inhibit
, bool recheck_tf
, bool jr
)
2642 gen_update_cc_op(s
);
2644 /* If several instructions disable interrupts, only the first does it. */
2645 if (inhibit
&& !(s
->flags
& HF_INHIBIT_IRQ_MASK
)) {
2646 gen_set_hflag(s
, HF_INHIBIT_IRQ_MASK
);
2648 gen_reset_hflag(s
, HF_INHIBIT_IRQ_MASK
);
2651 if (s
->base
.tb
->flags
& HF_RF_MASK
) {
2652 gen_helper_reset_rf(cpu_env
);
2654 if (s
->base
.singlestep_enabled
) {
2655 gen_helper_debug(cpu_env
);
2656 } else if (recheck_tf
) {
2657 gen_helper_rechecking_single_step(cpu_env
);
2658 tcg_gen_exit_tb(NULL
, 0);
2660 gen_helper_single_step(cpu_env
);
2662 tcg_gen_lookup_and_goto_ptr();
2664 tcg_gen_exit_tb(NULL
, 0);
2666 s
->base
.is_jmp
= DISAS_NORETURN
;
2670 gen_eob_worker(DisasContext
*s
, bool inhibit
, bool recheck_tf
)
2672 do_gen_eob_worker(s
, inhibit
, recheck_tf
, false);
2676 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set. */
2677 static void gen_eob_inhibit_irq(DisasContext
*s
, bool inhibit
)
2679 gen_eob_worker(s
, inhibit
, false);
2682 /* End of block, resetting the inhibit irq flag. */
2683 static void gen_eob(DisasContext
*s
)
2685 gen_eob_worker(s
, false, false);
2688 /* Jump to register */
2689 static void gen_jr(DisasContext
*s
, TCGv dest
)
2691 do_gen_eob_worker(s
, false, false, true);
2694 /* generate a jump to eip. No segment change must happen before as a
2695 direct call to the next block may occur */
2696 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
)
2698 gen_update_cc_op(s
);
2699 set_cc_op(s
, CC_OP_DYNAMIC
);
2701 gen_goto_tb(s
, tb_num
, eip
);
2708 static void gen_jmp(DisasContext
*s
, target_ulong eip
)
2710 gen_jmp_tb(s
, eip
, 0);
2713 static inline void gen_ldq_env_A0(DisasContext
*s
, int offset
)
2715 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
, s
->mem_index
, MO_LEQ
);
2716 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, offset
);
2719 static inline void gen_stq_env_A0(DisasContext
*s
, int offset
)
2721 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, offset
);
2722 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
, s
->mem_index
, MO_LEQ
);
2725 static inline void gen_ldo_env_A0(DisasContext
*s
, int offset
)
2727 int mem_index
= s
->mem_index
;
2728 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
, mem_index
, MO_LEQ
);
2729 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2730 tcg_gen_addi_tl(s
->tmp0
, s
->A0
, 8);
2731 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->tmp0
, mem_index
, MO_LEQ
);
2732 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2735 static inline void gen_sto_env_A0(DisasContext
*s
, int offset
)
2737 int mem_index
= s
->mem_index
;
2738 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2739 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
, mem_index
, MO_LEQ
);
2740 tcg_gen_addi_tl(s
->tmp0
, s
->A0
, 8);
2741 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2742 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->tmp0
, mem_index
, MO_LEQ
);
2745 static inline void gen_op_movo(DisasContext
*s
, int d_offset
, int s_offset
)
2747 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, s_offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2748 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, d_offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2749 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, s_offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2750 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, d_offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2753 static inline void gen_op_movq(DisasContext
*s
, int d_offset
, int s_offset
)
2755 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, s_offset
);
2756 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, d_offset
);
2759 static inline void gen_op_movl(DisasContext
*s
, int d_offset
, int s_offset
)
2761 tcg_gen_ld_i32(s
->tmp2_i32
, cpu_env
, s_offset
);
2762 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
, d_offset
);
2765 static inline void gen_op_movq_env_0(DisasContext
*s
, int d_offset
)
2767 tcg_gen_movi_i64(s
->tmp1_i64
, 0);
2768 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, d_offset
);
2771 typedef void (*SSEFunc_i_ep
)(TCGv_i32 val
, TCGv_ptr env
, TCGv_ptr reg
);
2772 typedef void (*SSEFunc_l_ep
)(TCGv_i64 val
, TCGv_ptr env
, TCGv_ptr reg
);
2773 typedef void (*SSEFunc_0_epi
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i32 val
);
2774 typedef void (*SSEFunc_0_epl
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i64 val
);
2775 typedef void (*SSEFunc_0_epp
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
);
2776 typedef void (*SSEFunc_0_eppi
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2778 typedef void (*SSEFunc_0_ppi
)(TCGv_ptr reg_a
, TCGv_ptr reg_b
, TCGv_i32 val
);
2779 typedef void (*SSEFunc_0_eppt
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2782 #define SSE_SPECIAL ((void *)1)
2783 #define SSE_DUMMY ((void *)2)
2785 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2786 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2787 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2789 static const SSEFunc_0_epp sse_op_table1
[256][4] = {
2790 /* 3DNow! extensions */
2791 [0x0e] = { SSE_DUMMY
}, /* femms */
2792 [0x0f] = { SSE_DUMMY
}, /* pf... */
2793 /* pure SSE operations */
2794 [0x10] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2795 [0x11] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2796 [0x12] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd, movsldup, movddup */
2797 [0x13] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd */
2798 [0x14] = { gen_helper_punpckldq_xmm
, gen_helper_punpcklqdq_xmm
},
2799 [0x15] = { gen_helper_punpckhdq_xmm
, gen_helper_punpckhqdq_xmm
},
2800 [0x16] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd, movshdup */
2801 [0x17] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd */
2803 [0x28] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2804 [0x29] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2805 [0x2a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2806 [0x2b] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movntps, movntpd, movntss, movntsd */
2807 [0x2c] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2808 [0x2d] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2809 [0x2e] = { gen_helper_ucomiss
, gen_helper_ucomisd
},
2810 [0x2f] = { gen_helper_comiss
, gen_helper_comisd
},
2811 [0x50] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movmskps, movmskpd */
2812 [0x51] = SSE_FOP(sqrt
),
2813 [0x52] = { gen_helper_rsqrtps
, NULL
, gen_helper_rsqrtss
, NULL
},
2814 [0x53] = { gen_helper_rcpps
, NULL
, gen_helper_rcpss
, NULL
},
2815 [0x54] = { gen_helper_pand_xmm
, gen_helper_pand_xmm
}, /* andps, andpd */
2816 [0x55] = { gen_helper_pandn_xmm
, gen_helper_pandn_xmm
}, /* andnps, andnpd */
2817 [0x56] = { gen_helper_por_xmm
, gen_helper_por_xmm
}, /* orps, orpd */
2818 [0x57] = { gen_helper_pxor_xmm
, gen_helper_pxor_xmm
}, /* xorps, xorpd */
2819 [0x58] = SSE_FOP(add
),
2820 [0x59] = SSE_FOP(mul
),
2821 [0x5a] = { gen_helper_cvtps2pd
, gen_helper_cvtpd2ps
,
2822 gen_helper_cvtss2sd
, gen_helper_cvtsd2ss
},
2823 [0x5b] = { gen_helper_cvtdq2ps
, gen_helper_cvtps2dq
, gen_helper_cvttps2dq
},
2824 [0x5c] = SSE_FOP(sub
),
2825 [0x5d] = SSE_FOP(min
),
2826 [0x5e] = SSE_FOP(div
),
2827 [0x5f] = SSE_FOP(max
),
2829 [0xc2] = SSE_FOP(cmpeq
),
2830 [0xc6] = { (SSEFunc_0_epp
)gen_helper_shufps
,
2831 (SSEFunc_0_epp
)gen_helper_shufpd
}, /* XXX: casts */
2833 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */
2834 [0x38] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2835 [0x3a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2837 /* MMX ops and their SSE extensions */
2838 [0x60] = MMX_OP2(punpcklbw
),
2839 [0x61] = MMX_OP2(punpcklwd
),
2840 [0x62] = MMX_OP2(punpckldq
),
2841 [0x63] = MMX_OP2(packsswb
),
2842 [0x64] = MMX_OP2(pcmpgtb
),
2843 [0x65] = MMX_OP2(pcmpgtw
),
2844 [0x66] = MMX_OP2(pcmpgtl
),
2845 [0x67] = MMX_OP2(packuswb
),
2846 [0x68] = MMX_OP2(punpckhbw
),
2847 [0x69] = MMX_OP2(punpckhwd
),
2848 [0x6a] = MMX_OP2(punpckhdq
),
2849 [0x6b] = MMX_OP2(packssdw
),
2850 [0x6c] = { NULL
, gen_helper_punpcklqdq_xmm
},
2851 [0x6d] = { NULL
, gen_helper_punpckhqdq_xmm
},
2852 [0x6e] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movd mm, ea */
2853 [0x6f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, , movqdu */
2854 [0x70] = { (SSEFunc_0_epp
)gen_helper_pshufw_mmx
,
2855 (SSEFunc_0_epp
)gen_helper_pshufd_xmm
,
2856 (SSEFunc_0_epp
)gen_helper_pshufhw_xmm
,
2857 (SSEFunc_0_epp
)gen_helper_pshuflw_xmm
}, /* XXX: casts */
2858 [0x71] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftw */
2859 [0x72] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftd */
2860 [0x73] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftq */
2861 [0x74] = MMX_OP2(pcmpeqb
),
2862 [0x75] = MMX_OP2(pcmpeqw
),
2863 [0x76] = MMX_OP2(pcmpeql
),
2864 [0x77] = { SSE_DUMMY
}, /* emms */
2865 [0x78] = { NULL
, SSE_SPECIAL
, NULL
, SSE_SPECIAL
}, /* extrq_i, insertq_i */
2866 [0x79] = { NULL
, gen_helper_extrq_r
, NULL
, gen_helper_insertq_r
},
2867 [0x7c] = { NULL
, gen_helper_haddpd
, NULL
, gen_helper_haddps
},
2868 [0x7d] = { NULL
, gen_helper_hsubpd
, NULL
, gen_helper_hsubps
},
2869 [0x7e] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movd, movd, , movq */
2870 [0x7f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, movdqu */
2871 [0xc4] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pinsrw */
2872 [0xc5] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pextrw */
2873 [0xd0] = { NULL
, gen_helper_addsubpd
, NULL
, gen_helper_addsubps
},
2874 [0xd1] = MMX_OP2(psrlw
),
2875 [0xd2] = MMX_OP2(psrld
),
2876 [0xd3] = MMX_OP2(psrlq
),
2877 [0xd4] = MMX_OP2(paddq
),
2878 [0xd5] = MMX_OP2(pmullw
),
2879 [0xd6] = { NULL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2880 [0xd7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pmovmskb */
2881 [0xd8] = MMX_OP2(psubusb
),
2882 [0xd9] = MMX_OP2(psubusw
),
2883 [0xda] = MMX_OP2(pminub
),
2884 [0xdb] = MMX_OP2(pand
),
2885 [0xdc] = MMX_OP2(paddusb
),
2886 [0xdd] = MMX_OP2(paddusw
),
2887 [0xde] = MMX_OP2(pmaxub
),
2888 [0xdf] = MMX_OP2(pandn
),
2889 [0xe0] = MMX_OP2(pavgb
),
2890 [0xe1] = MMX_OP2(psraw
),
2891 [0xe2] = MMX_OP2(psrad
),
2892 [0xe3] = MMX_OP2(pavgw
),
2893 [0xe4] = MMX_OP2(pmulhuw
),
2894 [0xe5] = MMX_OP2(pmulhw
),
2895 [0xe6] = { NULL
, gen_helper_cvttpd2dq
, gen_helper_cvtdq2pd
, gen_helper_cvtpd2dq
},
2896 [0xe7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movntq, movntq */
2897 [0xe8] = MMX_OP2(psubsb
),
2898 [0xe9] = MMX_OP2(psubsw
),
2899 [0xea] = MMX_OP2(pminsw
),
2900 [0xeb] = MMX_OP2(por
),
2901 [0xec] = MMX_OP2(paddsb
),
2902 [0xed] = MMX_OP2(paddsw
),
2903 [0xee] = MMX_OP2(pmaxsw
),
2904 [0xef] = MMX_OP2(pxor
),
2905 [0xf0] = { NULL
, NULL
, NULL
, SSE_SPECIAL
}, /* lddqu */
2906 [0xf1] = MMX_OP2(psllw
),
2907 [0xf2] = MMX_OP2(pslld
),
2908 [0xf3] = MMX_OP2(psllq
),
2909 [0xf4] = MMX_OP2(pmuludq
),
2910 [0xf5] = MMX_OP2(pmaddwd
),
2911 [0xf6] = MMX_OP2(psadbw
),
2912 [0xf7] = { (SSEFunc_0_epp
)gen_helper_maskmov_mmx
,
2913 (SSEFunc_0_epp
)gen_helper_maskmov_xmm
}, /* XXX: casts */
2914 [0xf8] = MMX_OP2(psubb
),
2915 [0xf9] = MMX_OP2(psubw
),
2916 [0xfa] = MMX_OP2(psubl
),
2917 [0xfb] = MMX_OP2(psubq
),
2918 [0xfc] = MMX_OP2(paddb
),
2919 [0xfd] = MMX_OP2(paddw
),
2920 [0xfe] = MMX_OP2(paddl
),
2923 static const SSEFunc_0_epp sse_op_table2
[3 * 8][2] = {
2924 [0 + 2] = MMX_OP2(psrlw
),
2925 [0 + 4] = MMX_OP2(psraw
),
2926 [0 + 6] = MMX_OP2(psllw
),
2927 [8 + 2] = MMX_OP2(psrld
),
2928 [8 + 4] = MMX_OP2(psrad
),
2929 [8 + 6] = MMX_OP2(pslld
),
2930 [16 + 2] = MMX_OP2(psrlq
),
2931 [16 + 3] = { NULL
, gen_helper_psrldq_xmm
},
2932 [16 + 6] = MMX_OP2(psllq
),
2933 [16 + 7] = { NULL
, gen_helper_pslldq_xmm
},
2936 static const SSEFunc_0_epi sse_op_table3ai
[] = {
2937 gen_helper_cvtsi2ss
,
2941 #ifdef TARGET_X86_64
2942 static const SSEFunc_0_epl sse_op_table3aq
[] = {
2943 gen_helper_cvtsq2ss
,
2948 static const SSEFunc_i_ep sse_op_table3bi
[] = {
2949 gen_helper_cvttss2si
,
2950 gen_helper_cvtss2si
,
2951 gen_helper_cvttsd2si
,
2955 #ifdef TARGET_X86_64
2956 static const SSEFunc_l_ep sse_op_table3bq
[] = {
2957 gen_helper_cvttss2sq
,
2958 gen_helper_cvtss2sq
,
2959 gen_helper_cvttsd2sq
,
2964 static const SSEFunc_0_epp sse_op_table4
[8][4] = {
2975 static const SSEFunc_0_epp sse_op_table5
[256] = {
2976 [0x0c] = gen_helper_pi2fw
,
2977 [0x0d] = gen_helper_pi2fd
,
2978 [0x1c] = gen_helper_pf2iw
,
2979 [0x1d] = gen_helper_pf2id
,
2980 [0x8a] = gen_helper_pfnacc
,
2981 [0x8e] = gen_helper_pfpnacc
,
2982 [0x90] = gen_helper_pfcmpge
,
2983 [0x94] = gen_helper_pfmin
,
2984 [0x96] = gen_helper_pfrcp
,
2985 [0x97] = gen_helper_pfrsqrt
,
2986 [0x9a] = gen_helper_pfsub
,
2987 [0x9e] = gen_helper_pfadd
,
2988 [0xa0] = gen_helper_pfcmpgt
,
2989 [0xa4] = gen_helper_pfmax
,
2990 [0xa6] = gen_helper_movq
, /* pfrcpit1; no need to actually increase precision */
2991 [0xa7] = gen_helper_movq
, /* pfrsqit1 */
2992 [0xaa] = gen_helper_pfsubr
,
2993 [0xae] = gen_helper_pfacc
,
2994 [0xb0] = gen_helper_pfcmpeq
,
2995 [0xb4] = gen_helper_pfmul
,
2996 [0xb6] = gen_helper_movq
, /* pfrcpit2 */
2997 [0xb7] = gen_helper_pmulhrw_mmx
,
2998 [0xbb] = gen_helper_pswapd
,
2999 [0xbf] = gen_helper_pavgb_mmx
/* pavgusb */
3002 struct SSEOpHelper_epp
{
3003 SSEFunc_0_epp op
[2];
3007 struct SSEOpHelper_eppi
{
3008 SSEFunc_0_eppi op
[2];
3012 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
3013 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
3014 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
3015 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
3016 #define PCLMULQDQ_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, \
3017 CPUID_EXT_PCLMULQDQ }
3018 #define AESNI_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_AES }
3020 static const struct SSEOpHelper_epp sse_op_table6
[256] = {
3021 [0x00] = SSSE3_OP(pshufb
),
3022 [0x01] = SSSE3_OP(phaddw
),
3023 [0x02] = SSSE3_OP(phaddd
),
3024 [0x03] = SSSE3_OP(phaddsw
),
3025 [0x04] = SSSE3_OP(pmaddubsw
),
3026 [0x05] = SSSE3_OP(phsubw
),
3027 [0x06] = SSSE3_OP(phsubd
),
3028 [0x07] = SSSE3_OP(phsubsw
),
3029 [0x08] = SSSE3_OP(psignb
),
3030 [0x09] = SSSE3_OP(psignw
),
3031 [0x0a] = SSSE3_OP(psignd
),
3032 [0x0b] = SSSE3_OP(pmulhrsw
),
3033 [0x10] = SSE41_OP(pblendvb
),
3034 [0x14] = SSE41_OP(blendvps
),
3035 [0x15] = SSE41_OP(blendvpd
),
3036 [0x17] = SSE41_OP(ptest
),
3037 [0x1c] = SSSE3_OP(pabsb
),
3038 [0x1d] = SSSE3_OP(pabsw
),
3039 [0x1e] = SSSE3_OP(pabsd
),
3040 [0x20] = SSE41_OP(pmovsxbw
),
3041 [0x21] = SSE41_OP(pmovsxbd
),
3042 [0x22] = SSE41_OP(pmovsxbq
),
3043 [0x23] = SSE41_OP(pmovsxwd
),
3044 [0x24] = SSE41_OP(pmovsxwq
),
3045 [0x25] = SSE41_OP(pmovsxdq
),
3046 [0x28] = SSE41_OP(pmuldq
),
3047 [0x29] = SSE41_OP(pcmpeqq
),
3048 [0x2a] = SSE41_SPECIAL
, /* movntqda */
3049 [0x2b] = SSE41_OP(packusdw
),
3050 [0x30] = SSE41_OP(pmovzxbw
),
3051 [0x31] = SSE41_OP(pmovzxbd
),
3052 [0x32] = SSE41_OP(pmovzxbq
),
3053 [0x33] = SSE41_OP(pmovzxwd
),
3054 [0x34] = SSE41_OP(pmovzxwq
),
3055 [0x35] = SSE41_OP(pmovzxdq
),
3056 [0x37] = SSE42_OP(pcmpgtq
),
3057 [0x38] = SSE41_OP(pminsb
),
3058 [0x39] = SSE41_OP(pminsd
),
3059 [0x3a] = SSE41_OP(pminuw
),
3060 [0x3b] = SSE41_OP(pminud
),
3061 [0x3c] = SSE41_OP(pmaxsb
),
3062 [0x3d] = SSE41_OP(pmaxsd
),
3063 [0x3e] = SSE41_OP(pmaxuw
),
3064 [0x3f] = SSE41_OP(pmaxud
),
3065 [0x40] = SSE41_OP(pmulld
),
3066 [0x41] = SSE41_OP(phminposuw
),
3067 [0xdb] = AESNI_OP(aesimc
),
3068 [0xdc] = AESNI_OP(aesenc
),
3069 [0xdd] = AESNI_OP(aesenclast
),
3070 [0xde] = AESNI_OP(aesdec
),
3071 [0xdf] = AESNI_OP(aesdeclast
),
3074 static const struct SSEOpHelper_eppi sse_op_table7
[256] = {
3075 [0x08] = SSE41_OP(roundps
),
3076 [0x09] = SSE41_OP(roundpd
),
3077 [0x0a] = SSE41_OP(roundss
),
3078 [0x0b] = SSE41_OP(roundsd
),
3079 [0x0c] = SSE41_OP(blendps
),
3080 [0x0d] = SSE41_OP(blendpd
),
3081 [0x0e] = SSE41_OP(pblendw
),
3082 [0x0f] = SSSE3_OP(palignr
),
3083 [0x14] = SSE41_SPECIAL
, /* pextrb */
3084 [0x15] = SSE41_SPECIAL
, /* pextrw */
3085 [0x16] = SSE41_SPECIAL
, /* pextrd/pextrq */
3086 [0x17] = SSE41_SPECIAL
, /* extractps */
3087 [0x20] = SSE41_SPECIAL
, /* pinsrb */
3088 [0x21] = SSE41_SPECIAL
, /* insertps */
3089 [0x22] = SSE41_SPECIAL
, /* pinsrd/pinsrq */
3090 [0x40] = SSE41_OP(dpps
),
3091 [0x41] = SSE41_OP(dppd
),
3092 [0x42] = SSE41_OP(mpsadbw
),
3093 [0x44] = PCLMULQDQ_OP(pclmulqdq
),
3094 [0x60] = SSE42_OP(pcmpestrm
),
3095 [0x61] = SSE42_OP(pcmpestri
),
3096 [0x62] = SSE42_OP(pcmpistrm
),
3097 [0x63] = SSE42_OP(pcmpistri
),
3098 [0xdf] = AESNI_OP(aeskeygenassist
),
3101 static void gen_sse(CPUX86State
*env
, DisasContext
*s
, int b
,
3102 target_ulong pc_start
)
3104 int b1
, op1_offset
, op2_offset
, is_xmm
, val
;
3105 int modrm
, mod
, rm
, reg
;
3106 SSEFunc_0_epp sse_fn_epp
;
3107 SSEFunc_0_eppi sse_fn_eppi
;
3108 SSEFunc_0_ppi sse_fn_ppi
;
3109 SSEFunc_0_eppt sse_fn_eppt
;
3113 if (s
->prefix
& PREFIX_DATA
)
3115 else if (s
->prefix
& PREFIX_REPZ
)
3117 else if (s
->prefix
& PREFIX_REPNZ
)
3121 sse_fn_epp
= sse_op_table1
[b
][b1
];
3125 if ((b
<= 0x5f && b
>= 0x10) || b
== 0xc6 || b
== 0xc2) {
3135 /* simple MMX/SSE operation */
3136 if (s
->flags
& HF_TS_MASK
) {
3137 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
3140 if (s
->flags
& HF_EM_MASK
) {
3142 gen_illegal_opcode(s
);
3146 && !(s
->flags
& HF_OSFXSR_MASK
)
3147 && (b
!= 0x38 && b
!= 0x3a)) {
3151 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
)) {
3152 /* If we were fully decoding this we might use illegal_op. */
3156 gen_helper_emms(cpu_env
);
3161 gen_helper_emms(cpu_env
);
3164 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3165 the static cpu state) */
3167 gen_helper_enter_mmx(cpu_env
);
3170 modrm
= x86_ldub_code(env
, s
);
3171 reg
= ((modrm
>> 3) & 7);
3175 mod
= (modrm
>> 6) & 3;
3176 if (sse_fn_epp
== SSE_SPECIAL
) {
3179 case 0x0e7: /* movntq */
3183 gen_lea_modrm(env
, s
, modrm
);
3184 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3186 case 0x1e7: /* movntdq */
3187 case 0x02b: /* movntps */
3188 case 0x12b: /* movntps */
3191 gen_lea_modrm(env
, s
, modrm
);
3192 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3194 case 0x3f0: /* lddqu */
3197 gen_lea_modrm(env
, s
, modrm
);
3198 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3200 case 0x22b: /* movntss */
3201 case 0x32b: /* movntsd */
3204 gen_lea_modrm(env
, s
, modrm
);
3206 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3207 xmm_regs
[reg
].ZMM_Q(0)));
3209 tcg_gen_ld32u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
3210 xmm_regs
[reg
].ZMM_L(0)));
3211 gen_op_st_v(s
, MO_32
, s
->T0
, s
->A0
);
3214 case 0x6e: /* movd mm, ea */
3215 #ifdef TARGET_X86_64
3216 if (s
->dflag
== MO_64
) {
3217 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3218 tcg_gen_st_tl(s
->T0
, cpu_env
,
3219 offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3223 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3224 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3225 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3226 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
3227 gen_helper_movl_mm_T0_mmx(s
->ptr0
, s
->tmp2_i32
);
3230 case 0x16e: /* movd xmm, ea */
3231 #ifdef TARGET_X86_64
3232 if (s
->dflag
== MO_64
) {
3233 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3234 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3235 offsetof(CPUX86State
,xmm_regs
[reg
]));
3236 gen_helper_movq_mm_T0_xmm(s
->ptr0
, s
->T0
);
3240 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3241 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3242 offsetof(CPUX86State
,xmm_regs
[reg
]));
3243 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
3244 gen_helper_movl_mm_T0_xmm(s
->ptr0
, s
->tmp2_i32
);
3247 case 0x6f: /* movq mm, ea */
3249 gen_lea_modrm(env
, s
, modrm
);
3250 gen_ldq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3253 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
,
3254 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3255 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
,
3256 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3259 case 0x010: /* movups */
3260 case 0x110: /* movupd */
3261 case 0x028: /* movaps */
3262 case 0x128: /* movapd */
3263 case 0x16f: /* movdqa xmm, ea */
3264 case 0x26f: /* movdqu xmm, ea */
3266 gen_lea_modrm(env
, s
, modrm
);
3267 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3269 rm
= (modrm
& 7) | REX_B(s
);
3270 gen_op_movo(s
, offsetof(CPUX86State
, xmm_regs
[reg
]),
3271 offsetof(CPUX86State
,xmm_regs
[rm
]));
3274 case 0x210: /* movss xmm, ea */
3276 gen_lea_modrm(env
, s
, modrm
);
3277 gen_op_ld_v(s
, MO_32
, s
->T0
, s
->A0
);
3278 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3279 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(0)));
3280 tcg_gen_movi_tl(s
->T0
, 0);
3281 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3282 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(1)));
3283 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3284 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(2)));
3285 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3286 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(3)));
3288 rm
= (modrm
& 7) | REX_B(s
);
3289 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(0)),
3290 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)));
3293 case 0x310: /* movsd xmm, ea */
3295 gen_lea_modrm(env
, s
, modrm
);
3296 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3297 xmm_regs
[reg
].ZMM_Q(0)));
3298 tcg_gen_movi_tl(s
->T0
, 0);
3299 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3300 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(2)));
3301 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3302 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(3)));
3304 rm
= (modrm
& 7) | REX_B(s
);
3305 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(0)),
3306 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3309 case 0x012: /* movlps */
3310 case 0x112: /* movlpd */
3312 gen_lea_modrm(env
, s
, modrm
);
3313 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3314 xmm_regs
[reg
].ZMM_Q(0)));
3317 rm
= (modrm
& 7) | REX_B(s
);
3318 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(0)),
3319 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(1)));
3322 case 0x212: /* movsldup */
3324 gen_lea_modrm(env
, s
, modrm
);
3325 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3327 rm
= (modrm
& 7) | REX_B(s
);
3328 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(0)),
3329 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)));
3330 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(2)),
3331 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(2)));
3333 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(1)),
3334 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3335 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(3)),
3336 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)));
3338 case 0x312: /* movddup */
3340 gen_lea_modrm(env
, s
, modrm
);
3341 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3342 xmm_regs
[reg
].ZMM_Q(0)));
3344 rm
= (modrm
& 7) | REX_B(s
);
3345 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(0)),
3346 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3348 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(1)),
3349 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3351 case 0x016: /* movhps */
3352 case 0x116: /* movhpd */
3354 gen_lea_modrm(env
, s
, modrm
);
3355 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3356 xmm_regs
[reg
].ZMM_Q(1)));
3359 rm
= (modrm
& 7) | REX_B(s
);
3360 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(1)),
3361 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3364 case 0x216: /* movshdup */
3366 gen_lea_modrm(env
, s
, modrm
);
3367 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3369 rm
= (modrm
& 7) | REX_B(s
);
3370 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(1)),
3371 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(1)));
3372 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(3)),
3373 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(3)));
3375 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(0)),
3376 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)));
3377 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(2)),
3378 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)));
3383 int bit_index
, field_length
;
3385 if (b1
== 1 && reg
!= 0)
3387 field_length
= x86_ldub_code(env
, s
) & 0x3F;
3388 bit_index
= x86_ldub_code(env
, s
) & 0x3F;
3389 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3390 offsetof(CPUX86State
,xmm_regs
[reg
]));
3392 gen_helper_extrq_i(cpu_env
, s
->ptr0
,
3393 tcg_const_i32(bit_index
),
3394 tcg_const_i32(field_length
));
3396 gen_helper_insertq_i(cpu_env
, s
->ptr0
,
3397 tcg_const_i32(bit_index
),
3398 tcg_const_i32(field_length
));
3401 case 0x7e: /* movd ea, mm */
3402 #ifdef TARGET_X86_64
3403 if (s
->dflag
== MO_64
) {
3404 tcg_gen_ld_i64(s
->T0
, cpu_env
,
3405 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3406 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3410 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
3411 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_L(0)));
3412 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3415 case 0x17e: /* movd ea, xmm */
3416 #ifdef TARGET_X86_64
3417 if (s
->dflag
== MO_64
) {
3418 tcg_gen_ld_i64(s
->T0
, cpu_env
,
3419 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3420 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3424 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
3425 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3426 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3429 case 0x27e: /* movq xmm, ea */
3431 gen_lea_modrm(env
, s
, modrm
);
3432 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3433 xmm_regs
[reg
].ZMM_Q(0)));
3435 rm
= (modrm
& 7) | REX_B(s
);
3436 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(0)),
3437 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3439 gen_op_movq_env_0(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(1)));
3441 case 0x7f: /* movq ea, mm */
3443 gen_lea_modrm(env
, s
, modrm
);
3444 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3447 gen_op_movq(s
, offsetof(CPUX86State
, fpregs
[rm
].mmx
),
3448 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3451 case 0x011: /* movups */
3452 case 0x111: /* movupd */
3453 case 0x029: /* movaps */
3454 case 0x129: /* movapd */
3455 case 0x17f: /* movdqa ea, xmm */
3456 case 0x27f: /* movdqu ea, xmm */
3458 gen_lea_modrm(env
, s
, modrm
);
3459 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3461 rm
= (modrm
& 7) | REX_B(s
);
3462 gen_op_movo(s
, offsetof(CPUX86State
, xmm_regs
[rm
]),
3463 offsetof(CPUX86State
,xmm_regs
[reg
]));
3466 case 0x211: /* movss ea, xmm */
3468 gen_lea_modrm(env
, s
, modrm
);
3469 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
3470 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(0)));
3471 gen_op_st_v(s
, MO_32
, s
->T0
, s
->A0
);
3473 rm
= (modrm
& 7) | REX_B(s
);
3474 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[rm
].ZMM_L(0)),
3475 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3478 case 0x311: /* movsd ea, xmm */
3480 gen_lea_modrm(env
, s
, modrm
);
3481 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3482 xmm_regs
[reg
].ZMM_Q(0)));
3484 rm
= (modrm
& 7) | REX_B(s
);
3485 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[rm
].ZMM_Q(0)),
3486 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3489 case 0x013: /* movlps */
3490 case 0x113: /* movlpd */
3492 gen_lea_modrm(env
, s
, modrm
);
3493 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3494 xmm_regs
[reg
].ZMM_Q(0)));
3499 case 0x017: /* movhps */
3500 case 0x117: /* movhpd */
3502 gen_lea_modrm(env
, s
, modrm
);
3503 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3504 xmm_regs
[reg
].ZMM_Q(1)));
3509 case 0x71: /* shift mm, im */
3512 case 0x171: /* shift xmm, im */
3518 val
= x86_ldub_code(env
, s
);
3520 tcg_gen_movi_tl(s
->T0
, val
);
3521 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3522 offsetof(CPUX86State
, xmm_t0
.ZMM_L(0)));
3523 tcg_gen_movi_tl(s
->T0
, 0);
3524 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3525 offsetof(CPUX86State
, xmm_t0
.ZMM_L(1)));
3526 op1_offset
= offsetof(CPUX86State
,xmm_t0
);
3528 tcg_gen_movi_tl(s
->T0
, val
);
3529 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3530 offsetof(CPUX86State
, mmx_t0
.MMX_L(0)));
3531 tcg_gen_movi_tl(s
->T0
, 0);
3532 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3533 offsetof(CPUX86State
, mmx_t0
.MMX_L(1)));
3534 op1_offset
= offsetof(CPUX86State
,mmx_t0
);
3536 sse_fn_epp
= sse_op_table2
[((b
- 1) & 3) * 8 +
3537 (((modrm
>> 3)) & 7)][b1
];
3542 rm
= (modrm
& 7) | REX_B(s
);
3543 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3546 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3548 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op2_offset
);
3549 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op1_offset
);
3550 sse_fn_epp(cpu_env
, s
->ptr0
, s
->ptr1
);
3552 case 0x050: /* movmskps */
3553 rm
= (modrm
& 7) | REX_B(s
);
3554 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3555 offsetof(CPUX86State
,xmm_regs
[rm
]));
3556 gen_helper_movmskps(s
->tmp2_i32
, cpu_env
, s
->ptr0
);
3557 tcg_gen_extu_i32_tl(cpu_regs
[reg
], s
->tmp2_i32
);
3559 case 0x150: /* movmskpd */
3560 rm
= (modrm
& 7) | REX_B(s
);
3561 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3562 offsetof(CPUX86State
,xmm_regs
[rm
]));
3563 gen_helper_movmskpd(s
->tmp2_i32
, cpu_env
, s
->ptr0
);
3564 tcg_gen_extu_i32_tl(cpu_regs
[reg
], s
->tmp2_i32
);
3566 case 0x02a: /* cvtpi2ps */
3567 case 0x12a: /* cvtpi2pd */
3568 gen_helper_enter_mmx(cpu_env
);
3570 gen_lea_modrm(env
, s
, modrm
);
3571 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3572 gen_ldq_env_A0(s
, op2_offset
);
3575 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3577 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3578 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
3579 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
3582 gen_helper_cvtpi2ps(cpu_env
, s
->ptr0
, s
->ptr1
);
3586 gen_helper_cvtpi2pd(cpu_env
, s
->ptr0
, s
->ptr1
);
3590 case 0x22a: /* cvtsi2ss */
3591 case 0x32a: /* cvtsi2sd */
3592 ot
= mo_64_32(s
->dflag
);
3593 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3594 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3595 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
3597 SSEFunc_0_epi sse_fn_epi
= sse_op_table3ai
[(b
>> 8) & 1];
3598 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
3599 sse_fn_epi(cpu_env
, s
->ptr0
, s
->tmp2_i32
);
3601 #ifdef TARGET_X86_64
3602 SSEFunc_0_epl sse_fn_epl
= sse_op_table3aq
[(b
>> 8) & 1];
3603 sse_fn_epl(cpu_env
, s
->ptr0
, s
->T0
);
3609 case 0x02c: /* cvttps2pi */
3610 case 0x12c: /* cvttpd2pi */
3611 case 0x02d: /* cvtps2pi */
3612 case 0x12d: /* cvtpd2pi */
3613 gen_helper_enter_mmx(cpu_env
);
3615 gen_lea_modrm(env
, s
, modrm
);
3616 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3617 gen_ldo_env_A0(s
, op2_offset
);
3619 rm
= (modrm
& 7) | REX_B(s
);
3620 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3622 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
);
3623 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
3624 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
3627 gen_helper_cvttps2pi(cpu_env
, s
->ptr0
, s
->ptr1
);
3630 gen_helper_cvttpd2pi(cpu_env
, s
->ptr0
, s
->ptr1
);
3633 gen_helper_cvtps2pi(cpu_env
, s
->ptr0
, s
->ptr1
);
3636 gen_helper_cvtpd2pi(cpu_env
, s
->ptr0
, s
->ptr1
);
3640 case 0x22c: /* cvttss2si */
3641 case 0x32c: /* cvttsd2si */
3642 case 0x22d: /* cvtss2si */
3643 case 0x32d: /* cvtsd2si */
3644 ot
= mo_64_32(s
->dflag
);
3646 gen_lea_modrm(env
, s
, modrm
);
3648 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.ZMM_Q(0)));
3650 gen_op_ld_v(s
, MO_32
, s
->T0
, s
->A0
);
3651 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3652 offsetof(CPUX86State
, xmm_t0
.ZMM_L(0)));
3654 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3656 rm
= (modrm
& 7) | REX_B(s
);
3657 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3659 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op2_offset
);
3661 SSEFunc_i_ep sse_fn_i_ep
=
3662 sse_op_table3bi
[((b
>> 7) & 2) | (b
& 1)];
3663 sse_fn_i_ep(s
->tmp2_i32
, cpu_env
, s
->ptr0
);
3664 tcg_gen_extu_i32_tl(s
->T0
, s
->tmp2_i32
);
3666 #ifdef TARGET_X86_64
3667 SSEFunc_l_ep sse_fn_l_ep
=
3668 sse_op_table3bq
[((b
>> 7) & 2) | (b
& 1)];
3669 sse_fn_l_ep(s
->T0
, cpu_env
, s
->ptr0
);
3674 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
3676 case 0xc4: /* pinsrw */
3679 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
3680 val
= x86_ldub_code(env
, s
);
3683 tcg_gen_st16_tl(s
->T0
, cpu_env
,
3684 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_W(val
)));
3687 tcg_gen_st16_tl(s
->T0
, cpu_env
,
3688 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_W(val
)));
3691 case 0xc5: /* pextrw */
3695 ot
= mo_64_32(s
->dflag
);
3696 val
= x86_ldub_code(env
, s
);
3699 rm
= (modrm
& 7) | REX_B(s
);
3700 tcg_gen_ld16u_tl(s
->T0
, cpu_env
,
3701 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_W(val
)));
3705 tcg_gen_ld16u_tl(s
->T0
, cpu_env
,
3706 offsetof(CPUX86State
,fpregs
[rm
].mmx
.MMX_W(val
)));
3708 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
3709 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
3711 case 0x1d6: /* movq ea, xmm */
3713 gen_lea_modrm(env
, s
, modrm
);
3714 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3715 xmm_regs
[reg
].ZMM_Q(0)));
3717 rm
= (modrm
& 7) | REX_B(s
);
3718 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[rm
].ZMM_Q(0)),
3719 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3720 gen_op_movq_env_0(s
,
3721 offsetof(CPUX86State
, xmm_regs
[rm
].ZMM_Q(1)));
3724 case 0x2d6: /* movq2dq */
3725 gen_helper_enter_mmx(cpu_env
);
3727 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(0)),
3728 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3729 gen_op_movq_env_0(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(1)));
3731 case 0x3d6: /* movdq2q */
3732 gen_helper_enter_mmx(cpu_env
);
3733 rm
= (modrm
& 7) | REX_B(s
);
3734 gen_op_movq(s
, offsetof(CPUX86State
, fpregs
[reg
& 7].mmx
),
3735 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3737 case 0xd7: /* pmovmskb */
3742 rm
= (modrm
& 7) | REX_B(s
);
3743 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3744 offsetof(CPUX86State
, xmm_regs
[rm
]));
3745 gen_helper_pmovmskb_xmm(s
->tmp2_i32
, cpu_env
, s
->ptr0
);
3748 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3749 offsetof(CPUX86State
, fpregs
[rm
].mmx
));
3750 gen_helper_pmovmskb_mmx(s
->tmp2_i32
, cpu_env
, s
->ptr0
);
3752 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
3753 tcg_gen_extu_i32_tl(cpu_regs
[reg
], s
->tmp2_i32
);
3759 if ((b
& 0xf0) == 0xf0) {
3762 modrm
= x86_ldub_code(env
, s
);
3764 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
3765 mod
= (modrm
>> 6) & 3;
3770 sse_fn_epp
= sse_op_table6
[b
].op
[b1
];
3774 if (!(s
->cpuid_ext_features
& sse_op_table6
[b
].ext_mask
))
3778 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3780 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
3782 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3783 gen_lea_modrm(env
, s
, modrm
);
3785 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3786 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3787 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3788 gen_ldq_env_A0(s
, op2_offset
+
3789 offsetof(ZMMReg
, ZMM_Q(0)));
3791 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3792 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3793 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
3794 s
->mem_index
, MO_LEUL
);
3795 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
, op2_offset
+
3796 offsetof(ZMMReg
, ZMM_L(0)));
3798 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3799 tcg_gen_qemu_ld_tl(s
->tmp0
, s
->A0
,
3800 s
->mem_index
, MO_LEUW
);
3801 tcg_gen_st16_tl(s
->tmp0
, cpu_env
, op2_offset
+
3802 offsetof(ZMMReg
, ZMM_W(0)));
3804 case 0x2a: /* movntqda */
3805 gen_ldo_env_A0(s
, op1_offset
);
3808 gen_ldo_env_A0(s
, op2_offset
);
3812 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
3814 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3816 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3817 gen_lea_modrm(env
, s
, modrm
);
3818 gen_ldq_env_A0(s
, op2_offset
);
3821 if (sse_fn_epp
== SSE_SPECIAL
) {
3825 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
3826 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
3827 sse_fn_epp(cpu_env
, s
->ptr0
, s
->ptr1
);
3830 set_cc_op(s
, CC_OP_EFLAGS
);
3837 /* Various integer extensions at 0f 38 f[0-f]. */
3838 b
= modrm
| (b1
<< 8);
3839 modrm
= x86_ldub_code(env
, s
);
3840 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
3843 case 0x3f0: /* crc32 Gd,Eb */
3844 case 0x3f1: /* crc32 Gd,Ey */
3846 if (!(s
->cpuid_ext_features
& CPUID_EXT_SSE42
)) {
3849 if ((b
& 0xff) == 0xf0) {
3851 } else if (s
->dflag
!= MO_64
) {
3852 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3857 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[reg
]);
3858 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3859 gen_helper_crc32(s
->T0
, s
->tmp2_i32
,
3860 s
->T0
, tcg_const_i32(8 << ot
));
3862 ot
= mo_64_32(s
->dflag
);
3863 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
3866 case 0x1f0: /* crc32 or movbe */
3868 /* For these insns, the f3 prefix is supposed to have priority
3869 over the 66 prefix, but that's not what we implement above
3871 if (s
->prefix
& PREFIX_REPNZ
) {
3875 case 0x0f0: /* movbe Gy,My */
3876 case 0x0f1: /* movbe My,Gy */
3877 if (!(s
->cpuid_ext_features
& CPUID_EXT_MOVBE
)) {
3880 if (s
->dflag
!= MO_64
) {
3881 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3886 gen_lea_modrm(env
, s
, modrm
);
3888 tcg_gen_qemu_ld_tl(s
->T0
, s
->A0
,
3889 s
->mem_index
, ot
| MO_BE
);
3890 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
3892 tcg_gen_qemu_st_tl(cpu_regs
[reg
], s
->A0
,
3893 s
->mem_index
, ot
| MO_BE
);
3897 case 0x0f2: /* andn Gy, By, Ey */
3898 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3899 || !(s
->prefix
& PREFIX_VEX
)
3903 ot
= mo_64_32(s
->dflag
);
3904 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3905 tcg_gen_andc_tl(s
->T0
, s
->T0
, cpu_regs
[s
->vex_v
]);
3906 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
3907 gen_op_update1_cc(s
);
3908 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3911 case 0x0f7: /* bextr Gy, Ey, By */
3912 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3913 || !(s
->prefix
& PREFIX_VEX
)
3917 ot
= mo_64_32(s
->dflag
);
3921 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3922 /* Extract START, and shift the operand.
3923 Shifts larger than operand size get zeros. */
3924 tcg_gen_ext8u_tl(s
->A0
, cpu_regs
[s
->vex_v
]);
3925 tcg_gen_shr_tl(s
->T0
, s
->T0
, s
->A0
);
3927 bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3928 zero
= tcg_const_tl(0);
3929 tcg_gen_movcond_tl(TCG_COND_LEU
, s
->T0
, s
->A0
, bound
,
3931 tcg_temp_free(zero
);
3933 /* Extract the LEN into a mask. Lengths larger than
3934 operand size get all ones. */
3935 tcg_gen_extract_tl(s
->A0
, cpu_regs
[s
->vex_v
], 8, 8);
3936 tcg_gen_movcond_tl(TCG_COND_LEU
, s
->A0
, s
->A0
, bound
,
3938 tcg_temp_free(bound
);
3939 tcg_gen_movi_tl(s
->T1
, 1);
3940 tcg_gen_shl_tl(s
->T1
, s
->T1
, s
->A0
);
3941 tcg_gen_subi_tl(s
->T1
, s
->T1
, 1);
3942 tcg_gen_and_tl(s
->T0
, s
->T0
, s
->T1
);
3944 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
3945 gen_op_update1_cc(s
);
3946 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3950 case 0x0f5: /* bzhi Gy, Ey, By */
3951 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3952 || !(s
->prefix
& PREFIX_VEX
)
3956 ot
= mo_64_32(s
->dflag
);
3957 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3958 tcg_gen_ext8u_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
3960 TCGv bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3961 /* Note that since we're using BMILG (in order to get O
3962 cleared) we need to store the inverse into C. */
3963 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_cc_src
,
3965 tcg_gen_movcond_tl(TCG_COND_GT
, s
->T1
, s
->T1
,
3966 bound
, bound
, s
->T1
);
3967 tcg_temp_free(bound
);
3969 tcg_gen_movi_tl(s
->A0
, -1);
3970 tcg_gen_shl_tl(s
->A0
, s
->A0
, s
->T1
);
3971 tcg_gen_andc_tl(s
->T0
, s
->T0
, s
->A0
);
3972 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
3973 gen_op_update1_cc(s
);
3974 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
3977 case 0x3f6: /* mulx By, Gy, rdx, Ey */
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);
3987 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
3988 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, cpu_regs
[R_EDX
]);
3989 tcg_gen_mulu2_i32(s
->tmp2_i32
, s
->tmp3_i32
,
3990 s
->tmp2_i32
, s
->tmp3_i32
);
3991 tcg_gen_extu_i32_tl(cpu_regs
[s
->vex_v
], s
->tmp2_i32
);
3992 tcg_gen_extu_i32_tl(cpu_regs
[reg
], s
->tmp3_i32
);
3994 #ifdef TARGET_X86_64
3996 tcg_gen_mulu2_i64(s
->T0
, s
->T1
,
3997 s
->T0
, cpu_regs
[R_EDX
]);
3998 tcg_gen_mov_i64(cpu_regs
[s
->vex_v
], s
->T0
);
3999 tcg_gen_mov_i64(cpu_regs
[reg
], s
->T1
);
4005 case 0x3f5: /* pdep Gy, By, Ey */
4006 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4007 || !(s
->prefix
& PREFIX_VEX
)
4011 ot
= mo_64_32(s
->dflag
);
4012 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4013 /* Note that by zero-extending the source operand, we
4014 automatically handle zero-extending the result. */
4016 tcg_gen_mov_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
4018 tcg_gen_ext32u_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
4020 gen_helper_pdep(cpu_regs
[reg
], s
->T1
, s
->T0
);
4023 case 0x2f5: /* pext Gy, By, Ey */
4024 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4025 || !(s
->prefix
& PREFIX_VEX
)
4029 ot
= mo_64_32(s
->dflag
);
4030 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4031 /* Note that by zero-extending the source operand, we
4032 automatically handle zero-extending the result. */
4034 tcg_gen_mov_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
4036 tcg_gen_ext32u_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
4038 gen_helper_pext(cpu_regs
[reg
], s
->T1
, s
->T0
);
4041 case 0x1f6: /* adcx Gy, Ey */
4042 case 0x2f6: /* adox Gy, Ey */
4043 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_ADX
)) {
4046 TCGv carry_in
, carry_out
, zero
;
4049 ot
= mo_64_32(s
->dflag
);
4050 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4052 /* Re-use the carry-out from a previous round. */
4054 carry_out
= (b
== 0x1f6 ? cpu_cc_dst
: cpu_cc_src2
);
4058 carry_in
= cpu_cc_dst
;
4059 end_op
= CC_OP_ADCX
;
4061 end_op
= CC_OP_ADCOX
;
4066 end_op
= CC_OP_ADCOX
;
4068 carry_in
= cpu_cc_src2
;
4069 end_op
= CC_OP_ADOX
;
4073 end_op
= CC_OP_ADCOX
;
4074 carry_in
= carry_out
;
4077 end_op
= (b
== 0x1f6 ? CC_OP_ADCX
: CC_OP_ADOX
);
4080 /* If we can't reuse carry-out, get it out of EFLAGS. */
4082 if (s
->cc_op
!= CC_OP_ADCX
&& s
->cc_op
!= CC_OP_ADOX
) {
4083 gen_compute_eflags(s
);
4086 tcg_gen_extract_tl(carry_in
, cpu_cc_src
,
4087 ctz32(b
== 0x1f6 ? CC_C
: CC_O
), 1);
4091 #ifdef TARGET_X86_64
4093 /* If we know TL is 64-bit, and we want a 32-bit
4094 result, just do everything in 64-bit arithmetic. */
4095 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_regs
[reg
]);
4096 tcg_gen_ext32u_i64(s
->T0
, s
->T0
);
4097 tcg_gen_add_i64(s
->T0
, s
->T0
, cpu_regs
[reg
]);
4098 tcg_gen_add_i64(s
->T0
, s
->T0
, carry_in
);
4099 tcg_gen_ext32u_i64(cpu_regs
[reg
], s
->T0
);
4100 tcg_gen_shri_i64(carry_out
, s
->T0
, 32);
4104 /* Otherwise compute the carry-out in two steps. */
4105 zero
= tcg_const_tl(0);
4106 tcg_gen_add2_tl(s
->T0
, carry_out
,
4109 tcg_gen_add2_tl(cpu_regs
[reg
], carry_out
,
4110 cpu_regs
[reg
], carry_out
,
4112 tcg_temp_free(zero
);
4115 set_cc_op(s
, end_op
);
4119 case 0x1f7: /* shlx Gy, Ey, By */
4120 case 0x2f7: /* sarx Gy, Ey, By */
4121 case 0x3f7: /* shrx Gy, Ey, By */
4122 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4123 || !(s
->prefix
& PREFIX_VEX
)
4127 ot
= mo_64_32(s
->dflag
);
4128 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4130 tcg_gen_andi_tl(s
->T1
, cpu_regs
[s
->vex_v
], 63);
4132 tcg_gen_andi_tl(s
->T1
, cpu_regs
[s
->vex_v
], 31);
4135 tcg_gen_shl_tl(s
->T0
, s
->T0
, s
->T1
);
4136 } else if (b
== 0x2f7) {
4138 tcg_gen_ext32s_tl(s
->T0
, s
->T0
);
4140 tcg_gen_sar_tl(s
->T0
, s
->T0
, s
->T1
);
4143 tcg_gen_ext32u_tl(s
->T0
, s
->T0
);
4145 tcg_gen_shr_tl(s
->T0
, s
->T0
, s
->T1
);
4147 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
4153 case 0x3f3: /* Group 17 */
4154 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
4155 || !(s
->prefix
& PREFIX_VEX
)
4159 ot
= mo_64_32(s
->dflag
);
4160 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4162 tcg_gen_mov_tl(cpu_cc_src
, s
->T0
);
4164 case 1: /* blsr By,Ey */
4165 tcg_gen_subi_tl(s
->T1
, s
->T0
, 1);
4166 tcg_gen_and_tl(s
->T0
, s
->T0
, s
->T1
);
4168 case 2: /* blsmsk By,Ey */
4169 tcg_gen_subi_tl(s
->T1
, s
->T0
, 1);
4170 tcg_gen_xor_tl(s
->T0
, s
->T0
, s
->T1
);
4172 case 3: /* blsi By, Ey */
4173 tcg_gen_neg_tl(s
->T1
, s
->T0
);
4174 tcg_gen_and_tl(s
->T0
, s
->T0
, s
->T1
);
4179 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
4180 gen_op_mov_reg_v(s
, ot
, s
->vex_v
, s
->T0
);
4181 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4192 modrm
= x86_ldub_code(env
, s
);
4194 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
4195 mod
= (modrm
>> 6) & 3;
4200 sse_fn_eppi
= sse_op_table7
[b
].op
[b1
];
4204 if (!(s
->cpuid_ext_features
& sse_op_table7
[b
].ext_mask
))
4209 if (sse_fn_eppi
== SSE_SPECIAL
) {
4210 ot
= mo_64_32(s
->dflag
);
4211 rm
= (modrm
& 7) | REX_B(s
);
4213 gen_lea_modrm(env
, s
, modrm
);
4214 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
4215 val
= x86_ldub_code(env
, s
);
4217 case 0x14: /* pextrb */
4218 tcg_gen_ld8u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
4219 xmm_regs
[reg
].ZMM_B(val
& 15)));
4221 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
4223 tcg_gen_qemu_st_tl(s
->T0
, s
->A0
,
4224 s
->mem_index
, MO_UB
);
4227 case 0x15: /* pextrw */
4228 tcg_gen_ld16u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
4229 xmm_regs
[reg
].ZMM_W(val
& 7)));
4231 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
4233 tcg_gen_qemu_st_tl(s
->T0
, s
->A0
,
4234 s
->mem_index
, MO_LEUW
);
4238 if (ot
== MO_32
) { /* pextrd */
4239 tcg_gen_ld_i32(s
->tmp2_i32
, cpu_env
,
4240 offsetof(CPUX86State
,
4241 xmm_regs
[reg
].ZMM_L(val
& 3)));
4243 tcg_gen_extu_i32_tl(cpu_regs
[rm
], s
->tmp2_i32
);
4245 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
4246 s
->mem_index
, MO_LEUL
);
4248 } else { /* pextrq */
4249 #ifdef TARGET_X86_64
4250 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
,
4251 offsetof(CPUX86State
,
4252 xmm_regs
[reg
].ZMM_Q(val
& 1)));
4254 tcg_gen_mov_i64(cpu_regs
[rm
], s
->tmp1_i64
);
4256 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
,
4257 s
->mem_index
, MO_LEQ
);
4264 case 0x17: /* extractps */
4265 tcg_gen_ld32u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
4266 xmm_regs
[reg
].ZMM_L(val
& 3)));
4268 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
4270 tcg_gen_qemu_st_tl(s
->T0
, s
->A0
,
4271 s
->mem_index
, MO_LEUL
);
4274 case 0x20: /* pinsrb */
4276 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, rm
);
4278 tcg_gen_qemu_ld_tl(s
->T0
, s
->A0
,
4279 s
->mem_index
, MO_UB
);
4281 tcg_gen_st8_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
4282 xmm_regs
[reg
].ZMM_B(val
& 15)));
4284 case 0x21: /* insertps */
4286 tcg_gen_ld_i32(s
->tmp2_i32
, cpu_env
,
4287 offsetof(CPUX86State
,xmm_regs
[rm
]
4288 .ZMM_L((val
>> 6) & 3)));
4290 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
4291 s
->mem_index
, MO_LEUL
);
4293 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
,
4294 offsetof(CPUX86State
,xmm_regs
[reg
]
4295 .ZMM_L((val
>> 4) & 3)));
4297 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4298 cpu_env
, offsetof(CPUX86State
,
4299 xmm_regs
[reg
].ZMM_L(0)));
4301 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4302 cpu_env
, offsetof(CPUX86State
,
4303 xmm_regs
[reg
].ZMM_L(1)));
4305 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4306 cpu_env
, offsetof(CPUX86State
,
4307 xmm_regs
[reg
].ZMM_L(2)));
4309 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4310 cpu_env
, offsetof(CPUX86State
,
4311 xmm_regs
[reg
].ZMM_L(3)));
4314 if (ot
== MO_32
) { /* pinsrd */
4316 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[rm
]);
4318 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
4319 s
->mem_index
, MO_LEUL
);
4321 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
,
4322 offsetof(CPUX86State
,
4323 xmm_regs
[reg
].ZMM_L(val
& 3)));
4324 } else { /* pinsrq */
4325 #ifdef TARGET_X86_64
4327 gen_op_mov_v_reg(s
, ot
, s
->tmp1_i64
, rm
);
4329 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
,
4330 s
->mem_index
, MO_LEQ
);
4332 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
,
4333 offsetof(CPUX86State
,
4334 xmm_regs
[reg
].ZMM_Q(val
& 1)));
4345 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4347 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
4349 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4350 gen_lea_modrm(env
, s
, modrm
);
4351 gen_ldo_env_A0(s
, op2_offset
);
4354 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4356 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4358 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4359 gen_lea_modrm(env
, s
, modrm
);
4360 gen_ldq_env_A0(s
, op2_offset
);
4363 val
= x86_ldub_code(env
, s
);
4365 if ((b
& 0xfc) == 0x60) { /* pcmpXstrX */
4366 set_cc_op(s
, CC_OP_EFLAGS
);
4368 if (s
->dflag
== MO_64
) {
4369 /* The helper must use entire 64-bit gp registers */
4374 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
4375 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
4376 sse_fn_eppi(cpu_env
, s
->ptr0
, s
->ptr1
, tcg_const_i32(val
));
4380 /* Various integer extensions at 0f 3a f[0-f]. */
4381 b
= modrm
| (b1
<< 8);
4382 modrm
= x86_ldub_code(env
, s
);
4383 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
4386 case 0x3f0: /* rorx Gy,Ey, Ib */
4387 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4388 || !(s
->prefix
& PREFIX_VEX
)
4392 ot
= mo_64_32(s
->dflag
);
4393 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4394 b
= x86_ldub_code(env
, s
);
4396 tcg_gen_rotri_tl(s
->T0
, s
->T0
, b
& 63);
4398 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
4399 tcg_gen_rotri_i32(s
->tmp2_i32
, s
->tmp2_i32
, b
& 31);
4400 tcg_gen_extu_i32_tl(s
->T0
, s
->tmp2_i32
);
4402 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
4412 gen_unknown_opcode(env
, s
);
4416 /* generic MMX or SSE operation */
4418 case 0x70: /* pshufx insn */
4419 case 0xc6: /* pshufx insn */
4420 case 0xc2: /* compare insns */
4427 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4431 gen_lea_modrm(env
, s
, modrm
);
4432 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4438 /* Most sse scalar operations. */
4441 } else if (b1
== 3) {
4446 case 0x2e: /* ucomis[sd] */
4447 case 0x2f: /* comis[sd] */
4459 gen_op_ld_v(s
, MO_32
, s
->T0
, s
->A0
);
4460 tcg_gen_st32_tl(s
->T0
, cpu_env
,
4461 offsetof(CPUX86State
,xmm_t0
.ZMM_L(0)));
4465 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.ZMM_D(0)));
4468 /* 128 bit access */
4469 gen_ldo_env_A0(s
, op2_offset
);
4473 rm
= (modrm
& 7) | REX_B(s
);
4474 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
4477 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4479 gen_lea_modrm(env
, s
, modrm
);
4480 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4481 gen_ldq_env_A0(s
, op2_offset
);
4484 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4488 case 0x0f: /* 3DNow! data insns */
4489 val
= x86_ldub_code(env
, s
);
4490 sse_fn_epp
= sse_op_table5
[val
];
4494 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
)) {
4497 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
4498 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
4499 sse_fn_epp(cpu_env
, s
->ptr0
, s
->ptr1
);
4501 case 0x70: /* pshufx insn */
4502 case 0xc6: /* pshufx insn */
4503 val
= x86_ldub_code(env
, s
);
4504 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
4505 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
4506 /* XXX: introduce a new table? */
4507 sse_fn_ppi
= (SSEFunc_0_ppi
)sse_fn_epp
;
4508 sse_fn_ppi(s
->ptr0
, s
->ptr1
, tcg_const_i32(val
));
4512 val
= x86_ldub_code(env
, s
);
4515 sse_fn_epp
= sse_op_table4
[val
][b1
];
4517 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
4518 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
4519 sse_fn_epp(cpu_env
, s
->ptr0
, s
->ptr1
);
4522 /* maskmov : we must prepare A0 */
4525 tcg_gen_mov_tl(s
->A0
, cpu_regs
[R_EDI
]);
4526 gen_extu(s
->aflag
, s
->A0
);
4527 gen_add_A0_ds_seg(s
);
4529 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
4530 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
4531 /* XXX: introduce a new table? */
4532 sse_fn_eppt
= (SSEFunc_0_eppt
)sse_fn_epp
;
4533 sse_fn_eppt(cpu_env
, s
->ptr0
, s
->ptr1
, s
->A0
);
4536 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
4537 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
4538 sse_fn_epp(cpu_env
, s
->ptr0
, s
->ptr1
);
4541 if (b
== 0x2e || b
== 0x2f) {
4542 set_cc_op(s
, CC_OP_EFLAGS
);
4547 /* convert one instruction. s->base.is_jmp is set if the translation must
4548 be stopped. Return the next pc value */
4549 static target_ulong
disas_insn(DisasContext
*s
, CPUState
*cpu
)
4551 CPUX86State
*env
= cpu
->env_ptr
;
4554 MemOp ot
, aflag
, dflag
;
4555 int modrm
, reg
, rm
, mod
, op
, opreg
, val
;
4556 target_ulong next_eip
, tval
;
4557 target_ulong pc_start
= s
->base
.pc_next
;
4559 s
->pc_start
= s
->pc
= pc_start
;
4561 #ifdef TARGET_X86_64
4567 s
->rip_offset
= 0; /* for relative ip address */
4570 if (sigsetjmp(s
->jmpbuf
, 0) != 0) {
4571 gen_exception_gpf(s
);
4578 b
= x86_ldub_code(env
, s
);
4579 /* Collect prefixes. */
4582 prefixes
|= PREFIX_REPZ
;
4585 prefixes
|= PREFIX_REPNZ
;
4588 prefixes
|= PREFIX_LOCK
;
4609 prefixes
|= PREFIX_DATA
;
4612 prefixes
|= PREFIX_ADR
;
4614 #ifdef TARGET_X86_64
4618 prefixes
|= PREFIX_REX
;
4619 s
->rex_w
= (b
>> 3) & 1;
4620 s
->rex_r
= (b
& 0x4) << 1;
4621 s
->rex_x
= (b
& 0x2) << 2;
4622 s
->rex_b
= (b
& 0x1) << 3;
4627 case 0xc5: /* 2-byte VEX */
4628 case 0xc4: /* 3-byte VEX */
4629 /* VEX prefixes cannot be used except in 32-bit mode.
4630 Otherwise the instruction is LES or LDS. */
4631 if (CODE32(s
) && !VM86(s
)) {
4632 static const int pp_prefix
[4] = {
4633 0, PREFIX_DATA
, PREFIX_REPZ
, PREFIX_REPNZ
4635 int vex3
, vex2
= x86_ldub_code(env
, s
);
4637 if (!CODE64(s
) && (vex2
& 0xc0) != 0xc0) {
4638 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4639 otherwise the instruction is LES or LDS. */
4640 s
->pc
--; /* rewind the advance_pc() x86_ldub_code() did */
4644 /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
4645 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
4646 | PREFIX_LOCK
| PREFIX_DATA
| PREFIX_REX
)) {
4649 #ifdef TARGET_X86_64
4650 s
->rex_r
= (~vex2
>> 4) & 8;
4653 /* 2-byte VEX prefix: RVVVVlpp, implied 0f leading opcode byte */
4655 b
= x86_ldub_code(env
, s
) | 0x100;
4657 /* 3-byte VEX prefix: RXBmmmmm wVVVVlpp */
4658 vex3
= x86_ldub_code(env
, s
);
4659 #ifdef TARGET_X86_64
4660 s
->rex_x
= (~vex2
>> 3) & 8;
4661 s
->rex_b
= (~vex2
>> 2) & 8;
4662 s
->rex_w
= (vex3
>> 7) & 1;
4664 switch (vex2
& 0x1f) {
4665 case 0x01: /* Implied 0f leading opcode bytes. */
4666 b
= x86_ldub_code(env
, s
) | 0x100;
4668 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4671 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4674 default: /* Reserved for future use. */
4678 s
->vex_v
= (~vex3
>> 3) & 0xf;
4679 s
->vex_l
= (vex3
>> 2) & 1;
4680 prefixes
|= pp_prefix
[vex3
& 3] | PREFIX_VEX
;
4685 /* Post-process prefixes. */
4687 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit
4688 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4689 over 0x66 if both are present. */
4690 dflag
= (REX_W(s
) ? MO_64
: prefixes
& PREFIX_DATA
? MO_16
: MO_32
);
4691 /* In 64-bit mode, 0x67 selects 32-bit addressing. */
4692 aflag
= (prefixes
& PREFIX_ADR
? MO_32
: MO_64
);
4694 /* In 16/32-bit mode, 0x66 selects the opposite data size. */
4695 if (CODE32(s
) ^ ((prefixes
& PREFIX_DATA
) != 0)) {
4700 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */
4701 if (CODE32(s
) ^ ((prefixes
& PREFIX_ADR
) != 0)) {
4708 s
->prefix
= prefixes
;
4712 /* now check op code */
4716 /**************************/
4717 /* extended op code */
4718 b
= x86_ldub_code(env
, s
) | 0x100;
4721 /**************************/
4736 ot
= mo_b_d(b
, dflag
);
4739 case 0: /* OP Ev, Gv */
4740 modrm
= x86_ldub_code(env
, s
);
4741 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
4742 mod
= (modrm
>> 6) & 3;
4743 rm
= (modrm
& 7) | REX_B(s
);
4745 gen_lea_modrm(env
, s
, modrm
);
4747 } else if (op
== OP_XORL
&& rm
== reg
) {
4749 /* xor reg, reg optimisation */
4750 set_cc_op(s
, CC_OP_CLR
);
4751 tcg_gen_movi_tl(s
->T0
, 0);
4752 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
4757 gen_op_mov_v_reg(s
, ot
, s
->T1
, reg
);
4758 gen_op(s
, op
, ot
, opreg
);
4760 case 1: /* OP Gv, Ev */
4761 modrm
= x86_ldub_code(env
, s
);
4762 mod
= (modrm
>> 6) & 3;
4763 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
4764 rm
= (modrm
& 7) | REX_B(s
);
4766 gen_lea_modrm(env
, s
, modrm
);
4767 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
4768 } else if (op
== OP_XORL
&& rm
== reg
) {
4771 gen_op_mov_v_reg(s
, ot
, s
->T1
, rm
);
4773 gen_op(s
, op
, ot
, reg
);
4775 case 2: /* OP A, Iv */
4776 val
= insn_get(env
, s
, ot
);
4777 tcg_gen_movi_tl(s
->T1
, val
);
4778 gen_op(s
, op
, ot
, OR_EAX
);
4788 case 0x80: /* GRP1 */
4794 ot
= mo_b_d(b
, dflag
);
4796 modrm
= x86_ldub_code(env
, s
);
4797 mod
= (modrm
>> 6) & 3;
4798 rm
= (modrm
& 7) | REX_B(s
);
4799 op
= (modrm
>> 3) & 7;
4805 s
->rip_offset
= insn_const_size(ot
);
4806 gen_lea_modrm(env
, s
, modrm
);
4817 val
= insn_get(env
, s
, ot
);
4820 val
= (int8_t)insn_get(env
, s
, MO_8
);
4823 tcg_gen_movi_tl(s
->T1
, val
);
4824 gen_op(s
, op
, ot
, opreg
);
4828 /**************************/
4829 /* inc, dec, and other misc arith */
4830 case 0x40 ... 0x47: /* inc Gv */
4832 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), 1);
4834 case 0x48 ... 0x4f: /* dec Gv */
4836 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), -1);
4838 case 0xf6: /* GRP3 */
4840 ot
= mo_b_d(b
, dflag
);
4842 modrm
= x86_ldub_code(env
, s
);
4843 mod
= (modrm
>> 6) & 3;
4844 rm
= (modrm
& 7) | REX_B(s
);
4845 op
= (modrm
>> 3) & 7;
4848 s
->rip_offset
= insn_const_size(ot
);
4850 gen_lea_modrm(env
, s
, modrm
);
4851 /* For those below that handle locked memory, don't load here. */
4852 if (!(s
->prefix
& PREFIX_LOCK
)
4854 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
4857 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
4862 val
= insn_get(env
, s
, ot
);
4863 tcg_gen_movi_tl(s
->T1
, val
);
4864 gen_op_testl_T0_T1_cc(s
);
4865 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4868 if (s
->prefix
& PREFIX_LOCK
) {
4872 tcg_gen_movi_tl(s
->T0
, ~0);
4873 tcg_gen_atomic_xor_fetch_tl(s
->T0
, s
->A0
, s
->T0
,
4874 s
->mem_index
, ot
| MO_LE
);
4876 tcg_gen_not_tl(s
->T0
, s
->T0
);
4878 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
4880 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
4885 if (s
->prefix
& PREFIX_LOCK
) {
4887 TCGv a0
, t0
, t1
, t2
;
4892 a0
= tcg_temp_local_new();
4893 t0
= tcg_temp_local_new();
4894 label1
= gen_new_label();
4896 tcg_gen_mov_tl(a0
, s
->A0
);
4897 tcg_gen_mov_tl(t0
, s
->T0
);
4899 gen_set_label(label1
);
4900 t1
= tcg_temp_new();
4901 t2
= tcg_temp_new();
4902 tcg_gen_mov_tl(t2
, t0
);
4903 tcg_gen_neg_tl(t1
, t0
);
4904 tcg_gen_atomic_cmpxchg_tl(t0
, a0
, t0
, t1
,
4905 s
->mem_index
, ot
| MO_LE
);
4907 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t2
, label1
);
4911 tcg_gen_mov_tl(s
->T0
, t0
);
4914 tcg_gen_neg_tl(s
->T0
, s
->T0
);
4916 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
4918 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
4921 gen_op_update_neg_cc(s
);
4922 set_cc_op(s
, CC_OP_SUBB
+ ot
);
4927 gen_op_mov_v_reg(s
, MO_8
, s
->T1
, R_EAX
);
4928 tcg_gen_ext8u_tl(s
->T0
, s
->T0
);
4929 tcg_gen_ext8u_tl(s
->T1
, s
->T1
);
4930 /* XXX: use 32 bit mul which could be faster */
4931 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
4932 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
4933 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
4934 tcg_gen_andi_tl(cpu_cc_src
, s
->T0
, 0xff00);
4935 set_cc_op(s
, CC_OP_MULB
);
4938 gen_op_mov_v_reg(s
, MO_16
, s
->T1
, R_EAX
);
4939 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
4940 tcg_gen_ext16u_tl(s
->T1
, s
->T1
);
4941 /* XXX: use 32 bit mul which could be faster */
4942 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
4943 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
4944 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
4945 tcg_gen_shri_tl(s
->T0
, s
->T0
, 16);
4946 gen_op_mov_reg_v(s
, MO_16
, R_EDX
, s
->T0
);
4947 tcg_gen_mov_tl(cpu_cc_src
, s
->T0
);
4948 set_cc_op(s
, CC_OP_MULW
);
4952 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
4953 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, cpu_regs
[R_EAX
]);
4954 tcg_gen_mulu2_i32(s
->tmp2_i32
, s
->tmp3_i32
,
4955 s
->tmp2_i32
, s
->tmp3_i32
);
4956 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], s
->tmp2_i32
);
4957 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], s
->tmp3_i32
);
4958 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4959 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4960 set_cc_op(s
, CC_OP_MULL
);
4962 #ifdef TARGET_X86_64
4964 tcg_gen_mulu2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4965 s
->T0
, cpu_regs
[R_EAX
]);
4966 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4967 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4968 set_cc_op(s
, CC_OP_MULQ
);
4976 gen_op_mov_v_reg(s
, MO_8
, s
->T1
, R_EAX
);
4977 tcg_gen_ext8s_tl(s
->T0
, s
->T0
);
4978 tcg_gen_ext8s_tl(s
->T1
, s
->T1
);
4979 /* XXX: use 32 bit mul which could be faster */
4980 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
4981 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
4982 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
4983 tcg_gen_ext8s_tl(s
->tmp0
, s
->T0
);
4984 tcg_gen_sub_tl(cpu_cc_src
, s
->T0
, s
->tmp0
);
4985 set_cc_op(s
, CC_OP_MULB
);
4988 gen_op_mov_v_reg(s
, MO_16
, s
->T1
, R_EAX
);
4989 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
4990 tcg_gen_ext16s_tl(s
->T1
, s
->T1
);
4991 /* XXX: use 32 bit mul which could be faster */
4992 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
4993 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
4994 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
4995 tcg_gen_ext16s_tl(s
->tmp0
, s
->T0
);
4996 tcg_gen_sub_tl(cpu_cc_src
, s
->T0
, s
->tmp0
);
4997 tcg_gen_shri_tl(s
->T0
, s
->T0
, 16);
4998 gen_op_mov_reg_v(s
, MO_16
, R_EDX
, s
->T0
);
4999 set_cc_op(s
, CC_OP_MULW
);
5003 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
5004 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, cpu_regs
[R_EAX
]);
5005 tcg_gen_muls2_i32(s
->tmp2_i32
, s
->tmp3_i32
,
5006 s
->tmp2_i32
, s
->tmp3_i32
);
5007 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], s
->tmp2_i32
);
5008 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], s
->tmp3_i32
);
5009 tcg_gen_sari_i32(s
->tmp2_i32
, s
->tmp2_i32
, 31);
5010 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
5011 tcg_gen_sub_i32(s
->tmp2_i32
, s
->tmp2_i32
, s
->tmp3_i32
);
5012 tcg_gen_extu_i32_tl(cpu_cc_src
, s
->tmp2_i32
);
5013 set_cc_op(s
, CC_OP_MULL
);
5015 #ifdef TARGET_X86_64
5017 tcg_gen_muls2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
5018 s
->T0
, cpu_regs
[R_EAX
]);
5019 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
5020 tcg_gen_sari_tl(cpu_cc_src
, cpu_regs
[R_EAX
], 63);
5021 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_regs
[R_EDX
]);
5022 set_cc_op(s
, CC_OP_MULQ
);
5030 gen_helper_divb_AL(cpu_env
, s
->T0
);
5033 gen_helper_divw_AX(cpu_env
, s
->T0
);
5037 gen_helper_divl_EAX(cpu_env
, s
->T0
);
5039 #ifdef TARGET_X86_64
5041 gen_helper_divq_EAX(cpu_env
, s
->T0
);
5049 gen_helper_idivb_AL(cpu_env
, s
->T0
);
5052 gen_helper_idivw_AX(cpu_env
, s
->T0
);
5056 gen_helper_idivl_EAX(cpu_env
, s
->T0
);
5058 #ifdef TARGET_X86_64
5060 gen_helper_idivq_EAX(cpu_env
, s
->T0
);
5070 case 0xfe: /* GRP4 */
5071 case 0xff: /* GRP5 */
5072 ot
= mo_b_d(b
, dflag
);
5074 modrm
= x86_ldub_code(env
, s
);
5075 mod
= (modrm
>> 6) & 3;
5076 rm
= (modrm
& 7) | REX_B(s
);
5077 op
= (modrm
>> 3) & 7;
5078 if (op
>= 2 && b
== 0xfe) {
5082 if (op
== 2 || op
== 4) {
5083 /* operand size for jumps is 64 bit */
5085 } else if (op
== 3 || op
== 5) {
5086 ot
= dflag
!= MO_16
? MO_32
+ REX_W(s
) : MO_16
;
5087 } else if (op
== 6) {
5088 /* default push size is 64 bit */
5089 ot
= mo_pushpop(s
, dflag
);
5093 gen_lea_modrm(env
, s
, modrm
);
5094 if (op
>= 2 && op
!= 3 && op
!= 5)
5095 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
5097 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
5101 case 0: /* inc Ev */
5106 gen_inc(s
, ot
, opreg
, 1);
5108 case 1: /* dec Ev */
5113 gen_inc(s
, ot
, opreg
, -1);
5115 case 2: /* call Ev */
5116 /* XXX: optimize if memory (no 'and' is necessary) */
5117 if (dflag
== MO_16
) {
5118 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
5120 next_eip
= s
->pc
- s
->cs_base
;
5121 tcg_gen_movi_tl(s
->T1
, next_eip
);
5122 gen_push_v(s
, s
->T1
);
5123 gen_op_jmp_v(s
->T0
);
5127 case 3: /* lcall Ev */
5131 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
5132 gen_add_A0_im(s
, 1 << ot
);
5133 gen_op_ld_v(s
, MO_16
, s
->T0
, s
->A0
);
5135 if (PE(s
) && !VM86(s
)) {
5136 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
5137 gen_helper_lcall_protected(cpu_env
, s
->tmp2_i32
, s
->T1
,
5138 tcg_const_i32(dflag
- 1),
5139 tcg_const_tl(s
->pc
- s
->cs_base
));
5141 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
5142 gen_helper_lcall_real(cpu_env
, s
->tmp2_i32
, s
->T1
,
5143 tcg_const_i32(dflag
- 1),
5144 tcg_const_i32(s
->pc
- s
->cs_base
));
5146 tcg_gen_ld_tl(s
->tmp4
, cpu_env
, offsetof(CPUX86State
, eip
));
5149 case 4: /* jmp Ev */
5150 if (dflag
== MO_16
) {
5151 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
5153 gen_op_jmp_v(s
->T0
);
5157 case 5: /* ljmp Ev */
5161 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
5162 gen_add_A0_im(s
, 1 << ot
);
5163 gen_op_ld_v(s
, MO_16
, s
->T0
, s
->A0
);
5165 if (PE(s
) && !VM86(s
)) {
5166 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
5167 gen_helper_ljmp_protected(cpu_env
, s
->tmp2_i32
, s
->T1
,
5168 tcg_const_tl(s
->pc
- s
->cs_base
));
5170 gen_op_movl_seg_T0_vm(s
, R_CS
);
5171 gen_op_jmp_v(s
->T1
);
5173 tcg_gen_ld_tl(s
->tmp4
, cpu_env
, offsetof(CPUX86State
, eip
));
5176 case 6: /* push Ev */
5177 gen_push_v(s
, s
->T0
);
5184 case 0x84: /* test Ev, Gv */
5186 ot
= mo_b_d(b
, dflag
);
5188 modrm
= x86_ldub_code(env
, s
);
5189 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5191 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5192 gen_op_mov_v_reg(s
, ot
, s
->T1
, reg
);
5193 gen_op_testl_T0_T1_cc(s
);
5194 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5197 case 0xa8: /* test eAX, Iv */
5199 ot
= mo_b_d(b
, dflag
);
5200 val
= insn_get(env
, s
, ot
);
5202 gen_op_mov_v_reg(s
, ot
, s
->T0
, OR_EAX
);
5203 tcg_gen_movi_tl(s
->T1
, val
);
5204 gen_op_testl_T0_T1_cc(s
);
5205 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5208 case 0x98: /* CWDE/CBW */
5210 #ifdef TARGET_X86_64
5212 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, R_EAX
);
5213 tcg_gen_ext32s_tl(s
->T0
, s
->T0
);
5214 gen_op_mov_reg_v(s
, MO_64
, R_EAX
, s
->T0
);
5218 gen_op_mov_v_reg(s
, MO_16
, s
->T0
, R_EAX
);
5219 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5220 gen_op_mov_reg_v(s
, MO_32
, R_EAX
, s
->T0
);
5223 gen_op_mov_v_reg(s
, MO_8
, s
->T0
, R_EAX
);
5224 tcg_gen_ext8s_tl(s
->T0
, s
->T0
);
5225 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
5231 case 0x99: /* CDQ/CWD */
5233 #ifdef TARGET_X86_64
5235 gen_op_mov_v_reg(s
, MO_64
, s
->T0
, R_EAX
);
5236 tcg_gen_sari_tl(s
->T0
, s
->T0
, 63);
5237 gen_op_mov_reg_v(s
, MO_64
, R_EDX
, s
->T0
);
5241 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, R_EAX
);
5242 tcg_gen_ext32s_tl(s
->T0
, s
->T0
);
5243 tcg_gen_sari_tl(s
->T0
, s
->T0
, 31);
5244 gen_op_mov_reg_v(s
, MO_32
, R_EDX
, s
->T0
);
5247 gen_op_mov_v_reg(s
, MO_16
, s
->T0
, R_EAX
);
5248 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5249 tcg_gen_sari_tl(s
->T0
, s
->T0
, 15);
5250 gen_op_mov_reg_v(s
, MO_16
, R_EDX
, s
->T0
);
5256 case 0x1af: /* imul Gv, Ev */
5257 case 0x69: /* imul Gv, Ev, I */
5260 modrm
= x86_ldub_code(env
, s
);
5261 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5263 s
->rip_offset
= insn_const_size(ot
);
5266 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5268 val
= insn_get(env
, s
, ot
);
5269 tcg_gen_movi_tl(s
->T1
, val
);
5270 } else if (b
== 0x6b) {
5271 val
= (int8_t)insn_get(env
, s
, MO_8
);
5272 tcg_gen_movi_tl(s
->T1
, val
);
5274 gen_op_mov_v_reg(s
, ot
, s
->T1
, reg
);
5277 #ifdef TARGET_X86_64
5279 tcg_gen_muls2_i64(cpu_regs
[reg
], s
->T1
, s
->T0
, s
->T1
);
5280 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5281 tcg_gen_sari_tl(cpu_cc_src
, cpu_cc_dst
, 63);
5282 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, s
->T1
);
5286 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
5287 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, s
->T1
);
5288 tcg_gen_muls2_i32(s
->tmp2_i32
, s
->tmp3_i32
,
5289 s
->tmp2_i32
, s
->tmp3_i32
);
5290 tcg_gen_extu_i32_tl(cpu_regs
[reg
], s
->tmp2_i32
);
5291 tcg_gen_sari_i32(s
->tmp2_i32
, s
->tmp2_i32
, 31);
5292 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5293 tcg_gen_sub_i32(s
->tmp2_i32
, s
->tmp2_i32
, s
->tmp3_i32
);
5294 tcg_gen_extu_i32_tl(cpu_cc_src
, s
->tmp2_i32
);
5297 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5298 tcg_gen_ext16s_tl(s
->T1
, s
->T1
);
5299 /* XXX: use 32 bit mul which could be faster */
5300 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
5301 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
5302 tcg_gen_ext16s_tl(s
->tmp0
, s
->T0
);
5303 tcg_gen_sub_tl(cpu_cc_src
, s
->T0
, s
->tmp0
);
5304 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
5307 set_cc_op(s
, CC_OP_MULB
+ ot
);
5310 case 0x1c1: /* xadd Ev, Gv */
5311 ot
= mo_b_d(b
, dflag
);
5312 modrm
= x86_ldub_code(env
, s
);
5313 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5314 mod
= (modrm
>> 6) & 3;
5315 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
5317 rm
= (modrm
& 7) | REX_B(s
);
5318 gen_op_mov_v_reg(s
, ot
, s
->T1
, rm
);
5319 tcg_gen_add_tl(s
->T0
, s
->T0
, s
->T1
);
5320 gen_op_mov_reg_v(s
, ot
, reg
, s
->T1
);
5321 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
5323 gen_lea_modrm(env
, s
, modrm
);
5324 if (s
->prefix
& PREFIX_LOCK
) {
5325 tcg_gen_atomic_fetch_add_tl(s
->T1
, s
->A0
, s
->T0
,
5326 s
->mem_index
, ot
| MO_LE
);
5327 tcg_gen_add_tl(s
->T0
, s
->T0
, s
->T1
);
5329 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
5330 tcg_gen_add_tl(s
->T0
, s
->T0
, s
->T1
);
5331 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
5333 gen_op_mov_reg_v(s
, ot
, reg
, s
->T1
);
5335 gen_op_update2_cc(s
);
5336 set_cc_op(s
, CC_OP_ADDB
+ ot
);
5339 case 0x1b1: /* cmpxchg Ev, Gv */
5341 TCGv oldv
, newv
, cmpv
;
5343 ot
= mo_b_d(b
, dflag
);
5344 modrm
= x86_ldub_code(env
, s
);
5345 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5346 mod
= (modrm
>> 6) & 3;
5347 oldv
= tcg_temp_new();
5348 newv
= tcg_temp_new();
5349 cmpv
= tcg_temp_new();
5350 gen_op_mov_v_reg(s
, ot
, newv
, reg
);
5351 tcg_gen_mov_tl(cmpv
, cpu_regs
[R_EAX
]);
5353 if (s
->prefix
& PREFIX_LOCK
) {
5357 gen_lea_modrm(env
, s
, modrm
);
5358 tcg_gen_atomic_cmpxchg_tl(oldv
, s
->A0
, cmpv
, newv
,
5359 s
->mem_index
, ot
| MO_LE
);
5360 gen_op_mov_reg_v(s
, ot
, R_EAX
, oldv
);
5363 rm
= (modrm
& 7) | REX_B(s
);
5364 gen_op_mov_v_reg(s
, ot
, oldv
, rm
);
5366 gen_lea_modrm(env
, s
, modrm
);
5367 gen_op_ld_v(s
, ot
, oldv
, s
->A0
);
5368 rm
= 0; /* avoid warning */
5372 /* store value = (old == cmp ? new : old); */
5373 tcg_gen_movcond_tl(TCG_COND_EQ
, newv
, oldv
, cmpv
, newv
, oldv
);
5375 gen_op_mov_reg_v(s
, ot
, R_EAX
, oldv
);
5376 gen_op_mov_reg_v(s
, ot
, rm
, newv
);
5378 /* Perform an unconditional store cycle like physical cpu;
5379 must be before changing accumulator to ensure
5380 idempotency if the store faults and the instruction
5382 gen_op_st_v(s
, ot
, newv
, s
->A0
);
5383 gen_op_mov_reg_v(s
, ot
, R_EAX
, oldv
);
5386 tcg_gen_mov_tl(cpu_cc_src
, oldv
);
5387 tcg_gen_mov_tl(s
->cc_srcT
, cmpv
);
5388 tcg_gen_sub_tl(cpu_cc_dst
, cmpv
, oldv
);
5389 set_cc_op(s
, CC_OP_SUBB
+ ot
);
5390 tcg_temp_free(oldv
);
5391 tcg_temp_free(newv
);
5392 tcg_temp_free(cmpv
);
5395 case 0x1c7: /* cmpxchg8b */
5396 modrm
= x86_ldub_code(env
, s
);
5397 mod
= (modrm
>> 6) & 3;
5398 switch ((modrm
>> 3) & 7) {
5399 case 1: /* CMPXCHG8, CMPXCHG16 */
5403 #ifdef TARGET_X86_64
5404 if (dflag
== MO_64
) {
5405 if (!(s
->cpuid_ext_features
& CPUID_EXT_CX16
)) {
5408 gen_lea_modrm(env
, s
, modrm
);
5409 if ((s
->prefix
& PREFIX_LOCK
) &&
5410 (tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
5411 gen_helper_cmpxchg16b(cpu_env
, s
->A0
);
5413 gen_helper_cmpxchg16b_unlocked(cpu_env
, s
->A0
);
5415 set_cc_op(s
, CC_OP_EFLAGS
);
5419 if (!(s
->cpuid_features
& CPUID_CX8
)) {
5422 gen_lea_modrm(env
, s
, modrm
);
5423 if ((s
->prefix
& PREFIX_LOCK
) &&
5424 (tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
5425 gen_helper_cmpxchg8b(cpu_env
, s
->A0
);
5427 gen_helper_cmpxchg8b_unlocked(cpu_env
, s
->A0
);
5429 set_cc_op(s
, CC_OP_EFLAGS
);
5432 case 7: /* RDSEED */
5433 case 6: /* RDRAND */
5435 (s
->prefix
& (PREFIX_LOCK
| PREFIX_REPZ
| PREFIX_REPNZ
)) ||
5436 !(s
->cpuid_ext_features
& CPUID_EXT_RDRAND
)) {
5439 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
5442 gen_helper_rdrand(s
->T0
, cpu_env
);
5443 rm
= (modrm
& 7) | REX_B(s
);
5444 gen_op_mov_reg_v(s
, dflag
, rm
, s
->T0
);
5445 set_cc_op(s
, CC_OP_EFLAGS
);
5446 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
5447 gen_jmp(s
, s
->pc
- s
->cs_base
);
5456 /**************************/
5458 case 0x50 ... 0x57: /* push */
5459 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, (b
& 7) | REX_B(s
));
5460 gen_push_v(s
, s
->T0
);
5462 case 0x58 ... 0x5f: /* pop */
5464 /* NOTE: order is important for pop %sp */
5465 gen_pop_update(s
, ot
);
5466 gen_op_mov_reg_v(s
, ot
, (b
& 7) | REX_B(s
), s
->T0
);
5468 case 0x60: /* pusha */
5473 case 0x61: /* popa */
5478 case 0x68: /* push Iv */
5480 ot
= mo_pushpop(s
, dflag
);
5482 val
= insn_get(env
, s
, ot
);
5484 val
= (int8_t)insn_get(env
, s
, MO_8
);
5485 tcg_gen_movi_tl(s
->T0
, val
);
5486 gen_push_v(s
, s
->T0
);
5488 case 0x8f: /* pop Ev */
5489 modrm
= x86_ldub_code(env
, s
);
5490 mod
= (modrm
>> 6) & 3;
5493 /* NOTE: order is important for pop %sp */
5494 gen_pop_update(s
, ot
);
5495 rm
= (modrm
& 7) | REX_B(s
);
5496 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
5498 /* NOTE: order is important too for MMU exceptions */
5499 s
->popl_esp_hack
= 1 << ot
;
5500 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5501 s
->popl_esp_hack
= 0;
5502 gen_pop_update(s
, ot
);
5505 case 0xc8: /* enter */
5508 val
= x86_lduw_code(env
, s
);
5509 level
= x86_ldub_code(env
, s
);
5510 gen_enter(s
, val
, level
);
5513 case 0xc9: /* leave */
5516 case 0x06: /* push es */
5517 case 0x0e: /* push cs */
5518 case 0x16: /* push ss */
5519 case 0x1e: /* push ds */
5522 gen_op_movl_T0_seg(s
, b
>> 3);
5523 gen_push_v(s
, s
->T0
);
5525 case 0x1a0: /* push fs */
5526 case 0x1a8: /* push gs */
5527 gen_op_movl_T0_seg(s
, (b
>> 3) & 7);
5528 gen_push_v(s
, s
->T0
);
5530 case 0x07: /* pop es */
5531 case 0x17: /* pop ss */
5532 case 0x1f: /* pop ds */
5537 gen_movl_seg_T0(s
, reg
);
5538 gen_pop_update(s
, ot
);
5539 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5540 if (s
->base
.is_jmp
) {
5541 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
5544 gen_eob_inhibit_irq(s
, true);
5550 case 0x1a1: /* pop fs */
5551 case 0x1a9: /* pop gs */
5553 gen_movl_seg_T0(s
, (b
>> 3) & 7);
5554 gen_pop_update(s
, ot
);
5555 if (s
->base
.is_jmp
) {
5556 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
5561 /**************************/
5564 case 0x89: /* mov Gv, Ev */
5565 ot
= mo_b_d(b
, dflag
);
5566 modrm
= x86_ldub_code(env
, s
);
5567 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5569 /* generate a generic store */
5570 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
5573 case 0xc7: /* mov Ev, Iv */
5574 ot
= mo_b_d(b
, dflag
);
5575 modrm
= x86_ldub_code(env
, s
);
5576 mod
= (modrm
>> 6) & 3;
5578 s
->rip_offset
= insn_const_size(ot
);
5579 gen_lea_modrm(env
, s
, modrm
);
5581 val
= insn_get(env
, s
, ot
);
5582 tcg_gen_movi_tl(s
->T0
, val
);
5584 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
5586 gen_op_mov_reg_v(s
, ot
, (modrm
& 7) | REX_B(s
), s
->T0
);
5590 case 0x8b: /* mov Ev, Gv */
5591 ot
= mo_b_d(b
, dflag
);
5592 modrm
= x86_ldub_code(env
, s
);
5593 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5595 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5596 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
5598 case 0x8e: /* mov seg, Gv */
5599 modrm
= x86_ldub_code(env
, s
);
5600 reg
= (modrm
>> 3) & 7;
5601 if (reg
>= 6 || reg
== R_CS
)
5603 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
5604 gen_movl_seg_T0(s
, reg
);
5605 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5606 if (s
->base
.is_jmp
) {
5607 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
5610 gen_eob_inhibit_irq(s
, true);
5616 case 0x8c: /* mov Gv, seg */
5617 modrm
= x86_ldub_code(env
, s
);
5618 reg
= (modrm
>> 3) & 7;
5619 mod
= (modrm
>> 6) & 3;
5622 gen_op_movl_T0_seg(s
, reg
);
5623 ot
= mod
== 3 ? dflag
: MO_16
;
5624 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5627 case 0x1b6: /* movzbS Gv, Eb */
5628 case 0x1b7: /* movzwS Gv, Eb */
5629 case 0x1be: /* movsbS Gv, Eb */
5630 case 0x1bf: /* movswS Gv, Eb */
5635 /* d_ot is the size of destination */
5637 /* ot is the size of source */
5638 ot
= (b
& 1) + MO_8
;
5639 /* s_ot is the sign+size of source */
5640 s_ot
= b
& 8 ? MO_SIGN
| ot
: ot
;
5642 modrm
= x86_ldub_code(env
, s
);
5643 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5644 mod
= (modrm
>> 6) & 3;
5645 rm
= (modrm
& 7) | REX_B(s
);
5648 if (s_ot
== MO_SB
&& byte_reg_is_xH(s
, rm
)) {
5649 tcg_gen_sextract_tl(s
->T0
, cpu_regs
[rm
- 4], 8, 8);
5651 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
5654 tcg_gen_ext8u_tl(s
->T0
, s
->T0
);
5657 tcg_gen_ext8s_tl(s
->T0
, s
->T0
);
5660 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
5664 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5668 gen_op_mov_reg_v(s
, d_ot
, reg
, s
->T0
);
5670 gen_lea_modrm(env
, s
, modrm
);
5671 gen_op_ld_v(s
, s_ot
, s
->T0
, s
->A0
);
5672 gen_op_mov_reg_v(s
, d_ot
, reg
, s
->T0
);
5677 case 0x8d: /* lea */
5678 modrm
= x86_ldub_code(env
, s
);
5679 mod
= (modrm
>> 6) & 3;
5682 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5684 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
5685 TCGv ea
= gen_lea_modrm_1(s
, a
);
5686 gen_lea_v_seg(s
, s
->aflag
, ea
, -1, -1);
5687 gen_op_mov_reg_v(s
, dflag
, reg
, s
->A0
);
5691 case 0xa0: /* mov EAX, Ov */
5693 case 0xa2: /* mov Ov, EAX */
5696 target_ulong offset_addr
;
5698 ot
= mo_b_d(b
, dflag
);
5700 #ifdef TARGET_X86_64
5702 offset_addr
= x86_ldq_code(env
, s
);
5706 offset_addr
= insn_get(env
, s
, s
->aflag
);
5709 tcg_gen_movi_tl(s
->A0
, offset_addr
);
5710 gen_add_A0_ds_seg(s
);
5712 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
5713 gen_op_mov_reg_v(s
, ot
, R_EAX
, s
->T0
);
5715 gen_op_mov_v_reg(s
, ot
, s
->T0
, R_EAX
);
5716 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
5720 case 0xd7: /* xlat */
5721 tcg_gen_mov_tl(s
->A0
, cpu_regs
[R_EBX
]);
5722 tcg_gen_ext8u_tl(s
->T0
, cpu_regs
[R_EAX
]);
5723 tcg_gen_add_tl(s
->A0
, s
->A0
, s
->T0
);
5724 gen_extu(s
->aflag
, s
->A0
);
5725 gen_add_A0_ds_seg(s
);
5726 gen_op_ld_v(s
, MO_8
, s
->T0
, s
->A0
);
5727 gen_op_mov_reg_v(s
, MO_8
, R_EAX
, s
->T0
);
5729 case 0xb0 ... 0xb7: /* mov R, Ib */
5730 val
= insn_get(env
, s
, MO_8
);
5731 tcg_gen_movi_tl(s
->T0
, val
);
5732 gen_op_mov_reg_v(s
, MO_8
, (b
& 7) | REX_B(s
), s
->T0
);
5734 case 0xb8 ... 0xbf: /* mov R, Iv */
5735 #ifdef TARGET_X86_64
5736 if (dflag
== MO_64
) {
5739 tmp
= x86_ldq_code(env
, s
);
5740 reg
= (b
& 7) | REX_B(s
);
5741 tcg_gen_movi_tl(s
->T0
, tmp
);
5742 gen_op_mov_reg_v(s
, MO_64
, reg
, s
->T0
);
5747 val
= insn_get(env
, s
, ot
);
5748 reg
= (b
& 7) | REX_B(s
);
5749 tcg_gen_movi_tl(s
->T0
, val
);
5750 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
5754 case 0x91 ... 0x97: /* xchg R, EAX */
5757 reg
= (b
& 7) | REX_B(s
);
5761 case 0x87: /* xchg Ev, Gv */
5762 ot
= mo_b_d(b
, dflag
);
5763 modrm
= x86_ldub_code(env
, s
);
5764 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5765 mod
= (modrm
>> 6) & 3;
5767 rm
= (modrm
& 7) | REX_B(s
);
5769 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
5770 gen_op_mov_v_reg(s
, ot
, s
->T1
, rm
);
5771 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
5772 gen_op_mov_reg_v(s
, ot
, reg
, s
->T1
);
5774 gen_lea_modrm(env
, s
, modrm
);
5775 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
5776 /* for xchg, lock is implicit */
5777 tcg_gen_atomic_xchg_tl(s
->T1
, s
->A0
, s
->T0
,
5778 s
->mem_index
, ot
| MO_LE
);
5779 gen_op_mov_reg_v(s
, ot
, reg
, s
->T1
);
5782 case 0xc4: /* les Gv */
5783 /* In CODE64 this is VEX3; see above. */
5786 case 0xc5: /* lds Gv */
5787 /* In CODE64 this is VEX2; see above. */
5790 case 0x1b2: /* lss Gv */
5793 case 0x1b4: /* lfs Gv */
5796 case 0x1b5: /* lgs Gv */
5799 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
5800 modrm
= x86_ldub_code(env
, s
);
5801 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5802 mod
= (modrm
>> 6) & 3;
5805 gen_lea_modrm(env
, s
, modrm
);
5806 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
5807 gen_add_A0_im(s
, 1 << ot
);
5808 /* load the segment first to handle exceptions properly */
5809 gen_op_ld_v(s
, MO_16
, s
->T0
, s
->A0
);
5810 gen_movl_seg_T0(s
, op
);
5811 /* then put the data */
5812 gen_op_mov_reg_v(s
, ot
, reg
, s
->T1
);
5813 if (s
->base
.is_jmp
) {
5814 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
5819 /************************/
5827 ot
= mo_b_d(b
, dflag
);
5828 modrm
= x86_ldub_code(env
, s
);
5829 mod
= (modrm
>> 6) & 3;
5830 op
= (modrm
>> 3) & 7;
5836 gen_lea_modrm(env
, s
, modrm
);
5839 opreg
= (modrm
& 7) | REX_B(s
);
5844 gen_shift(s
, op
, ot
, opreg
, OR_ECX
);
5847 shift
= x86_ldub_code(env
, s
);
5849 gen_shifti(s
, op
, ot
, opreg
, shift
);
5864 case 0x1a4: /* shld imm */
5868 case 0x1a5: /* shld cl */
5872 case 0x1ac: /* shrd imm */
5876 case 0x1ad: /* shrd cl */
5881 modrm
= x86_ldub_code(env
, s
);
5882 mod
= (modrm
>> 6) & 3;
5883 rm
= (modrm
& 7) | REX_B(s
);
5884 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5886 gen_lea_modrm(env
, s
, modrm
);
5891 gen_op_mov_v_reg(s
, ot
, s
->T1
, reg
);
5894 TCGv imm
= tcg_const_tl(x86_ldub_code(env
, s
));
5895 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, imm
);
5898 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, cpu_regs
[R_ECX
]);
5902 /************************/
5905 if (s
->flags
& (HF_EM_MASK
| HF_TS_MASK
)) {
5906 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5907 /* XXX: what to do if illegal op ? */
5908 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
5911 modrm
= x86_ldub_code(env
, s
);
5912 mod
= (modrm
>> 6) & 3;
5914 op
= ((b
& 7) << 3) | ((modrm
>> 3) & 7);
5917 gen_lea_modrm(env
, s
, modrm
);
5919 case 0x00 ... 0x07: /* fxxxs */
5920 case 0x10 ... 0x17: /* fixxxl */
5921 case 0x20 ... 0x27: /* fxxxl */
5922 case 0x30 ... 0x37: /* fixxx */
5929 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
5930 s
->mem_index
, MO_LEUL
);
5931 gen_helper_flds_FT0(cpu_env
, s
->tmp2_i32
);
5934 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
5935 s
->mem_index
, MO_LEUL
);
5936 gen_helper_fildl_FT0(cpu_env
, s
->tmp2_i32
);
5939 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
,
5940 s
->mem_index
, MO_LEQ
);
5941 gen_helper_fldl_FT0(cpu_env
, s
->tmp1_i64
);
5945 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
5946 s
->mem_index
, MO_LESW
);
5947 gen_helper_fildl_FT0(cpu_env
, s
->tmp2_i32
);
5951 gen_helper_fp_arith_ST0_FT0(op1
);
5953 /* fcomp needs pop */
5954 gen_helper_fpop(cpu_env
);
5958 case 0x08: /* flds */
5959 case 0x0a: /* fsts */
5960 case 0x0b: /* fstps */
5961 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5962 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5963 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5968 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
5969 s
->mem_index
, MO_LEUL
);
5970 gen_helper_flds_ST0(cpu_env
, s
->tmp2_i32
);
5973 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
5974 s
->mem_index
, MO_LEUL
);
5975 gen_helper_fildl_ST0(cpu_env
, s
->tmp2_i32
);
5978 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
,
5979 s
->mem_index
, MO_LEQ
);
5980 gen_helper_fldl_ST0(cpu_env
, s
->tmp1_i64
);
5984 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
5985 s
->mem_index
, MO_LESW
);
5986 gen_helper_fildl_ST0(cpu_env
, s
->tmp2_i32
);
5991 /* XXX: the corresponding CPUID bit must be tested ! */
5994 gen_helper_fisttl_ST0(s
->tmp2_i32
, cpu_env
);
5995 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
5996 s
->mem_index
, MO_LEUL
);
5999 gen_helper_fisttll_ST0(s
->tmp1_i64
, cpu_env
);
6000 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
,
6001 s
->mem_index
, MO_LEQ
);
6005 gen_helper_fistt_ST0(s
->tmp2_i32
, cpu_env
);
6006 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
6007 s
->mem_index
, MO_LEUW
);
6010 gen_helper_fpop(cpu_env
);
6015 gen_helper_fsts_ST0(s
->tmp2_i32
, cpu_env
);
6016 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
6017 s
->mem_index
, MO_LEUL
);
6020 gen_helper_fistl_ST0(s
->tmp2_i32
, cpu_env
);
6021 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
6022 s
->mem_index
, MO_LEUL
);
6025 gen_helper_fstl_ST0(s
->tmp1_i64
, cpu_env
);
6026 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
,
6027 s
->mem_index
, MO_LEQ
);
6031 gen_helper_fist_ST0(s
->tmp2_i32
, cpu_env
);
6032 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
6033 s
->mem_index
, MO_LEUW
);
6037 gen_helper_fpop(cpu_env
);
6041 case 0x0c: /* fldenv mem */
6042 gen_helper_fldenv(cpu_env
, s
->A0
, tcg_const_i32(dflag
- 1));
6044 case 0x0d: /* fldcw mem */
6045 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
6046 s
->mem_index
, MO_LEUW
);
6047 gen_helper_fldcw(cpu_env
, s
->tmp2_i32
);
6049 case 0x0e: /* fnstenv mem */
6050 gen_helper_fstenv(cpu_env
, s
->A0
, tcg_const_i32(dflag
- 1));
6052 case 0x0f: /* fnstcw mem */
6053 gen_helper_fnstcw(s
->tmp2_i32
, cpu_env
);
6054 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
6055 s
->mem_index
, MO_LEUW
);
6057 case 0x1d: /* fldt mem */
6058 gen_helper_fldt_ST0(cpu_env
, s
->A0
);
6060 case 0x1f: /* fstpt mem */
6061 gen_helper_fstt_ST0(cpu_env
, s
->A0
);
6062 gen_helper_fpop(cpu_env
);
6064 case 0x2c: /* frstor mem */
6065 gen_helper_frstor(cpu_env
, s
->A0
, tcg_const_i32(dflag
- 1));
6067 case 0x2e: /* fnsave mem */
6068 gen_helper_fsave(cpu_env
, s
->A0
, tcg_const_i32(dflag
- 1));
6070 case 0x2f: /* fnstsw mem */
6071 gen_helper_fnstsw(s
->tmp2_i32
, cpu_env
);
6072 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
6073 s
->mem_index
, MO_LEUW
);
6075 case 0x3c: /* fbld */
6076 gen_helper_fbld_ST0(cpu_env
, s
->A0
);
6078 case 0x3e: /* fbstp */
6079 gen_helper_fbst_ST0(cpu_env
, s
->A0
);
6080 gen_helper_fpop(cpu_env
);
6082 case 0x3d: /* fildll */
6083 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
, s
->mem_index
, MO_LEQ
);
6084 gen_helper_fildll_ST0(cpu_env
, s
->tmp1_i64
);
6086 case 0x3f: /* fistpll */
6087 gen_helper_fistll_ST0(s
->tmp1_i64
, cpu_env
);
6088 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
, s
->mem_index
, MO_LEQ
);
6089 gen_helper_fpop(cpu_env
);
6095 /* register float ops */
6099 case 0x08: /* fld sti */
6100 gen_helper_fpush(cpu_env
);
6101 gen_helper_fmov_ST0_STN(cpu_env
,
6102 tcg_const_i32((opreg
+ 1) & 7));
6104 case 0x09: /* fxchg sti */
6105 case 0x29: /* fxchg4 sti, undocumented op */
6106 case 0x39: /* fxchg7 sti, undocumented op */
6107 gen_helper_fxchg_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6109 case 0x0a: /* grp d9/2 */
6112 /* check exceptions (FreeBSD FPU probe) */
6113 gen_helper_fwait(cpu_env
);
6119 case 0x0c: /* grp d9/4 */
6122 gen_helper_fchs_ST0(cpu_env
);
6125 gen_helper_fabs_ST0(cpu_env
);
6128 gen_helper_fldz_FT0(cpu_env
);
6129 gen_helper_fcom_ST0_FT0(cpu_env
);
6132 gen_helper_fxam_ST0(cpu_env
);
6138 case 0x0d: /* grp d9/5 */
6142 gen_helper_fpush(cpu_env
);
6143 gen_helper_fld1_ST0(cpu_env
);
6146 gen_helper_fpush(cpu_env
);
6147 gen_helper_fldl2t_ST0(cpu_env
);
6150 gen_helper_fpush(cpu_env
);
6151 gen_helper_fldl2e_ST0(cpu_env
);
6154 gen_helper_fpush(cpu_env
);
6155 gen_helper_fldpi_ST0(cpu_env
);
6158 gen_helper_fpush(cpu_env
);
6159 gen_helper_fldlg2_ST0(cpu_env
);
6162 gen_helper_fpush(cpu_env
);
6163 gen_helper_fldln2_ST0(cpu_env
);
6166 gen_helper_fpush(cpu_env
);
6167 gen_helper_fldz_ST0(cpu_env
);
6174 case 0x0e: /* grp d9/6 */
6177 gen_helper_f2xm1(cpu_env
);
6180 gen_helper_fyl2x(cpu_env
);
6183 gen_helper_fptan(cpu_env
);
6185 case 3: /* fpatan */
6186 gen_helper_fpatan(cpu_env
);
6188 case 4: /* fxtract */
6189 gen_helper_fxtract(cpu_env
);
6191 case 5: /* fprem1 */
6192 gen_helper_fprem1(cpu_env
);
6194 case 6: /* fdecstp */
6195 gen_helper_fdecstp(cpu_env
);
6198 case 7: /* fincstp */
6199 gen_helper_fincstp(cpu_env
);
6203 case 0x0f: /* grp d9/7 */
6206 gen_helper_fprem(cpu_env
);
6208 case 1: /* fyl2xp1 */
6209 gen_helper_fyl2xp1(cpu_env
);
6212 gen_helper_fsqrt(cpu_env
);
6214 case 3: /* fsincos */
6215 gen_helper_fsincos(cpu_env
);
6217 case 5: /* fscale */
6218 gen_helper_fscale(cpu_env
);
6220 case 4: /* frndint */
6221 gen_helper_frndint(cpu_env
);
6224 gen_helper_fsin(cpu_env
);
6228 gen_helper_fcos(cpu_env
);
6232 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6233 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6234 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6240 gen_helper_fp_arith_STN_ST0(op1
, opreg
);
6242 gen_helper_fpop(cpu_env
);
6244 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6245 gen_helper_fp_arith_ST0_FT0(op1
);
6249 case 0x02: /* fcom */
6250 case 0x22: /* fcom2, undocumented op */
6251 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6252 gen_helper_fcom_ST0_FT0(cpu_env
);
6254 case 0x03: /* fcomp */
6255 case 0x23: /* fcomp3, undocumented op */
6256 case 0x32: /* fcomp5, undocumented op */
6257 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6258 gen_helper_fcom_ST0_FT0(cpu_env
);
6259 gen_helper_fpop(cpu_env
);
6261 case 0x15: /* da/5 */
6263 case 1: /* fucompp */
6264 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6265 gen_helper_fucom_ST0_FT0(cpu_env
);
6266 gen_helper_fpop(cpu_env
);
6267 gen_helper_fpop(cpu_env
);
6275 case 0: /* feni (287 only, just do nop here) */
6277 case 1: /* fdisi (287 only, just do nop here) */
6280 gen_helper_fclex(cpu_env
);
6282 case 3: /* fninit */
6283 gen_helper_fninit(cpu_env
);
6285 case 4: /* fsetpm (287 only, just do nop here) */
6291 case 0x1d: /* fucomi */
6292 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6295 gen_update_cc_op(s
);
6296 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6297 gen_helper_fucomi_ST0_FT0(cpu_env
);
6298 set_cc_op(s
, CC_OP_EFLAGS
);
6300 case 0x1e: /* fcomi */
6301 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6304 gen_update_cc_op(s
);
6305 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6306 gen_helper_fcomi_ST0_FT0(cpu_env
);
6307 set_cc_op(s
, CC_OP_EFLAGS
);
6309 case 0x28: /* ffree sti */
6310 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6312 case 0x2a: /* fst sti */
6313 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6315 case 0x2b: /* fstp sti */
6316 case 0x0b: /* fstp1 sti, undocumented op */
6317 case 0x3a: /* fstp8 sti, undocumented op */
6318 case 0x3b: /* fstp9 sti, undocumented op */
6319 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6320 gen_helper_fpop(cpu_env
);
6322 case 0x2c: /* fucom st(i) */
6323 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6324 gen_helper_fucom_ST0_FT0(cpu_env
);
6326 case 0x2d: /* fucomp st(i) */
6327 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6328 gen_helper_fucom_ST0_FT0(cpu_env
);
6329 gen_helper_fpop(cpu_env
);
6331 case 0x33: /* de/3 */
6333 case 1: /* fcompp */
6334 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6335 gen_helper_fcom_ST0_FT0(cpu_env
);
6336 gen_helper_fpop(cpu_env
);
6337 gen_helper_fpop(cpu_env
);
6343 case 0x38: /* ffreep sti, undocumented op */
6344 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6345 gen_helper_fpop(cpu_env
);
6347 case 0x3c: /* df/4 */
6350 gen_helper_fnstsw(s
->tmp2_i32
, cpu_env
);
6351 tcg_gen_extu_i32_tl(s
->T0
, s
->tmp2_i32
);
6352 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
6358 case 0x3d: /* fucomip */
6359 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6362 gen_update_cc_op(s
);
6363 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6364 gen_helper_fucomi_ST0_FT0(cpu_env
);
6365 gen_helper_fpop(cpu_env
);
6366 set_cc_op(s
, CC_OP_EFLAGS
);
6368 case 0x3e: /* fcomip */
6369 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6372 gen_update_cc_op(s
);
6373 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6374 gen_helper_fcomi_ST0_FT0(cpu_env
);
6375 gen_helper_fpop(cpu_env
);
6376 set_cc_op(s
, CC_OP_EFLAGS
);
6378 case 0x10 ... 0x13: /* fcmovxx */
6383 static const uint8_t fcmov_cc
[8] = {
6390 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6393 op1
= fcmov_cc
[op
& 3] | (((op
>> 3) & 1) ^ 1);
6394 l1
= gen_new_label();
6395 gen_jcc1_noeob(s
, op1
, l1
);
6396 gen_helper_fmov_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6405 /************************/
6408 case 0xa4: /* movsS */
6410 ot
= mo_b_d(b
, dflag
);
6411 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6412 gen_repz_movs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6418 case 0xaa: /* stosS */
6420 ot
= mo_b_d(b
, dflag
);
6421 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6422 gen_repz_stos(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6427 case 0xac: /* lodsS */
6429 ot
= mo_b_d(b
, dflag
);
6430 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6431 gen_repz_lods(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6436 case 0xae: /* scasS */
6438 ot
= mo_b_d(b
, dflag
);
6439 if (prefixes
& PREFIX_REPNZ
) {
6440 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6441 } else if (prefixes
& PREFIX_REPZ
) {
6442 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6448 case 0xa6: /* cmpsS */
6450 ot
= mo_b_d(b
, dflag
);
6451 if (prefixes
& PREFIX_REPNZ
) {
6452 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6453 } else if (prefixes
& PREFIX_REPZ
) {
6454 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6459 case 0x6c: /* insS */
6461 ot
= mo_b_d32(b
, dflag
);
6462 tcg_gen_ext16u_tl(s
->T0
, cpu_regs
[R_EDX
]);
6463 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6464 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
) | 4);
6465 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6468 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6469 gen_repz_ins(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6470 /* jump generated by gen_repz_ins */
6473 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6474 gen_jmp(s
, s
->pc
- s
->cs_base
);
6478 case 0x6e: /* outsS */
6480 ot
= mo_b_d32(b
, dflag
);
6481 tcg_gen_ext16u_tl(s
->T0
, cpu_regs
[R_EDX
]);
6482 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6483 svm_is_rep(prefixes
) | 4);
6484 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6487 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6488 gen_repz_outs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6489 /* jump generated by gen_repz_outs */
6492 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6493 gen_jmp(s
, s
->pc
- s
->cs_base
);
6498 /************************/
6503 ot
= mo_b_d32(b
, dflag
);
6504 val
= x86_ldub_code(env
, s
);
6505 tcg_gen_movi_tl(s
->T0
, val
);
6506 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6507 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6508 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6511 tcg_gen_movi_i32(s
->tmp2_i32
, val
);
6512 gen_helper_in_func(ot
, s
->T1
, s
->tmp2_i32
);
6513 gen_op_mov_reg_v(s
, ot
, R_EAX
, s
->T1
);
6514 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
6515 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6516 gen_jmp(s
, s
->pc
- s
->cs_base
);
6521 ot
= mo_b_d32(b
, dflag
);
6522 val
= x86_ldub_code(env
, s
);
6523 tcg_gen_movi_tl(s
->T0
, val
);
6524 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6525 svm_is_rep(prefixes
));
6526 gen_op_mov_v_reg(s
, ot
, s
->T1
, R_EAX
);
6528 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6531 tcg_gen_movi_i32(s
->tmp2_i32
, val
);
6532 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, s
->T1
);
6533 gen_helper_out_func(ot
, s
->tmp2_i32
, s
->tmp3_i32
);
6534 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
6535 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6536 gen_jmp(s
, s
->pc
- s
->cs_base
);
6541 ot
= mo_b_d32(b
, dflag
);
6542 tcg_gen_ext16u_tl(s
->T0
, cpu_regs
[R_EDX
]);
6543 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6544 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6545 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6548 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
6549 gen_helper_in_func(ot
, s
->T1
, s
->tmp2_i32
);
6550 gen_op_mov_reg_v(s
, ot
, R_EAX
, s
->T1
);
6551 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
6552 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6553 gen_jmp(s
, s
->pc
- s
->cs_base
);
6558 ot
= mo_b_d32(b
, dflag
);
6559 tcg_gen_ext16u_tl(s
->T0
, cpu_regs
[R_EDX
]);
6560 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6561 svm_is_rep(prefixes
));
6562 gen_op_mov_v_reg(s
, ot
, s
->T1
, R_EAX
);
6564 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6567 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
6568 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, s
->T1
);
6569 gen_helper_out_func(ot
, s
->tmp2_i32
, s
->tmp3_i32
);
6570 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
6571 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6572 gen_jmp(s
, s
->pc
- s
->cs_base
);
6576 /************************/
6578 case 0xc2: /* ret im */
6579 val
= x86_ldsw_code(env
, s
);
6581 gen_stack_update(s
, val
+ (1 << ot
));
6582 /* Note that gen_pop_T0 uses a zero-extending load. */
6583 gen_op_jmp_v(s
->T0
);
6587 case 0xc3: /* ret */
6589 gen_pop_update(s
, ot
);
6590 /* Note that gen_pop_T0 uses a zero-extending load. */
6591 gen_op_jmp_v(s
->T0
);
6595 case 0xca: /* lret im */
6596 val
= x86_ldsw_code(env
, s
);
6598 if (PE(s
) && !VM86(s
)) {
6599 gen_update_cc_op(s
);
6600 gen_jmp_im(s
, pc_start
- s
->cs_base
);
6601 gen_helper_lret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6602 tcg_const_i32(val
));
6606 gen_op_ld_v(s
, dflag
, s
->T0
, s
->A0
);
6607 /* NOTE: keeping EIP updated is not a problem in case of
6609 gen_op_jmp_v(s
->T0
);
6611 gen_add_A0_im(s
, 1 << dflag
);
6612 gen_op_ld_v(s
, dflag
, s
->T0
, s
->A0
);
6613 gen_op_movl_seg_T0_vm(s
, R_CS
);
6614 /* add stack offset */
6615 gen_stack_update(s
, val
+ (2 << dflag
));
6619 case 0xcb: /* lret */
6622 case 0xcf: /* iret */
6623 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IRET
);
6624 if (!PE(s
) || VM86(s
)) {
6625 /* real mode or vm86 mode */
6626 if (!check_vm86_iopl(s
)) {
6629 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6631 gen_helper_iret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6632 tcg_const_i32(s
->pc
- s
->cs_base
));
6634 set_cc_op(s
, CC_OP_EFLAGS
);
6637 case 0xe8: /* call im */
6639 if (dflag
!= MO_16
) {
6640 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6642 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6644 next_eip
= s
->pc
- s
->cs_base
;
6646 if (dflag
== MO_16
) {
6648 } else if (!CODE64(s
)) {
6651 tcg_gen_movi_tl(s
->T0
, next_eip
);
6652 gen_push_v(s
, s
->T0
);
6657 case 0x9a: /* lcall im */
6659 unsigned int selector
, offset
;
6664 offset
= insn_get(env
, s
, ot
);
6665 selector
= insn_get(env
, s
, MO_16
);
6667 tcg_gen_movi_tl(s
->T0
, selector
);
6668 tcg_gen_movi_tl(s
->T1
, offset
);
6671 case 0xe9: /* jmp im */
6672 if (dflag
!= MO_16
) {
6673 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6675 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6677 tval
+= s
->pc
- s
->cs_base
;
6678 if (dflag
== MO_16
) {
6680 } else if (!CODE64(s
)) {
6686 case 0xea: /* ljmp im */
6688 unsigned int selector
, offset
;
6693 offset
= insn_get(env
, s
, ot
);
6694 selector
= insn_get(env
, s
, MO_16
);
6696 tcg_gen_movi_tl(s
->T0
, selector
);
6697 tcg_gen_movi_tl(s
->T1
, offset
);
6700 case 0xeb: /* jmp Jb */
6701 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6702 tval
+= s
->pc
- s
->cs_base
;
6703 if (dflag
== MO_16
) {
6708 case 0x70 ... 0x7f: /* jcc Jb */
6709 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6711 case 0x180 ... 0x18f: /* jcc Jv */
6712 if (dflag
!= MO_16
) {
6713 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6715 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6718 next_eip
= s
->pc
- s
->cs_base
;
6720 if (dflag
== MO_16
) {
6724 gen_jcc(s
, b
, tval
, next_eip
);
6727 case 0x190 ... 0x19f: /* setcc Gv */
6728 modrm
= x86_ldub_code(env
, s
);
6729 gen_setcc1(s
, b
, s
->T0
);
6730 gen_ldst_modrm(env
, s
, modrm
, MO_8
, OR_TMP0
, 1);
6732 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6733 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6737 modrm
= x86_ldub_code(env
, s
);
6738 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
6739 gen_cmovcc1(env
, s
, ot
, b
, modrm
, reg
);
6742 /************************/
6744 case 0x9c: /* pushf */
6745 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_PUSHF
);
6746 if (check_vm86_iopl(s
)) {
6747 gen_update_cc_op(s
);
6748 gen_helper_read_eflags(s
->T0
, cpu_env
);
6749 gen_push_v(s
, s
->T0
);
6752 case 0x9d: /* popf */
6753 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_POPF
);
6754 if (check_vm86_iopl(s
)) {
6757 if (dflag
!= MO_16
) {
6758 gen_helper_write_eflags(cpu_env
, s
->T0
,
6759 tcg_const_i32((TF_MASK
| AC_MASK
|
6764 gen_helper_write_eflags(cpu_env
, s
->T0
,
6765 tcg_const_i32((TF_MASK
| AC_MASK
|
6767 IF_MASK
| IOPL_MASK
)
6771 if (CPL(s
) <= IOPL(s
)) {
6772 if (dflag
!= MO_16
) {
6773 gen_helper_write_eflags(cpu_env
, s
->T0
,
6774 tcg_const_i32((TF_MASK
|
6780 gen_helper_write_eflags(cpu_env
, s
->T0
,
6781 tcg_const_i32((TF_MASK
|
6789 if (dflag
!= MO_16
) {
6790 gen_helper_write_eflags(cpu_env
, s
->T0
,
6791 tcg_const_i32((TF_MASK
| AC_MASK
|
6792 ID_MASK
| NT_MASK
)));
6794 gen_helper_write_eflags(cpu_env
, s
->T0
,
6795 tcg_const_i32((TF_MASK
| AC_MASK
|
6801 gen_pop_update(s
, ot
);
6802 set_cc_op(s
, CC_OP_EFLAGS
);
6803 /* abort translation because TF/AC flag may change */
6804 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
6808 case 0x9e: /* sahf */
6809 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6811 gen_op_mov_v_reg(s
, MO_8
, s
->T0
, R_AH
);
6812 gen_compute_eflags(s
);
6813 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, CC_O
);
6814 tcg_gen_andi_tl(s
->T0
, s
->T0
, CC_S
| CC_Z
| CC_A
| CC_P
| CC_C
);
6815 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, s
->T0
);
6817 case 0x9f: /* lahf */
6818 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6820 gen_compute_eflags(s
);
6821 /* Note: gen_compute_eflags() only gives the condition codes */
6822 tcg_gen_ori_tl(s
->T0
, cpu_cc_src
, 0x02);
6823 gen_op_mov_reg_v(s
, MO_8
, R_AH
, s
->T0
);
6825 case 0xf5: /* cmc */
6826 gen_compute_eflags(s
);
6827 tcg_gen_xori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6829 case 0xf8: /* clc */
6830 gen_compute_eflags(s
);
6831 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_C
);
6833 case 0xf9: /* stc */
6834 gen_compute_eflags(s
);
6835 tcg_gen_ori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6837 case 0xfc: /* cld */
6838 tcg_gen_movi_i32(s
->tmp2_i32
, 1);
6839 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6841 case 0xfd: /* std */
6842 tcg_gen_movi_i32(s
->tmp2_i32
, -1);
6843 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6846 /************************/
6847 /* bit operations */
6848 case 0x1ba: /* bt/bts/btr/btc Gv, im */
6850 modrm
= x86_ldub_code(env
, s
);
6851 op
= (modrm
>> 3) & 7;
6852 mod
= (modrm
>> 6) & 3;
6853 rm
= (modrm
& 7) | REX_B(s
);
6856 gen_lea_modrm(env
, s
, modrm
);
6857 if (!(s
->prefix
& PREFIX_LOCK
)) {
6858 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
6861 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
6864 val
= x86_ldub_code(env
, s
);
6865 tcg_gen_movi_tl(s
->T1
, val
);
6870 case 0x1a3: /* bt Gv, Ev */
6873 case 0x1ab: /* bts */
6876 case 0x1b3: /* btr */
6879 case 0x1bb: /* btc */
6883 modrm
= x86_ldub_code(env
, s
);
6884 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
6885 mod
= (modrm
>> 6) & 3;
6886 rm
= (modrm
& 7) | REX_B(s
);
6887 gen_op_mov_v_reg(s
, MO_32
, s
->T1
, reg
);
6889 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
6890 /* specific case: we need to add a displacement */
6891 gen_exts(ot
, s
->T1
);
6892 tcg_gen_sari_tl(s
->tmp0
, s
->T1
, 3 + ot
);
6893 tcg_gen_shli_tl(s
->tmp0
, s
->tmp0
, ot
);
6894 tcg_gen_add_tl(s
->A0
, gen_lea_modrm_1(s
, a
), s
->tmp0
);
6895 gen_lea_v_seg(s
, s
->aflag
, s
->A0
, a
.def_seg
, s
->override
);
6896 if (!(s
->prefix
& PREFIX_LOCK
)) {
6897 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
6900 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
6903 tcg_gen_andi_tl(s
->T1
, s
->T1
, (1 << (3 + ot
)) - 1);
6904 tcg_gen_movi_tl(s
->tmp0
, 1);
6905 tcg_gen_shl_tl(s
->tmp0
, s
->tmp0
, s
->T1
);
6906 if (s
->prefix
& PREFIX_LOCK
) {
6909 /* Needs no atomic ops; we surpressed the normal
6910 memory load for LOCK above so do it now. */
6911 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
6914 tcg_gen_atomic_fetch_or_tl(s
->T0
, s
->A0
, s
->tmp0
,
6915 s
->mem_index
, ot
| MO_LE
);
6918 tcg_gen_not_tl(s
->tmp0
, s
->tmp0
);
6919 tcg_gen_atomic_fetch_and_tl(s
->T0
, s
->A0
, s
->tmp0
,
6920 s
->mem_index
, ot
| MO_LE
);
6924 tcg_gen_atomic_fetch_xor_tl(s
->T0
, s
->A0
, s
->tmp0
,
6925 s
->mem_index
, ot
| MO_LE
);
6928 tcg_gen_shr_tl(s
->tmp4
, s
->T0
, s
->T1
);
6930 tcg_gen_shr_tl(s
->tmp4
, s
->T0
, s
->T1
);
6933 /* Data already loaded; nothing to do. */
6936 tcg_gen_or_tl(s
->T0
, s
->T0
, s
->tmp0
);
6939 tcg_gen_andc_tl(s
->T0
, s
->T0
, s
->tmp0
);
6943 tcg_gen_xor_tl(s
->T0
, s
->T0
, s
->tmp0
);
6948 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
6950 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
6955 /* Delay all CC updates until after the store above. Note that
6956 C is the result of the test, Z is unchanged, and the others
6957 are all undefined. */
6959 case CC_OP_MULB
... CC_OP_MULQ
:
6960 case CC_OP_ADDB
... CC_OP_ADDQ
:
6961 case CC_OP_ADCB
... CC_OP_ADCQ
:
6962 case CC_OP_SUBB
... CC_OP_SUBQ
:
6963 case CC_OP_SBBB
... CC_OP_SBBQ
:
6964 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
6965 case CC_OP_INCB
... CC_OP_INCQ
:
6966 case CC_OP_DECB
... CC_OP_DECQ
:
6967 case CC_OP_SHLB
... CC_OP_SHLQ
:
6968 case CC_OP_SARB
... CC_OP_SARQ
:
6969 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
6970 /* Z was going to be computed from the non-zero status of CC_DST.
6971 We can get that same Z value (and the new C value) by leaving
6972 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
6974 tcg_gen_mov_tl(cpu_cc_src
, s
->tmp4
);
6975 set_cc_op(s
, ((s
->cc_op
- CC_OP_MULB
) & 3) + CC_OP_SARB
);
6978 /* Otherwise, generate EFLAGS and replace the C bit. */
6979 gen_compute_eflags(s
);
6980 tcg_gen_deposit_tl(cpu_cc_src
, cpu_cc_src
, s
->tmp4
,
6985 case 0x1bc: /* bsf / tzcnt */
6986 case 0x1bd: /* bsr / lzcnt */
6988 modrm
= x86_ldub_code(env
, s
);
6989 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
6990 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
6991 gen_extu(ot
, s
->T0
);
6993 /* Note that lzcnt and tzcnt are in different extensions. */
6994 if ((prefixes
& PREFIX_REPZ
)
6996 ? s
->cpuid_ext3_features
& CPUID_EXT3_ABM
6997 : s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)) {
6999 /* For lzcnt/tzcnt, C bit is defined related to the input. */
7000 tcg_gen_mov_tl(cpu_cc_src
, s
->T0
);
7002 /* For lzcnt, reduce the target_ulong result by the
7003 number of zeros that we expect to find at the top. */
7004 tcg_gen_clzi_tl(s
->T0
, s
->T0
, TARGET_LONG_BITS
);
7005 tcg_gen_subi_tl(s
->T0
, s
->T0
, TARGET_LONG_BITS
- size
);
7007 /* For tzcnt, a zero input must return the operand size. */
7008 tcg_gen_ctzi_tl(s
->T0
, s
->T0
, size
);
7010 /* For lzcnt/tzcnt, Z bit is defined related to the result. */
7011 gen_op_update1_cc(s
);
7012 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
7014 /* For bsr/bsf, only the Z bit is defined and it is related
7015 to the input and not the result. */
7016 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
7017 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
7019 /* ??? The manual says that the output is undefined when the
7020 input is zero, but real hardware leaves it unchanged, and
7021 real programs appear to depend on that. Accomplish this
7022 by passing the output as the value to return upon zero. */
7024 /* For bsr, return the bit index of the first 1 bit,
7025 not the count of leading zeros. */
7026 tcg_gen_xori_tl(s
->T1
, cpu_regs
[reg
], TARGET_LONG_BITS
- 1);
7027 tcg_gen_clz_tl(s
->T0
, s
->T0
, s
->T1
);
7028 tcg_gen_xori_tl(s
->T0
, s
->T0
, TARGET_LONG_BITS
- 1);
7030 tcg_gen_ctz_tl(s
->T0
, s
->T0
, cpu_regs
[reg
]);
7033 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
7035 /************************/
7037 case 0x27: /* daa */
7040 gen_update_cc_op(s
);
7041 gen_helper_daa(cpu_env
);
7042 set_cc_op(s
, CC_OP_EFLAGS
);
7044 case 0x2f: /* das */
7047 gen_update_cc_op(s
);
7048 gen_helper_das(cpu_env
);
7049 set_cc_op(s
, CC_OP_EFLAGS
);
7051 case 0x37: /* aaa */
7054 gen_update_cc_op(s
);
7055 gen_helper_aaa(cpu_env
);
7056 set_cc_op(s
, CC_OP_EFLAGS
);
7058 case 0x3f: /* aas */
7061 gen_update_cc_op(s
);
7062 gen_helper_aas(cpu_env
);
7063 set_cc_op(s
, CC_OP_EFLAGS
);
7065 case 0xd4: /* aam */
7068 val
= x86_ldub_code(env
, s
);
7070 gen_exception(s
, EXCP00_DIVZ
, pc_start
- s
->cs_base
);
7072 gen_helper_aam(cpu_env
, tcg_const_i32(val
));
7073 set_cc_op(s
, CC_OP_LOGICB
);
7076 case 0xd5: /* aad */
7079 val
= x86_ldub_code(env
, s
);
7080 gen_helper_aad(cpu_env
, tcg_const_i32(val
));
7081 set_cc_op(s
, CC_OP_LOGICB
);
7083 /************************/
7085 case 0x90: /* nop */
7086 /* XXX: correct lock test for all insn */
7087 if (prefixes
& PREFIX_LOCK
) {
7090 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
7092 goto do_xchg_reg_eax
;
7094 if (prefixes
& PREFIX_REPZ
) {
7095 gen_update_cc_op(s
);
7096 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7097 gen_helper_pause(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7098 s
->base
.is_jmp
= DISAS_NORETURN
;
7101 case 0x9b: /* fwait */
7102 if ((s
->flags
& (HF_MP_MASK
| HF_TS_MASK
)) ==
7103 (HF_MP_MASK
| HF_TS_MASK
)) {
7104 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7106 gen_helper_fwait(cpu_env
);
7109 case 0xcc: /* int3 */
7110 gen_interrupt(s
, EXCP03_INT3
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
7112 case 0xcd: /* int N */
7113 val
= x86_ldub_code(env
, s
);
7114 if (check_vm86_iopl(s
)) {
7115 gen_interrupt(s
, val
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
7118 case 0xce: /* into */
7121 gen_update_cc_op(s
);
7122 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7123 gen_helper_into(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7126 case 0xf1: /* icebp (undocumented, exits to external debugger) */
7127 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_ICEBP
);
7128 gen_debug(s
, pc_start
- s
->cs_base
);
7131 case 0xfa: /* cli */
7132 if (check_iopl(s
)) {
7133 gen_helper_cli(cpu_env
);
7136 case 0xfb: /* sti */
7137 if (check_iopl(s
)) {
7138 gen_helper_sti(cpu_env
);
7139 /* interruptions are enabled only the first insn after sti */
7140 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7141 gen_eob_inhibit_irq(s
, true);
7144 case 0x62: /* bound */
7148 modrm
= x86_ldub_code(env
, s
);
7149 reg
= (modrm
>> 3) & 7;
7150 mod
= (modrm
>> 6) & 3;
7153 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
7154 gen_lea_modrm(env
, s
, modrm
);
7155 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
7157 gen_helper_boundw(cpu_env
, s
->A0
, s
->tmp2_i32
);
7159 gen_helper_boundl(cpu_env
, s
->A0
, s
->tmp2_i32
);
7162 case 0x1c8 ... 0x1cf: /* bswap reg */
7163 reg
= (b
& 7) | REX_B(s
);
7164 #ifdef TARGET_X86_64
7165 if (dflag
== MO_64
) {
7166 gen_op_mov_v_reg(s
, MO_64
, s
->T0
, reg
);
7167 tcg_gen_bswap64_i64(s
->T0
, s
->T0
);
7168 gen_op_mov_reg_v(s
, MO_64
, reg
, s
->T0
);
7172 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, reg
);
7173 tcg_gen_ext32u_tl(s
->T0
, s
->T0
);
7174 tcg_gen_bswap32_tl(s
->T0
, s
->T0
);
7175 gen_op_mov_reg_v(s
, MO_32
, reg
, s
->T0
);
7178 case 0xd6: /* salc */
7181 gen_compute_eflags_c(s
, s
->T0
);
7182 tcg_gen_neg_tl(s
->T0
, s
->T0
);
7183 gen_op_mov_reg_v(s
, MO_8
, R_EAX
, s
->T0
);
7185 case 0xe0: /* loopnz */
7186 case 0xe1: /* loopz */
7187 case 0xe2: /* loop */
7188 case 0xe3: /* jecxz */
7190 TCGLabel
*l1
, *l2
, *l3
;
7192 tval
= (int8_t)insn_get(env
, s
, MO_8
);
7193 next_eip
= s
->pc
- s
->cs_base
;
7195 if (dflag
== MO_16
) {
7199 l1
= gen_new_label();
7200 l2
= gen_new_label();
7201 l3
= gen_new_label();
7202 gen_update_cc_op(s
);
7205 case 0: /* loopnz */
7207 gen_op_add_reg_im(s
, s
->aflag
, R_ECX
, -1);
7208 gen_op_jz_ecx(s
, s
->aflag
, l3
);
7209 gen_jcc1(s
, (JCC_Z
<< 1) | (b
^ 1), l1
);
7212 gen_op_add_reg_im(s
, s
->aflag
, R_ECX
, -1);
7213 gen_op_jnz_ecx(s
, s
->aflag
, l1
);
7217 gen_op_jz_ecx(s
, s
->aflag
, l1
);
7222 gen_jmp_im(s
, next_eip
);
7226 gen_jmp_im(s
, tval
);
7231 case 0x130: /* wrmsr */
7232 case 0x132: /* rdmsr */
7233 if (check_cpl0(s
)) {
7234 gen_update_cc_op(s
);
7235 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7237 gen_helper_rdmsr(cpu_env
);
7239 gen_helper_wrmsr(cpu_env
);
7243 case 0x131: /* rdtsc */
7244 gen_update_cc_op(s
);
7245 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7246 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7249 gen_helper_rdtsc(cpu_env
);
7250 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7251 gen_jmp(s
, s
->pc
- s
->cs_base
);
7254 case 0x133: /* rdpmc */
7255 gen_update_cc_op(s
);
7256 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7257 gen_helper_rdpmc(cpu_env
);
7259 case 0x134: /* sysenter */
7260 /* For Intel SYSENTER is valid on 64-bit */
7261 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7264 gen_exception_gpf(s
);
7266 gen_helper_sysenter(cpu_env
);
7270 case 0x135: /* sysexit */
7271 /* For Intel SYSEXIT is valid on 64-bit */
7272 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7275 gen_exception_gpf(s
);
7277 gen_helper_sysexit(cpu_env
, tcg_const_i32(dflag
- 1));
7281 #ifdef TARGET_X86_64
7282 case 0x105: /* syscall */
7283 /* XXX: is it usable in real mode ? */
7284 gen_update_cc_op(s
);
7285 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7286 gen_helper_syscall(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7287 /* TF handling for the syscall insn is different. The TF bit is checked
7288 after the syscall insn completes. This allows #DB to not be
7289 generated after one has entered CPL0 if TF is set in FMASK. */
7290 gen_eob_worker(s
, false, true);
7292 case 0x107: /* sysret */
7294 gen_exception_gpf(s
);
7296 gen_helper_sysret(cpu_env
, tcg_const_i32(dflag
- 1));
7297 /* condition codes are modified only in long mode */
7299 set_cc_op(s
, CC_OP_EFLAGS
);
7301 /* TF handling for the sysret insn is different. The TF bit is
7302 checked after the sysret insn completes. This allows #DB to be
7303 generated "as if" the syscall insn in userspace has just
7305 gen_eob_worker(s
, false, true);
7309 case 0x1a2: /* cpuid */
7310 gen_update_cc_op(s
);
7311 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7312 gen_helper_cpuid(cpu_env
);
7314 case 0xf4: /* hlt */
7315 if (check_cpl0(s
)) {
7316 gen_update_cc_op(s
);
7317 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7318 gen_helper_hlt(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7319 s
->base
.is_jmp
= DISAS_NORETURN
;
7323 modrm
= x86_ldub_code(env
, s
);
7324 mod
= (modrm
>> 6) & 3;
7325 op
= (modrm
>> 3) & 7;
7328 if (!PE(s
) || VM86(s
))
7330 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_READ
);
7331 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
7332 offsetof(CPUX86State
, ldt
.selector
));
7333 ot
= mod
== 3 ? dflag
: MO_16
;
7334 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7337 if (!PE(s
) || VM86(s
))
7339 if (check_cpl0(s
)) {
7340 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_WRITE
);
7341 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7342 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
7343 gen_helper_lldt(cpu_env
, s
->tmp2_i32
);
7347 if (!PE(s
) || VM86(s
))
7349 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_READ
);
7350 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
7351 offsetof(CPUX86State
, tr
.selector
));
7352 ot
= mod
== 3 ? dflag
: MO_16
;
7353 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7356 if (!PE(s
) || VM86(s
))
7358 if (check_cpl0(s
)) {
7359 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_WRITE
);
7360 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7361 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
7362 gen_helper_ltr(cpu_env
, s
->tmp2_i32
);
7367 if (!PE(s
) || VM86(s
))
7369 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7370 gen_update_cc_op(s
);
7372 gen_helper_verr(cpu_env
, s
->T0
);
7374 gen_helper_verw(cpu_env
, s
->T0
);
7376 set_cc_op(s
, CC_OP_EFLAGS
);
7384 modrm
= x86_ldub_code(env
, s
);
7386 CASE_MODRM_MEM_OP(0): /* sgdt */
7387 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_READ
);
7388 gen_lea_modrm(env
, s
, modrm
);
7389 tcg_gen_ld32u_tl(s
->T0
,
7390 cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7391 gen_op_st_v(s
, MO_16
, s
->T0
, s
->A0
);
7392 gen_add_A0_im(s
, 2);
7393 tcg_gen_ld_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7394 if (dflag
== MO_16
) {
7395 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xffffff);
7397 gen_op_st_v(s
, CODE64(s
) + MO_32
, s
->T0
, s
->A0
);
7400 case 0xc8: /* monitor */
7401 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) || CPL(s
) != 0) {
7404 gen_update_cc_op(s
);
7405 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7406 tcg_gen_mov_tl(s
->A0
, cpu_regs
[R_EAX
]);
7407 gen_extu(s
->aflag
, s
->A0
);
7408 gen_add_A0_ds_seg(s
);
7409 gen_helper_monitor(cpu_env
, s
->A0
);
7412 case 0xc9: /* mwait */
7413 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) || CPL(s
) != 0) {
7416 gen_update_cc_op(s
);
7417 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7418 gen_helper_mwait(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7422 case 0xca: /* clac */
7423 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
)
7427 gen_helper_clac(cpu_env
);
7428 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7432 case 0xcb: /* stac */
7433 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
)
7437 gen_helper_stac(cpu_env
);
7438 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7442 CASE_MODRM_MEM_OP(1): /* sidt */
7443 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_READ
);
7444 gen_lea_modrm(env
, s
, modrm
);
7445 tcg_gen_ld32u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7446 gen_op_st_v(s
, MO_16
, s
->T0
, s
->A0
);
7447 gen_add_A0_im(s
, 2);
7448 tcg_gen_ld_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, idt
.base
));
7449 if (dflag
== MO_16
) {
7450 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xffffff);
7452 gen_op_st_v(s
, CODE64(s
) + MO_32
, s
->T0
, s
->A0
);
7455 case 0xd0: /* xgetbv */
7456 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
7457 || (s
->prefix
& (PREFIX_LOCK
| PREFIX_DATA
7458 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
7461 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_ECX
]);
7462 gen_helper_xgetbv(s
->tmp1_i64
, cpu_env
, s
->tmp2_i32
);
7463 tcg_gen_extr_i64_tl(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
], s
->tmp1_i64
);
7466 case 0xd1: /* xsetbv */
7467 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
7468 || (s
->prefix
& (PREFIX_LOCK
| PREFIX_DATA
7469 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
7472 if (!check_cpl0(s
)) {
7475 tcg_gen_concat_tl_i64(s
->tmp1_i64
, cpu_regs
[R_EAX
],
7477 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_ECX
]);
7478 gen_helper_xsetbv(cpu_env
, s
->tmp2_i32
, s
->tmp1_i64
);
7479 /* End TB because translation flags may change. */
7480 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7484 case 0xd8: /* VMRUN */
7485 if (!(s
->flags
& HF_SVME_MASK
) || !PE(s
)) {
7488 if (!check_cpl0(s
)) {
7491 gen_update_cc_op(s
);
7492 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7493 gen_helper_vmrun(cpu_env
, tcg_const_i32(s
->aflag
- 1),
7494 tcg_const_i32(s
->pc
- pc_start
));
7495 tcg_gen_exit_tb(NULL
, 0);
7496 s
->base
.is_jmp
= DISAS_NORETURN
;
7499 case 0xd9: /* VMMCALL */
7500 if (!(s
->flags
& HF_SVME_MASK
)) {
7503 gen_update_cc_op(s
);
7504 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7505 gen_helper_vmmcall(cpu_env
);
7508 case 0xda: /* VMLOAD */
7509 if (!(s
->flags
& HF_SVME_MASK
) || !PE(s
)) {
7512 if (!check_cpl0(s
)) {
7515 gen_update_cc_op(s
);
7516 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7517 gen_helper_vmload(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7520 case 0xdb: /* VMSAVE */
7521 if (!(s
->flags
& HF_SVME_MASK
) || !PE(s
)) {
7524 if (!check_cpl0(s
)) {
7527 gen_update_cc_op(s
);
7528 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7529 gen_helper_vmsave(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7532 case 0xdc: /* STGI */
7533 if ((!(s
->flags
& HF_SVME_MASK
)
7534 && !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
))
7538 if (!check_cpl0(s
)) {
7541 gen_update_cc_op(s
);
7542 gen_helper_stgi(cpu_env
);
7543 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7547 case 0xdd: /* CLGI */
7548 if (!(s
->flags
& HF_SVME_MASK
) || !PE(s
)) {
7551 if (!check_cpl0(s
)) {
7554 gen_update_cc_op(s
);
7555 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7556 gen_helper_clgi(cpu_env
);
7559 case 0xde: /* SKINIT */
7560 if ((!(s
->flags
& HF_SVME_MASK
)
7561 && !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
))
7565 gen_update_cc_op(s
);
7566 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7567 gen_helper_skinit(cpu_env
);
7570 case 0xdf: /* INVLPGA */
7571 if (!(s
->flags
& HF_SVME_MASK
) || !PE(s
)) {
7574 if (!check_cpl0(s
)) {
7577 gen_update_cc_op(s
);
7578 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7579 gen_helper_invlpga(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7582 CASE_MODRM_MEM_OP(2): /* lgdt */
7583 if (!check_cpl0(s
)) {
7586 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_WRITE
);
7587 gen_lea_modrm(env
, s
, modrm
);
7588 gen_op_ld_v(s
, MO_16
, s
->T1
, s
->A0
);
7589 gen_add_A0_im(s
, 2);
7590 gen_op_ld_v(s
, CODE64(s
) + MO_32
, s
->T0
, s
->A0
);
7591 if (dflag
== MO_16
) {
7592 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xffffff);
7594 tcg_gen_st_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7595 tcg_gen_st32_tl(s
->T1
, cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7598 CASE_MODRM_MEM_OP(3): /* lidt */
7599 if (!check_cpl0(s
)) {
7602 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_WRITE
);
7603 gen_lea_modrm(env
, s
, modrm
);
7604 gen_op_ld_v(s
, MO_16
, s
->T1
, s
->A0
);
7605 gen_add_A0_im(s
, 2);
7606 gen_op_ld_v(s
, CODE64(s
) + MO_32
, s
->T0
, s
->A0
);
7607 if (dflag
== MO_16
) {
7608 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xffffff);
7610 tcg_gen_st_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, idt
.base
));
7611 tcg_gen_st32_tl(s
->T1
, cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7614 CASE_MODRM_OP(4): /* smsw */
7615 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_CR0
);
7616 tcg_gen_ld_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, cr
[0]));
7618 * In 32-bit mode, the higher 16 bits of the destination
7619 * register are undefined. In practice CR0[31:0] is stored
7620 * just like in 64-bit mode.
7622 mod
= (modrm
>> 6) & 3;
7623 ot
= (mod
!= 3 ? MO_16
: s
->dflag
);
7624 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7626 case 0xee: /* rdpkru */
7627 if (prefixes
& PREFIX_LOCK
) {
7630 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_ECX
]);
7631 gen_helper_rdpkru(s
->tmp1_i64
, cpu_env
, s
->tmp2_i32
);
7632 tcg_gen_extr_i64_tl(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
], s
->tmp1_i64
);
7634 case 0xef: /* wrpkru */
7635 if (prefixes
& PREFIX_LOCK
) {
7638 tcg_gen_concat_tl_i64(s
->tmp1_i64
, cpu_regs
[R_EAX
],
7640 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_ECX
]);
7641 gen_helper_wrpkru(cpu_env
, s
->tmp2_i32
, s
->tmp1_i64
);
7643 CASE_MODRM_OP(6): /* lmsw */
7644 if (!check_cpl0(s
)) {
7647 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7648 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7649 gen_helper_lmsw(cpu_env
, s
->T0
);
7650 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7654 CASE_MODRM_MEM_OP(7): /* invlpg */
7655 if (!check_cpl0(s
)) {
7658 gen_update_cc_op(s
);
7659 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7660 gen_lea_modrm(env
, s
, modrm
);
7661 gen_helper_invlpg(cpu_env
, s
->A0
);
7662 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7666 case 0xf8: /* swapgs */
7667 #ifdef TARGET_X86_64
7669 if (check_cpl0(s
)) {
7670 tcg_gen_mov_tl(s
->T0
, cpu_seg_base
[R_GS
]);
7671 tcg_gen_ld_tl(cpu_seg_base
[R_GS
], cpu_env
,
7672 offsetof(CPUX86State
, kernelgsbase
));
7673 tcg_gen_st_tl(s
->T0
, cpu_env
,
7674 offsetof(CPUX86State
, kernelgsbase
));
7681 case 0xf9: /* rdtscp */
7682 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_RDTSCP
)) {
7685 gen_update_cc_op(s
);
7686 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7687 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7690 gen_helper_rdtscp(cpu_env
);
7691 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7692 gen_jmp(s
, s
->pc
- s
->cs_base
);
7701 case 0x108: /* invd */
7702 case 0x109: /* wbinvd */
7703 if (check_cpl0(s
)) {
7704 gen_svm_check_intercept(s
, pc_start
, (b
& 2) ? SVM_EXIT_INVD
: SVM_EXIT_WBINVD
);
7708 case 0x63: /* arpl or movslS (x86_64) */
7709 #ifdef TARGET_X86_64
7712 /* d_ot is the size of destination */
7715 modrm
= x86_ldub_code(env
, s
);
7716 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
7717 mod
= (modrm
>> 6) & 3;
7718 rm
= (modrm
& 7) | REX_B(s
);
7721 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, rm
);
7723 if (d_ot
== MO_64
) {
7724 tcg_gen_ext32s_tl(s
->T0
, s
->T0
);
7726 gen_op_mov_reg_v(s
, d_ot
, reg
, s
->T0
);
7728 gen_lea_modrm(env
, s
, modrm
);
7729 gen_op_ld_v(s
, MO_32
| MO_SIGN
, s
->T0
, s
->A0
);
7730 gen_op_mov_reg_v(s
, d_ot
, reg
, s
->T0
);
7736 TCGv t0
, t1
, t2
, a0
;
7738 if (!PE(s
) || VM86(s
))
7740 t0
= tcg_temp_local_new();
7741 t1
= tcg_temp_local_new();
7742 t2
= tcg_temp_local_new();
7744 modrm
= x86_ldub_code(env
, s
);
7745 reg
= (modrm
>> 3) & 7;
7746 mod
= (modrm
>> 6) & 3;
7749 gen_lea_modrm(env
, s
, modrm
);
7750 gen_op_ld_v(s
, ot
, t0
, s
->A0
);
7751 a0
= tcg_temp_local_new();
7752 tcg_gen_mov_tl(a0
, s
->A0
);
7754 gen_op_mov_v_reg(s
, ot
, t0
, rm
);
7757 gen_op_mov_v_reg(s
, ot
, t1
, reg
);
7758 tcg_gen_andi_tl(s
->tmp0
, t0
, 3);
7759 tcg_gen_andi_tl(t1
, t1
, 3);
7760 tcg_gen_movi_tl(t2
, 0);
7761 label1
= gen_new_label();
7762 tcg_gen_brcond_tl(TCG_COND_GE
, s
->tmp0
, t1
, label1
);
7763 tcg_gen_andi_tl(t0
, t0
, ~3);
7764 tcg_gen_or_tl(t0
, t0
, t1
);
7765 tcg_gen_movi_tl(t2
, CC_Z
);
7766 gen_set_label(label1
);
7768 gen_op_st_v(s
, ot
, t0
, a0
);
7771 gen_op_mov_reg_v(s
, ot
, rm
, t0
);
7773 gen_compute_eflags(s
);
7774 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_Z
);
7775 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, t2
);
7781 case 0x102: /* lar */
7782 case 0x103: /* lsl */
7786 if (!PE(s
) || VM86(s
))
7788 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
7789 modrm
= x86_ldub_code(env
, s
);
7790 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
7791 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7792 t0
= tcg_temp_local_new();
7793 gen_update_cc_op(s
);
7795 gen_helper_lar(t0
, cpu_env
, s
->T0
);
7797 gen_helper_lsl(t0
, cpu_env
, s
->T0
);
7799 tcg_gen_andi_tl(s
->tmp0
, cpu_cc_src
, CC_Z
);
7800 label1
= gen_new_label();
7801 tcg_gen_brcondi_tl(TCG_COND_EQ
, s
->tmp0
, 0, label1
);
7802 gen_op_mov_reg_v(s
, ot
, reg
, t0
);
7803 gen_set_label(label1
);
7804 set_cc_op(s
, CC_OP_EFLAGS
);
7809 modrm
= x86_ldub_code(env
, s
);
7810 mod
= (modrm
>> 6) & 3;
7811 op
= (modrm
>> 3) & 7;
7813 case 0: /* prefetchnta */
7814 case 1: /* prefetchnt0 */
7815 case 2: /* prefetchnt0 */
7816 case 3: /* prefetchnt0 */
7819 gen_nop_modrm(env
, s
, modrm
);
7820 /* nothing more to do */
7822 default: /* nop (multi byte) */
7823 gen_nop_modrm(env
, s
, modrm
);
7828 modrm
= x86_ldub_code(env
, s
);
7829 if (s
->flags
& HF_MPX_EN_MASK
) {
7830 mod
= (modrm
>> 6) & 3;
7831 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
7832 if (prefixes
& PREFIX_REPZ
) {
7835 || (prefixes
& PREFIX_LOCK
)
7836 || s
->aflag
== MO_16
) {
7839 gen_bndck(env
, s
, modrm
, TCG_COND_LTU
, cpu_bndl
[reg
]);
7840 } else if (prefixes
& PREFIX_REPNZ
) {
7843 || (prefixes
& PREFIX_LOCK
)
7844 || s
->aflag
== MO_16
) {
7847 TCGv_i64 notu
= tcg_temp_new_i64();
7848 tcg_gen_not_i64(notu
, cpu_bndu
[reg
]);
7849 gen_bndck(env
, s
, modrm
, TCG_COND_GTU
, notu
);
7850 tcg_temp_free_i64(notu
);
7851 } else if (prefixes
& PREFIX_DATA
) {
7852 /* bndmov -- from reg/mem */
7853 if (reg
>= 4 || s
->aflag
== MO_16
) {
7857 int reg2
= (modrm
& 7) | REX_B(s
);
7858 if (reg2
>= 4 || (prefixes
& PREFIX_LOCK
)) {
7861 if (s
->flags
& HF_MPX_IU_MASK
) {
7862 tcg_gen_mov_i64(cpu_bndl
[reg
], cpu_bndl
[reg2
]);
7863 tcg_gen_mov_i64(cpu_bndu
[reg
], cpu_bndu
[reg2
]);
7866 gen_lea_modrm(env
, s
, modrm
);
7868 tcg_gen_qemu_ld_i64(cpu_bndl
[reg
], s
->A0
,
7869 s
->mem_index
, MO_LEQ
);
7870 tcg_gen_addi_tl(s
->A0
, s
->A0
, 8);
7871 tcg_gen_qemu_ld_i64(cpu_bndu
[reg
], s
->A0
,
7872 s
->mem_index
, MO_LEQ
);
7874 tcg_gen_qemu_ld_i64(cpu_bndl
[reg
], s
->A0
,
7875 s
->mem_index
, MO_LEUL
);
7876 tcg_gen_addi_tl(s
->A0
, s
->A0
, 4);
7877 tcg_gen_qemu_ld_i64(cpu_bndu
[reg
], s
->A0
,
7878 s
->mem_index
, MO_LEUL
);
7880 /* bnd registers are now in-use */
7881 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7883 } else if (mod
!= 3) {
7885 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7887 || (prefixes
& PREFIX_LOCK
)
7888 || s
->aflag
== MO_16
7893 tcg_gen_addi_tl(s
->A0
, cpu_regs
[a
.base
], a
.disp
);
7895 tcg_gen_movi_tl(s
->A0
, 0);
7897 gen_lea_v_seg(s
, s
->aflag
, s
->A0
, a
.def_seg
, s
->override
);
7899 tcg_gen_mov_tl(s
->T0
, cpu_regs
[a
.index
]);
7901 tcg_gen_movi_tl(s
->T0
, 0);
7904 gen_helper_bndldx64(cpu_bndl
[reg
], cpu_env
, s
->A0
, s
->T0
);
7905 tcg_gen_ld_i64(cpu_bndu
[reg
], cpu_env
,
7906 offsetof(CPUX86State
, mmx_t0
.MMX_Q(0)));
7908 gen_helper_bndldx32(cpu_bndu
[reg
], cpu_env
, s
->A0
, s
->T0
);
7909 tcg_gen_ext32u_i64(cpu_bndl
[reg
], cpu_bndu
[reg
]);
7910 tcg_gen_shri_i64(cpu_bndu
[reg
], cpu_bndu
[reg
], 32);
7912 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7915 gen_nop_modrm(env
, s
, modrm
);
7918 modrm
= x86_ldub_code(env
, s
);
7919 if (s
->flags
& HF_MPX_EN_MASK
) {
7920 mod
= (modrm
>> 6) & 3;
7921 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
7922 if (mod
!= 3 && (prefixes
& PREFIX_REPZ
)) {
7925 || (prefixes
& PREFIX_LOCK
)
7926 || s
->aflag
== MO_16
) {
7929 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7931 tcg_gen_extu_tl_i64(cpu_bndl
[reg
], cpu_regs
[a
.base
]);
7933 tcg_gen_ext32u_i64(cpu_bndl
[reg
], cpu_bndl
[reg
]);
7935 } else if (a
.base
== -1) {
7936 /* no base register has lower bound of 0 */
7937 tcg_gen_movi_i64(cpu_bndl
[reg
], 0);
7939 /* rip-relative generates #ud */
7942 tcg_gen_not_tl(s
->A0
, gen_lea_modrm_1(s
, a
));
7944 tcg_gen_ext32u_tl(s
->A0
, s
->A0
);
7946 tcg_gen_extu_tl_i64(cpu_bndu
[reg
], s
->A0
);
7947 /* bnd registers are now in-use */
7948 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7950 } else if (prefixes
& PREFIX_REPNZ
) {
7953 || (prefixes
& PREFIX_LOCK
)
7954 || s
->aflag
== MO_16
) {
7957 gen_bndck(env
, s
, modrm
, TCG_COND_GTU
, cpu_bndu
[reg
]);
7958 } else if (prefixes
& PREFIX_DATA
) {
7959 /* bndmov -- to reg/mem */
7960 if (reg
>= 4 || s
->aflag
== MO_16
) {
7964 int reg2
= (modrm
& 7) | REX_B(s
);
7965 if (reg2
>= 4 || (prefixes
& PREFIX_LOCK
)) {
7968 if (s
->flags
& HF_MPX_IU_MASK
) {
7969 tcg_gen_mov_i64(cpu_bndl
[reg2
], cpu_bndl
[reg
]);
7970 tcg_gen_mov_i64(cpu_bndu
[reg2
], cpu_bndu
[reg
]);
7973 gen_lea_modrm(env
, s
, modrm
);
7975 tcg_gen_qemu_st_i64(cpu_bndl
[reg
], s
->A0
,
7976 s
->mem_index
, MO_LEQ
);
7977 tcg_gen_addi_tl(s
->A0
, s
->A0
, 8);
7978 tcg_gen_qemu_st_i64(cpu_bndu
[reg
], s
->A0
,
7979 s
->mem_index
, MO_LEQ
);
7981 tcg_gen_qemu_st_i64(cpu_bndl
[reg
], s
->A0
,
7982 s
->mem_index
, MO_LEUL
);
7983 tcg_gen_addi_tl(s
->A0
, s
->A0
, 4);
7984 tcg_gen_qemu_st_i64(cpu_bndu
[reg
], s
->A0
,
7985 s
->mem_index
, MO_LEUL
);
7988 } else if (mod
!= 3) {
7990 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7992 || (prefixes
& PREFIX_LOCK
)
7993 || s
->aflag
== MO_16
7998 tcg_gen_addi_tl(s
->A0
, cpu_regs
[a
.base
], a
.disp
);
8000 tcg_gen_movi_tl(s
->A0
, 0);
8002 gen_lea_v_seg(s
, s
->aflag
, s
->A0
, a
.def_seg
, s
->override
);
8004 tcg_gen_mov_tl(s
->T0
, cpu_regs
[a
.index
]);
8006 tcg_gen_movi_tl(s
->T0
, 0);
8009 gen_helper_bndstx64(cpu_env
, s
->A0
, s
->T0
,
8010 cpu_bndl
[reg
], cpu_bndu
[reg
]);
8012 gen_helper_bndstx32(cpu_env
, s
->A0
, s
->T0
,
8013 cpu_bndl
[reg
], cpu_bndu
[reg
]);
8017 gen_nop_modrm(env
, s
, modrm
);
8019 case 0x119: case 0x11c ... 0x11f: /* nop (multi byte) */
8020 modrm
= x86_ldub_code(env
, s
);
8021 gen_nop_modrm(env
, s
, modrm
);
8023 case 0x120: /* mov reg, crN */
8024 case 0x122: /* mov crN, reg */
8025 if (check_cpl0(s
)) {
8026 modrm
= x86_ldub_code(env
, s
);
8027 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
8028 * AMD documentation (24594.pdf) and testing of
8029 * intel 386 and 486 processors all show that the mod bits
8030 * are assumed to be 1's, regardless of actual values.
8032 rm
= (modrm
& 7) | REX_B(s
);
8033 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
8038 if ((prefixes
& PREFIX_LOCK
) && (reg
== 0) &&
8039 (s
->cpuid_ext3_features
& CPUID_EXT3_CR8LEG
)) {
8048 gen_update_cc_op(s
);
8049 gen_jmp_im(s
, pc_start
- s
->cs_base
);
8051 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
8054 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
8055 gen_helper_write_crN(cpu_env
, tcg_const_i32(reg
),
8057 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8060 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
8063 gen_helper_read_crN(s
->T0
, cpu_env
, tcg_const_i32(reg
));
8064 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
8065 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
8066 gen_jmp(s
, s
->pc
- s
->cs_base
);
8075 case 0x121: /* mov reg, drN */
8076 case 0x123: /* mov drN, reg */
8077 if (check_cpl0(s
)) {
8078 #ifndef CONFIG_USER_ONLY
8079 modrm
= x86_ldub_code(env
, s
);
8080 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
8081 * AMD documentation (24594.pdf) and testing of
8082 * intel 386 and 486 processors all show that the mod bits
8083 * are assumed to be 1's, regardless of actual values.
8085 rm
= (modrm
& 7) | REX_B(s
);
8086 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
8095 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_DR0
+ reg
);
8096 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
8097 tcg_gen_movi_i32(s
->tmp2_i32
, reg
);
8098 gen_helper_set_dr(cpu_env
, s
->tmp2_i32
, s
->T0
);
8099 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8102 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_DR0
+ reg
);
8103 tcg_gen_movi_i32(s
->tmp2_i32
, reg
);
8104 gen_helper_get_dr(s
->T0
, cpu_env
, s
->tmp2_i32
);
8105 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
8107 #endif /* !CONFIG_USER_ONLY */
8110 case 0x106: /* clts */
8111 if (check_cpl0(s
)) {
8112 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
8113 gen_helper_clts(cpu_env
);
8114 /* abort block because static cpu state changed */
8115 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8119 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
8120 case 0x1c3: /* MOVNTI reg, mem */
8121 if (!(s
->cpuid_features
& CPUID_SSE2
))
8123 ot
= mo_64_32(dflag
);
8124 modrm
= x86_ldub_code(env
, s
);
8125 mod
= (modrm
>> 6) & 3;
8128 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
8129 /* generate a generic store */
8130 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
8133 modrm
= x86_ldub_code(env
, s
);
8135 CASE_MODRM_MEM_OP(0): /* fxsave */
8136 if (!(s
->cpuid_features
& CPUID_FXSR
)
8137 || (prefixes
& PREFIX_LOCK
)) {
8140 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
8141 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8144 gen_lea_modrm(env
, s
, modrm
);
8145 gen_helper_fxsave(cpu_env
, s
->A0
);
8148 CASE_MODRM_MEM_OP(1): /* fxrstor */
8149 if (!(s
->cpuid_features
& CPUID_FXSR
)
8150 || (prefixes
& PREFIX_LOCK
)) {
8153 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
8154 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8157 gen_lea_modrm(env
, s
, modrm
);
8158 gen_helper_fxrstor(cpu_env
, s
->A0
);
8161 CASE_MODRM_MEM_OP(2): /* ldmxcsr */
8162 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
)) {
8165 if (s
->flags
& HF_TS_MASK
) {
8166 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8169 gen_lea_modrm(env
, s
, modrm
);
8170 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
, s
->mem_index
, MO_LEUL
);
8171 gen_helper_ldmxcsr(cpu_env
, s
->tmp2_i32
);
8174 CASE_MODRM_MEM_OP(3): /* stmxcsr */
8175 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
)) {
8178 if (s
->flags
& HF_TS_MASK
) {
8179 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8182 gen_helper_update_mxcsr(cpu_env
);
8183 gen_lea_modrm(env
, s
, modrm
);
8184 tcg_gen_ld32u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, mxcsr
));
8185 gen_op_st_v(s
, MO_32
, s
->T0
, s
->A0
);
8188 CASE_MODRM_MEM_OP(4): /* xsave */
8189 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8190 || (prefixes
& (PREFIX_LOCK
| PREFIX_DATA
8191 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
8194 gen_lea_modrm(env
, s
, modrm
);
8195 tcg_gen_concat_tl_i64(s
->tmp1_i64
, cpu_regs
[R_EAX
],
8197 gen_helper_xsave(cpu_env
, s
->A0
, s
->tmp1_i64
);
8200 CASE_MODRM_MEM_OP(5): /* xrstor */
8201 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8202 || (prefixes
& (PREFIX_LOCK
| PREFIX_DATA
8203 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
8206 gen_lea_modrm(env
, s
, modrm
);
8207 tcg_gen_concat_tl_i64(s
->tmp1_i64
, cpu_regs
[R_EAX
],
8209 gen_helper_xrstor(cpu_env
, s
->A0
, s
->tmp1_i64
);
8210 /* XRSTOR is how MPX is enabled, which changes how
8211 we translate. Thus we need to end the TB. */
8212 gen_update_cc_op(s
);
8213 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8217 CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */
8218 if (prefixes
& PREFIX_LOCK
) {
8221 if (prefixes
& PREFIX_DATA
) {
8223 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLWB
)) {
8226 gen_nop_modrm(env
, s
, modrm
);
8229 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8230 || (s
->cpuid_xsave_features
& CPUID_XSAVE_XSAVEOPT
) == 0
8231 || (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
))) {
8234 gen_lea_modrm(env
, s
, modrm
);
8235 tcg_gen_concat_tl_i64(s
->tmp1_i64
, cpu_regs
[R_EAX
],
8237 gen_helper_xsaveopt(cpu_env
, s
->A0
, s
->tmp1_i64
);
8241 CASE_MODRM_MEM_OP(7): /* clflush / clflushopt */
8242 if (prefixes
& PREFIX_LOCK
) {
8245 if (prefixes
& PREFIX_DATA
) {
8247 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLFLUSHOPT
)) {
8252 if ((s
->prefix
& (PREFIX_REPZ
| PREFIX_REPNZ
))
8253 || !(s
->cpuid_features
& CPUID_CLFLUSH
)) {
8257 gen_nop_modrm(env
, s
, modrm
);
8260 case 0xc0 ... 0xc7: /* rdfsbase (f3 0f ae /0) */
8261 case 0xc8 ... 0xcf: /* rdgsbase (f3 0f ae /1) */
8262 case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */
8263 case 0xd8 ... 0xdf: /* wrgsbase (f3 0f ae /3) */
8265 && (prefixes
& PREFIX_REPZ
)
8266 && !(prefixes
& PREFIX_LOCK
)
8267 && (s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_FSGSBASE
)) {
8268 TCGv base
, treg
, src
, dst
;
8270 /* Preserve hflags bits by testing CR4 at runtime. */
8271 tcg_gen_movi_i32(s
->tmp2_i32
, CR4_FSGSBASE_MASK
);
8272 gen_helper_cr4_testbit(cpu_env
, s
->tmp2_i32
);
8274 base
= cpu_seg_base
[modrm
& 8 ? R_GS
: R_FS
];
8275 treg
= cpu_regs
[(modrm
& 7) | REX_B(s
)];
8279 dst
= base
, src
= treg
;
8282 dst
= treg
, src
= base
;
8285 if (s
->dflag
== MO_32
) {
8286 tcg_gen_ext32u_tl(dst
, src
);
8288 tcg_gen_mov_tl(dst
, src
);
8294 case 0xf8: /* sfence / pcommit */
8295 if (prefixes
& PREFIX_DATA
) {
8297 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_PCOMMIT
)
8298 || (prefixes
& PREFIX_LOCK
)) {
8304 case 0xf9 ... 0xff: /* sfence */
8305 if (!(s
->cpuid_features
& CPUID_SSE
)
8306 || (prefixes
& PREFIX_LOCK
)) {
8309 tcg_gen_mb(TCG_MO_ST_ST
| TCG_BAR_SC
);
8311 case 0xe8 ... 0xef: /* lfence */
8312 if (!(s
->cpuid_features
& CPUID_SSE
)
8313 || (prefixes
& PREFIX_LOCK
)) {
8316 tcg_gen_mb(TCG_MO_LD_LD
| TCG_BAR_SC
);
8318 case 0xf0 ... 0xf7: /* mfence */
8319 if (!(s
->cpuid_features
& CPUID_SSE2
)
8320 || (prefixes
& PREFIX_LOCK
)) {
8323 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8331 case 0x10d: /* 3DNow! prefetch(w) */
8332 modrm
= x86_ldub_code(env
, s
);
8333 mod
= (modrm
>> 6) & 3;
8336 gen_nop_modrm(env
, s
, modrm
);
8338 case 0x1aa: /* rsm */
8339 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_RSM
);
8340 if (!(s
->flags
& HF_SMM_MASK
))
8342 #ifdef CONFIG_USER_ONLY
8343 /* we should not be in SMM mode */
8344 g_assert_not_reached();
8346 gen_update_cc_op(s
);
8347 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8348 gen_helper_rsm(cpu_env
);
8349 #endif /* CONFIG_USER_ONLY */
8352 case 0x1b8: /* SSE4.2 popcnt */
8353 if ((prefixes
& (PREFIX_REPZ
| PREFIX_LOCK
| PREFIX_REPNZ
)) !=
8356 if (!(s
->cpuid_ext_features
& CPUID_EXT_POPCNT
))
8359 modrm
= x86_ldub_code(env
, s
);
8360 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
8362 if (s
->prefix
& PREFIX_DATA
) {
8365 ot
= mo_64_32(dflag
);
8368 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
8369 gen_extu(ot
, s
->T0
);
8370 tcg_gen_mov_tl(cpu_cc_src
, s
->T0
);
8371 tcg_gen_ctpop_tl(s
->T0
, s
->T0
);
8372 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
8374 set_cc_op(s
, CC_OP_POPCNT
);
8376 case 0x10e ... 0x10f:
8377 /* 3DNow! instructions, ignore prefixes */
8378 s
->prefix
&= ~(PREFIX_REPZ
| PREFIX_REPNZ
| PREFIX_DATA
);
8380 case 0x110 ... 0x117:
8381 case 0x128 ... 0x12f:
8382 case 0x138 ... 0x13a:
8383 case 0x150 ... 0x179:
8384 case 0x17c ... 0x17f:
8386 case 0x1c4 ... 0x1c6:
8387 case 0x1d0 ... 0x1fe:
8388 gen_sse(env
, s
, b
, pc_start
);
8395 gen_illegal_opcode(s
);
8398 gen_unknown_opcode(env
, s
);
8402 void tcg_x86_init(void)
8404 static const char reg_names
[CPU_NB_REGS
][4] = {
8405 #ifdef TARGET_X86_64
8433 static const char seg_base_names
[6][8] = {
8441 static const char bnd_regl_names
[4][8] = {
8442 "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb"
8444 static const char bnd_regu_names
[4][8] = {
8445 "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub"
8449 cpu_cc_op
= tcg_global_mem_new_i32(cpu_env
,
8450 offsetof(CPUX86State
, cc_op
), "cc_op");
8451 cpu_cc_dst
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_dst
),
8453 cpu_cc_src
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_src
),
8455 cpu_cc_src2
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_src2
),
8458 for (i
= 0; i
< CPU_NB_REGS
; ++i
) {
8459 cpu_regs
[i
] = tcg_global_mem_new(cpu_env
,
8460 offsetof(CPUX86State
, regs
[i
]),
8464 for (i
= 0; i
< 6; ++i
) {
8466 = tcg_global_mem_new(cpu_env
,
8467 offsetof(CPUX86State
, segs
[i
].base
),
8471 for (i
= 0; i
< 4; ++i
) {
8473 = tcg_global_mem_new_i64(cpu_env
,
8474 offsetof(CPUX86State
, bnd_regs
[i
].lb
),
8477 = tcg_global_mem_new_i64(cpu_env
,
8478 offsetof(CPUX86State
, bnd_regs
[i
].ub
),
8483 static void i386_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cpu
)
8485 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8486 CPUX86State
*env
= cpu
->env_ptr
;
8487 uint32_t flags
= dc
->base
.tb
->flags
;
8488 int cpl
= (flags
>> HF_CPL_SHIFT
) & 3;
8489 int iopl
= (flags
>> IOPL_SHIFT
) & 3;
8491 dc
->cs_base
= dc
->base
.tb
->cs_base
;
8493 #ifndef CONFIG_USER_ONLY
8498 /* We make some simplifying assumptions; validate they're correct. */
8499 g_assert(PE(dc
) == ((flags
& HF_PE_MASK
) != 0));
8500 g_assert(CPL(dc
) == cpl
);
8501 g_assert(IOPL(dc
) == iopl
);
8502 g_assert(VM86(dc
) == ((flags
& HF_VM_MASK
) != 0));
8503 g_assert(CODE32(dc
) == ((flags
& HF_CS32_MASK
) != 0));
8504 g_assert(CODE64(dc
) == ((flags
& HF_CS64_MASK
) != 0));
8505 g_assert(SS32(dc
) == ((flags
& HF_SS32_MASK
) != 0));
8506 g_assert(LMA(dc
) == ((flags
& HF_LMA_MASK
) != 0));
8507 g_assert(ADDSEG(dc
) == ((flags
& HF_ADDSEG_MASK
) != 0));
8509 dc
->tf
= (flags
>> TF_SHIFT
) & 1;
8510 dc
->cc_op
= CC_OP_DYNAMIC
;
8511 dc
->cc_op_dirty
= false;
8512 dc
->popl_esp_hack
= 0;
8513 /* select memory access functions */
8515 #ifdef CONFIG_SOFTMMU
8516 dc
->mem_index
= cpu_mmu_index(env
, false);
8518 dc
->cpuid_features
= env
->features
[FEAT_1_EDX
];
8519 dc
->cpuid_ext_features
= env
->features
[FEAT_1_ECX
];
8520 dc
->cpuid_ext2_features
= env
->features
[FEAT_8000_0001_EDX
];
8521 dc
->cpuid_ext3_features
= env
->features
[FEAT_8000_0001_ECX
];
8522 dc
->cpuid_7_0_ebx_features
= env
->features
[FEAT_7_0_EBX
];
8523 dc
->cpuid_xsave_features
= env
->features
[FEAT_XSAVE
];
8524 dc
->jmp_opt
= !(dc
->tf
|| dc
->base
.singlestep_enabled
||
8525 (flags
& HF_INHIBIT_IRQ_MASK
));
8526 /* Do not optimize repz jumps at all in icount mode, because
8527 rep movsS instructions are execured with different paths
8528 in !repz_opt and repz_opt modes. The first one was used
8529 always except single step mode. And this setting
8530 disables jumps optimization and control paths become
8531 equivalent in run and single step modes.
8532 Now there will be no jump optimization for repz in
8533 record/replay modes and there will always be an
8534 additional step for ecx=0 when icount is enabled.
8536 dc
->repz_opt
= !dc
->jmp_opt
&& !(tb_cflags(dc
->base
.tb
) & CF_USE_ICOUNT
);
8538 dc
->T0
= tcg_temp_new();
8539 dc
->T1
= tcg_temp_new();
8540 dc
->A0
= tcg_temp_new();
8542 dc
->tmp0
= tcg_temp_new();
8543 dc
->tmp1_i64
= tcg_temp_new_i64();
8544 dc
->tmp2_i32
= tcg_temp_new_i32();
8545 dc
->tmp3_i32
= tcg_temp_new_i32();
8546 dc
->tmp4
= tcg_temp_new();
8547 dc
->ptr0
= tcg_temp_new_ptr();
8548 dc
->ptr1
= tcg_temp_new_ptr();
8549 dc
->cc_srcT
= tcg_temp_local_new();
8552 static void i386_tr_tb_start(DisasContextBase
*db
, CPUState
*cpu
)
8556 static void i386_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
8558 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8560 tcg_gen_insn_start(dc
->base
.pc_next
, dc
->cc_op
);
8563 static bool i386_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cpu
,
8564 const CPUBreakpoint
*bp
)
8566 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8567 /* If RF is set, suppress an internally generated breakpoint. */
8568 int flags
= dc
->base
.tb
->flags
& HF_RF_MASK
? BP_GDB
: BP_ANY
;
8569 if (bp
->flags
& flags
) {
8570 gen_debug(dc
, dc
->base
.pc_next
- dc
->cs_base
);
8571 dc
->base
.is_jmp
= DISAS_NORETURN
;
8572 /* The address covered by the breakpoint must be included in
8573 [tb->pc, tb->pc + tb->size) in order to for it to be
8574 properly cleared -- thus we increment the PC here so that
8575 the generic logic setting tb->size later does the right thing. */
8576 dc
->base
.pc_next
+= 1;
8583 static void i386_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
8585 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8586 target_ulong pc_next
;
8588 #ifdef TARGET_VSYSCALL_PAGE
8590 * Detect entry into the vsyscall page and invoke the syscall.
8592 if ((dc
->base
.pc_next
& TARGET_PAGE_MASK
) == TARGET_VSYSCALL_PAGE
) {
8593 gen_exception(dc
, EXCP_VSYSCALL
, dc
->base
.pc_next
);
8598 pc_next
= disas_insn(dc
, cpu
);
8600 if (dc
->tf
|| (dc
->base
.tb
->flags
& HF_INHIBIT_IRQ_MASK
)) {
8601 /* if single step mode, we generate only one instruction and
8602 generate an exception */
8603 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
8604 the flag and abort the translation to give the irqs a
8606 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
8607 } else if ((tb_cflags(dc
->base
.tb
) & CF_USE_ICOUNT
)
8608 && ((pc_next
& TARGET_PAGE_MASK
)
8609 != ((pc_next
+ TARGET_MAX_INSN_SIZE
- 1)
8611 || (pc_next
& ~TARGET_PAGE_MASK
) == 0)) {
8612 /* Do not cross the boundary of the pages in icount mode,
8613 it can cause an exception. Do it only when boundary is
8614 crossed by the first instruction in the block.
8615 If current instruction already crossed the bound - it's ok,
8616 because an exception hasn't stopped this code.
8618 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
8619 } else if ((pc_next
- dc
->base
.pc_first
) >= (TARGET_PAGE_SIZE
- 32)) {
8620 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
8623 dc
->base
.pc_next
= pc_next
;
8626 static void i386_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cpu
)
8628 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8630 if (dc
->base
.is_jmp
== DISAS_TOO_MANY
) {
8631 gen_jmp_im(dc
, dc
->base
.pc_next
- dc
->cs_base
);
8636 static void i386_tr_disas_log(const DisasContextBase
*dcbase
,
8639 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8641 qemu_log("IN: %s\n", lookup_symbol(dc
->base
.pc_first
));
8642 log_target_disas(cpu
, dc
->base
.pc_first
, dc
->base
.tb
->size
);
8645 static const TranslatorOps i386_tr_ops
= {
8646 .init_disas_context
= i386_tr_init_disas_context
,
8647 .tb_start
= i386_tr_tb_start
,
8648 .insn_start
= i386_tr_insn_start
,
8649 .breakpoint_check
= i386_tr_breakpoint_check
,
8650 .translate_insn
= i386_tr_translate_insn
,
8651 .tb_stop
= i386_tr_tb_stop
,
8652 .disas_log
= i386_tr_disas_log
,
8655 /* generate intermediate code for basic block 'tb'. */
8656 void gen_intermediate_code(CPUState
*cpu
, TranslationBlock
*tb
, int max_insns
)
8660 translator_loop(&i386_tr_ops
, &dc
.base
, cpu
, tb
, max_insns
);
8663 void restore_state_to_opc(CPUX86State
*env
, TranslationBlock
*tb
,
8666 int cc_op
= data
[1];
8667 env
->eip
= data
[0] - tb
->cs_base
;
8668 if (cc_op
!= CC_OP_DYNAMIC
) {