4 * Copyright (c) 2003 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 #include "qemu/osdep.h"
21 #include "qemu/host-utils.h"
23 #include "disas/disas.h"
24 #include "exec/exec-all.h"
26 #include "exec/cpu_ldst.h"
28 #include "exec/helper-proto.h"
29 #include "exec/helper-gen.h"
31 #if defined(CONFIG_USER_ONLY) && defined(TARGET_X86_64)
35 #include "trace-tcg.h"
39 #define PREFIX_REPZ 0x01
40 #define PREFIX_REPNZ 0x02
41 #define PREFIX_LOCK 0x04
42 #define PREFIX_DATA 0x08
43 #define PREFIX_ADR 0x10
44 #define PREFIX_VEX 0x20
47 #define CODE64(s) ((s)->code64)
48 #define REX_X(s) ((s)->rex_x)
49 #define REX_B(s) ((s)->rex_b)
64 /* For a switch indexed by MODRM, match all memory operands for a given OP. */
65 #define CASE_MODRM_MEM_OP(OP) \
66 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
67 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
68 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7
70 #define CASE_MODRM_OP(OP) \
71 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
72 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
73 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7: \
74 case (3 << 6) | (OP << 3) | 0 ... (3 << 6) | (OP << 3) | 7
76 //#define MACRO_TEST 1
78 /* global register indexes */
79 static TCGv_env cpu_env
;
81 static TCGv cpu_cc_dst
, cpu_cc_src
, cpu_cc_src2
, cpu_cc_srcT
;
82 static TCGv_i32 cpu_cc_op
;
83 static TCGv cpu_regs
[CPU_NB_REGS
];
84 static TCGv cpu_seg_base
[6];
85 static TCGv_i64 cpu_bndl
[4];
86 static TCGv_i64 cpu_bndu
[4];
88 static TCGv cpu_T0
, cpu_T1
;
89 /* local register indexes (only used inside old micro ops) */
90 static TCGv cpu_tmp0
, cpu_tmp4
;
91 static TCGv_ptr cpu_ptr0
, cpu_ptr1
;
92 static TCGv_i32 cpu_tmp2_i32
, cpu_tmp3_i32
;
93 static TCGv_i64 cpu_tmp1_i64
;
95 #include "exec/gen-icount.h"
98 static int x86_64_hregs
;
101 typedef struct DisasContext
{
102 /* current insn context */
103 int override
; /* -1 if no override */
107 target_ulong pc_start
;
108 target_ulong pc
; /* pc = eip + cs_base */
109 int is_jmp
; /* 1 = means jump (stop translation), 2 means CPU
110 static state change (stop translation) */
111 /* current block context */
112 target_ulong cs_base
; /* base of CS segment */
113 int pe
; /* protected mode */
114 int code32
; /* 32 bit code segment */
116 int lma
; /* long mode active */
117 int code64
; /* 64 bit code segment */
120 int vex_l
; /* vex vector length */
121 int vex_v
; /* vex vvvv register, without 1's compliment. */
122 int ss32
; /* 32 bit stack segment */
123 CCOp cc_op
; /* current CC operation */
125 int addseg
; /* non zero if either DS/ES/SS have a non zero base */
126 int f_st
; /* currently unused */
127 int vm86
; /* vm86 mode */
130 int tf
; /* TF cpu flag */
131 int singlestep_enabled
; /* "hardware" single step enabled */
132 int jmp_opt
; /* use direct block chaining for direct jumps */
133 int repz_opt
; /* optimize jumps within repz instructions */
134 int mem_index
; /* select memory access functions */
135 uint64_t flags
; /* all execution flags */
136 struct TranslationBlock
*tb
;
137 int popl_esp_hack
; /* for correct popl with esp base handling */
138 int rip_offset
; /* only used in x86_64, but left for simplicity */
140 int cpuid_ext_features
;
141 int cpuid_ext2_features
;
142 int cpuid_ext3_features
;
143 int cpuid_7_0_ebx_features
;
144 int cpuid_xsave_features
;
147 static void gen_eob(DisasContext
*s
);
148 static void gen_jmp(DisasContext
*s
, target_ulong eip
);
149 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
);
150 static void gen_op(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
);
152 /* i386 arith/logic operations */
172 OP_SHL1
, /* undocumented */
188 /* I386 int registers */
189 OR_EAX
, /* MUST be even numbered */
198 OR_TMP0
= 16, /* temporary operand register */
200 OR_A0
, /* temporary register used when doing address evaluation */
210 /* Bit set if the global variable is live after setting CC_OP to X. */
211 static const uint8_t cc_op_live
[CC_OP_NB
] = {
212 [CC_OP_DYNAMIC
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
213 [CC_OP_EFLAGS
] = USES_CC_SRC
,
214 [CC_OP_MULB
... CC_OP_MULQ
] = USES_CC_DST
| USES_CC_SRC
,
215 [CC_OP_ADDB
... CC_OP_ADDQ
] = USES_CC_DST
| USES_CC_SRC
,
216 [CC_OP_ADCB
... CC_OP_ADCQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
217 [CC_OP_SUBB
... CC_OP_SUBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRCT
,
218 [CC_OP_SBBB
... CC_OP_SBBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
219 [CC_OP_LOGICB
... CC_OP_LOGICQ
] = USES_CC_DST
,
220 [CC_OP_INCB
... CC_OP_INCQ
] = USES_CC_DST
| USES_CC_SRC
,
221 [CC_OP_DECB
... CC_OP_DECQ
] = USES_CC_DST
| USES_CC_SRC
,
222 [CC_OP_SHLB
... CC_OP_SHLQ
] = USES_CC_DST
| USES_CC_SRC
,
223 [CC_OP_SARB
... CC_OP_SARQ
] = USES_CC_DST
| USES_CC_SRC
,
224 [CC_OP_BMILGB
... CC_OP_BMILGQ
] = USES_CC_DST
| USES_CC_SRC
,
225 [CC_OP_ADCX
] = USES_CC_DST
| USES_CC_SRC
,
226 [CC_OP_ADOX
] = USES_CC_SRC
| USES_CC_SRC2
,
227 [CC_OP_ADCOX
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
229 [CC_OP_POPCNT
] = USES_CC_SRC
,
232 static void set_cc_op(DisasContext
*s
, CCOp op
)
236 if (s
->cc_op
== op
) {
240 /* Discard CC computation that will no longer be used. */
241 dead
= cc_op_live
[s
->cc_op
] & ~cc_op_live
[op
];
242 if (dead
& USES_CC_DST
) {
243 tcg_gen_discard_tl(cpu_cc_dst
);
245 if (dead
& USES_CC_SRC
) {
246 tcg_gen_discard_tl(cpu_cc_src
);
248 if (dead
& USES_CC_SRC2
) {
249 tcg_gen_discard_tl(cpu_cc_src2
);
251 if (dead
& USES_CC_SRCT
) {
252 tcg_gen_discard_tl(cpu_cc_srcT
);
255 if (op
== CC_OP_DYNAMIC
) {
256 /* The DYNAMIC setting is translator only, and should never be
257 stored. Thus we always consider it clean. */
258 s
->cc_op_dirty
= false;
260 /* Discard any computed CC_OP value (see shifts). */
261 if (s
->cc_op
== CC_OP_DYNAMIC
) {
262 tcg_gen_discard_i32(cpu_cc_op
);
264 s
->cc_op_dirty
= true;
269 static void gen_update_cc_op(DisasContext
*s
)
271 if (s
->cc_op_dirty
) {
272 tcg_gen_movi_i32(cpu_cc_op
, s
->cc_op
);
273 s
->cc_op_dirty
= false;
279 #define NB_OP_SIZES 4
281 #else /* !TARGET_X86_64 */
283 #define NB_OP_SIZES 3
285 #endif /* !TARGET_X86_64 */
287 #if defined(HOST_WORDS_BIGENDIAN)
288 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
289 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
290 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
291 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
292 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
294 #define REG_B_OFFSET 0
295 #define REG_H_OFFSET 1
296 #define REG_W_OFFSET 0
297 #define REG_L_OFFSET 0
298 #define REG_LH_OFFSET 4
301 /* In instruction encodings for byte register accesses the
302 * register number usually indicates "low 8 bits of register N";
303 * however there are some special cases where N 4..7 indicates
304 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
305 * true for this special case, false otherwise.
307 static inline bool byte_reg_is_xH(int reg
)
313 if (reg
>= 8 || x86_64_hregs
) {
320 /* Select the size of a push/pop operation. */
321 static inline TCGMemOp
mo_pushpop(DisasContext
*s
, TCGMemOp ot
)
324 return ot
== MO_16
? MO_16
: MO_64
;
330 /* Select the size of the stack pointer. */
331 static inline TCGMemOp
mo_stacksize(DisasContext
*s
)
333 return CODE64(s
) ? MO_64
: s
->ss32
? MO_32
: MO_16
;
336 /* Select only size 64 else 32. Used for SSE operand sizes. */
337 static inline TCGMemOp
mo_64_32(TCGMemOp ot
)
340 return ot
== MO_64
? MO_64
: MO_32
;
346 /* Select size 8 if lsb of B is clear, else OT. Used for decoding
347 byte vs word opcodes. */
348 static inline TCGMemOp
mo_b_d(int b
, TCGMemOp ot
)
350 return b
& 1 ? ot
: MO_8
;
353 /* Select size 8 if lsb of B is clear, else OT capped at 32.
354 Used for decoding operand size of port opcodes. */
355 static inline TCGMemOp
mo_b_d32(int b
, TCGMemOp ot
)
357 return b
& 1 ? (ot
== MO_16
? MO_16
: MO_32
) : MO_8
;
360 static void gen_op_mov_reg_v(TCGMemOp ot
, int reg
, TCGv t0
)
364 if (!byte_reg_is_xH(reg
)) {
365 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 8);
367 tcg_gen_deposit_tl(cpu_regs
[reg
- 4], cpu_regs
[reg
- 4], t0
, 8, 8);
371 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 16);
374 /* For x86_64, this sets the higher half of register to zero.
375 For i386, this is equivalent to a mov. */
376 tcg_gen_ext32u_tl(cpu_regs
[reg
], t0
);
380 tcg_gen_mov_tl(cpu_regs
[reg
], t0
);
388 static inline void gen_op_mov_v_reg(TCGMemOp ot
, TCGv t0
, int reg
)
390 if (ot
== MO_8
&& byte_reg_is_xH(reg
)) {
391 tcg_gen_extract_tl(t0
, cpu_regs
[reg
- 4], 8, 8);
393 tcg_gen_mov_tl(t0
, cpu_regs
[reg
]);
397 static void gen_add_A0_im(DisasContext
*s
, int val
)
399 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, val
);
401 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
405 static inline void gen_op_jmp_v(TCGv dest
)
407 tcg_gen_st_tl(dest
, cpu_env
, offsetof(CPUX86State
, eip
));
410 static inline void gen_op_add_reg_im(TCGMemOp size
, int reg
, int32_t val
)
412 tcg_gen_addi_tl(cpu_tmp0
, cpu_regs
[reg
], val
);
413 gen_op_mov_reg_v(size
, reg
, cpu_tmp0
);
416 static inline void gen_op_add_reg_T0(TCGMemOp size
, int reg
)
418 tcg_gen_add_tl(cpu_tmp0
, cpu_regs
[reg
], cpu_T0
);
419 gen_op_mov_reg_v(size
, reg
, cpu_tmp0
);
422 static inline void gen_op_ld_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
424 tcg_gen_qemu_ld_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
427 static inline void gen_op_st_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
429 tcg_gen_qemu_st_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
432 static inline void gen_op_st_rm_T0_A0(DisasContext
*s
, int idx
, int d
)
435 gen_op_st_v(s
, idx
, cpu_T0
, cpu_A0
);
437 gen_op_mov_reg_v(idx
, d
, cpu_T0
);
441 static inline void gen_jmp_im(target_ulong pc
)
443 tcg_gen_movi_tl(cpu_tmp0
, pc
);
444 gen_op_jmp_v(cpu_tmp0
);
447 /* Compute SEG:REG into A0. SEG is selected from the override segment
448 (OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to
449 indicate no override. */
450 static void gen_lea_v_seg(DisasContext
*s
, TCGMemOp aflag
, TCGv a0
,
451 int def_seg
, int ovr_seg
)
457 tcg_gen_mov_tl(cpu_A0
, a0
);
464 if (ovr_seg
< 0 && s
->addseg
) {
468 tcg_gen_ext32u_tl(cpu_A0
, a0
);
474 tcg_gen_ext16u_tl(cpu_A0
, a0
);
489 TCGv seg
= cpu_seg_base
[ovr_seg
];
491 if (aflag
== MO_64
) {
492 tcg_gen_add_tl(cpu_A0
, a0
, seg
);
493 } else if (CODE64(s
)) {
494 tcg_gen_ext32u_tl(cpu_A0
, a0
);
495 tcg_gen_add_tl(cpu_A0
, cpu_A0
, seg
);
497 tcg_gen_add_tl(cpu_A0
, a0
, seg
);
498 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
503 static inline void gen_string_movl_A0_ESI(DisasContext
*s
)
505 gen_lea_v_seg(s
, s
->aflag
, cpu_regs
[R_ESI
], R_DS
, s
->override
);
508 static inline void gen_string_movl_A0_EDI(DisasContext
*s
)
510 gen_lea_v_seg(s
, s
->aflag
, cpu_regs
[R_EDI
], R_ES
, -1);
513 static inline void gen_op_movl_T0_Dshift(TCGMemOp ot
)
515 tcg_gen_ld32s_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, df
));
516 tcg_gen_shli_tl(cpu_T0
, cpu_T0
, ot
);
519 static TCGv
gen_ext_tl(TCGv dst
, TCGv src
, TCGMemOp size
, bool sign
)
524 tcg_gen_ext8s_tl(dst
, src
);
526 tcg_gen_ext8u_tl(dst
, src
);
531 tcg_gen_ext16s_tl(dst
, src
);
533 tcg_gen_ext16u_tl(dst
, src
);
539 tcg_gen_ext32s_tl(dst
, src
);
541 tcg_gen_ext32u_tl(dst
, src
);
550 static void gen_extu(TCGMemOp ot
, TCGv reg
)
552 gen_ext_tl(reg
, reg
, ot
, false);
555 static void gen_exts(TCGMemOp ot
, TCGv reg
)
557 gen_ext_tl(reg
, reg
, ot
, true);
560 static inline void gen_op_jnz_ecx(TCGMemOp size
, TCGLabel
*label1
)
562 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[R_ECX
]);
563 gen_extu(size
, cpu_tmp0
);
564 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_tmp0
, 0, label1
);
567 static inline void gen_op_jz_ecx(TCGMemOp size
, TCGLabel
*label1
)
569 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[R_ECX
]);
570 gen_extu(size
, cpu_tmp0
);
571 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
574 static void gen_helper_in_func(TCGMemOp ot
, TCGv v
, TCGv_i32 n
)
578 gen_helper_inb(v
, cpu_env
, n
);
581 gen_helper_inw(v
, cpu_env
, n
);
584 gen_helper_inl(v
, cpu_env
, n
);
591 static void gen_helper_out_func(TCGMemOp ot
, TCGv_i32 v
, TCGv_i32 n
)
595 gen_helper_outb(cpu_env
, v
, n
);
598 gen_helper_outw(cpu_env
, v
, n
);
601 gen_helper_outl(cpu_env
, v
, n
);
608 static void gen_check_io(DisasContext
*s
, TCGMemOp ot
, target_ulong cur_eip
,
611 target_ulong next_eip
;
613 if (s
->pe
&& (s
->cpl
> s
->iopl
|| s
->vm86
)) {
614 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
617 gen_helper_check_iob(cpu_env
, cpu_tmp2_i32
);
620 gen_helper_check_iow(cpu_env
, cpu_tmp2_i32
);
623 gen_helper_check_iol(cpu_env
, cpu_tmp2_i32
);
629 if(s
->flags
& HF_SVMI_MASK
) {
632 svm_flags
|= (1 << (4 + ot
));
633 next_eip
= s
->pc
- s
->cs_base
;
634 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
635 gen_helper_svm_check_io(cpu_env
, cpu_tmp2_i32
,
636 tcg_const_i32(svm_flags
),
637 tcg_const_i32(next_eip
- cur_eip
));
641 static inline void gen_movs(DisasContext
*s
, TCGMemOp ot
)
643 gen_string_movl_A0_ESI(s
);
644 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
645 gen_string_movl_A0_EDI(s
);
646 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
647 gen_op_movl_T0_Dshift(ot
);
648 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
649 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
652 static void gen_op_update1_cc(void)
654 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
657 static void gen_op_update2_cc(void)
659 tcg_gen_mov_tl(cpu_cc_src
, cpu_T1
);
660 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
663 static void gen_op_update3_cc(TCGv reg
)
665 tcg_gen_mov_tl(cpu_cc_src2
, reg
);
666 tcg_gen_mov_tl(cpu_cc_src
, cpu_T1
);
667 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
670 static inline void gen_op_testl_T0_T1_cc(void)
672 tcg_gen_and_tl(cpu_cc_dst
, cpu_T0
, cpu_T1
);
675 static void gen_op_update_neg_cc(void)
677 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
678 tcg_gen_neg_tl(cpu_cc_src
, cpu_T0
);
679 tcg_gen_movi_tl(cpu_cc_srcT
, 0);
682 /* compute all eflags to cc_src */
683 static void gen_compute_eflags(DisasContext
*s
)
685 TCGv zero
, dst
, src1
, src2
;
688 if (s
->cc_op
== CC_OP_EFLAGS
) {
691 if (s
->cc_op
== CC_OP_CLR
) {
692 tcg_gen_movi_tl(cpu_cc_src
, CC_Z
| CC_P
);
693 set_cc_op(s
, CC_OP_EFLAGS
);
702 /* Take care to not read values that are not live. */
703 live
= cc_op_live
[s
->cc_op
] & ~USES_CC_SRCT
;
704 dead
= live
^ (USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
);
706 zero
= tcg_const_tl(0);
707 if (dead
& USES_CC_DST
) {
710 if (dead
& USES_CC_SRC
) {
713 if (dead
& USES_CC_SRC2
) {
719 gen_helper_cc_compute_all(cpu_cc_src
, dst
, src1
, src2
, cpu_cc_op
);
720 set_cc_op(s
, CC_OP_EFLAGS
);
727 typedef struct CCPrepare
{
737 /* compute eflags.C to reg */
738 static CCPrepare
gen_prepare_eflags_c(DisasContext
*s
, TCGv reg
)
744 case CC_OP_SUBB
... CC_OP_SUBQ
:
745 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
746 size
= s
->cc_op
- CC_OP_SUBB
;
747 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
748 /* If no temporary was used, be careful not to alias t1 and t0. */
749 t0
= TCGV_EQUAL(t1
, cpu_cc_src
) ? cpu_tmp0
: reg
;
750 tcg_gen_mov_tl(t0
, cpu_cc_srcT
);
754 case CC_OP_ADDB
... CC_OP_ADDQ
:
755 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
756 size
= s
->cc_op
- CC_OP_ADDB
;
757 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
758 t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
760 return (CCPrepare
) { .cond
= TCG_COND_LTU
, .reg
= t0
,
761 .reg2
= t1
, .mask
= -1, .use_reg2
= true };
763 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
766 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
768 case CC_OP_INCB
... CC_OP_INCQ
:
769 case CC_OP_DECB
... CC_OP_DECQ
:
770 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
771 .mask
= -1, .no_setcond
= true };
773 case CC_OP_SHLB
... CC_OP_SHLQ
:
774 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
775 size
= s
->cc_op
- CC_OP_SHLB
;
776 shift
= (8 << size
) - 1;
777 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
778 .mask
= (target_ulong
)1 << shift
};
780 case CC_OP_MULB
... CC_OP_MULQ
:
781 return (CCPrepare
) { .cond
= TCG_COND_NE
,
782 .reg
= cpu_cc_src
, .mask
= -1 };
784 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
785 size
= s
->cc_op
- CC_OP_BMILGB
;
786 t0
= gen_ext_tl(reg
, cpu_cc_src
, size
, false);
787 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
791 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_dst
,
792 .mask
= -1, .no_setcond
= true };
795 case CC_OP_SARB
... CC_OP_SARQ
:
797 return (CCPrepare
) { .cond
= TCG_COND_NE
,
798 .reg
= cpu_cc_src
, .mask
= CC_C
};
801 /* The need to compute only C from CC_OP_DYNAMIC is important
802 in efficiently implementing e.g. INC at the start of a TB. */
804 gen_helper_cc_compute_c(reg
, cpu_cc_dst
, cpu_cc_src
,
805 cpu_cc_src2
, cpu_cc_op
);
806 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
807 .mask
= -1, .no_setcond
= true };
811 /* compute eflags.P to reg */
812 static CCPrepare
gen_prepare_eflags_p(DisasContext
*s
, TCGv reg
)
814 gen_compute_eflags(s
);
815 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
819 /* compute eflags.S to reg */
820 static CCPrepare
gen_prepare_eflags_s(DisasContext
*s
, TCGv reg
)
824 gen_compute_eflags(s
);
830 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
834 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
837 TCGMemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
838 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, true);
839 return (CCPrepare
) { .cond
= TCG_COND_LT
, .reg
= t0
, .mask
= -1 };
844 /* compute eflags.O to reg */
845 static CCPrepare
gen_prepare_eflags_o(DisasContext
*s
, TCGv reg
)
850 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src2
,
851 .mask
= -1, .no_setcond
= true };
854 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
856 gen_compute_eflags(s
);
857 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
862 /* compute eflags.Z to reg */
863 static CCPrepare
gen_prepare_eflags_z(DisasContext
*s
, TCGv reg
)
867 gen_compute_eflags(s
);
873 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
876 return (CCPrepare
) { .cond
= TCG_COND_ALWAYS
, .mask
= -1 };
878 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= cpu_cc_src
,
882 TCGMemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
883 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
884 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
889 /* perform a conditional store into register 'reg' according to jump opcode
890 value 'b'. In the fast case, T0 is guaranted not to be used. */
891 static CCPrepare
gen_prepare_cc(DisasContext
*s
, int b
, TCGv reg
)
893 int inv
, jcc_op
, cond
;
899 jcc_op
= (b
>> 1) & 7;
902 case CC_OP_SUBB
... CC_OP_SUBQ
:
903 /* We optimize relational operators for the cmp/jcc case. */
904 size
= s
->cc_op
- CC_OP_SUBB
;
907 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
908 gen_extu(size
, cpu_tmp4
);
909 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
910 cc
= (CCPrepare
) { .cond
= TCG_COND_LEU
, .reg
= cpu_tmp4
,
911 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
920 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
921 gen_exts(size
, cpu_tmp4
);
922 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, true);
923 cc
= (CCPrepare
) { .cond
= cond
, .reg
= cpu_tmp4
,
924 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
934 /* This actually generates good code for JC, JZ and JS. */
937 cc
= gen_prepare_eflags_o(s
, reg
);
940 cc
= gen_prepare_eflags_c(s
, reg
);
943 cc
= gen_prepare_eflags_z(s
, reg
);
946 gen_compute_eflags(s
);
947 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
948 .mask
= CC_Z
| CC_C
};
951 cc
= gen_prepare_eflags_s(s
, reg
);
954 cc
= gen_prepare_eflags_p(s
, reg
);
957 gen_compute_eflags(s
);
958 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
961 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
962 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
963 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
968 gen_compute_eflags(s
);
969 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
972 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
973 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
974 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
975 .mask
= CC_S
| CC_Z
};
982 cc
.cond
= tcg_invert_cond(cc
.cond
);
987 static void gen_setcc1(DisasContext
*s
, int b
, TCGv reg
)
989 CCPrepare cc
= gen_prepare_cc(s
, b
, reg
);
992 if (cc
.cond
== TCG_COND_EQ
) {
993 tcg_gen_xori_tl(reg
, cc
.reg
, 1);
995 tcg_gen_mov_tl(reg
, cc
.reg
);
1000 if (cc
.cond
== TCG_COND_NE
&& !cc
.use_reg2
&& cc
.imm
== 0 &&
1001 cc
.mask
!= 0 && (cc
.mask
& (cc
.mask
- 1)) == 0) {
1002 tcg_gen_shri_tl(reg
, cc
.reg
, ctztl(cc
.mask
));
1003 tcg_gen_andi_tl(reg
, reg
, 1);
1006 if (cc
.mask
!= -1) {
1007 tcg_gen_andi_tl(reg
, cc
.reg
, cc
.mask
);
1011 tcg_gen_setcond_tl(cc
.cond
, reg
, cc
.reg
, cc
.reg2
);
1013 tcg_gen_setcondi_tl(cc
.cond
, reg
, cc
.reg
, cc
.imm
);
1017 static inline void gen_compute_eflags_c(DisasContext
*s
, TCGv reg
)
1019 gen_setcc1(s
, JCC_B
<< 1, reg
);
1022 /* generate a conditional jump to label 'l1' according to jump opcode
1023 value 'b'. In the fast case, T0 is guaranted not to be used. */
1024 static inline void gen_jcc1_noeob(DisasContext
*s
, int b
, TCGLabel
*l1
)
1026 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T0
);
1028 if (cc
.mask
!= -1) {
1029 tcg_gen_andi_tl(cpu_T0
, cc
.reg
, cc
.mask
);
1033 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1035 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1039 /* Generate a conditional jump to label 'l1' according to jump opcode
1040 value 'b'. In the fast case, T0 is guaranted not to be used.
1041 A translation block must end soon. */
1042 static inline void gen_jcc1(DisasContext
*s
, int b
, TCGLabel
*l1
)
1044 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T0
);
1046 gen_update_cc_op(s
);
1047 if (cc
.mask
!= -1) {
1048 tcg_gen_andi_tl(cpu_T0
, cc
.reg
, cc
.mask
);
1051 set_cc_op(s
, CC_OP_DYNAMIC
);
1053 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1055 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1059 /* XXX: does not work with gdbstub "ice" single step - not a
1061 static TCGLabel
*gen_jz_ecx_string(DisasContext
*s
, target_ulong next_eip
)
1063 TCGLabel
*l1
= gen_new_label();
1064 TCGLabel
*l2
= gen_new_label();
1065 gen_op_jnz_ecx(s
->aflag
, l1
);
1067 gen_jmp_tb(s
, next_eip
, 1);
1072 static inline void gen_stos(DisasContext
*s
, TCGMemOp ot
)
1074 gen_op_mov_v_reg(MO_32
, cpu_T0
, R_EAX
);
1075 gen_string_movl_A0_EDI(s
);
1076 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
1077 gen_op_movl_T0_Dshift(ot
);
1078 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1081 static inline void gen_lods(DisasContext
*s
, TCGMemOp ot
)
1083 gen_string_movl_A0_ESI(s
);
1084 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1085 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T0
);
1086 gen_op_movl_T0_Dshift(ot
);
1087 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1090 static inline void gen_scas(DisasContext
*s
, TCGMemOp ot
)
1092 gen_string_movl_A0_EDI(s
);
1093 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
1094 gen_op(s
, OP_CMPL
, ot
, R_EAX
);
1095 gen_op_movl_T0_Dshift(ot
);
1096 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1099 static inline void gen_cmps(DisasContext
*s
, TCGMemOp ot
)
1101 gen_string_movl_A0_EDI(s
);
1102 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
1103 gen_string_movl_A0_ESI(s
);
1104 gen_op(s
, OP_CMPL
, ot
, OR_TMP0
);
1105 gen_op_movl_T0_Dshift(ot
);
1106 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1107 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1110 static void gen_bpt_io(DisasContext
*s
, TCGv_i32 t_port
, int ot
)
1112 if (s
->flags
& HF_IOBPT_MASK
) {
1113 TCGv_i32 t_size
= tcg_const_i32(1 << ot
);
1114 TCGv t_next
= tcg_const_tl(s
->pc
- s
->cs_base
);
1116 gen_helper_bpt_io(cpu_env
, t_port
, t_size
, t_next
);
1117 tcg_temp_free_i32(t_size
);
1118 tcg_temp_free(t_next
);
1123 static inline void gen_ins(DisasContext
*s
, TCGMemOp ot
)
1125 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1128 gen_string_movl_A0_EDI(s
);
1129 /* Note: we must do this dummy write first to be restartable in
1130 case of page fault. */
1131 tcg_gen_movi_tl(cpu_T0
, 0);
1132 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
1133 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_EDX
]);
1134 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1135 gen_helper_in_func(ot
, cpu_T0
, cpu_tmp2_i32
);
1136 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
1137 gen_op_movl_T0_Dshift(ot
);
1138 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1139 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
1140 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1145 static inline void gen_outs(DisasContext
*s
, TCGMemOp ot
)
1147 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1150 gen_string_movl_A0_ESI(s
);
1151 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1153 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_EDX
]);
1154 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1155 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T0
);
1156 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1157 gen_op_movl_T0_Dshift(ot
);
1158 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1159 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
1160 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1165 /* same method as Valgrind : we generate jumps to current or next
1167 #define GEN_REPZ(op) \
1168 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1169 target_ulong cur_eip, target_ulong next_eip) \
1172 gen_update_cc_op(s); \
1173 l2 = gen_jz_ecx_string(s, next_eip); \
1174 gen_ ## op(s, ot); \
1175 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1176 /* a loop would cause two single step exceptions if ECX = 1 \
1177 before rep string_insn */ \
1179 gen_op_jz_ecx(s->aflag, l2); \
1180 gen_jmp(s, cur_eip); \
1183 #define GEN_REPZ2(op) \
1184 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1185 target_ulong cur_eip, \
1186 target_ulong next_eip, \
1190 gen_update_cc_op(s); \
1191 l2 = gen_jz_ecx_string(s, next_eip); \
1192 gen_ ## op(s, ot); \
1193 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1194 gen_update_cc_op(s); \
1195 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
1197 gen_op_jz_ecx(s->aflag, l2); \
1198 gen_jmp(s, cur_eip); \
1209 static void gen_helper_fp_arith_ST0_FT0(int op
)
1213 gen_helper_fadd_ST0_FT0(cpu_env
);
1216 gen_helper_fmul_ST0_FT0(cpu_env
);
1219 gen_helper_fcom_ST0_FT0(cpu_env
);
1222 gen_helper_fcom_ST0_FT0(cpu_env
);
1225 gen_helper_fsub_ST0_FT0(cpu_env
);
1228 gen_helper_fsubr_ST0_FT0(cpu_env
);
1231 gen_helper_fdiv_ST0_FT0(cpu_env
);
1234 gen_helper_fdivr_ST0_FT0(cpu_env
);
1239 /* NOTE the exception in "r" op ordering */
1240 static void gen_helper_fp_arith_STN_ST0(int op
, int opreg
)
1242 TCGv_i32 tmp
= tcg_const_i32(opreg
);
1245 gen_helper_fadd_STN_ST0(cpu_env
, tmp
);
1248 gen_helper_fmul_STN_ST0(cpu_env
, tmp
);
1251 gen_helper_fsubr_STN_ST0(cpu_env
, tmp
);
1254 gen_helper_fsub_STN_ST0(cpu_env
, tmp
);
1257 gen_helper_fdivr_STN_ST0(cpu_env
, tmp
);
1260 gen_helper_fdiv_STN_ST0(cpu_env
, tmp
);
1265 /* if d == OR_TMP0, it means memory operand (address in A0) */
1266 static void gen_op(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
)
1269 gen_op_mov_v_reg(ot
, cpu_T0
, d
);
1270 } else if (!(s1
->prefix
& PREFIX_LOCK
)) {
1271 gen_op_ld_v(s1
, ot
, cpu_T0
, cpu_A0
);
1275 gen_compute_eflags_c(s1
, cpu_tmp4
);
1276 if (s1
->prefix
& PREFIX_LOCK
) {
1277 tcg_gen_add_tl(cpu_T0
, cpu_tmp4
, cpu_T1
);
1278 tcg_gen_atomic_add_fetch_tl(cpu_T0
, cpu_A0
, cpu_T0
,
1279 s1
->mem_index
, ot
| MO_LE
);
1281 tcg_gen_add_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1282 tcg_gen_add_tl(cpu_T0
, cpu_T0
, cpu_tmp4
);
1283 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1285 gen_op_update3_cc(cpu_tmp4
);
1286 set_cc_op(s1
, CC_OP_ADCB
+ ot
);
1289 gen_compute_eflags_c(s1
, cpu_tmp4
);
1290 if (s1
->prefix
& PREFIX_LOCK
) {
1291 tcg_gen_add_tl(cpu_T0
, cpu_T1
, cpu_tmp4
);
1292 tcg_gen_neg_tl(cpu_T0
, cpu_T0
);
1293 tcg_gen_atomic_add_fetch_tl(cpu_T0
, cpu_A0
, cpu_T0
,
1294 s1
->mem_index
, ot
| MO_LE
);
1296 tcg_gen_sub_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1297 tcg_gen_sub_tl(cpu_T0
, cpu_T0
, cpu_tmp4
);
1298 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1300 gen_op_update3_cc(cpu_tmp4
);
1301 set_cc_op(s1
, CC_OP_SBBB
+ ot
);
1304 if (s1
->prefix
& PREFIX_LOCK
) {
1305 tcg_gen_atomic_add_fetch_tl(cpu_T0
, cpu_A0
, cpu_T1
,
1306 s1
->mem_index
, ot
| MO_LE
);
1308 tcg_gen_add_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1309 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1311 gen_op_update2_cc();
1312 set_cc_op(s1
, CC_OP_ADDB
+ ot
);
1315 if (s1
->prefix
& PREFIX_LOCK
) {
1316 tcg_gen_neg_tl(cpu_T0
, cpu_T1
);
1317 tcg_gen_atomic_fetch_add_tl(cpu_cc_srcT
, cpu_A0
, cpu_T0
,
1318 s1
->mem_index
, ot
| MO_LE
);
1319 tcg_gen_sub_tl(cpu_T0
, cpu_cc_srcT
, cpu_T1
);
1321 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T0
);
1322 tcg_gen_sub_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1323 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1325 gen_op_update2_cc();
1326 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1330 if (s1
->prefix
& PREFIX_LOCK
) {
1331 tcg_gen_atomic_and_fetch_tl(cpu_T0
, cpu_A0
, cpu_T1
,
1332 s1
->mem_index
, ot
| MO_LE
);
1334 tcg_gen_and_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1335 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1337 gen_op_update1_cc();
1338 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1341 if (s1
->prefix
& PREFIX_LOCK
) {
1342 tcg_gen_atomic_or_fetch_tl(cpu_T0
, cpu_A0
, cpu_T1
,
1343 s1
->mem_index
, ot
| MO_LE
);
1345 tcg_gen_or_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1346 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1348 gen_op_update1_cc();
1349 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1352 if (s1
->prefix
& PREFIX_LOCK
) {
1353 tcg_gen_atomic_xor_fetch_tl(cpu_T0
, cpu_A0
, cpu_T1
,
1354 s1
->mem_index
, ot
| MO_LE
);
1356 tcg_gen_xor_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1357 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1359 gen_op_update1_cc();
1360 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1363 tcg_gen_mov_tl(cpu_cc_src
, cpu_T1
);
1364 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T0
);
1365 tcg_gen_sub_tl(cpu_cc_dst
, cpu_T0
, cpu_T1
);
1366 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1371 /* if d == OR_TMP0, it means memory operand (address in A0) */
1372 static void gen_inc(DisasContext
*s1
, TCGMemOp ot
, int d
, int c
)
1374 if (s1
->prefix
& PREFIX_LOCK
) {
1375 tcg_gen_movi_tl(cpu_T0
, c
> 0 ? 1 : -1);
1376 tcg_gen_atomic_add_fetch_tl(cpu_T0
, cpu_A0
, cpu_T0
,
1377 s1
->mem_index
, ot
| MO_LE
);
1380 gen_op_mov_v_reg(ot
, cpu_T0
, d
);
1382 gen_op_ld_v(s1
, ot
, cpu_T0
, cpu_A0
);
1384 tcg_gen_addi_tl(cpu_T0
, cpu_T0
, (c
> 0 ? 1 : -1));
1385 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1388 gen_compute_eflags_c(s1
, cpu_cc_src
);
1389 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
1390 set_cc_op(s1
, (c
> 0 ? CC_OP_INCB
: CC_OP_DECB
) + ot
);
1393 static void gen_shift_flags(DisasContext
*s
, TCGMemOp ot
, TCGv result
,
1394 TCGv shm1
, TCGv count
, bool is_right
)
1396 TCGv_i32 z32
, s32
, oldop
;
1399 /* Store the results into the CC variables. If we know that the
1400 variable must be dead, store unconditionally. Otherwise we'll
1401 need to not disrupt the current contents. */
1402 z_tl
= tcg_const_tl(0);
1403 if (cc_op_live
[s
->cc_op
] & USES_CC_DST
) {
1404 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_dst
, count
, z_tl
,
1405 result
, cpu_cc_dst
);
1407 tcg_gen_mov_tl(cpu_cc_dst
, result
);
1409 if (cc_op_live
[s
->cc_op
] & USES_CC_SRC
) {
1410 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_src
, count
, z_tl
,
1413 tcg_gen_mov_tl(cpu_cc_src
, shm1
);
1415 tcg_temp_free(z_tl
);
1417 /* Get the two potential CC_OP values into temporaries. */
1418 tcg_gen_movi_i32(cpu_tmp2_i32
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1419 if (s
->cc_op
== CC_OP_DYNAMIC
) {
1422 tcg_gen_movi_i32(cpu_tmp3_i32
, s
->cc_op
);
1423 oldop
= cpu_tmp3_i32
;
1426 /* Conditionally store the CC_OP value. */
1427 z32
= tcg_const_i32(0);
1428 s32
= tcg_temp_new_i32();
1429 tcg_gen_trunc_tl_i32(s32
, count
);
1430 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, s32
, z32
, cpu_tmp2_i32
, oldop
);
1431 tcg_temp_free_i32(z32
);
1432 tcg_temp_free_i32(s32
);
1434 /* The CC_OP value is no longer predictable. */
1435 set_cc_op(s
, CC_OP_DYNAMIC
);
1438 static void gen_shift_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1439 int is_right
, int is_arith
)
1441 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1444 if (op1
== OR_TMP0
) {
1445 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1447 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1450 tcg_gen_andi_tl(cpu_T1
, cpu_T1
, mask
);
1451 tcg_gen_subi_tl(cpu_tmp0
, cpu_T1
, 1);
1455 gen_exts(ot
, cpu_T0
);
1456 tcg_gen_sar_tl(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1457 tcg_gen_sar_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1459 gen_extu(ot
, cpu_T0
);
1460 tcg_gen_shr_tl(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1461 tcg_gen_shr_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1464 tcg_gen_shl_tl(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1465 tcg_gen_shl_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1469 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1471 gen_shift_flags(s
, ot
, cpu_T0
, cpu_tmp0
, cpu_T1
, is_right
);
1474 static void gen_shift_rm_im(DisasContext
*s
, TCGMemOp ot
, int op1
, int op2
,
1475 int is_right
, int is_arith
)
1477 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1481 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1483 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1489 gen_exts(ot
, cpu_T0
);
1490 tcg_gen_sari_tl(cpu_tmp4
, cpu_T0
, op2
- 1);
1491 tcg_gen_sari_tl(cpu_T0
, cpu_T0
, op2
);
1493 gen_extu(ot
, cpu_T0
);
1494 tcg_gen_shri_tl(cpu_tmp4
, cpu_T0
, op2
- 1);
1495 tcg_gen_shri_tl(cpu_T0
, cpu_T0
, op2
);
1498 tcg_gen_shli_tl(cpu_tmp4
, cpu_T0
, op2
- 1);
1499 tcg_gen_shli_tl(cpu_T0
, cpu_T0
, op2
);
1504 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1506 /* update eflags if non zero shift */
1508 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
1509 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
1510 set_cc_op(s
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1514 static void gen_rot_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
, int is_right
)
1516 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1520 if (op1
== OR_TMP0
) {
1521 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1523 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1526 tcg_gen_andi_tl(cpu_T1
, cpu_T1
, mask
);
1530 /* Replicate the 8-bit input so that a 32-bit rotate works. */
1531 tcg_gen_ext8u_tl(cpu_T0
, cpu_T0
);
1532 tcg_gen_muli_tl(cpu_T0
, cpu_T0
, 0x01010101);
1535 /* Replicate the 16-bit input so that a 32-bit rotate works. */
1536 tcg_gen_deposit_tl(cpu_T0
, cpu_T0
, cpu_T0
, 16, 16);
1539 #ifdef TARGET_X86_64
1541 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
1542 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T1
);
1544 tcg_gen_rotr_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1546 tcg_gen_rotl_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1548 tcg_gen_extu_i32_tl(cpu_T0
, cpu_tmp2_i32
);
1553 tcg_gen_rotr_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1555 tcg_gen_rotl_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1561 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1563 /* We'll need the flags computed into CC_SRC. */
1564 gen_compute_eflags(s
);
1566 /* The value that was "rotated out" is now present at the other end
1567 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1568 since we've computed the flags into CC_SRC, these variables are
1571 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T0
, mask
- 1);
1572 tcg_gen_shri_tl(cpu_cc_dst
, cpu_T0
, mask
);
1573 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1575 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T0
, mask
);
1576 tcg_gen_andi_tl(cpu_cc_dst
, cpu_T0
, 1);
1578 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1579 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1581 /* Now conditionally store the new CC_OP value. If the shift count
1582 is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1583 Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1584 exactly as we computed above. */
1585 t0
= tcg_const_i32(0);
1586 t1
= tcg_temp_new_i32();
1587 tcg_gen_trunc_tl_i32(t1
, cpu_T1
);
1588 tcg_gen_movi_i32(cpu_tmp2_i32
, CC_OP_ADCOX
);
1589 tcg_gen_movi_i32(cpu_tmp3_i32
, CC_OP_EFLAGS
);
1590 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, t1
, t0
,
1591 cpu_tmp2_i32
, cpu_tmp3_i32
);
1592 tcg_temp_free_i32(t0
);
1593 tcg_temp_free_i32(t1
);
1595 /* The CC_OP value is no longer predictable. */
1596 set_cc_op(s
, CC_OP_DYNAMIC
);
1599 static void gen_rot_rm_im(DisasContext
*s
, TCGMemOp ot
, int op1
, int op2
,
1602 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1606 if (op1
== OR_TMP0
) {
1607 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1609 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1615 #ifdef TARGET_X86_64
1617 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
1619 tcg_gen_rotri_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, op2
);
1621 tcg_gen_rotli_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, op2
);
1623 tcg_gen_extu_i32_tl(cpu_T0
, cpu_tmp2_i32
);
1628 tcg_gen_rotri_tl(cpu_T0
, cpu_T0
, op2
);
1630 tcg_gen_rotli_tl(cpu_T0
, cpu_T0
, op2
);
1641 shift
= mask
+ 1 - shift
;
1643 gen_extu(ot
, cpu_T0
);
1644 tcg_gen_shli_tl(cpu_tmp0
, cpu_T0
, shift
);
1645 tcg_gen_shri_tl(cpu_T0
, cpu_T0
, mask
+ 1 - shift
);
1646 tcg_gen_or_tl(cpu_T0
, cpu_T0
, cpu_tmp0
);
1652 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1655 /* Compute the flags into CC_SRC. */
1656 gen_compute_eflags(s
);
1658 /* The value that was "rotated out" is now present at the other end
1659 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1660 since we've computed the flags into CC_SRC, these variables are
1663 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T0
, mask
- 1);
1664 tcg_gen_shri_tl(cpu_cc_dst
, cpu_T0
, mask
);
1665 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1667 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T0
, mask
);
1668 tcg_gen_andi_tl(cpu_cc_dst
, cpu_T0
, 1);
1670 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1671 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1672 set_cc_op(s
, CC_OP_ADCOX
);
1676 /* XXX: add faster immediate = 1 case */
1677 static void gen_rotc_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1680 gen_compute_eflags(s
);
1681 assert(s
->cc_op
== CC_OP_EFLAGS
);
1685 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1687 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1692 gen_helper_rcrb(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1695 gen_helper_rcrw(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1698 gen_helper_rcrl(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1700 #ifdef TARGET_X86_64
1702 gen_helper_rcrq(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1711 gen_helper_rclb(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1714 gen_helper_rclw(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1717 gen_helper_rcll(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1719 #ifdef TARGET_X86_64
1721 gen_helper_rclq(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1729 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1732 /* XXX: add faster immediate case */
1733 static void gen_shiftd_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1734 bool is_right
, TCGv count_in
)
1736 target_ulong mask
= (ot
== MO_64
? 63 : 31);
1740 if (op1
== OR_TMP0
) {
1741 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1743 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1746 count
= tcg_temp_new();
1747 tcg_gen_andi_tl(count
, count_in
, mask
);
1751 /* Note: we implement the Intel behaviour for shift count > 16.
1752 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A
1753 portion by constructing it as a 32-bit value. */
1755 tcg_gen_deposit_tl(cpu_tmp0
, cpu_T0
, cpu_T1
, 16, 16);
1756 tcg_gen_mov_tl(cpu_T1
, cpu_T0
);
1757 tcg_gen_mov_tl(cpu_T0
, cpu_tmp0
);
1759 tcg_gen_deposit_tl(cpu_T1
, cpu_T0
, cpu_T1
, 16, 16);
1762 #ifdef TARGET_X86_64
1764 /* Concatenate the two 32-bit values and use a 64-bit shift. */
1765 tcg_gen_subi_tl(cpu_tmp0
, count
, 1);
1767 tcg_gen_concat_tl_i64(cpu_T0
, cpu_T0
, cpu_T1
);
1768 tcg_gen_shr_i64(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1769 tcg_gen_shr_i64(cpu_T0
, cpu_T0
, count
);
1771 tcg_gen_concat_tl_i64(cpu_T0
, cpu_T1
, cpu_T0
);
1772 tcg_gen_shl_i64(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1773 tcg_gen_shl_i64(cpu_T0
, cpu_T0
, count
);
1774 tcg_gen_shri_i64(cpu_tmp0
, cpu_tmp0
, 32);
1775 tcg_gen_shri_i64(cpu_T0
, cpu_T0
, 32);
1780 tcg_gen_subi_tl(cpu_tmp0
, count
, 1);
1782 tcg_gen_shr_tl(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1784 tcg_gen_subfi_tl(cpu_tmp4
, mask
+ 1, count
);
1785 tcg_gen_shr_tl(cpu_T0
, cpu_T0
, count
);
1786 tcg_gen_shl_tl(cpu_T1
, cpu_T1
, cpu_tmp4
);
1788 tcg_gen_shl_tl(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1790 /* Only needed if count > 16, for Intel behaviour. */
1791 tcg_gen_subfi_tl(cpu_tmp4
, 33, count
);
1792 tcg_gen_shr_tl(cpu_tmp4
, cpu_T1
, cpu_tmp4
);
1793 tcg_gen_or_tl(cpu_tmp0
, cpu_tmp0
, cpu_tmp4
);
1796 tcg_gen_subfi_tl(cpu_tmp4
, mask
+ 1, count
);
1797 tcg_gen_shl_tl(cpu_T0
, cpu_T0
, count
);
1798 tcg_gen_shr_tl(cpu_T1
, cpu_T1
, cpu_tmp4
);
1800 tcg_gen_movi_tl(cpu_tmp4
, 0);
1801 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_T1
, count
, cpu_tmp4
,
1803 tcg_gen_or_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1808 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1810 gen_shift_flags(s
, ot
, cpu_T0
, cpu_tmp0
, count
, is_right
);
1811 tcg_temp_free(count
);
1814 static void gen_shift(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
, int s
)
1817 gen_op_mov_v_reg(ot
, cpu_T1
, s
);
1820 gen_rot_rm_T1(s1
, ot
, d
, 0);
1823 gen_rot_rm_T1(s1
, ot
, d
, 1);
1827 gen_shift_rm_T1(s1
, ot
, d
, 0, 0);
1830 gen_shift_rm_T1(s1
, ot
, d
, 1, 0);
1833 gen_shift_rm_T1(s1
, ot
, d
, 1, 1);
1836 gen_rotc_rm_T1(s1
, ot
, d
, 0);
1839 gen_rotc_rm_T1(s1
, ot
, d
, 1);
1844 static void gen_shifti(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
, int c
)
1848 gen_rot_rm_im(s1
, ot
, d
, c
, 0);
1851 gen_rot_rm_im(s1
, ot
, d
, c
, 1);
1855 gen_shift_rm_im(s1
, ot
, d
, c
, 0, 0);
1858 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 0);
1861 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 1);
1864 /* currently not optimized */
1865 tcg_gen_movi_tl(cpu_T1
, c
);
1866 gen_shift(s1
, op
, ot
, d
, OR_TMP1
);
1871 /* Decompose an address. */
1873 typedef struct AddressParts
{
1881 static AddressParts
gen_lea_modrm_0(CPUX86State
*env
, DisasContext
*s
,
1884 int def_seg
, base
, index
, scale
, mod
, rm
;
1893 mod
= (modrm
>> 6) & 3;
1895 base
= rm
| REX_B(s
);
1898 /* Normally filtered out earlier, but including this path
1899 simplifies multi-byte nop, as well as bndcl, bndcu, bndcn. */
1908 int code
= cpu_ldub_code(env
, s
->pc
++);
1909 scale
= (code
>> 6) & 3;
1910 index
= ((code
>> 3) & 7) | REX_X(s
);
1912 index
= -1; /* no index */
1914 base
= (code
& 7) | REX_B(s
);
1920 if ((base
& 7) == 5) {
1922 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
1924 if (CODE64(s
) && !havesib
) {
1926 disp
+= s
->pc
+ s
->rip_offset
;
1931 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
1935 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
1940 /* For correct popl handling with esp. */
1941 if (base
== R_ESP
&& s
->popl_esp_hack
) {
1942 disp
+= s
->popl_esp_hack
;
1944 if (base
== R_EBP
|| base
== R_ESP
) {
1953 disp
= cpu_lduw_code(env
, s
->pc
);
1957 } else if (mod
== 1) {
1958 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
1960 disp
= (int16_t)cpu_lduw_code(env
, s
->pc
);
2005 return (AddressParts
){ def_seg
, base
, index
, scale
, disp
};
2008 /* Compute the address, with a minimum number of TCG ops. */
2009 static TCGv
gen_lea_modrm_1(AddressParts a
)
2016 ea
= cpu_regs
[a
.index
];
2018 tcg_gen_shli_tl(cpu_A0
, cpu_regs
[a
.index
], a
.scale
);
2022 tcg_gen_add_tl(cpu_A0
, ea
, cpu_regs
[a
.base
]);
2025 } else if (a
.base
>= 0) {
2026 ea
= cpu_regs
[a
.base
];
2028 if (TCGV_IS_UNUSED(ea
)) {
2029 tcg_gen_movi_tl(cpu_A0
, a
.disp
);
2031 } else if (a
.disp
!= 0) {
2032 tcg_gen_addi_tl(cpu_A0
, ea
, a
.disp
);
2039 static void gen_lea_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2041 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
2042 TCGv ea
= gen_lea_modrm_1(a
);
2043 gen_lea_v_seg(s
, s
->aflag
, ea
, a
.def_seg
, s
->override
);
2046 static void gen_nop_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2048 (void)gen_lea_modrm_0(env
, s
, modrm
);
2051 /* Used for BNDCL, BNDCU, BNDCN. */
2052 static void gen_bndck(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2053 TCGCond cond
, TCGv_i64 bndv
)
2055 TCGv ea
= gen_lea_modrm_1(gen_lea_modrm_0(env
, s
, modrm
));
2057 tcg_gen_extu_tl_i64(cpu_tmp1_i64
, ea
);
2059 tcg_gen_ext32u_i64(cpu_tmp1_i64
, cpu_tmp1_i64
);
2061 tcg_gen_setcond_i64(cond
, cpu_tmp1_i64
, cpu_tmp1_i64
, bndv
);
2062 tcg_gen_extrl_i64_i32(cpu_tmp2_i32
, cpu_tmp1_i64
);
2063 gen_helper_bndck(cpu_env
, cpu_tmp2_i32
);
2066 /* used for LEA and MOV AX, mem */
2067 static void gen_add_A0_ds_seg(DisasContext
*s
)
2069 gen_lea_v_seg(s
, s
->aflag
, cpu_A0
, R_DS
, s
->override
);
2072 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2074 static void gen_ldst_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2075 TCGMemOp ot
, int reg
, int is_store
)
2079 mod
= (modrm
>> 6) & 3;
2080 rm
= (modrm
& 7) | REX_B(s
);
2084 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
2085 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
2087 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
2089 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
2092 gen_lea_modrm(env
, s
, modrm
);
2095 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
2096 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
2098 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
2100 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
2105 static inline uint32_t insn_get(CPUX86State
*env
, DisasContext
*s
, TCGMemOp ot
)
2111 ret
= cpu_ldub_code(env
, s
->pc
);
2115 ret
= cpu_lduw_code(env
, s
->pc
);
2119 #ifdef TARGET_X86_64
2122 ret
= cpu_ldl_code(env
, s
->pc
);
2131 static inline int insn_const_size(TCGMemOp ot
)
2140 static inline bool use_goto_tb(DisasContext
*s
, target_ulong pc
)
2142 #ifndef CONFIG_USER_ONLY
2143 return (pc
& TARGET_PAGE_MASK
) == (s
->tb
->pc
& TARGET_PAGE_MASK
) ||
2144 (pc
& TARGET_PAGE_MASK
) == (s
->pc_start
& TARGET_PAGE_MASK
);
2150 static inline void gen_goto_tb(DisasContext
*s
, int tb_num
, target_ulong eip
)
2152 target_ulong pc
= s
->cs_base
+ eip
;
2154 if (use_goto_tb(s
, pc
)) {
2155 /* jump to same page: we can use a direct jump */
2156 tcg_gen_goto_tb(tb_num
);
2158 tcg_gen_exit_tb((uintptr_t)s
->tb
+ tb_num
);
2160 /* jump to another page: currently not optimized */
2166 static inline void gen_jcc(DisasContext
*s
, int b
,
2167 target_ulong val
, target_ulong next_eip
)
2172 l1
= gen_new_label();
2175 gen_goto_tb(s
, 0, next_eip
);
2178 gen_goto_tb(s
, 1, val
);
2179 s
->is_jmp
= DISAS_TB_JUMP
;
2181 l1
= gen_new_label();
2182 l2
= gen_new_label();
2185 gen_jmp_im(next_eip
);
2195 static void gen_cmovcc1(CPUX86State
*env
, DisasContext
*s
, TCGMemOp ot
, int b
,
2200 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
2202 cc
= gen_prepare_cc(s
, b
, cpu_T1
);
2203 if (cc
.mask
!= -1) {
2204 TCGv t0
= tcg_temp_new();
2205 tcg_gen_andi_tl(t0
, cc
.reg
, cc
.mask
);
2209 cc
.reg2
= tcg_const_tl(cc
.imm
);
2212 tcg_gen_movcond_tl(cc
.cond
, cpu_T0
, cc
.reg
, cc
.reg2
,
2213 cpu_T0
, cpu_regs
[reg
]);
2214 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
2216 if (cc
.mask
!= -1) {
2217 tcg_temp_free(cc
.reg
);
2220 tcg_temp_free(cc
.reg2
);
2224 static inline void gen_op_movl_T0_seg(int seg_reg
)
2226 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
,
2227 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2230 static inline void gen_op_movl_seg_T0_vm(int seg_reg
)
2232 tcg_gen_ext16u_tl(cpu_T0
, cpu_T0
);
2233 tcg_gen_st32_tl(cpu_T0
, cpu_env
,
2234 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2235 tcg_gen_shli_tl(cpu_seg_base
[seg_reg
], cpu_T0
, 4);
2238 /* move T0 to seg_reg and compute if the CPU state may change. Never
2239 call this function with seg_reg == R_CS */
2240 static void gen_movl_seg_T0(DisasContext
*s
, int seg_reg
)
2242 if (s
->pe
&& !s
->vm86
) {
2243 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
2244 gen_helper_load_seg(cpu_env
, tcg_const_i32(seg_reg
), cpu_tmp2_i32
);
2245 /* abort translation because the addseg value may change or
2246 because ss32 may change. For R_SS, translation must always
2247 stop as a special handling must be done to disable hardware
2248 interrupts for the next instruction */
2249 if (seg_reg
== R_SS
|| (s
->code32
&& seg_reg
< R_FS
))
2250 s
->is_jmp
= DISAS_TB_JUMP
;
2252 gen_op_movl_seg_T0_vm(seg_reg
);
2253 if (seg_reg
== R_SS
)
2254 s
->is_jmp
= DISAS_TB_JUMP
;
2258 static inline int svm_is_rep(int prefixes
)
2260 return ((prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) ? 8 : 0);
2264 gen_svm_check_intercept_param(DisasContext
*s
, target_ulong pc_start
,
2265 uint32_t type
, uint64_t param
)
2267 /* no SVM activated; fast case */
2268 if (likely(!(s
->flags
& HF_SVMI_MASK
)))
2270 gen_update_cc_op(s
);
2271 gen_jmp_im(pc_start
- s
->cs_base
);
2272 gen_helper_svm_check_intercept_param(cpu_env
, tcg_const_i32(type
),
2273 tcg_const_i64(param
));
2277 gen_svm_check_intercept(DisasContext
*s
, target_ulong pc_start
, uint64_t type
)
2279 gen_svm_check_intercept_param(s
, pc_start
, type
, 0);
2282 static inline void gen_stack_update(DisasContext
*s
, int addend
)
2284 gen_op_add_reg_im(mo_stacksize(s
), R_ESP
, addend
);
2287 /* Generate a push. It depends on ss32, addseg and dflag. */
2288 static void gen_push_v(DisasContext
*s
, TCGv val
)
2290 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2291 TCGMemOp a_ot
= mo_stacksize(s
);
2292 int size
= 1 << d_ot
;
2293 TCGv new_esp
= cpu_A0
;
2295 tcg_gen_subi_tl(cpu_A0
, cpu_regs
[R_ESP
], size
);
2300 tcg_gen_mov_tl(new_esp
, cpu_A0
);
2302 gen_lea_v_seg(s
, a_ot
, cpu_A0
, R_SS
, -1);
2305 gen_op_st_v(s
, d_ot
, val
, cpu_A0
);
2306 gen_op_mov_reg_v(a_ot
, R_ESP
, new_esp
);
2309 /* two step pop is necessary for precise exceptions */
2310 static TCGMemOp
gen_pop_T0(DisasContext
*s
)
2312 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2314 gen_lea_v_seg(s
, mo_stacksize(s
), cpu_regs
[R_ESP
], R_SS
, -1);
2315 gen_op_ld_v(s
, d_ot
, cpu_T0
, cpu_A0
);
2320 static inline void gen_pop_update(DisasContext
*s
, TCGMemOp ot
)
2322 gen_stack_update(s
, 1 << ot
);
2325 static inline void gen_stack_A0(DisasContext
*s
)
2327 gen_lea_v_seg(s
, s
->ss32
? MO_32
: MO_16
, cpu_regs
[R_ESP
], R_SS
, -1);
2330 static void gen_pusha(DisasContext
*s
)
2332 TCGMemOp s_ot
= s
->ss32
? MO_32
: MO_16
;
2333 TCGMemOp d_ot
= s
->dflag
;
2334 int size
= 1 << d_ot
;
2337 for (i
= 0; i
< 8; i
++) {
2338 tcg_gen_addi_tl(cpu_A0
, cpu_regs
[R_ESP
], (i
- 8) * size
);
2339 gen_lea_v_seg(s
, s_ot
, cpu_A0
, R_SS
, -1);
2340 gen_op_st_v(s
, d_ot
, cpu_regs
[7 - i
], cpu_A0
);
2343 gen_stack_update(s
, -8 * size
);
2346 static void gen_popa(DisasContext
*s
)
2348 TCGMemOp s_ot
= s
->ss32
? MO_32
: MO_16
;
2349 TCGMemOp d_ot
= s
->dflag
;
2350 int size
= 1 << d_ot
;
2353 for (i
= 0; i
< 8; i
++) {
2354 /* ESP is not reloaded */
2355 if (7 - i
== R_ESP
) {
2358 tcg_gen_addi_tl(cpu_A0
, cpu_regs
[R_ESP
], i
* size
);
2359 gen_lea_v_seg(s
, s_ot
, cpu_A0
, R_SS
, -1);
2360 gen_op_ld_v(s
, d_ot
, cpu_T0
, cpu_A0
);
2361 gen_op_mov_reg_v(d_ot
, 7 - i
, cpu_T0
);
2364 gen_stack_update(s
, 8 * size
);
2367 static void gen_enter(DisasContext
*s
, int esp_addend
, int level
)
2369 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2370 TCGMemOp a_ot
= CODE64(s
) ? MO_64
: s
->ss32
? MO_32
: MO_16
;
2371 int size
= 1 << d_ot
;
2373 /* Push BP; compute FrameTemp into T1. */
2374 tcg_gen_subi_tl(cpu_T1
, cpu_regs
[R_ESP
], size
);
2375 gen_lea_v_seg(s
, a_ot
, cpu_T1
, R_SS
, -1);
2376 gen_op_st_v(s
, d_ot
, cpu_regs
[R_EBP
], cpu_A0
);
2382 /* Copy level-1 pointers from the previous frame. */
2383 for (i
= 1; i
< level
; ++i
) {
2384 tcg_gen_subi_tl(cpu_A0
, cpu_regs
[R_EBP
], size
* i
);
2385 gen_lea_v_seg(s
, a_ot
, cpu_A0
, R_SS
, -1);
2386 gen_op_ld_v(s
, d_ot
, cpu_tmp0
, cpu_A0
);
2388 tcg_gen_subi_tl(cpu_A0
, cpu_T1
, size
* i
);
2389 gen_lea_v_seg(s
, a_ot
, cpu_A0
, R_SS
, -1);
2390 gen_op_st_v(s
, d_ot
, cpu_tmp0
, cpu_A0
);
2393 /* Push the current FrameTemp as the last level. */
2394 tcg_gen_subi_tl(cpu_A0
, cpu_T1
, size
* level
);
2395 gen_lea_v_seg(s
, a_ot
, cpu_A0
, R_SS
, -1);
2396 gen_op_st_v(s
, d_ot
, cpu_T1
, cpu_A0
);
2399 /* Copy the FrameTemp value to EBP. */
2400 gen_op_mov_reg_v(a_ot
, R_EBP
, cpu_T1
);
2402 /* Compute the final value of ESP. */
2403 tcg_gen_subi_tl(cpu_T1
, cpu_T1
, esp_addend
+ size
* level
);
2404 gen_op_mov_reg_v(a_ot
, R_ESP
, cpu_T1
);
2407 static void gen_leave(DisasContext
*s
)
2409 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2410 TCGMemOp a_ot
= mo_stacksize(s
);
2412 gen_lea_v_seg(s
, a_ot
, cpu_regs
[R_EBP
], R_SS
, -1);
2413 gen_op_ld_v(s
, d_ot
, cpu_T0
, cpu_A0
);
2415 tcg_gen_addi_tl(cpu_T1
, cpu_regs
[R_EBP
], 1 << d_ot
);
2417 gen_op_mov_reg_v(d_ot
, R_EBP
, cpu_T0
);
2418 gen_op_mov_reg_v(a_ot
, R_ESP
, cpu_T1
);
2421 static void gen_exception(DisasContext
*s
, int trapno
, target_ulong cur_eip
)
2423 gen_update_cc_op(s
);
2424 gen_jmp_im(cur_eip
);
2425 gen_helper_raise_exception(cpu_env
, tcg_const_i32(trapno
));
2426 s
->is_jmp
= DISAS_TB_JUMP
;
2429 /* Generate #UD for the current instruction. The assumption here is that
2430 the instruction is known, but it isn't allowed in the current cpu mode. */
2431 static void gen_illegal_opcode(DisasContext
*s
)
2433 gen_exception(s
, EXCP06_ILLOP
, s
->pc_start
- s
->cs_base
);
2436 /* Similarly, except that the assumption here is that we don't decode
2437 the instruction at all -- either a missing opcode, an unimplemented
2438 feature, or just a bogus instruction stream. */
2439 static void gen_unknown_opcode(CPUX86State
*env
, DisasContext
*s
)
2441 gen_illegal_opcode(s
);
2443 if (qemu_loglevel_mask(LOG_UNIMP
)) {
2444 target_ulong pc
= s
->pc_start
, end
= s
->pc
;
2446 qemu_log("ILLOPC: " TARGET_FMT_lx
":", pc
);
2447 for (; pc
< end
; ++pc
) {
2448 qemu_log(" %02x", cpu_ldub_code(env
, pc
));
2455 /* an interrupt is different from an exception because of the
2457 static void gen_interrupt(DisasContext
*s
, int intno
,
2458 target_ulong cur_eip
, target_ulong next_eip
)
2460 gen_update_cc_op(s
);
2461 gen_jmp_im(cur_eip
);
2462 gen_helper_raise_interrupt(cpu_env
, tcg_const_i32(intno
),
2463 tcg_const_i32(next_eip
- cur_eip
));
2464 s
->is_jmp
= DISAS_TB_JUMP
;
2467 static void gen_debug(DisasContext
*s
, target_ulong cur_eip
)
2469 gen_update_cc_op(s
);
2470 gen_jmp_im(cur_eip
);
2471 gen_helper_debug(cpu_env
);
2472 s
->is_jmp
= DISAS_TB_JUMP
;
2475 static void gen_set_hflag(DisasContext
*s
, uint32_t mask
)
2477 if ((s
->flags
& mask
) == 0) {
2478 TCGv_i32 t
= tcg_temp_new_i32();
2479 tcg_gen_ld_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2480 tcg_gen_ori_i32(t
, t
, mask
);
2481 tcg_gen_st_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2482 tcg_temp_free_i32(t
);
2487 static void gen_reset_hflag(DisasContext
*s
, uint32_t mask
)
2489 if (s
->flags
& mask
) {
2490 TCGv_i32 t
= tcg_temp_new_i32();
2491 tcg_gen_ld_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2492 tcg_gen_andi_i32(t
, t
, ~mask
);
2493 tcg_gen_st_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2494 tcg_temp_free_i32(t
);
2499 /* Clear BND registers during legacy branches. */
2500 static void gen_bnd_jmp(DisasContext
*s
)
2502 /* Clear the registers only if BND prefix is missing, MPX is enabled,
2503 and if the BNDREGs are known to be in use (non-zero) already.
2504 The helper itself will check BNDPRESERVE at runtime. */
2505 if ((s
->prefix
& PREFIX_REPNZ
) == 0
2506 && (s
->flags
& HF_MPX_EN_MASK
) != 0
2507 && (s
->flags
& HF_MPX_IU_MASK
) != 0) {
2508 gen_helper_bnd_jmp(cpu_env
);
2512 /* Generate an end of block. Trace exception is also generated if needed.
2513 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set.
2514 If RECHECK_TF, emit a rechecking helper for #DB, ignoring the state of
2515 S->TF. This is used by the syscall/sysret insns. */
2516 static void gen_eob_worker(DisasContext
*s
, bool inhibit
, bool recheck_tf
)
2518 gen_update_cc_op(s
);
2520 /* If several instructions disable interrupts, only the first does it. */
2521 if (inhibit
&& !(s
->flags
& HF_INHIBIT_IRQ_MASK
)) {
2522 gen_set_hflag(s
, HF_INHIBIT_IRQ_MASK
);
2524 gen_reset_hflag(s
, HF_INHIBIT_IRQ_MASK
);
2527 if (s
->tb
->flags
& HF_RF_MASK
) {
2528 gen_helper_reset_rf(cpu_env
);
2530 if (s
->singlestep_enabled
) {
2531 gen_helper_debug(cpu_env
);
2532 } else if (recheck_tf
) {
2533 gen_helper_rechecking_single_step(cpu_env
);
2536 gen_helper_single_step(cpu_env
);
2540 s
->is_jmp
= DISAS_TB_JUMP
;
2544 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set. */
2545 static void gen_eob_inhibit_irq(DisasContext
*s
, bool inhibit
)
2547 gen_eob_worker(s
, inhibit
, false);
2550 /* End of block, resetting the inhibit irq flag. */
2551 static void gen_eob(DisasContext
*s
)
2553 gen_eob_worker(s
, false, false);
2556 /* generate a jump to eip. No segment change must happen before as a
2557 direct call to the next block may occur */
2558 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
)
2560 gen_update_cc_op(s
);
2561 set_cc_op(s
, CC_OP_DYNAMIC
);
2563 gen_goto_tb(s
, tb_num
, eip
);
2564 s
->is_jmp
= DISAS_TB_JUMP
;
2571 static void gen_jmp(DisasContext
*s
, target_ulong eip
)
2573 gen_jmp_tb(s
, eip
, 0);
2576 static inline void gen_ldq_env_A0(DisasContext
*s
, int offset
)
2578 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
2579 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2582 static inline void gen_stq_env_A0(DisasContext
*s
, int offset
)
2584 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2585 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
2588 static inline void gen_ldo_env_A0(DisasContext
*s
, int offset
)
2590 int mem_index
= s
->mem_index
;
2591 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, mem_index
, MO_LEQ
);
2592 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2593 tcg_gen_addi_tl(cpu_tmp0
, cpu_A0
, 8);
2594 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
, MO_LEQ
);
2595 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2598 static inline void gen_sto_env_A0(DisasContext
*s
, int offset
)
2600 int mem_index
= s
->mem_index
;
2601 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2602 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, mem_index
, MO_LEQ
);
2603 tcg_gen_addi_tl(cpu_tmp0
, cpu_A0
, 8);
2604 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2605 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
, MO_LEQ
);
2608 static inline void gen_op_movo(int d_offset
, int s_offset
)
2610 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2611 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2612 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2613 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2616 static inline void gen_op_movq(int d_offset
, int s_offset
)
2618 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
);
2619 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2622 static inline void gen_op_movl(int d_offset
, int s_offset
)
2624 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
, s_offset
);
2625 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, d_offset
);
2628 static inline void gen_op_movq_env_0(int d_offset
)
2630 tcg_gen_movi_i64(cpu_tmp1_i64
, 0);
2631 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2634 typedef void (*SSEFunc_i_ep
)(TCGv_i32 val
, TCGv_ptr env
, TCGv_ptr reg
);
2635 typedef void (*SSEFunc_l_ep
)(TCGv_i64 val
, TCGv_ptr env
, TCGv_ptr reg
);
2636 typedef void (*SSEFunc_0_epi
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i32 val
);
2637 typedef void (*SSEFunc_0_epl
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i64 val
);
2638 typedef void (*SSEFunc_0_epp
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
);
2639 typedef void (*SSEFunc_0_eppi
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2641 typedef void (*SSEFunc_0_ppi
)(TCGv_ptr reg_a
, TCGv_ptr reg_b
, TCGv_i32 val
);
2642 typedef void (*SSEFunc_0_eppt
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2645 #define SSE_SPECIAL ((void *)1)
2646 #define SSE_DUMMY ((void *)2)
2648 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2649 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2650 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2652 static const SSEFunc_0_epp sse_op_table1
[256][4] = {
2653 /* 3DNow! extensions */
2654 [0x0e] = { SSE_DUMMY
}, /* femms */
2655 [0x0f] = { SSE_DUMMY
}, /* pf... */
2656 /* pure SSE operations */
2657 [0x10] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2658 [0x11] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2659 [0x12] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd, movsldup, movddup */
2660 [0x13] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd */
2661 [0x14] = { gen_helper_punpckldq_xmm
, gen_helper_punpcklqdq_xmm
},
2662 [0x15] = { gen_helper_punpckhdq_xmm
, gen_helper_punpckhqdq_xmm
},
2663 [0x16] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd, movshdup */
2664 [0x17] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd */
2666 [0x28] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2667 [0x29] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2668 [0x2a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2669 [0x2b] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movntps, movntpd, movntss, movntsd */
2670 [0x2c] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2671 [0x2d] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2672 [0x2e] = { gen_helper_ucomiss
, gen_helper_ucomisd
},
2673 [0x2f] = { gen_helper_comiss
, gen_helper_comisd
},
2674 [0x50] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movmskps, movmskpd */
2675 [0x51] = SSE_FOP(sqrt
),
2676 [0x52] = { gen_helper_rsqrtps
, NULL
, gen_helper_rsqrtss
, NULL
},
2677 [0x53] = { gen_helper_rcpps
, NULL
, gen_helper_rcpss
, NULL
},
2678 [0x54] = { gen_helper_pand_xmm
, gen_helper_pand_xmm
}, /* andps, andpd */
2679 [0x55] = { gen_helper_pandn_xmm
, gen_helper_pandn_xmm
}, /* andnps, andnpd */
2680 [0x56] = { gen_helper_por_xmm
, gen_helper_por_xmm
}, /* orps, orpd */
2681 [0x57] = { gen_helper_pxor_xmm
, gen_helper_pxor_xmm
}, /* xorps, xorpd */
2682 [0x58] = SSE_FOP(add
),
2683 [0x59] = SSE_FOP(mul
),
2684 [0x5a] = { gen_helper_cvtps2pd
, gen_helper_cvtpd2ps
,
2685 gen_helper_cvtss2sd
, gen_helper_cvtsd2ss
},
2686 [0x5b] = { gen_helper_cvtdq2ps
, gen_helper_cvtps2dq
, gen_helper_cvttps2dq
},
2687 [0x5c] = SSE_FOP(sub
),
2688 [0x5d] = SSE_FOP(min
),
2689 [0x5e] = SSE_FOP(div
),
2690 [0x5f] = SSE_FOP(max
),
2692 [0xc2] = SSE_FOP(cmpeq
),
2693 [0xc6] = { (SSEFunc_0_epp
)gen_helper_shufps
,
2694 (SSEFunc_0_epp
)gen_helper_shufpd
}, /* XXX: casts */
2696 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */
2697 [0x38] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2698 [0x3a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2700 /* MMX ops and their SSE extensions */
2701 [0x60] = MMX_OP2(punpcklbw
),
2702 [0x61] = MMX_OP2(punpcklwd
),
2703 [0x62] = MMX_OP2(punpckldq
),
2704 [0x63] = MMX_OP2(packsswb
),
2705 [0x64] = MMX_OP2(pcmpgtb
),
2706 [0x65] = MMX_OP2(pcmpgtw
),
2707 [0x66] = MMX_OP2(pcmpgtl
),
2708 [0x67] = MMX_OP2(packuswb
),
2709 [0x68] = MMX_OP2(punpckhbw
),
2710 [0x69] = MMX_OP2(punpckhwd
),
2711 [0x6a] = MMX_OP2(punpckhdq
),
2712 [0x6b] = MMX_OP2(packssdw
),
2713 [0x6c] = { NULL
, gen_helper_punpcklqdq_xmm
},
2714 [0x6d] = { NULL
, gen_helper_punpckhqdq_xmm
},
2715 [0x6e] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movd mm, ea */
2716 [0x6f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, , movqdu */
2717 [0x70] = { (SSEFunc_0_epp
)gen_helper_pshufw_mmx
,
2718 (SSEFunc_0_epp
)gen_helper_pshufd_xmm
,
2719 (SSEFunc_0_epp
)gen_helper_pshufhw_xmm
,
2720 (SSEFunc_0_epp
)gen_helper_pshuflw_xmm
}, /* XXX: casts */
2721 [0x71] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftw */
2722 [0x72] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftd */
2723 [0x73] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftq */
2724 [0x74] = MMX_OP2(pcmpeqb
),
2725 [0x75] = MMX_OP2(pcmpeqw
),
2726 [0x76] = MMX_OP2(pcmpeql
),
2727 [0x77] = { SSE_DUMMY
}, /* emms */
2728 [0x78] = { NULL
, SSE_SPECIAL
, NULL
, SSE_SPECIAL
}, /* extrq_i, insertq_i */
2729 [0x79] = { NULL
, gen_helper_extrq_r
, NULL
, gen_helper_insertq_r
},
2730 [0x7c] = { NULL
, gen_helper_haddpd
, NULL
, gen_helper_haddps
},
2731 [0x7d] = { NULL
, gen_helper_hsubpd
, NULL
, gen_helper_hsubps
},
2732 [0x7e] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movd, movd, , movq */
2733 [0x7f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, movdqu */
2734 [0xc4] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pinsrw */
2735 [0xc5] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pextrw */
2736 [0xd0] = { NULL
, gen_helper_addsubpd
, NULL
, gen_helper_addsubps
},
2737 [0xd1] = MMX_OP2(psrlw
),
2738 [0xd2] = MMX_OP2(psrld
),
2739 [0xd3] = MMX_OP2(psrlq
),
2740 [0xd4] = MMX_OP2(paddq
),
2741 [0xd5] = MMX_OP2(pmullw
),
2742 [0xd6] = { NULL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2743 [0xd7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pmovmskb */
2744 [0xd8] = MMX_OP2(psubusb
),
2745 [0xd9] = MMX_OP2(psubusw
),
2746 [0xda] = MMX_OP2(pminub
),
2747 [0xdb] = MMX_OP2(pand
),
2748 [0xdc] = MMX_OP2(paddusb
),
2749 [0xdd] = MMX_OP2(paddusw
),
2750 [0xde] = MMX_OP2(pmaxub
),
2751 [0xdf] = MMX_OP2(pandn
),
2752 [0xe0] = MMX_OP2(pavgb
),
2753 [0xe1] = MMX_OP2(psraw
),
2754 [0xe2] = MMX_OP2(psrad
),
2755 [0xe3] = MMX_OP2(pavgw
),
2756 [0xe4] = MMX_OP2(pmulhuw
),
2757 [0xe5] = MMX_OP2(pmulhw
),
2758 [0xe6] = { NULL
, gen_helper_cvttpd2dq
, gen_helper_cvtdq2pd
, gen_helper_cvtpd2dq
},
2759 [0xe7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movntq, movntq */
2760 [0xe8] = MMX_OP2(psubsb
),
2761 [0xe9] = MMX_OP2(psubsw
),
2762 [0xea] = MMX_OP2(pminsw
),
2763 [0xeb] = MMX_OP2(por
),
2764 [0xec] = MMX_OP2(paddsb
),
2765 [0xed] = MMX_OP2(paddsw
),
2766 [0xee] = MMX_OP2(pmaxsw
),
2767 [0xef] = MMX_OP2(pxor
),
2768 [0xf0] = { NULL
, NULL
, NULL
, SSE_SPECIAL
}, /* lddqu */
2769 [0xf1] = MMX_OP2(psllw
),
2770 [0xf2] = MMX_OP2(pslld
),
2771 [0xf3] = MMX_OP2(psllq
),
2772 [0xf4] = MMX_OP2(pmuludq
),
2773 [0xf5] = MMX_OP2(pmaddwd
),
2774 [0xf6] = MMX_OP2(psadbw
),
2775 [0xf7] = { (SSEFunc_0_epp
)gen_helper_maskmov_mmx
,
2776 (SSEFunc_0_epp
)gen_helper_maskmov_xmm
}, /* XXX: casts */
2777 [0xf8] = MMX_OP2(psubb
),
2778 [0xf9] = MMX_OP2(psubw
),
2779 [0xfa] = MMX_OP2(psubl
),
2780 [0xfb] = MMX_OP2(psubq
),
2781 [0xfc] = MMX_OP2(paddb
),
2782 [0xfd] = MMX_OP2(paddw
),
2783 [0xfe] = MMX_OP2(paddl
),
2786 static const SSEFunc_0_epp sse_op_table2
[3 * 8][2] = {
2787 [0 + 2] = MMX_OP2(psrlw
),
2788 [0 + 4] = MMX_OP2(psraw
),
2789 [0 + 6] = MMX_OP2(psllw
),
2790 [8 + 2] = MMX_OP2(psrld
),
2791 [8 + 4] = MMX_OP2(psrad
),
2792 [8 + 6] = MMX_OP2(pslld
),
2793 [16 + 2] = MMX_OP2(psrlq
),
2794 [16 + 3] = { NULL
, gen_helper_psrldq_xmm
},
2795 [16 + 6] = MMX_OP2(psllq
),
2796 [16 + 7] = { NULL
, gen_helper_pslldq_xmm
},
2799 static const SSEFunc_0_epi sse_op_table3ai
[] = {
2800 gen_helper_cvtsi2ss
,
2804 #ifdef TARGET_X86_64
2805 static const SSEFunc_0_epl sse_op_table3aq
[] = {
2806 gen_helper_cvtsq2ss
,
2811 static const SSEFunc_i_ep sse_op_table3bi
[] = {
2812 gen_helper_cvttss2si
,
2813 gen_helper_cvtss2si
,
2814 gen_helper_cvttsd2si
,
2818 #ifdef TARGET_X86_64
2819 static const SSEFunc_l_ep sse_op_table3bq
[] = {
2820 gen_helper_cvttss2sq
,
2821 gen_helper_cvtss2sq
,
2822 gen_helper_cvttsd2sq
,
2827 static const SSEFunc_0_epp sse_op_table4
[8][4] = {
2838 static const SSEFunc_0_epp sse_op_table5
[256] = {
2839 [0x0c] = gen_helper_pi2fw
,
2840 [0x0d] = gen_helper_pi2fd
,
2841 [0x1c] = gen_helper_pf2iw
,
2842 [0x1d] = gen_helper_pf2id
,
2843 [0x8a] = gen_helper_pfnacc
,
2844 [0x8e] = gen_helper_pfpnacc
,
2845 [0x90] = gen_helper_pfcmpge
,
2846 [0x94] = gen_helper_pfmin
,
2847 [0x96] = gen_helper_pfrcp
,
2848 [0x97] = gen_helper_pfrsqrt
,
2849 [0x9a] = gen_helper_pfsub
,
2850 [0x9e] = gen_helper_pfadd
,
2851 [0xa0] = gen_helper_pfcmpgt
,
2852 [0xa4] = gen_helper_pfmax
,
2853 [0xa6] = gen_helper_movq
, /* pfrcpit1; no need to actually increase precision */
2854 [0xa7] = gen_helper_movq
, /* pfrsqit1 */
2855 [0xaa] = gen_helper_pfsubr
,
2856 [0xae] = gen_helper_pfacc
,
2857 [0xb0] = gen_helper_pfcmpeq
,
2858 [0xb4] = gen_helper_pfmul
,
2859 [0xb6] = gen_helper_movq
, /* pfrcpit2 */
2860 [0xb7] = gen_helper_pmulhrw_mmx
,
2861 [0xbb] = gen_helper_pswapd
,
2862 [0xbf] = gen_helper_pavgb_mmx
/* pavgusb */
2865 struct SSEOpHelper_epp
{
2866 SSEFunc_0_epp op
[2];
2870 struct SSEOpHelper_eppi
{
2871 SSEFunc_0_eppi op
[2];
2875 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
2876 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
2877 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
2878 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
2879 #define PCLMULQDQ_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, \
2880 CPUID_EXT_PCLMULQDQ }
2881 #define AESNI_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_AES }
2883 static const struct SSEOpHelper_epp sse_op_table6
[256] = {
2884 [0x00] = SSSE3_OP(pshufb
),
2885 [0x01] = SSSE3_OP(phaddw
),
2886 [0x02] = SSSE3_OP(phaddd
),
2887 [0x03] = SSSE3_OP(phaddsw
),
2888 [0x04] = SSSE3_OP(pmaddubsw
),
2889 [0x05] = SSSE3_OP(phsubw
),
2890 [0x06] = SSSE3_OP(phsubd
),
2891 [0x07] = SSSE3_OP(phsubsw
),
2892 [0x08] = SSSE3_OP(psignb
),
2893 [0x09] = SSSE3_OP(psignw
),
2894 [0x0a] = SSSE3_OP(psignd
),
2895 [0x0b] = SSSE3_OP(pmulhrsw
),
2896 [0x10] = SSE41_OP(pblendvb
),
2897 [0x14] = SSE41_OP(blendvps
),
2898 [0x15] = SSE41_OP(blendvpd
),
2899 [0x17] = SSE41_OP(ptest
),
2900 [0x1c] = SSSE3_OP(pabsb
),
2901 [0x1d] = SSSE3_OP(pabsw
),
2902 [0x1e] = SSSE3_OP(pabsd
),
2903 [0x20] = SSE41_OP(pmovsxbw
),
2904 [0x21] = SSE41_OP(pmovsxbd
),
2905 [0x22] = SSE41_OP(pmovsxbq
),
2906 [0x23] = SSE41_OP(pmovsxwd
),
2907 [0x24] = SSE41_OP(pmovsxwq
),
2908 [0x25] = SSE41_OP(pmovsxdq
),
2909 [0x28] = SSE41_OP(pmuldq
),
2910 [0x29] = SSE41_OP(pcmpeqq
),
2911 [0x2a] = SSE41_SPECIAL
, /* movntqda */
2912 [0x2b] = SSE41_OP(packusdw
),
2913 [0x30] = SSE41_OP(pmovzxbw
),
2914 [0x31] = SSE41_OP(pmovzxbd
),
2915 [0x32] = SSE41_OP(pmovzxbq
),
2916 [0x33] = SSE41_OP(pmovzxwd
),
2917 [0x34] = SSE41_OP(pmovzxwq
),
2918 [0x35] = SSE41_OP(pmovzxdq
),
2919 [0x37] = SSE42_OP(pcmpgtq
),
2920 [0x38] = SSE41_OP(pminsb
),
2921 [0x39] = SSE41_OP(pminsd
),
2922 [0x3a] = SSE41_OP(pminuw
),
2923 [0x3b] = SSE41_OP(pminud
),
2924 [0x3c] = SSE41_OP(pmaxsb
),
2925 [0x3d] = SSE41_OP(pmaxsd
),
2926 [0x3e] = SSE41_OP(pmaxuw
),
2927 [0x3f] = SSE41_OP(pmaxud
),
2928 [0x40] = SSE41_OP(pmulld
),
2929 [0x41] = SSE41_OP(phminposuw
),
2930 [0xdb] = AESNI_OP(aesimc
),
2931 [0xdc] = AESNI_OP(aesenc
),
2932 [0xdd] = AESNI_OP(aesenclast
),
2933 [0xde] = AESNI_OP(aesdec
),
2934 [0xdf] = AESNI_OP(aesdeclast
),
2937 static const struct SSEOpHelper_eppi sse_op_table7
[256] = {
2938 [0x08] = SSE41_OP(roundps
),
2939 [0x09] = SSE41_OP(roundpd
),
2940 [0x0a] = SSE41_OP(roundss
),
2941 [0x0b] = SSE41_OP(roundsd
),
2942 [0x0c] = SSE41_OP(blendps
),
2943 [0x0d] = SSE41_OP(blendpd
),
2944 [0x0e] = SSE41_OP(pblendw
),
2945 [0x0f] = SSSE3_OP(palignr
),
2946 [0x14] = SSE41_SPECIAL
, /* pextrb */
2947 [0x15] = SSE41_SPECIAL
, /* pextrw */
2948 [0x16] = SSE41_SPECIAL
, /* pextrd/pextrq */
2949 [0x17] = SSE41_SPECIAL
, /* extractps */
2950 [0x20] = SSE41_SPECIAL
, /* pinsrb */
2951 [0x21] = SSE41_SPECIAL
, /* insertps */
2952 [0x22] = SSE41_SPECIAL
, /* pinsrd/pinsrq */
2953 [0x40] = SSE41_OP(dpps
),
2954 [0x41] = SSE41_OP(dppd
),
2955 [0x42] = SSE41_OP(mpsadbw
),
2956 [0x44] = PCLMULQDQ_OP(pclmulqdq
),
2957 [0x60] = SSE42_OP(pcmpestrm
),
2958 [0x61] = SSE42_OP(pcmpestri
),
2959 [0x62] = SSE42_OP(pcmpistrm
),
2960 [0x63] = SSE42_OP(pcmpistri
),
2961 [0xdf] = AESNI_OP(aeskeygenassist
),
2964 static void gen_sse(CPUX86State
*env
, DisasContext
*s
, int b
,
2965 target_ulong pc_start
, int rex_r
)
2967 int b1
, op1_offset
, op2_offset
, is_xmm
, val
;
2968 int modrm
, mod
, rm
, reg
;
2969 SSEFunc_0_epp sse_fn_epp
;
2970 SSEFunc_0_eppi sse_fn_eppi
;
2971 SSEFunc_0_ppi sse_fn_ppi
;
2972 SSEFunc_0_eppt sse_fn_eppt
;
2976 if (s
->prefix
& PREFIX_DATA
)
2978 else if (s
->prefix
& PREFIX_REPZ
)
2980 else if (s
->prefix
& PREFIX_REPNZ
)
2984 sse_fn_epp
= sse_op_table1
[b
][b1
];
2988 if ((b
<= 0x5f && b
>= 0x10) || b
== 0xc6 || b
== 0xc2) {
2998 /* simple MMX/SSE operation */
2999 if (s
->flags
& HF_TS_MASK
) {
3000 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
3003 if (s
->flags
& HF_EM_MASK
) {
3005 gen_illegal_opcode(s
);
3009 && !(s
->flags
& HF_OSFXSR_MASK
)
3010 && ((b
!= 0x38 && b
!= 0x3a) || (s
->prefix
& PREFIX_DATA
))) {
3014 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
)) {
3015 /* If we were fully decoding this we might use illegal_op. */
3019 gen_helper_emms(cpu_env
);
3024 gen_helper_emms(cpu_env
);
3027 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3028 the static cpu state) */
3030 gen_helper_enter_mmx(cpu_env
);
3033 modrm
= cpu_ldub_code(env
, s
->pc
++);
3034 reg
= ((modrm
>> 3) & 7);
3037 mod
= (modrm
>> 6) & 3;
3038 if (sse_fn_epp
== SSE_SPECIAL
) {
3041 case 0x0e7: /* movntq */
3045 gen_lea_modrm(env
, s
, modrm
);
3046 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3048 case 0x1e7: /* movntdq */
3049 case 0x02b: /* movntps */
3050 case 0x12b: /* movntps */
3053 gen_lea_modrm(env
, s
, modrm
);
3054 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3056 case 0x3f0: /* lddqu */
3059 gen_lea_modrm(env
, s
, modrm
);
3060 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3062 case 0x22b: /* movntss */
3063 case 0x32b: /* movntsd */
3066 gen_lea_modrm(env
, s
, modrm
);
3068 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3069 xmm_regs
[reg
].ZMM_Q(0)));
3071 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,
3072 xmm_regs
[reg
].ZMM_L(0)));
3073 gen_op_st_v(s
, MO_32
, cpu_T0
, cpu_A0
);
3076 case 0x6e: /* movd mm, ea */
3077 #ifdef TARGET_X86_64
3078 if (s
->dflag
== MO_64
) {
3079 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3080 tcg_gen_st_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3084 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3085 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3086 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3087 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
3088 gen_helper_movl_mm_T0_mmx(cpu_ptr0
, cpu_tmp2_i32
);
3091 case 0x16e: /* movd xmm, ea */
3092 #ifdef TARGET_X86_64
3093 if (s
->dflag
== MO_64
) {
3094 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3095 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3096 offsetof(CPUX86State
,xmm_regs
[reg
]));
3097 gen_helper_movq_mm_T0_xmm(cpu_ptr0
, cpu_T0
);
3101 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3102 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3103 offsetof(CPUX86State
,xmm_regs
[reg
]));
3104 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
3105 gen_helper_movl_mm_T0_xmm(cpu_ptr0
, cpu_tmp2_i32
);
3108 case 0x6f: /* movq mm, ea */
3110 gen_lea_modrm(env
, s
, modrm
);
3111 gen_ldq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3114 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
3115 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3116 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
3117 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3120 case 0x010: /* movups */
3121 case 0x110: /* movupd */
3122 case 0x028: /* movaps */
3123 case 0x128: /* movapd */
3124 case 0x16f: /* movdqa xmm, ea */
3125 case 0x26f: /* movdqu xmm, ea */
3127 gen_lea_modrm(env
, s
, modrm
);
3128 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3130 rm
= (modrm
& 7) | REX_B(s
);
3131 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[reg
]),
3132 offsetof(CPUX86State
,xmm_regs
[rm
]));
3135 case 0x210: /* movss xmm, ea */
3137 gen_lea_modrm(env
, s
, modrm
);
3138 gen_op_ld_v(s
, MO_32
, cpu_T0
, cpu_A0
);
3139 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3140 tcg_gen_movi_tl(cpu_T0
, 0);
3141 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)));
3142 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)));
3143 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)));
3145 rm
= (modrm
& 7) | REX_B(s
);
3146 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)),
3147 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)));
3150 case 0x310: /* movsd xmm, ea */
3152 gen_lea_modrm(env
, s
, modrm
);
3153 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3154 xmm_regs
[reg
].ZMM_Q(0)));
3155 tcg_gen_movi_tl(cpu_T0
, 0);
3156 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)));
3157 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)));
3159 rm
= (modrm
& 7) | REX_B(s
);
3160 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3161 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3164 case 0x012: /* movlps */
3165 case 0x112: /* movlpd */
3167 gen_lea_modrm(env
, s
, modrm
);
3168 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3169 xmm_regs
[reg
].ZMM_Q(0)));
3172 rm
= (modrm
& 7) | REX_B(s
);
3173 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3174 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(1)));
3177 case 0x212: /* movsldup */
3179 gen_lea_modrm(env
, s
, modrm
);
3180 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3182 rm
= (modrm
& 7) | REX_B(s
);
3183 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)),
3184 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)));
3185 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)),
3186 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(2)));
3188 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)),
3189 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3190 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)),
3191 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)));
3193 case 0x312: /* movddup */
3195 gen_lea_modrm(env
, s
, modrm
);
3196 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3197 xmm_regs
[reg
].ZMM_Q(0)));
3199 rm
= (modrm
& 7) | REX_B(s
);
3200 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3201 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3203 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)),
3204 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3206 case 0x016: /* movhps */
3207 case 0x116: /* movhpd */
3209 gen_lea_modrm(env
, s
, modrm
);
3210 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3211 xmm_regs
[reg
].ZMM_Q(1)));
3214 rm
= (modrm
& 7) | REX_B(s
);
3215 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)),
3216 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3219 case 0x216: /* movshdup */
3221 gen_lea_modrm(env
, s
, modrm
);
3222 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3224 rm
= (modrm
& 7) | REX_B(s
);
3225 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)),
3226 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(1)));
3227 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)),
3228 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(3)));
3230 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)),
3231 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)));
3232 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)),
3233 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)));
3238 int bit_index
, field_length
;
3240 if (b1
== 1 && reg
!= 0)
3242 field_length
= cpu_ldub_code(env
, s
->pc
++) & 0x3F;
3243 bit_index
= cpu_ldub_code(env
, s
->pc
++) & 0x3F;
3244 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3245 offsetof(CPUX86State
,xmm_regs
[reg
]));
3247 gen_helper_extrq_i(cpu_env
, cpu_ptr0
,
3248 tcg_const_i32(bit_index
),
3249 tcg_const_i32(field_length
));
3251 gen_helper_insertq_i(cpu_env
, cpu_ptr0
,
3252 tcg_const_i32(bit_index
),
3253 tcg_const_i32(field_length
));
3256 case 0x7e: /* movd ea, mm */
3257 #ifdef TARGET_X86_64
3258 if (s
->dflag
== MO_64
) {
3259 tcg_gen_ld_i64(cpu_T0
, cpu_env
,
3260 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3261 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3265 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
,
3266 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_L(0)));
3267 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3270 case 0x17e: /* movd ea, xmm */
3271 #ifdef TARGET_X86_64
3272 if (s
->dflag
== MO_64
) {
3273 tcg_gen_ld_i64(cpu_T0
, cpu_env
,
3274 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3275 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3279 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
,
3280 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3281 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3284 case 0x27e: /* movq xmm, ea */
3286 gen_lea_modrm(env
, s
, modrm
);
3287 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3288 xmm_regs
[reg
].ZMM_Q(0)));
3290 rm
= (modrm
& 7) | REX_B(s
);
3291 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3292 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3294 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)));
3296 case 0x7f: /* movq ea, mm */
3298 gen_lea_modrm(env
, s
, modrm
);
3299 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3302 gen_op_movq(offsetof(CPUX86State
,fpregs
[rm
].mmx
),
3303 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3306 case 0x011: /* movups */
3307 case 0x111: /* movupd */
3308 case 0x029: /* movaps */
3309 case 0x129: /* movapd */
3310 case 0x17f: /* movdqa ea, xmm */
3311 case 0x27f: /* movdqu ea, xmm */
3313 gen_lea_modrm(env
, s
, modrm
);
3314 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3316 rm
= (modrm
& 7) | REX_B(s
);
3317 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[rm
]),
3318 offsetof(CPUX86State
,xmm_regs
[reg
]));
3321 case 0x211: /* movss ea, xmm */
3323 gen_lea_modrm(env
, s
, modrm
);
3324 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3325 gen_op_st_v(s
, MO_32
, cpu_T0
, cpu_A0
);
3327 rm
= (modrm
& 7) | REX_B(s
);
3328 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)),
3329 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3332 case 0x311: /* movsd ea, xmm */
3334 gen_lea_modrm(env
, s
, modrm
);
3335 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3336 xmm_regs
[reg
].ZMM_Q(0)));
3338 rm
= (modrm
& 7) | REX_B(s
);
3339 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)),
3340 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3343 case 0x013: /* movlps */
3344 case 0x113: /* movlpd */
3346 gen_lea_modrm(env
, s
, modrm
);
3347 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3348 xmm_regs
[reg
].ZMM_Q(0)));
3353 case 0x017: /* movhps */
3354 case 0x117: /* movhpd */
3356 gen_lea_modrm(env
, s
, modrm
);
3357 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3358 xmm_regs
[reg
].ZMM_Q(1)));
3363 case 0x71: /* shift mm, im */
3366 case 0x171: /* shift xmm, im */
3372 val
= cpu_ldub_code(env
, s
->pc
++);
3374 tcg_gen_movi_tl(cpu_T0
, val
);
3375 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_t0
.ZMM_L(0)));
3376 tcg_gen_movi_tl(cpu_T0
, 0);
3377 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_t0
.ZMM_L(1)));
3378 op1_offset
= offsetof(CPUX86State
,xmm_t0
);
3380 tcg_gen_movi_tl(cpu_T0
, val
);
3381 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,mmx_t0
.MMX_L(0)));
3382 tcg_gen_movi_tl(cpu_T0
, 0);
3383 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,mmx_t0
.MMX_L(1)));
3384 op1_offset
= offsetof(CPUX86State
,mmx_t0
);
3386 sse_fn_epp
= sse_op_table2
[((b
- 1) & 3) * 8 +
3387 (((modrm
>> 3)) & 7)][b1
];
3392 rm
= (modrm
& 7) | REX_B(s
);
3393 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3396 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3398 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3399 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op1_offset
);
3400 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3402 case 0x050: /* movmskps */
3403 rm
= (modrm
& 7) | REX_B(s
);
3404 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3405 offsetof(CPUX86State
,xmm_regs
[rm
]));
3406 gen_helper_movmskps(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3407 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3409 case 0x150: /* movmskpd */
3410 rm
= (modrm
& 7) | REX_B(s
);
3411 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3412 offsetof(CPUX86State
,xmm_regs
[rm
]));
3413 gen_helper_movmskpd(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3414 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3416 case 0x02a: /* cvtpi2ps */
3417 case 0x12a: /* cvtpi2pd */
3418 gen_helper_enter_mmx(cpu_env
);
3420 gen_lea_modrm(env
, s
, modrm
);
3421 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3422 gen_ldq_env_A0(s
, op2_offset
);
3425 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3427 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3428 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3429 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3432 gen_helper_cvtpi2ps(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3436 gen_helper_cvtpi2pd(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3440 case 0x22a: /* cvtsi2ss */
3441 case 0x32a: /* cvtsi2sd */
3442 ot
= mo_64_32(s
->dflag
);
3443 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3444 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3445 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3447 SSEFunc_0_epi sse_fn_epi
= sse_op_table3ai
[(b
>> 8) & 1];
3448 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
3449 sse_fn_epi(cpu_env
, cpu_ptr0
, cpu_tmp2_i32
);
3451 #ifdef TARGET_X86_64
3452 SSEFunc_0_epl sse_fn_epl
= sse_op_table3aq
[(b
>> 8) & 1];
3453 sse_fn_epl(cpu_env
, cpu_ptr0
, cpu_T0
);
3459 case 0x02c: /* cvttps2pi */
3460 case 0x12c: /* cvttpd2pi */
3461 case 0x02d: /* cvtps2pi */
3462 case 0x12d: /* cvtpd2pi */
3463 gen_helper_enter_mmx(cpu_env
);
3465 gen_lea_modrm(env
, s
, modrm
);
3466 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3467 gen_ldo_env_A0(s
, op2_offset
);
3469 rm
= (modrm
& 7) | REX_B(s
);
3470 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3472 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
);
3473 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3474 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3477 gen_helper_cvttps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3480 gen_helper_cvttpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3483 gen_helper_cvtps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3486 gen_helper_cvtpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3490 case 0x22c: /* cvttss2si */
3491 case 0x22d: /* cvtss2si */
3492 case 0x32c: /* cvttsd2si */
3493 case 0x32d: /* cvtsd2si */
3494 ot
= mo_64_32(s
->dflag
);
3496 gen_lea_modrm(env
, s
, modrm
);
3498 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.ZMM_Q(0)));
3500 gen_op_ld_v(s
, MO_32
, cpu_T0
, cpu_A0
);
3501 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_t0
.ZMM_L(0)));
3503 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3505 rm
= (modrm
& 7) | REX_B(s
);
3506 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3508 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3510 SSEFunc_i_ep sse_fn_i_ep
=
3511 sse_op_table3bi
[((b
>> 7) & 2) | (b
& 1)];
3512 sse_fn_i_ep(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3513 tcg_gen_extu_i32_tl(cpu_T0
, cpu_tmp2_i32
);
3515 #ifdef TARGET_X86_64
3516 SSEFunc_l_ep sse_fn_l_ep
=
3517 sse_op_table3bq
[((b
>> 7) & 2) | (b
& 1)];
3518 sse_fn_l_ep(cpu_T0
, cpu_env
, cpu_ptr0
);
3523 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3525 case 0xc4: /* pinsrw */
3528 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
3529 val
= cpu_ldub_code(env
, s
->pc
++);
3532 tcg_gen_st16_tl(cpu_T0
, cpu_env
,
3533 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_W(val
)));
3536 tcg_gen_st16_tl(cpu_T0
, cpu_env
,
3537 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_W(val
)));
3540 case 0xc5: /* pextrw */
3544 ot
= mo_64_32(s
->dflag
);
3545 val
= cpu_ldub_code(env
, s
->pc
++);
3548 rm
= (modrm
& 7) | REX_B(s
);
3549 tcg_gen_ld16u_tl(cpu_T0
, cpu_env
,
3550 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_W(val
)));
3554 tcg_gen_ld16u_tl(cpu_T0
, cpu_env
,
3555 offsetof(CPUX86State
,fpregs
[rm
].mmx
.MMX_W(val
)));
3557 reg
= ((modrm
>> 3) & 7) | rex_r
;
3558 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3560 case 0x1d6: /* movq ea, xmm */
3562 gen_lea_modrm(env
, s
, modrm
);
3563 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3564 xmm_regs
[reg
].ZMM_Q(0)));
3566 rm
= (modrm
& 7) | REX_B(s
);
3567 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)),
3568 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3569 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(1)));
3572 case 0x2d6: /* movq2dq */
3573 gen_helper_enter_mmx(cpu_env
);
3575 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3576 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3577 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)));
3579 case 0x3d6: /* movdq2q */
3580 gen_helper_enter_mmx(cpu_env
);
3581 rm
= (modrm
& 7) | REX_B(s
);
3582 gen_op_movq(offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
),
3583 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3585 case 0xd7: /* pmovmskb */
3590 rm
= (modrm
& 7) | REX_B(s
);
3591 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[rm
]));
3592 gen_helper_pmovmskb_xmm(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3595 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3596 gen_helper_pmovmskb_mmx(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3598 reg
= ((modrm
>> 3) & 7) | rex_r
;
3599 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3605 if ((b
& 0xf0) == 0xf0) {
3608 modrm
= cpu_ldub_code(env
, s
->pc
++);
3610 reg
= ((modrm
>> 3) & 7) | rex_r
;
3611 mod
= (modrm
>> 6) & 3;
3616 sse_fn_epp
= sse_op_table6
[b
].op
[b1
];
3620 if (!(s
->cpuid_ext_features
& sse_op_table6
[b
].ext_mask
))
3624 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3626 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
3628 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3629 gen_lea_modrm(env
, s
, modrm
);
3631 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3632 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3633 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3634 gen_ldq_env_A0(s
, op2_offset
+
3635 offsetof(ZMMReg
, ZMM_Q(0)));
3637 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3638 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3639 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
3640 s
->mem_index
, MO_LEUL
);
3641 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, op2_offset
+
3642 offsetof(ZMMReg
, ZMM_L(0)));
3644 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3645 tcg_gen_qemu_ld_tl(cpu_tmp0
, cpu_A0
,
3646 s
->mem_index
, MO_LEUW
);
3647 tcg_gen_st16_tl(cpu_tmp0
, cpu_env
, op2_offset
+
3648 offsetof(ZMMReg
, ZMM_W(0)));
3650 case 0x2a: /* movntqda */
3651 gen_ldo_env_A0(s
, op1_offset
);
3654 gen_ldo_env_A0(s
, op2_offset
);
3658 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
3660 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3662 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3663 gen_lea_modrm(env
, s
, modrm
);
3664 gen_ldq_env_A0(s
, op2_offset
);
3667 if (sse_fn_epp
== SSE_SPECIAL
) {
3671 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3672 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3673 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3676 set_cc_op(s
, CC_OP_EFLAGS
);
3683 /* Various integer extensions at 0f 38 f[0-f]. */
3684 b
= modrm
| (b1
<< 8);
3685 modrm
= cpu_ldub_code(env
, s
->pc
++);
3686 reg
= ((modrm
>> 3) & 7) | rex_r
;
3689 case 0x3f0: /* crc32 Gd,Eb */
3690 case 0x3f1: /* crc32 Gd,Ey */
3692 if (!(s
->cpuid_ext_features
& CPUID_EXT_SSE42
)) {
3695 if ((b
& 0xff) == 0xf0) {
3697 } else if (s
->dflag
!= MO_64
) {
3698 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3703 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[reg
]);
3704 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3705 gen_helper_crc32(cpu_T0
, cpu_tmp2_i32
,
3706 cpu_T0
, tcg_const_i32(8 << ot
));
3708 ot
= mo_64_32(s
->dflag
);
3709 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3712 case 0x1f0: /* crc32 or movbe */
3714 /* For these insns, the f3 prefix is supposed to have priority
3715 over the 66 prefix, but that's not what we implement above
3717 if (s
->prefix
& PREFIX_REPNZ
) {
3721 case 0x0f0: /* movbe Gy,My */
3722 case 0x0f1: /* movbe My,Gy */
3723 if (!(s
->cpuid_ext_features
& CPUID_EXT_MOVBE
)) {
3726 if (s
->dflag
!= MO_64
) {
3727 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3732 gen_lea_modrm(env
, s
, modrm
);
3734 tcg_gen_qemu_ld_tl(cpu_T0
, cpu_A0
,
3735 s
->mem_index
, ot
| MO_BE
);
3736 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3738 tcg_gen_qemu_st_tl(cpu_regs
[reg
], cpu_A0
,
3739 s
->mem_index
, ot
| MO_BE
);
3743 case 0x0f2: /* andn Gy, By, Ey */
3744 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3745 || !(s
->prefix
& PREFIX_VEX
)
3749 ot
= mo_64_32(s
->dflag
);
3750 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3751 tcg_gen_andc_tl(cpu_T0
, cpu_regs
[s
->vex_v
], cpu_T0
);
3752 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3753 gen_op_update1_cc();
3754 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3757 case 0x0f7: /* bextr Gy, Ey, By */
3758 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3759 || !(s
->prefix
& PREFIX_VEX
)
3763 ot
= mo_64_32(s
->dflag
);
3767 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3768 /* Extract START, and shift the operand.
3769 Shifts larger than operand size get zeros. */
3770 tcg_gen_ext8u_tl(cpu_A0
, cpu_regs
[s
->vex_v
]);
3771 tcg_gen_shr_tl(cpu_T0
, cpu_T0
, cpu_A0
);
3773 bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3774 zero
= tcg_const_tl(0);
3775 tcg_gen_movcond_tl(TCG_COND_LEU
, cpu_T0
, cpu_A0
, bound
,
3777 tcg_temp_free(zero
);
3779 /* Extract the LEN into a mask. Lengths larger than
3780 operand size get all ones. */
3781 tcg_gen_extract_tl(cpu_A0
, cpu_regs
[s
->vex_v
], 8, 8);
3782 tcg_gen_movcond_tl(TCG_COND_LEU
, cpu_A0
, cpu_A0
, bound
,
3784 tcg_temp_free(bound
);
3785 tcg_gen_movi_tl(cpu_T1
, 1);
3786 tcg_gen_shl_tl(cpu_T1
, cpu_T1
, cpu_A0
);
3787 tcg_gen_subi_tl(cpu_T1
, cpu_T1
, 1);
3788 tcg_gen_and_tl(cpu_T0
, cpu_T0
, cpu_T1
);
3790 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3791 gen_op_update1_cc();
3792 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3796 case 0x0f5: /* bzhi Gy, Ey, By */
3797 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3798 || !(s
->prefix
& PREFIX_VEX
)
3802 ot
= mo_64_32(s
->dflag
);
3803 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3804 tcg_gen_ext8u_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3806 TCGv bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3807 /* Note that since we're using BMILG (in order to get O
3808 cleared) we need to store the inverse into C. */
3809 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_cc_src
,
3811 tcg_gen_movcond_tl(TCG_COND_GT
, cpu_T1
, cpu_T1
,
3812 bound
, bound
, cpu_T1
);
3813 tcg_temp_free(bound
);
3815 tcg_gen_movi_tl(cpu_A0
, -1);
3816 tcg_gen_shl_tl(cpu_A0
, cpu_A0
, cpu_T1
);
3817 tcg_gen_andc_tl(cpu_T0
, cpu_T0
, cpu_A0
);
3818 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3819 gen_op_update1_cc();
3820 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
3823 case 0x3f6: /* mulx By, Gy, rdx, Ey */
3824 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3825 || !(s
->prefix
& PREFIX_VEX
)
3829 ot
= mo_64_32(s
->dflag
);
3830 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3833 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
3834 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EDX
]);
3835 tcg_gen_mulu2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
3836 cpu_tmp2_i32
, cpu_tmp3_i32
);
3837 tcg_gen_extu_i32_tl(cpu_regs
[s
->vex_v
], cpu_tmp2_i32
);
3838 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp3_i32
);
3840 #ifdef TARGET_X86_64
3842 tcg_gen_mulu2_i64(cpu_T0
, cpu_T1
,
3843 cpu_T0
, cpu_regs
[R_EDX
]);
3844 tcg_gen_mov_i64(cpu_regs
[s
->vex_v
], cpu_T0
);
3845 tcg_gen_mov_i64(cpu_regs
[reg
], cpu_T1
);
3851 case 0x3f5: /* pdep Gy, By, Ey */
3852 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3853 || !(s
->prefix
& PREFIX_VEX
)
3857 ot
= mo_64_32(s
->dflag
);
3858 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3859 /* Note that by zero-extending the mask operand, we
3860 automatically handle zero-extending the result. */
3862 tcg_gen_mov_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3864 tcg_gen_ext32u_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3866 gen_helper_pdep(cpu_regs
[reg
], cpu_T0
, cpu_T1
);
3869 case 0x2f5: /* pext Gy, By, Ey */
3870 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3871 || !(s
->prefix
& PREFIX_VEX
)
3875 ot
= mo_64_32(s
->dflag
);
3876 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3877 /* Note that by zero-extending the mask operand, we
3878 automatically handle zero-extending the result. */
3880 tcg_gen_mov_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3882 tcg_gen_ext32u_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3884 gen_helper_pext(cpu_regs
[reg
], cpu_T0
, cpu_T1
);
3887 case 0x1f6: /* adcx Gy, Ey */
3888 case 0x2f6: /* adox Gy, Ey */
3889 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_ADX
)) {
3892 TCGv carry_in
, carry_out
, zero
;
3895 ot
= mo_64_32(s
->dflag
);
3896 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3898 /* Re-use the carry-out from a previous round. */
3899 TCGV_UNUSED(carry_in
);
3900 carry_out
= (b
== 0x1f6 ? cpu_cc_dst
: cpu_cc_src2
);
3904 carry_in
= cpu_cc_dst
;
3905 end_op
= CC_OP_ADCX
;
3907 end_op
= CC_OP_ADCOX
;
3912 end_op
= CC_OP_ADCOX
;
3914 carry_in
= cpu_cc_src2
;
3915 end_op
= CC_OP_ADOX
;
3919 end_op
= CC_OP_ADCOX
;
3920 carry_in
= carry_out
;
3923 end_op
= (b
== 0x1f6 ? CC_OP_ADCX
: CC_OP_ADOX
);
3926 /* If we can't reuse carry-out, get it out of EFLAGS. */
3927 if (TCGV_IS_UNUSED(carry_in
)) {
3928 if (s
->cc_op
!= CC_OP_ADCX
&& s
->cc_op
!= CC_OP_ADOX
) {
3929 gen_compute_eflags(s
);
3931 carry_in
= cpu_tmp0
;
3932 tcg_gen_extract_tl(carry_in
, cpu_cc_src
,
3933 ctz32(b
== 0x1f6 ? CC_C
: CC_O
), 1);
3937 #ifdef TARGET_X86_64
3939 /* If we know TL is 64-bit, and we want a 32-bit
3940 result, just do everything in 64-bit arithmetic. */
3941 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_regs
[reg
]);
3942 tcg_gen_ext32u_i64(cpu_T0
, cpu_T0
);
3943 tcg_gen_add_i64(cpu_T0
, cpu_T0
, cpu_regs
[reg
]);
3944 tcg_gen_add_i64(cpu_T0
, cpu_T0
, carry_in
);
3945 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_T0
);
3946 tcg_gen_shri_i64(carry_out
, cpu_T0
, 32);
3950 /* Otherwise compute the carry-out in two steps. */
3951 zero
= tcg_const_tl(0);
3952 tcg_gen_add2_tl(cpu_T0
, carry_out
,
3955 tcg_gen_add2_tl(cpu_regs
[reg
], carry_out
,
3956 cpu_regs
[reg
], carry_out
,
3958 tcg_temp_free(zero
);
3961 set_cc_op(s
, end_op
);
3965 case 0x1f7: /* shlx Gy, Ey, By */
3966 case 0x2f7: /* sarx Gy, Ey, By */
3967 case 0x3f7: /* shrx Gy, Ey, By */
3968 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3969 || !(s
->prefix
& PREFIX_VEX
)
3973 ot
= mo_64_32(s
->dflag
);
3974 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3976 tcg_gen_andi_tl(cpu_T1
, cpu_regs
[s
->vex_v
], 63);
3978 tcg_gen_andi_tl(cpu_T1
, cpu_regs
[s
->vex_v
], 31);
3981 tcg_gen_shl_tl(cpu_T0
, cpu_T0
, cpu_T1
);
3982 } else if (b
== 0x2f7) {
3984 tcg_gen_ext32s_tl(cpu_T0
, cpu_T0
);
3986 tcg_gen_sar_tl(cpu_T0
, cpu_T0
, cpu_T1
);
3989 tcg_gen_ext32u_tl(cpu_T0
, cpu_T0
);
3991 tcg_gen_shr_tl(cpu_T0
, cpu_T0
, cpu_T1
);
3993 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3999 case 0x3f3: /* Group 17 */
4000 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
4001 || !(s
->prefix
& PREFIX_VEX
)
4005 ot
= mo_64_32(s
->dflag
);
4006 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4009 case 1: /* blsr By,Ey */
4010 tcg_gen_neg_tl(cpu_T1
, cpu_T0
);
4011 tcg_gen_and_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4012 gen_op_mov_reg_v(ot
, s
->vex_v
, cpu_T0
);
4013 gen_op_update2_cc();
4014 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4017 case 2: /* blsmsk By,Ey */
4018 tcg_gen_mov_tl(cpu_cc_src
, cpu_T0
);
4019 tcg_gen_subi_tl(cpu_T0
, cpu_T0
, 1);
4020 tcg_gen_xor_tl(cpu_T0
, cpu_T0
, cpu_cc_src
);
4021 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
4022 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4025 case 3: /* blsi By, Ey */
4026 tcg_gen_mov_tl(cpu_cc_src
, cpu_T0
);
4027 tcg_gen_subi_tl(cpu_T0
, cpu_T0
, 1);
4028 tcg_gen_and_tl(cpu_T0
, cpu_T0
, cpu_cc_src
);
4029 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
4030 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4046 modrm
= cpu_ldub_code(env
, s
->pc
++);
4048 reg
= ((modrm
>> 3) & 7) | rex_r
;
4049 mod
= (modrm
>> 6) & 3;
4054 sse_fn_eppi
= sse_op_table7
[b
].op
[b1
];
4058 if (!(s
->cpuid_ext_features
& sse_op_table7
[b
].ext_mask
))
4061 if (sse_fn_eppi
== SSE_SPECIAL
) {
4062 ot
= mo_64_32(s
->dflag
);
4063 rm
= (modrm
& 7) | REX_B(s
);
4065 gen_lea_modrm(env
, s
, modrm
);
4066 reg
= ((modrm
>> 3) & 7) | rex_r
;
4067 val
= cpu_ldub_code(env
, s
->pc
++);
4069 case 0x14: /* pextrb */
4070 tcg_gen_ld8u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,
4071 xmm_regs
[reg
].ZMM_B(val
& 15)));
4073 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
4075 tcg_gen_qemu_st_tl(cpu_T0
, cpu_A0
,
4076 s
->mem_index
, MO_UB
);
4079 case 0x15: /* pextrw */
4080 tcg_gen_ld16u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,
4081 xmm_regs
[reg
].ZMM_W(val
& 7)));
4083 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
4085 tcg_gen_qemu_st_tl(cpu_T0
, cpu_A0
,
4086 s
->mem_index
, MO_LEUW
);
4090 if (ot
== MO_32
) { /* pextrd */
4091 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4092 offsetof(CPUX86State
,
4093 xmm_regs
[reg
].ZMM_L(val
& 3)));
4095 tcg_gen_extu_i32_tl(cpu_regs
[rm
], cpu_tmp2_i32
);
4097 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
4098 s
->mem_index
, MO_LEUL
);
4100 } else { /* pextrq */
4101 #ifdef TARGET_X86_64
4102 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
4103 offsetof(CPUX86State
,
4104 xmm_regs
[reg
].ZMM_Q(val
& 1)));
4106 tcg_gen_mov_i64(cpu_regs
[rm
], cpu_tmp1_i64
);
4108 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
4109 s
->mem_index
, MO_LEQ
);
4116 case 0x17: /* extractps */
4117 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,
4118 xmm_regs
[reg
].ZMM_L(val
& 3)));
4120 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
4122 tcg_gen_qemu_st_tl(cpu_T0
, cpu_A0
,
4123 s
->mem_index
, MO_LEUL
);
4126 case 0x20: /* pinsrb */
4128 gen_op_mov_v_reg(MO_32
, cpu_T0
, rm
);
4130 tcg_gen_qemu_ld_tl(cpu_T0
, cpu_A0
,
4131 s
->mem_index
, MO_UB
);
4133 tcg_gen_st8_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,
4134 xmm_regs
[reg
].ZMM_B(val
& 15)));
4136 case 0x21: /* insertps */
4138 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4139 offsetof(CPUX86State
,xmm_regs
[rm
]
4140 .ZMM_L((val
>> 6) & 3)));
4142 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
4143 s
->mem_index
, MO_LEUL
);
4145 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4146 offsetof(CPUX86State
,xmm_regs
[reg
]
4147 .ZMM_L((val
>> 4) & 3)));
4149 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4150 cpu_env
, offsetof(CPUX86State
,
4151 xmm_regs
[reg
].ZMM_L(0)));
4153 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4154 cpu_env
, offsetof(CPUX86State
,
4155 xmm_regs
[reg
].ZMM_L(1)));
4157 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4158 cpu_env
, offsetof(CPUX86State
,
4159 xmm_regs
[reg
].ZMM_L(2)));
4161 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4162 cpu_env
, offsetof(CPUX86State
,
4163 xmm_regs
[reg
].ZMM_L(3)));
4166 if (ot
== MO_32
) { /* pinsrd */
4168 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[rm
]);
4170 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
4171 s
->mem_index
, MO_LEUL
);
4173 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4174 offsetof(CPUX86State
,
4175 xmm_regs
[reg
].ZMM_L(val
& 3)));
4176 } else { /* pinsrq */
4177 #ifdef TARGET_X86_64
4179 gen_op_mov_v_reg(ot
, cpu_tmp1_i64
, rm
);
4181 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
4182 s
->mem_index
, MO_LEQ
);
4184 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
4185 offsetof(CPUX86State
,
4186 xmm_regs
[reg
].ZMM_Q(val
& 1)));
4197 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4199 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
4201 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4202 gen_lea_modrm(env
, s
, modrm
);
4203 gen_ldo_env_A0(s
, op2_offset
);
4206 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4208 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4210 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4211 gen_lea_modrm(env
, s
, modrm
);
4212 gen_ldq_env_A0(s
, op2_offset
);
4215 val
= cpu_ldub_code(env
, s
->pc
++);
4217 if ((b
& 0xfc) == 0x60) { /* pcmpXstrX */
4218 set_cc_op(s
, CC_OP_EFLAGS
);
4220 if (s
->dflag
== MO_64
) {
4221 /* The helper must use entire 64-bit gp registers */
4226 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4227 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4228 sse_fn_eppi(cpu_env
, cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4232 /* Various integer extensions at 0f 3a f[0-f]. */
4233 b
= modrm
| (b1
<< 8);
4234 modrm
= cpu_ldub_code(env
, s
->pc
++);
4235 reg
= ((modrm
>> 3) & 7) | rex_r
;
4238 case 0x3f0: /* rorx Gy,Ey, Ib */
4239 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4240 || !(s
->prefix
& PREFIX_VEX
)
4244 ot
= mo_64_32(s
->dflag
);
4245 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4246 b
= cpu_ldub_code(env
, s
->pc
++);
4248 tcg_gen_rotri_tl(cpu_T0
, cpu_T0
, b
& 63);
4250 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
4251 tcg_gen_rotri_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, b
& 31);
4252 tcg_gen_extu_i32_tl(cpu_T0
, cpu_tmp2_i32
);
4254 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
4264 gen_unknown_opcode(env
, s
);
4268 /* generic MMX or SSE operation */
4270 case 0x70: /* pshufx insn */
4271 case 0xc6: /* pshufx insn */
4272 case 0xc2: /* compare insns */
4279 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4283 gen_lea_modrm(env
, s
, modrm
);
4284 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4290 /* Most sse scalar operations. */
4293 } else if (b1
== 3) {
4298 case 0x2e: /* ucomis[sd] */
4299 case 0x2f: /* comis[sd] */
4311 gen_op_ld_v(s
, MO_32
, cpu_T0
, cpu_A0
);
4312 tcg_gen_st32_tl(cpu_T0
, cpu_env
,
4313 offsetof(CPUX86State
,xmm_t0
.ZMM_L(0)));
4317 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.ZMM_D(0)));
4320 /* 128 bit access */
4321 gen_ldo_env_A0(s
, op2_offset
);
4325 rm
= (modrm
& 7) | REX_B(s
);
4326 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
4329 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4331 gen_lea_modrm(env
, s
, modrm
);
4332 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4333 gen_ldq_env_A0(s
, op2_offset
);
4336 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4340 case 0x0f: /* 3DNow! data insns */
4341 val
= cpu_ldub_code(env
, s
->pc
++);
4342 sse_fn_epp
= sse_op_table5
[val
];
4346 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
)) {
4349 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4350 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4351 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4353 case 0x70: /* pshufx insn */
4354 case 0xc6: /* pshufx insn */
4355 val
= cpu_ldub_code(env
, s
->pc
++);
4356 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4357 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4358 /* XXX: introduce a new table? */
4359 sse_fn_ppi
= (SSEFunc_0_ppi
)sse_fn_epp
;
4360 sse_fn_ppi(cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4364 val
= cpu_ldub_code(env
, s
->pc
++);
4367 sse_fn_epp
= sse_op_table4
[val
][b1
];
4369 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4370 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4371 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4374 /* maskmov : we must prepare A0 */
4377 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EDI
]);
4378 gen_extu(s
->aflag
, cpu_A0
);
4379 gen_add_A0_ds_seg(s
);
4381 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4382 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4383 /* XXX: introduce a new table? */
4384 sse_fn_eppt
= (SSEFunc_0_eppt
)sse_fn_epp
;
4385 sse_fn_eppt(cpu_env
, cpu_ptr0
, cpu_ptr1
, cpu_A0
);
4388 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4389 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4390 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4393 if (b
== 0x2e || b
== 0x2f) {
4394 set_cc_op(s
, CC_OP_EFLAGS
);
4399 /* convert one instruction. s->is_jmp is set if the translation must
4400 be stopped. Return the next pc value */
4401 static target_ulong
disas_insn(CPUX86State
*env
, DisasContext
*s
,
4402 target_ulong pc_start
)
4406 TCGMemOp ot
, aflag
, dflag
;
4407 int modrm
, reg
, rm
, mod
, op
, opreg
, val
;
4408 target_ulong next_eip
, tval
;
4411 s
->pc_start
= s
->pc
= pc_start
;
4416 #ifdef TARGET_X86_64
4421 s
->rip_offset
= 0; /* for relative ip address */
4425 b
= cpu_ldub_code(env
, s
->pc
);
4427 /* Collect prefixes. */
4430 prefixes
|= PREFIX_REPZ
;
4433 prefixes
|= PREFIX_REPNZ
;
4436 prefixes
|= PREFIX_LOCK
;
4457 prefixes
|= PREFIX_DATA
;
4460 prefixes
|= PREFIX_ADR
;
4462 #ifdef TARGET_X86_64
4466 rex_w
= (b
>> 3) & 1;
4467 rex_r
= (b
& 0x4) << 1;
4468 s
->rex_x
= (b
& 0x2) << 2;
4469 REX_B(s
) = (b
& 0x1) << 3;
4470 x86_64_hregs
= 1; /* select uniform byte register addressing */
4475 case 0xc5: /* 2-byte VEX */
4476 case 0xc4: /* 3-byte VEX */
4477 /* VEX prefixes cannot be used except in 32-bit mode.
4478 Otherwise the instruction is LES or LDS. */
4479 if (s
->code32
&& !s
->vm86
) {
4480 static const int pp_prefix
[4] = {
4481 0, PREFIX_DATA
, PREFIX_REPZ
, PREFIX_REPNZ
4483 int vex3
, vex2
= cpu_ldub_code(env
, s
->pc
);
4485 if (!CODE64(s
) && (vex2
& 0xc0) != 0xc0) {
4486 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4487 otherwise the instruction is LES or LDS. */
4492 /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
4493 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
4494 | PREFIX_LOCK
| PREFIX_DATA
)) {
4497 #ifdef TARGET_X86_64
4502 rex_r
= (~vex2
>> 4) & 8;
4505 b
= cpu_ldub_code(env
, s
->pc
++);
4507 #ifdef TARGET_X86_64
4508 s
->rex_x
= (~vex2
>> 3) & 8;
4509 s
->rex_b
= (~vex2
>> 2) & 8;
4511 vex3
= cpu_ldub_code(env
, s
->pc
++);
4512 rex_w
= (vex3
>> 7) & 1;
4513 switch (vex2
& 0x1f) {
4514 case 0x01: /* Implied 0f leading opcode bytes. */
4515 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4517 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4520 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4523 default: /* Reserved for future use. */
4527 s
->vex_v
= (~vex3
>> 3) & 0xf;
4528 s
->vex_l
= (vex3
>> 2) & 1;
4529 prefixes
|= pp_prefix
[vex3
& 3] | PREFIX_VEX
;
4534 /* Post-process prefixes. */
4536 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit
4537 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4538 over 0x66 if both are present. */
4539 dflag
= (rex_w
> 0 ? MO_64
: prefixes
& PREFIX_DATA
? MO_16
: MO_32
);
4540 /* In 64-bit mode, 0x67 selects 32-bit addressing. */
4541 aflag
= (prefixes
& PREFIX_ADR
? MO_32
: MO_64
);
4543 /* In 16/32-bit mode, 0x66 selects the opposite data size. */
4544 if (s
->code32
^ ((prefixes
& PREFIX_DATA
) != 0)) {
4549 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */
4550 if (s
->code32
^ ((prefixes
& PREFIX_ADR
) != 0)) {
4557 s
->prefix
= prefixes
;
4561 /* now check op code */
4565 /**************************/
4566 /* extended op code */
4567 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4570 /**************************/
4585 ot
= mo_b_d(b
, dflag
);
4588 case 0: /* OP Ev, Gv */
4589 modrm
= cpu_ldub_code(env
, s
->pc
++);
4590 reg
= ((modrm
>> 3) & 7) | rex_r
;
4591 mod
= (modrm
>> 6) & 3;
4592 rm
= (modrm
& 7) | REX_B(s
);
4594 gen_lea_modrm(env
, s
, modrm
);
4596 } else if (op
== OP_XORL
&& rm
== reg
) {
4598 /* xor reg, reg optimisation */
4599 set_cc_op(s
, CC_OP_CLR
);
4600 tcg_gen_movi_tl(cpu_T0
, 0);
4601 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
4606 gen_op_mov_v_reg(ot
, cpu_T1
, reg
);
4607 gen_op(s
, op
, ot
, opreg
);
4609 case 1: /* OP Gv, Ev */
4610 modrm
= cpu_ldub_code(env
, s
->pc
++);
4611 mod
= (modrm
>> 6) & 3;
4612 reg
= ((modrm
>> 3) & 7) | rex_r
;
4613 rm
= (modrm
& 7) | REX_B(s
);
4615 gen_lea_modrm(env
, s
, modrm
);
4616 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
4617 } else if (op
== OP_XORL
&& rm
== reg
) {
4620 gen_op_mov_v_reg(ot
, cpu_T1
, rm
);
4622 gen_op(s
, op
, ot
, reg
);
4624 case 2: /* OP A, Iv */
4625 val
= insn_get(env
, s
, ot
);
4626 tcg_gen_movi_tl(cpu_T1
, val
);
4627 gen_op(s
, op
, ot
, OR_EAX
);
4636 case 0x80: /* GRP1 */
4642 ot
= mo_b_d(b
, dflag
);
4644 modrm
= cpu_ldub_code(env
, s
->pc
++);
4645 mod
= (modrm
>> 6) & 3;
4646 rm
= (modrm
& 7) | REX_B(s
);
4647 op
= (modrm
>> 3) & 7;
4653 s
->rip_offset
= insn_const_size(ot
);
4654 gen_lea_modrm(env
, s
, modrm
);
4665 val
= insn_get(env
, s
, ot
);
4668 val
= (int8_t)insn_get(env
, s
, MO_8
);
4671 tcg_gen_movi_tl(cpu_T1
, val
);
4672 gen_op(s
, op
, ot
, opreg
);
4676 /**************************/
4677 /* inc, dec, and other misc arith */
4678 case 0x40 ... 0x47: /* inc Gv */
4680 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), 1);
4682 case 0x48 ... 0x4f: /* dec Gv */
4684 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), -1);
4686 case 0xf6: /* GRP3 */
4688 ot
= mo_b_d(b
, dflag
);
4690 modrm
= cpu_ldub_code(env
, s
->pc
++);
4691 mod
= (modrm
>> 6) & 3;
4692 rm
= (modrm
& 7) | REX_B(s
);
4693 op
= (modrm
>> 3) & 7;
4696 s
->rip_offset
= insn_const_size(ot
);
4698 gen_lea_modrm(env
, s
, modrm
);
4699 /* For those below that handle locked memory, don't load here. */
4700 if (!(s
->prefix
& PREFIX_LOCK
)
4702 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
4705 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
4710 val
= insn_get(env
, s
, ot
);
4711 tcg_gen_movi_tl(cpu_T1
, val
);
4712 gen_op_testl_T0_T1_cc();
4713 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4716 if (s
->prefix
& PREFIX_LOCK
) {
4720 tcg_gen_movi_tl(cpu_T0
, ~0);
4721 tcg_gen_atomic_xor_fetch_tl(cpu_T0
, cpu_A0
, cpu_T0
,
4722 s
->mem_index
, ot
| MO_LE
);
4724 tcg_gen_not_tl(cpu_T0
, cpu_T0
);
4726 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
4728 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
4733 if (s
->prefix
& PREFIX_LOCK
) {
4735 TCGv a0
, t0
, t1
, t2
;
4740 a0
= tcg_temp_local_new();
4741 t0
= tcg_temp_local_new();
4742 label1
= gen_new_label();
4744 tcg_gen_mov_tl(a0
, cpu_A0
);
4745 tcg_gen_mov_tl(t0
, cpu_T0
);
4747 gen_set_label(label1
);
4748 t1
= tcg_temp_new();
4749 t2
= tcg_temp_new();
4750 tcg_gen_mov_tl(t2
, t0
);
4751 tcg_gen_neg_tl(t1
, t0
);
4752 tcg_gen_atomic_cmpxchg_tl(t0
, a0
, t0
, t1
,
4753 s
->mem_index
, ot
| MO_LE
);
4755 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t2
, label1
);
4759 tcg_gen_mov_tl(cpu_T0
, t0
);
4762 tcg_gen_neg_tl(cpu_T0
, cpu_T0
);
4764 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
4766 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
4769 gen_op_update_neg_cc();
4770 set_cc_op(s
, CC_OP_SUBB
+ ot
);
4775 gen_op_mov_v_reg(MO_8
, cpu_T1
, R_EAX
);
4776 tcg_gen_ext8u_tl(cpu_T0
, cpu_T0
);
4777 tcg_gen_ext8u_tl(cpu_T1
, cpu_T1
);
4778 /* XXX: use 32 bit mul which could be faster */
4779 tcg_gen_mul_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4780 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
4781 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
4782 tcg_gen_andi_tl(cpu_cc_src
, cpu_T0
, 0xff00);
4783 set_cc_op(s
, CC_OP_MULB
);
4786 gen_op_mov_v_reg(MO_16
, cpu_T1
, R_EAX
);
4787 tcg_gen_ext16u_tl(cpu_T0
, cpu_T0
);
4788 tcg_gen_ext16u_tl(cpu_T1
, cpu_T1
);
4789 /* XXX: use 32 bit mul which could be faster */
4790 tcg_gen_mul_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4791 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
4792 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
4793 tcg_gen_shri_tl(cpu_T0
, cpu_T0
, 16);
4794 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T0
);
4795 tcg_gen_mov_tl(cpu_cc_src
, cpu_T0
);
4796 set_cc_op(s
, CC_OP_MULW
);
4800 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
4801 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
4802 tcg_gen_mulu2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4803 cpu_tmp2_i32
, cpu_tmp3_i32
);
4804 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
4805 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
4806 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4807 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4808 set_cc_op(s
, CC_OP_MULL
);
4810 #ifdef TARGET_X86_64
4812 tcg_gen_mulu2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4813 cpu_T0
, cpu_regs
[R_EAX
]);
4814 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4815 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4816 set_cc_op(s
, CC_OP_MULQ
);
4824 gen_op_mov_v_reg(MO_8
, cpu_T1
, R_EAX
);
4825 tcg_gen_ext8s_tl(cpu_T0
, cpu_T0
);
4826 tcg_gen_ext8s_tl(cpu_T1
, cpu_T1
);
4827 /* XXX: use 32 bit mul which could be faster */
4828 tcg_gen_mul_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4829 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
4830 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
4831 tcg_gen_ext8s_tl(cpu_tmp0
, cpu_T0
);
4832 tcg_gen_sub_tl(cpu_cc_src
, cpu_T0
, cpu_tmp0
);
4833 set_cc_op(s
, CC_OP_MULB
);
4836 gen_op_mov_v_reg(MO_16
, cpu_T1
, R_EAX
);
4837 tcg_gen_ext16s_tl(cpu_T0
, cpu_T0
);
4838 tcg_gen_ext16s_tl(cpu_T1
, cpu_T1
);
4839 /* XXX: use 32 bit mul which could be faster */
4840 tcg_gen_mul_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4841 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
4842 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
4843 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T0
);
4844 tcg_gen_sub_tl(cpu_cc_src
, cpu_T0
, cpu_tmp0
);
4845 tcg_gen_shri_tl(cpu_T0
, cpu_T0
, 16);
4846 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T0
);
4847 set_cc_op(s
, CC_OP_MULW
);
4851 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
4852 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
4853 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4854 cpu_tmp2_i32
, cpu_tmp3_i32
);
4855 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
4856 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
4857 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
4858 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4859 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
4860 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
4861 set_cc_op(s
, CC_OP_MULL
);
4863 #ifdef TARGET_X86_64
4865 tcg_gen_muls2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4866 cpu_T0
, cpu_regs
[R_EAX
]);
4867 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4868 tcg_gen_sari_tl(cpu_cc_src
, cpu_regs
[R_EAX
], 63);
4869 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_regs
[R_EDX
]);
4870 set_cc_op(s
, CC_OP_MULQ
);
4878 gen_helper_divb_AL(cpu_env
, cpu_T0
);
4881 gen_helper_divw_AX(cpu_env
, cpu_T0
);
4885 gen_helper_divl_EAX(cpu_env
, cpu_T0
);
4887 #ifdef TARGET_X86_64
4889 gen_helper_divq_EAX(cpu_env
, cpu_T0
);
4897 gen_helper_idivb_AL(cpu_env
, cpu_T0
);
4900 gen_helper_idivw_AX(cpu_env
, cpu_T0
);
4904 gen_helper_idivl_EAX(cpu_env
, cpu_T0
);
4906 #ifdef TARGET_X86_64
4908 gen_helper_idivq_EAX(cpu_env
, cpu_T0
);
4918 case 0xfe: /* GRP4 */
4919 case 0xff: /* GRP5 */
4920 ot
= mo_b_d(b
, dflag
);
4922 modrm
= cpu_ldub_code(env
, s
->pc
++);
4923 mod
= (modrm
>> 6) & 3;
4924 rm
= (modrm
& 7) | REX_B(s
);
4925 op
= (modrm
>> 3) & 7;
4926 if (op
>= 2 && b
== 0xfe) {
4930 if (op
== 2 || op
== 4) {
4931 /* operand size for jumps is 64 bit */
4933 } else if (op
== 3 || op
== 5) {
4934 ot
= dflag
!= MO_16
? MO_32
+ (rex_w
== 1) : MO_16
;
4935 } else if (op
== 6) {
4936 /* default push size is 64 bit */
4937 ot
= mo_pushpop(s
, dflag
);
4941 gen_lea_modrm(env
, s
, modrm
);
4942 if (op
>= 2 && op
!= 3 && op
!= 5)
4943 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
4945 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
4949 case 0: /* inc Ev */
4954 gen_inc(s
, ot
, opreg
, 1);
4956 case 1: /* dec Ev */
4961 gen_inc(s
, ot
, opreg
, -1);
4963 case 2: /* call Ev */
4964 /* XXX: optimize if memory (no 'and' is necessary) */
4965 if (dflag
== MO_16
) {
4966 tcg_gen_ext16u_tl(cpu_T0
, cpu_T0
);
4968 next_eip
= s
->pc
- s
->cs_base
;
4969 tcg_gen_movi_tl(cpu_T1
, next_eip
);
4970 gen_push_v(s
, cpu_T1
);
4971 gen_op_jmp_v(cpu_T0
);
4975 case 3: /* lcall Ev */
4976 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
4977 gen_add_A0_im(s
, 1 << ot
);
4978 gen_op_ld_v(s
, MO_16
, cpu_T0
, cpu_A0
);
4980 if (s
->pe
&& !s
->vm86
) {
4981 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
4982 gen_helper_lcall_protected(cpu_env
, cpu_tmp2_i32
, cpu_T1
,
4983 tcg_const_i32(dflag
- 1),
4984 tcg_const_tl(s
->pc
- s
->cs_base
));
4986 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
4987 gen_helper_lcall_real(cpu_env
, cpu_tmp2_i32
, cpu_T1
,
4988 tcg_const_i32(dflag
- 1),
4989 tcg_const_i32(s
->pc
- s
->cs_base
));
4993 case 4: /* jmp Ev */
4994 if (dflag
== MO_16
) {
4995 tcg_gen_ext16u_tl(cpu_T0
, cpu_T0
);
4997 gen_op_jmp_v(cpu_T0
);
5001 case 5: /* ljmp Ev */
5002 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
5003 gen_add_A0_im(s
, 1 << ot
);
5004 gen_op_ld_v(s
, MO_16
, cpu_T0
, cpu_A0
);
5006 if (s
->pe
&& !s
->vm86
) {
5007 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
5008 gen_helper_ljmp_protected(cpu_env
, cpu_tmp2_i32
, cpu_T1
,
5009 tcg_const_tl(s
->pc
- s
->cs_base
));
5011 gen_op_movl_seg_T0_vm(R_CS
);
5012 gen_op_jmp_v(cpu_T1
);
5016 case 6: /* push Ev */
5017 gen_push_v(s
, cpu_T0
);
5024 case 0x84: /* test Ev, Gv */
5026 ot
= mo_b_d(b
, dflag
);
5028 modrm
= cpu_ldub_code(env
, s
->pc
++);
5029 reg
= ((modrm
>> 3) & 7) | rex_r
;
5031 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5032 gen_op_mov_v_reg(ot
, cpu_T1
, reg
);
5033 gen_op_testl_T0_T1_cc();
5034 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5037 case 0xa8: /* test eAX, Iv */
5039 ot
= mo_b_d(b
, dflag
);
5040 val
= insn_get(env
, s
, ot
);
5042 gen_op_mov_v_reg(ot
, cpu_T0
, OR_EAX
);
5043 tcg_gen_movi_tl(cpu_T1
, val
);
5044 gen_op_testl_T0_T1_cc();
5045 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5048 case 0x98: /* CWDE/CBW */
5050 #ifdef TARGET_X86_64
5052 gen_op_mov_v_reg(MO_32
, cpu_T0
, R_EAX
);
5053 tcg_gen_ext32s_tl(cpu_T0
, cpu_T0
);
5054 gen_op_mov_reg_v(MO_64
, R_EAX
, cpu_T0
);
5058 gen_op_mov_v_reg(MO_16
, cpu_T0
, R_EAX
);
5059 tcg_gen_ext16s_tl(cpu_T0
, cpu_T0
);
5060 gen_op_mov_reg_v(MO_32
, R_EAX
, cpu_T0
);
5063 gen_op_mov_v_reg(MO_8
, cpu_T0
, R_EAX
);
5064 tcg_gen_ext8s_tl(cpu_T0
, cpu_T0
);
5065 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
5071 case 0x99: /* CDQ/CWD */
5073 #ifdef TARGET_X86_64
5075 gen_op_mov_v_reg(MO_64
, cpu_T0
, R_EAX
);
5076 tcg_gen_sari_tl(cpu_T0
, cpu_T0
, 63);
5077 gen_op_mov_reg_v(MO_64
, R_EDX
, cpu_T0
);
5081 gen_op_mov_v_reg(MO_32
, cpu_T0
, R_EAX
);
5082 tcg_gen_ext32s_tl(cpu_T0
, cpu_T0
);
5083 tcg_gen_sari_tl(cpu_T0
, cpu_T0
, 31);
5084 gen_op_mov_reg_v(MO_32
, R_EDX
, cpu_T0
);
5087 gen_op_mov_v_reg(MO_16
, cpu_T0
, R_EAX
);
5088 tcg_gen_ext16s_tl(cpu_T0
, cpu_T0
);
5089 tcg_gen_sari_tl(cpu_T0
, cpu_T0
, 15);
5090 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T0
);
5096 case 0x1af: /* imul Gv, Ev */
5097 case 0x69: /* imul Gv, Ev, I */
5100 modrm
= cpu_ldub_code(env
, s
->pc
++);
5101 reg
= ((modrm
>> 3) & 7) | rex_r
;
5103 s
->rip_offset
= insn_const_size(ot
);
5106 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5108 val
= insn_get(env
, s
, ot
);
5109 tcg_gen_movi_tl(cpu_T1
, val
);
5110 } else if (b
== 0x6b) {
5111 val
= (int8_t)insn_get(env
, s
, MO_8
);
5112 tcg_gen_movi_tl(cpu_T1
, val
);
5114 gen_op_mov_v_reg(ot
, cpu_T1
, reg
);
5117 #ifdef TARGET_X86_64
5119 tcg_gen_muls2_i64(cpu_regs
[reg
], cpu_T1
, cpu_T0
, cpu_T1
);
5120 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5121 tcg_gen_sari_tl(cpu_cc_src
, cpu_cc_dst
, 63);
5122 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_T1
);
5126 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
5127 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T1
);
5128 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
5129 cpu_tmp2_i32
, cpu_tmp3_i32
);
5130 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
5131 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
5132 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5133 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
5134 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
5137 tcg_gen_ext16s_tl(cpu_T0
, cpu_T0
);
5138 tcg_gen_ext16s_tl(cpu_T1
, cpu_T1
);
5139 /* XXX: use 32 bit mul which could be faster */
5140 tcg_gen_mul_tl(cpu_T0
, cpu_T0
, cpu_T1
);
5141 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
5142 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T0
);
5143 tcg_gen_sub_tl(cpu_cc_src
, cpu_T0
, cpu_tmp0
);
5144 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
5147 set_cc_op(s
, CC_OP_MULB
+ ot
);
5150 case 0x1c1: /* xadd Ev, Gv */
5151 ot
= mo_b_d(b
, dflag
);
5152 modrm
= cpu_ldub_code(env
, s
->pc
++);
5153 reg
= ((modrm
>> 3) & 7) | rex_r
;
5154 mod
= (modrm
>> 6) & 3;
5155 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
5157 rm
= (modrm
& 7) | REX_B(s
);
5158 gen_op_mov_v_reg(ot
, cpu_T1
, rm
);
5159 tcg_gen_add_tl(cpu_T0
, cpu_T0
, cpu_T1
);
5160 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
5161 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
5163 gen_lea_modrm(env
, s
, modrm
);
5164 if (s
->prefix
& PREFIX_LOCK
) {
5165 tcg_gen_atomic_fetch_add_tl(cpu_T1
, cpu_A0
, cpu_T0
,
5166 s
->mem_index
, ot
| MO_LE
);
5167 tcg_gen_add_tl(cpu_T0
, cpu_T0
, cpu_T1
);
5169 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
5170 tcg_gen_add_tl(cpu_T0
, cpu_T0
, cpu_T1
);
5171 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
5173 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
5175 gen_op_update2_cc();
5176 set_cc_op(s
, CC_OP_ADDB
+ ot
);
5179 case 0x1b1: /* cmpxchg Ev, Gv */
5181 TCGv oldv
, newv
, cmpv
;
5183 ot
= mo_b_d(b
, dflag
);
5184 modrm
= cpu_ldub_code(env
, s
->pc
++);
5185 reg
= ((modrm
>> 3) & 7) | rex_r
;
5186 mod
= (modrm
>> 6) & 3;
5187 oldv
= tcg_temp_new();
5188 newv
= tcg_temp_new();
5189 cmpv
= tcg_temp_new();
5190 gen_op_mov_v_reg(ot
, newv
, reg
);
5191 tcg_gen_mov_tl(cmpv
, cpu_regs
[R_EAX
]);
5193 if (s
->prefix
& PREFIX_LOCK
) {
5197 gen_lea_modrm(env
, s
, modrm
);
5198 tcg_gen_atomic_cmpxchg_tl(oldv
, cpu_A0
, cmpv
, newv
,
5199 s
->mem_index
, ot
| MO_LE
);
5200 gen_op_mov_reg_v(ot
, R_EAX
, oldv
);
5203 rm
= (modrm
& 7) | REX_B(s
);
5204 gen_op_mov_v_reg(ot
, oldv
, rm
);
5206 gen_lea_modrm(env
, s
, modrm
);
5207 gen_op_ld_v(s
, ot
, oldv
, cpu_A0
);
5208 rm
= 0; /* avoid warning */
5212 /* store value = (old == cmp ? new : old); */
5213 tcg_gen_movcond_tl(TCG_COND_EQ
, newv
, oldv
, cmpv
, newv
, oldv
);
5215 gen_op_mov_reg_v(ot
, R_EAX
, oldv
);
5216 gen_op_mov_reg_v(ot
, rm
, newv
);
5218 /* Perform an unconditional store cycle like physical cpu;
5219 must be before changing accumulator to ensure
5220 idempotency if the store faults and the instruction
5222 gen_op_st_v(s
, ot
, newv
, cpu_A0
);
5223 gen_op_mov_reg_v(ot
, R_EAX
, oldv
);
5226 tcg_gen_mov_tl(cpu_cc_src
, oldv
);
5227 tcg_gen_mov_tl(cpu_cc_srcT
, cmpv
);
5228 tcg_gen_sub_tl(cpu_cc_dst
, cmpv
, oldv
);
5229 set_cc_op(s
, CC_OP_SUBB
+ ot
);
5230 tcg_temp_free(oldv
);
5231 tcg_temp_free(newv
);
5232 tcg_temp_free(cmpv
);
5235 case 0x1c7: /* cmpxchg8b */
5236 modrm
= cpu_ldub_code(env
, s
->pc
++);
5237 mod
= (modrm
>> 6) & 3;
5238 if ((mod
== 3) || ((modrm
& 0x38) != 0x8))
5240 #ifdef TARGET_X86_64
5241 if (dflag
== MO_64
) {
5242 if (!(s
->cpuid_ext_features
& CPUID_EXT_CX16
))
5244 gen_lea_modrm(env
, s
, modrm
);
5245 if ((s
->prefix
& PREFIX_LOCK
) && parallel_cpus
) {
5246 gen_helper_cmpxchg16b(cpu_env
, cpu_A0
);
5248 gen_helper_cmpxchg16b_unlocked(cpu_env
, cpu_A0
);
5253 if (!(s
->cpuid_features
& CPUID_CX8
))
5255 gen_lea_modrm(env
, s
, modrm
);
5256 if ((s
->prefix
& PREFIX_LOCK
) && parallel_cpus
) {
5257 gen_helper_cmpxchg8b(cpu_env
, cpu_A0
);
5259 gen_helper_cmpxchg8b_unlocked(cpu_env
, cpu_A0
);
5262 set_cc_op(s
, CC_OP_EFLAGS
);
5265 /**************************/
5267 case 0x50 ... 0x57: /* push */
5268 gen_op_mov_v_reg(MO_32
, cpu_T0
, (b
& 7) | REX_B(s
));
5269 gen_push_v(s
, cpu_T0
);
5271 case 0x58 ... 0x5f: /* pop */
5273 /* NOTE: order is important for pop %sp */
5274 gen_pop_update(s
, ot
);
5275 gen_op_mov_reg_v(ot
, (b
& 7) | REX_B(s
), cpu_T0
);
5277 case 0x60: /* pusha */
5282 case 0x61: /* popa */
5287 case 0x68: /* push Iv */
5289 ot
= mo_pushpop(s
, dflag
);
5291 val
= insn_get(env
, s
, ot
);
5293 val
= (int8_t)insn_get(env
, s
, MO_8
);
5294 tcg_gen_movi_tl(cpu_T0
, val
);
5295 gen_push_v(s
, cpu_T0
);
5297 case 0x8f: /* pop Ev */
5298 modrm
= cpu_ldub_code(env
, s
->pc
++);
5299 mod
= (modrm
>> 6) & 3;
5302 /* NOTE: order is important for pop %sp */
5303 gen_pop_update(s
, ot
);
5304 rm
= (modrm
& 7) | REX_B(s
);
5305 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
5307 /* NOTE: order is important too for MMU exceptions */
5308 s
->popl_esp_hack
= 1 << ot
;
5309 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5310 s
->popl_esp_hack
= 0;
5311 gen_pop_update(s
, ot
);
5314 case 0xc8: /* enter */
5317 val
= cpu_lduw_code(env
, s
->pc
);
5319 level
= cpu_ldub_code(env
, s
->pc
++);
5320 gen_enter(s
, val
, level
);
5323 case 0xc9: /* leave */
5326 case 0x06: /* push es */
5327 case 0x0e: /* push cs */
5328 case 0x16: /* push ss */
5329 case 0x1e: /* push ds */
5332 gen_op_movl_T0_seg(b
>> 3);
5333 gen_push_v(s
, cpu_T0
);
5335 case 0x1a0: /* push fs */
5336 case 0x1a8: /* push gs */
5337 gen_op_movl_T0_seg((b
>> 3) & 7);
5338 gen_push_v(s
, cpu_T0
);
5340 case 0x07: /* pop es */
5341 case 0x17: /* pop ss */
5342 case 0x1f: /* pop ds */
5347 gen_movl_seg_T0(s
, reg
);
5348 gen_pop_update(s
, ot
);
5349 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5351 gen_jmp_im(s
->pc
- s
->cs_base
);
5354 gen_eob_inhibit_irq(s
, true);
5360 case 0x1a1: /* pop fs */
5361 case 0x1a9: /* pop gs */
5363 gen_movl_seg_T0(s
, (b
>> 3) & 7);
5364 gen_pop_update(s
, ot
);
5366 gen_jmp_im(s
->pc
- s
->cs_base
);
5371 /**************************/
5374 case 0x89: /* mov Gv, Ev */
5375 ot
= mo_b_d(b
, dflag
);
5376 modrm
= cpu_ldub_code(env
, s
->pc
++);
5377 reg
= ((modrm
>> 3) & 7) | rex_r
;
5379 /* generate a generic store */
5380 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
5383 case 0xc7: /* mov Ev, Iv */
5384 ot
= mo_b_d(b
, dflag
);
5385 modrm
= cpu_ldub_code(env
, s
->pc
++);
5386 mod
= (modrm
>> 6) & 3;
5388 s
->rip_offset
= insn_const_size(ot
);
5389 gen_lea_modrm(env
, s
, modrm
);
5391 val
= insn_get(env
, s
, ot
);
5392 tcg_gen_movi_tl(cpu_T0
, val
);
5394 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
5396 gen_op_mov_reg_v(ot
, (modrm
& 7) | REX_B(s
), cpu_T0
);
5400 case 0x8b: /* mov Ev, Gv */
5401 ot
= mo_b_d(b
, dflag
);
5402 modrm
= cpu_ldub_code(env
, s
->pc
++);
5403 reg
= ((modrm
>> 3) & 7) | rex_r
;
5405 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5406 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
5408 case 0x8e: /* mov seg, Gv */
5409 modrm
= cpu_ldub_code(env
, s
->pc
++);
5410 reg
= (modrm
>> 3) & 7;
5411 if (reg
>= 6 || reg
== R_CS
)
5413 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
5414 gen_movl_seg_T0(s
, reg
);
5415 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5417 gen_jmp_im(s
->pc
- s
->cs_base
);
5420 gen_eob_inhibit_irq(s
, true);
5426 case 0x8c: /* mov Gv, seg */
5427 modrm
= cpu_ldub_code(env
, s
->pc
++);
5428 reg
= (modrm
>> 3) & 7;
5429 mod
= (modrm
>> 6) & 3;
5432 gen_op_movl_T0_seg(reg
);
5433 ot
= mod
== 3 ? dflag
: MO_16
;
5434 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5437 case 0x1b6: /* movzbS Gv, Eb */
5438 case 0x1b7: /* movzwS Gv, Eb */
5439 case 0x1be: /* movsbS Gv, Eb */
5440 case 0x1bf: /* movswS Gv, Eb */
5445 /* d_ot is the size of destination */
5447 /* ot is the size of source */
5448 ot
= (b
& 1) + MO_8
;
5449 /* s_ot is the sign+size of source */
5450 s_ot
= b
& 8 ? MO_SIGN
| ot
: ot
;
5452 modrm
= cpu_ldub_code(env
, s
->pc
++);
5453 reg
= ((modrm
>> 3) & 7) | rex_r
;
5454 mod
= (modrm
>> 6) & 3;
5455 rm
= (modrm
& 7) | REX_B(s
);
5458 if (s_ot
== MO_SB
&& byte_reg_is_xH(rm
)) {
5459 tcg_gen_sextract_tl(cpu_T0
, cpu_regs
[rm
- 4], 8, 8);
5461 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
5464 tcg_gen_ext8u_tl(cpu_T0
, cpu_T0
);
5467 tcg_gen_ext8s_tl(cpu_T0
, cpu_T0
);
5470 tcg_gen_ext16u_tl(cpu_T0
, cpu_T0
);
5474 tcg_gen_ext16s_tl(cpu_T0
, cpu_T0
);
5478 gen_op_mov_reg_v(d_ot
, reg
, cpu_T0
);
5480 gen_lea_modrm(env
, s
, modrm
);
5481 gen_op_ld_v(s
, s_ot
, cpu_T0
, cpu_A0
);
5482 gen_op_mov_reg_v(d_ot
, reg
, cpu_T0
);
5487 case 0x8d: /* lea */
5488 modrm
= cpu_ldub_code(env
, s
->pc
++);
5489 mod
= (modrm
>> 6) & 3;
5492 reg
= ((modrm
>> 3) & 7) | rex_r
;
5494 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
5495 TCGv ea
= gen_lea_modrm_1(a
);
5496 gen_lea_v_seg(s
, s
->aflag
, ea
, -1, -1);
5497 gen_op_mov_reg_v(dflag
, reg
, cpu_A0
);
5501 case 0xa0: /* mov EAX, Ov */
5503 case 0xa2: /* mov Ov, EAX */
5506 target_ulong offset_addr
;
5508 ot
= mo_b_d(b
, dflag
);
5510 #ifdef TARGET_X86_64
5512 offset_addr
= cpu_ldq_code(env
, s
->pc
);
5517 offset_addr
= insn_get(env
, s
, s
->aflag
);
5520 tcg_gen_movi_tl(cpu_A0
, offset_addr
);
5521 gen_add_A0_ds_seg(s
);
5523 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
5524 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T0
);
5526 gen_op_mov_v_reg(ot
, cpu_T0
, R_EAX
);
5527 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
5531 case 0xd7: /* xlat */
5532 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EBX
]);
5533 tcg_gen_ext8u_tl(cpu_T0
, cpu_regs
[R_EAX
]);
5534 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_T0
);
5535 gen_extu(s
->aflag
, cpu_A0
);
5536 gen_add_A0_ds_seg(s
);
5537 gen_op_ld_v(s
, MO_8
, cpu_T0
, cpu_A0
);
5538 gen_op_mov_reg_v(MO_8
, R_EAX
, cpu_T0
);
5540 case 0xb0 ... 0xb7: /* mov R, Ib */
5541 val
= insn_get(env
, s
, MO_8
);
5542 tcg_gen_movi_tl(cpu_T0
, val
);
5543 gen_op_mov_reg_v(MO_8
, (b
& 7) | REX_B(s
), cpu_T0
);
5545 case 0xb8 ... 0xbf: /* mov R, Iv */
5546 #ifdef TARGET_X86_64
5547 if (dflag
== MO_64
) {
5550 tmp
= cpu_ldq_code(env
, s
->pc
);
5552 reg
= (b
& 7) | REX_B(s
);
5553 tcg_gen_movi_tl(cpu_T0
, tmp
);
5554 gen_op_mov_reg_v(MO_64
, reg
, cpu_T0
);
5559 val
= insn_get(env
, s
, ot
);
5560 reg
= (b
& 7) | REX_B(s
);
5561 tcg_gen_movi_tl(cpu_T0
, val
);
5562 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
5566 case 0x91 ... 0x97: /* xchg R, EAX */
5569 reg
= (b
& 7) | REX_B(s
);
5573 case 0x87: /* xchg Ev, Gv */
5574 ot
= mo_b_d(b
, dflag
);
5575 modrm
= cpu_ldub_code(env
, s
->pc
++);
5576 reg
= ((modrm
>> 3) & 7) | rex_r
;
5577 mod
= (modrm
>> 6) & 3;
5579 rm
= (modrm
& 7) | REX_B(s
);
5581 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
5582 gen_op_mov_v_reg(ot
, cpu_T1
, rm
);
5583 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
5584 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
5586 gen_lea_modrm(env
, s
, modrm
);
5587 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
5588 /* for xchg, lock is implicit */
5589 tcg_gen_atomic_xchg_tl(cpu_T1
, cpu_A0
, cpu_T0
,
5590 s
->mem_index
, ot
| MO_LE
);
5591 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
5594 case 0xc4: /* les Gv */
5595 /* In CODE64 this is VEX3; see above. */
5598 case 0xc5: /* lds Gv */
5599 /* In CODE64 this is VEX2; see above. */
5602 case 0x1b2: /* lss Gv */
5605 case 0x1b4: /* lfs Gv */
5608 case 0x1b5: /* lgs Gv */
5611 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
5612 modrm
= cpu_ldub_code(env
, s
->pc
++);
5613 reg
= ((modrm
>> 3) & 7) | rex_r
;
5614 mod
= (modrm
>> 6) & 3;
5617 gen_lea_modrm(env
, s
, modrm
);
5618 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
5619 gen_add_A0_im(s
, 1 << ot
);
5620 /* load the segment first to handle exceptions properly */
5621 gen_op_ld_v(s
, MO_16
, cpu_T0
, cpu_A0
);
5622 gen_movl_seg_T0(s
, op
);
5623 /* then put the data */
5624 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
5626 gen_jmp_im(s
->pc
- s
->cs_base
);
5631 /************************/
5639 ot
= mo_b_d(b
, dflag
);
5640 modrm
= cpu_ldub_code(env
, s
->pc
++);
5641 mod
= (modrm
>> 6) & 3;
5642 op
= (modrm
>> 3) & 7;
5648 gen_lea_modrm(env
, s
, modrm
);
5651 opreg
= (modrm
& 7) | REX_B(s
);
5656 gen_shift(s
, op
, ot
, opreg
, OR_ECX
);
5659 shift
= cpu_ldub_code(env
, s
->pc
++);
5661 gen_shifti(s
, op
, ot
, opreg
, shift
);
5676 case 0x1a4: /* shld imm */
5680 case 0x1a5: /* shld cl */
5684 case 0x1ac: /* shrd imm */
5688 case 0x1ad: /* shrd cl */
5693 modrm
= cpu_ldub_code(env
, s
->pc
++);
5694 mod
= (modrm
>> 6) & 3;
5695 rm
= (modrm
& 7) | REX_B(s
);
5696 reg
= ((modrm
>> 3) & 7) | rex_r
;
5698 gen_lea_modrm(env
, s
, modrm
);
5703 gen_op_mov_v_reg(ot
, cpu_T1
, reg
);
5706 TCGv imm
= tcg_const_tl(cpu_ldub_code(env
, s
->pc
++));
5707 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, imm
);
5710 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, cpu_regs
[R_ECX
]);
5714 /************************/
5717 if (s
->flags
& (HF_EM_MASK
| HF_TS_MASK
)) {
5718 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5719 /* XXX: what to do if illegal op ? */
5720 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
5723 modrm
= cpu_ldub_code(env
, s
->pc
++);
5724 mod
= (modrm
>> 6) & 3;
5726 op
= ((b
& 7) << 3) | ((modrm
>> 3) & 7);
5729 gen_lea_modrm(env
, s
, modrm
);
5731 case 0x00 ... 0x07: /* fxxxs */
5732 case 0x10 ... 0x17: /* fixxxl */
5733 case 0x20 ... 0x27: /* fxxxl */
5734 case 0x30 ... 0x37: /* fixxx */
5741 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5742 s
->mem_index
, MO_LEUL
);
5743 gen_helper_flds_FT0(cpu_env
, cpu_tmp2_i32
);
5746 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5747 s
->mem_index
, MO_LEUL
);
5748 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
5751 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
5752 s
->mem_index
, MO_LEQ
);
5753 gen_helper_fldl_FT0(cpu_env
, cpu_tmp1_i64
);
5757 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5758 s
->mem_index
, MO_LESW
);
5759 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
5763 gen_helper_fp_arith_ST0_FT0(op1
);
5765 /* fcomp needs pop */
5766 gen_helper_fpop(cpu_env
);
5770 case 0x08: /* flds */
5771 case 0x0a: /* fsts */
5772 case 0x0b: /* fstps */
5773 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5774 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5775 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5780 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5781 s
->mem_index
, MO_LEUL
);
5782 gen_helper_flds_ST0(cpu_env
, cpu_tmp2_i32
);
5785 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5786 s
->mem_index
, MO_LEUL
);
5787 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
5790 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
5791 s
->mem_index
, MO_LEQ
);
5792 gen_helper_fldl_ST0(cpu_env
, cpu_tmp1_i64
);
5796 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5797 s
->mem_index
, MO_LESW
);
5798 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
5803 /* XXX: the corresponding CPUID bit must be tested ! */
5806 gen_helper_fisttl_ST0(cpu_tmp2_i32
, cpu_env
);
5807 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5808 s
->mem_index
, MO_LEUL
);
5811 gen_helper_fisttll_ST0(cpu_tmp1_i64
, cpu_env
);
5812 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
5813 s
->mem_index
, MO_LEQ
);
5817 gen_helper_fistt_ST0(cpu_tmp2_i32
, cpu_env
);
5818 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5819 s
->mem_index
, MO_LEUW
);
5822 gen_helper_fpop(cpu_env
);
5827 gen_helper_fsts_ST0(cpu_tmp2_i32
, cpu_env
);
5828 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5829 s
->mem_index
, MO_LEUL
);
5832 gen_helper_fistl_ST0(cpu_tmp2_i32
, cpu_env
);
5833 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5834 s
->mem_index
, MO_LEUL
);
5837 gen_helper_fstl_ST0(cpu_tmp1_i64
, cpu_env
);
5838 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
5839 s
->mem_index
, MO_LEQ
);
5843 gen_helper_fist_ST0(cpu_tmp2_i32
, cpu_env
);
5844 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5845 s
->mem_index
, MO_LEUW
);
5849 gen_helper_fpop(cpu_env
);
5853 case 0x0c: /* fldenv mem */
5854 gen_helper_fldenv(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5856 case 0x0d: /* fldcw mem */
5857 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5858 s
->mem_index
, MO_LEUW
);
5859 gen_helper_fldcw(cpu_env
, cpu_tmp2_i32
);
5861 case 0x0e: /* fnstenv mem */
5862 gen_helper_fstenv(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5864 case 0x0f: /* fnstcw mem */
5865 gen_helper_fnstcw(cpu_tmp2_i32
, cpu_env
);
5866 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5867 s
->mem_index
, MO_LEUW
);
5869 case 0x1d: /* fldt mem */
5870 gen_helper_fldt_ST0(cpu_env
, cpu_A0
);
5872 case 0x1f: /* fstpt mem */
5873 gen_helper_fstt_ST0(cpu_env
, cpu_A0
);
5874 gen_helper_fpop(cpu_env
);
5876 case 0x2c: /* frstor mem */
5877 gen_helper_frstor(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5879 case 0x2e: /* fnsave mem */
5880 gen_helper_fsave(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5882 case 0x2f: /* fnstsw mem */
5883 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
5884 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5885 s
->mem_index
, MO_LEUW
);
5887 case 0x3c: /* fbld */
5888 gen_helper_fbld_ST0(cpu_env
, cpu_A0
);
5890 case 0x3e: /* fbstp */
5891 gen_helper_fbst_ST0(cpu_env
, cpu_A0
);
5892 gen_helper_fpop(cpu_env
);
5894 case 0x3d: /* fildll */
5895 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
5896 gen_helper_fildll_ST0(cpu_env
, cpu_tmp1_i64
);
5898 case 0x3f: /* fistpll */
5899 gen_helper_fistll_ST0(cpu_tmp1_i64
, cpu_env
);
5900 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
5901 gen_helper_fpop(cpu_env
);
5907 /* register float ops */
5911 case 0x08: /* fld sti */
5912 gen_helper_fpush(cpu_env
);
5913 gen_helper_fmov_ST0_STN(cpu_env
,
5914 tcg_const_i32((opreg
+ 1) & 7));
5916 case 0x09: /* fxchg sti */
5917 case 0x29: /* fxchg4 sti, undocumented op */
5918 case 0x39: /* fxchg7 sti, undocumented op */
5919 gen_helper_fxchg_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
5921 case 0x0a: /* grp d9/2 */
5924 /* check exceptions (FreeBSD FPU probe) */
5925 gen_helper_fwait(cpu_env
);
5931 case 0x0c: /* grp d9/4 */
5934 gen_helper_fchs_ST0(cpu_env
);
5937 gen_helper_fabs_ST0(cpu_env
);
5940 gen_helper_fldz_FT0(cpu_env
);
5941 gen_helper_fcom_ST0_FT0(cpu_env
);
5944 gen_helper_fxam_ST0(cpu_env
);
5950 case 0x0d: /* grp d9/5 */
5954 gen_helper_fpush(cpu_env
);
5955 gen_helper_fld1_ST0(cpu_env
);
5958 gen_helper_fpush(cpu_env
);
5959 gen_helper_fldl2t_ST0(cpu_env
);
5962 gen_helper_fpush(cpu_env
);
5963 gen_helper_fldl2e_ST0(cpu_env
);
5966 gen_helper_fpush(cpu_env
);
5967 gen_helper_fldpi_ST0(cpu_env
);
5970 gen_helper_fpush(cpu_env
);
5971 gen_helper_fldlg2_ST0(cpu_env
);
5974 gen_helper_fpush(cpu_env
);
5975 gen_helper_fldln2_ST0(cpu_env
);
5978 gen_helper_fpush(cpu_env
);
5979 gen_helper_fldz_ST0(cpu_env
);
5986 case 0x0e: /* grp d9/6 */
5989 gen_helper_f2xm1(cpu_env
);
5992 gen_helper_fyl2x(cpu_env
);
5995 gen_helper_fptan(cpu_env
);
5997 case 3: /* fpatan */
5998 gen_helper_fpatan(cpu_env
);
6000 case 4: /* fxtract */
6001 gen_helper_fxtract(cpu_env
);
6003 case 5: /* fprem1 */
6004 gen_helper_fprem1(cpu_env
);
6006 case 6: /* fdecstp */
6007 gen_helper_fdecstp(cpu_env
);
6010 case 7: /* fincstp */
6011 gen_helper_fincstp(cpu_env
);
6015 case 0x0f: /* grp d9/7 */
6018 gen_helper_fprem(cpu_env
);
6020 case 1: /* fyl2xp1 */
6021 gen_helper_fyl2xp1(cpu_env
);
6024 gen_helper_fsqrt(cpu_env
);
6026 case 3: /* fsincos */
6027 gen_helper_fsincos(cpu_env
);
6029 case 5: /* fscale */
6030 gen_helper_fscale(cpu_env
);
6032 case 4: /* frndint */
6033 gen_helper_frndint(cpu_env
);
6036 gen_helper_fsin(cpu_env
);
6040 gen_helper_fcos(cpu_env
);
6044 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6045 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6046 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6052 gen_helper_fp_arith_STN_ST0(op1
, opreg
);
6054 gen_helper_fpop(cpu_env
);
6056 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6057 gen_helper_fp_arith_ST0_FT0(op1
);
6061 case 0x02: /* fcom */
6062 case 0x22: /* fcom2, undocumented op */
6063 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6064 gen_helper_fcom_ST0_FT0(cpu_env
);
6066 case 0x03: /* fcomp */
6067 case 0x23: /* fcomp3, undocumented op */
6068 case 0x32: /* fcomp5, undocumented op */
6069 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6070 gen_helper_fcom_ST0_FT0(cpu_env
);
6071 gen_helper_fpop(cpu_env
);
6073 case 0x15: /* da/5 */
6075 case 1: /* fucompp */
6076 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6077 gen_helper_fucom_ST0_FT0(cpu_env
);
6078 gen_helper_fpop(cpu_env
);
6079 gen_helper_fpop(cpu_env
);
6087 case 0: /* feni (287 only, just do nop here) */
6089 case 1: /* fdisi (287 only, just do nop here) */
6092 gen_helper_fclex(cpu_env
);
6094 case 3: /* fninit */
6095 gen_helper_fninit(cpu_env
);
6097 case 4: /* fsetpm (287 only, just do nop here) */
6103 case 0x1d: /* fucomi */
6104 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6107 gen_update_cc_op(s
);
6108 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6109 gen_helper_fucomi_ST0_FT0(cpu_env
);
6110 set_cc_op(s
, CC_OP_EFLAGS
);
6112 case 0x1e: /* fcomi */
6113 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6116 gen_update_cc_op(s
);
6117 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6118 gen_helper_fcomi_ST0_FT0(cpu_env
);
6119 set_cc_op(s
, CC_OP_EFLAGS
);
6121 case 0x28: /* ffree sti */
6122 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6124 case 0x2a: /* fst sti */
6125 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6127 case 0x2b: /* fstp sti */
6128 case 0x0b: /* fstp1 sti, undocumented op */
6129 case 0x3a: /* fstp8 sti, undocumented op */
6130 case 0x3b: /* fstp9 sti, undocumented op */
6131 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6132 gen_helper_fpop(cpu_env
);
6134 case 0x2c: /* fucom st(i) */
6135 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6136 gen_helper_fucom_ST0_FT0(cpu_env
);
6138 case 0x2d: /* fucomp st(i) */
6139 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6140 gen_helper_fucom_ST0_FT0(cpu_env
);
6141 gen_helper_fpop(cpu_env
);
6143 case 0x33: /* de/3 */
6145 case 1: /* fcompp */
6146 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6147 gen_helper_fcom_ST0_FT0(cpu_env
);
6148 gen_helper_fpop(cpu_env
);
6149 gen_helper_fpop(cpu_env
);
6155 case 0x38: /* ffreep sti, undocumented op */
6156 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6157 gen_helper_fpop(cpu_env
);
6159 case 0x3c: /* df/4 */
6162 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
6163 tcg_gen_extu_i32_tl(cpu_T0
, cpu_tmp2_i32
);
6164 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
6170 case 0x3d: /* fucomip */
6171 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6174 gen_update_cc_op(s
);
6175 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6176 gen_helper_fucomi_ST0_FT0(cpu_env
);
6177 gen_helper_fpop(cpu_env
);
6178 set_cc_op(s
, CC_OP_EFLAGS
);
6180 case 0x3e: /* fcomip */
6181 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6184 gen_update_cc_op(s
);
6185 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6186 gen_helper_fcomi_ST0_FT0(cpu_env
);
6187 gen_helper_fpop(cpu_env
);
6188 set_cc_op(s
, CC_OP_EFLAGS
);
6190 case 0x10 ... 0x13: /* fcmovxx */
6195 static const uint8_t fcmov_cc
[8] = {
6202 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6205 op1
= fcmov_cc
[op
& 3] | (((op
>> 3) & 1) ^ 1);
6206 l1
= gen_new_label();
6207 gen_jcc1_noeob(s
, op1
, l1
);
6208 gen_helper_fmov_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6217 /************************/
6220 case 0xa4: /* movsS */
6222 ot
= mo_b_d(b
, dflag
);
6223 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6224 gen_repz_movs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6230 case 0xaa: /* stosS */
6232 ot
= mo_b_d(b
, dflag
);
6233 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6234 gen_repz_stos(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6239 case 0xac: /* lodsS */
6241 ot
= mo_b_d(b
, dflag
);
6242 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6243 gen_repz_lods(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6248 case 0xae: /* scasS */
6250 ot
= mo_b_d(b
, dflag
);
6251 if (prefixes
& PREFIX_REPNZ
) {
6252 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6253 } else if (prefixes
& PREFIX_REPZ
) {
6254 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6260 case 0xa6: /* cmpsS */
6262 ot
= mo_b_d(b
, dflag
);
6263 if (prefixes
& PREFIX_REPNZ
) {
6264 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6265 } else if (prefixes
& PREFIX_REPZ
) {
6266 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6271 case 0x6c: /* insS */
6273 ot
= mo_b_d32(b
, dflag
);
6274 tcg_gen_ext16u_tl(cpu_T0
, cpu_regs
[R_EDX
]);
6275 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6276 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
) | 4);
6277 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6278 gen_repz_ins(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6281 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6282 gen_jmp(s
, s
->pc
- s
->cs_base
);
6286 case 0x6e: /* outsS */
6288 ot
= mo_b_d32(b
, dflag
);
6289 tcg_gen_ext16u_tl(cpu_T0
, cpu_regs
[R_EDX
]);
6290 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6291 svm_is_rep(prefixes
) | 4);
6292 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6293 gen_repz_outs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6296 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6297 gen_jmp(s
, s
->pc
- s
->cs_base
);
6302 /************************/
6307 ot
= mo_b_d32(b
, dflag
);
6308 val
= cpu_ldub_code(env
, s
->pc
++);
6309 tcg_gen_movi_tl(cpu_T0
, val
);
6310 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6311 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6312 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6315 tcg_gen_movi_i32(cpu_tmp2_i32
, val
);
6316 gen_helper_in_func(ot
, cpu_T1
, cpu_tmp2_i32
);
6317 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T1
);
6318 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6319 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6321 gen_jmp(s
, s
->pc
- s
->cs_base
);
6326 ot
= mo_b_d32(b
, dflag
);
6327 val
= cpu_ldub_code(env
, s
->pc
++);
6328 tcg_gen_movi_tl(cpu_T0
, val
);
6329 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6330 svm_is_rep(prefixes
));
6331 gen_op_mov_v_reg(ot
, cpu_T1
, R_EAX
);
6333 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6336 tcg_gen_movi_i32(cpu_tmp2_i32
, val
);
6337 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T1
);
6338 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6339 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6340 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6342 gen_jmp(s
, s
->pc
- s
->cs_base
);
6347 ot
= mo_b_d32(b
, dflag
);
6348 tcg_gen_ext16u_tl(cpu_T0
, cpu_regs
[R_EDX
]);
6349 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6350 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6351 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6354 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
6355 gen_helper_in_func(ot
, cpu_T1
, cpu_tmp2_i32
);
6356 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T1
);
6357 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6358 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6360 gen_jmp(s
, s
->pc
- s
->cs_base
);
6365 ot
= mo_b_d32(b
, dflag
);
6366 tcg_gen_ext16u_tl(cpu_T0
, cpu_regs
[R_EDX
]);
6367 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6368 svm_is_rep(prefixes
));
6369 gen_op_mov_v_reg(ot
, cpu_T1
, R_EAX
);
6371 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6374 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
6375 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T1
);
6376 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6377 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6378 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6380 gen_jmp(s
, s
->pc
- s
->cs_base
);
6384 /************************/
6386 case 0xc2: /* ret im */
6387 val
= cpu_ldsw_code(env
, s
->pc
);
6390 gen_stack_update(s
, val
+ (1 << ot
));
6391 /* Note that gen_pop_T0 uses a zero-extending load. */
6392 gen_op_jmp_v(cpu_T0
);
6396 case 0xc3: /* ret */
6398 gen_pop_update(s
, ot
);
6399 /* Note that gen_pop_T0 uses a zero-extending load. */
6400 gen_op_jmp_v(cpu_T0
);
6404 case 0xca: /* lret im */
6405 val
= cpu_ldsw_code(env
, s
->pc
);
6408 if (s
->pe
&& !s
->vm86
) {
6409 gen_update_cc_op(s
);
6410 gen_jmp_im(pc_start
- s
->cs_base
);
6411 gen_helper_lret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6412 tcg_const_i32(val
));
6416 gen_op_ld_v(s
, dflag
, cpu_T0
, cpu_A0
);
6417 /* NOTE: keeping EIP updated is not a problem in case of
6419 gen_op_jmp_v(cpu_T0
);
6421 gen_add_A0_im(s
, 1 << dflag
);
6422 gen_op_ld_v(s
, dflag
, cpu_T0
, cpu_A0
);
6423 gen_op_movl_seg_T0_vm(R_CS
);
6424 /* add stack offset */
6425 gen_stack_update(s
, val
+ (2 << dflag
));
6429 case 0xcb: /* lret */
6432 case 0xcf: /* iret */
6433 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IRET
);
6436 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6437 set_cc_op(s
, CC_OP_EFLAGS
);
6438 } else if (s
->vm86
) {
6440 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6442 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6443 set_cc_op(s
, CC_OP_EFLAGS
);
6446 gen_helper_iret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6447 tcg_const_i32(s
->pc
- s
->cs_base
));
6448 set_cc_op(s
, CC_OP_EFLAGS
);
6452 case 0xe8: /* call im */
6454 if (dflag
!= MO_16
) {
6455 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6457 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6459 next_eip
= s
->pc
- s
->cs_base
;
6461 if (dflag
== MO_16
) {
6463 } else if (!CODE64(s
)) {
6466 tcg_gen_movi_tl(cpu_T0
, next_eip
);
6467 gen_push_v(s
, cpu_T0
);
6472 case 0x9a: /* lcall im */
6474 unsigned int selector
, offset
;
6479 offset
= insn_get(env
, s
, ot
);
6480 selector
= insn_get(env
, s
, MO_16
);
6482 tcg_gen_movi_tl(cpu_T0
, selector
);
6483 tcg_gen_movi_tl(cpu_T1
, offset
);
6486 case 0xe9: /* jmp im */
6487 if (dflag
!= MO_16
) {
6488 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6490 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6492 tval
+= s
->pc
- s
->cs_base
;
6493 if (dflag
== MO_16
) {
6495 } else if (!CODE64(s
)) {
6501 case 0xea: /* ljmp im */
6503 unsigned int selector
, offset
;
6508 offset
= insn_get(env
, s
, ot
);
6509 selector
= insn_get(env
, s
, MO_16
);
6511 tcg_gen_movi_tl(cpu_T0
, selector
);
6512 tcg_gen_movi_tl(cpu_T1
, offset
);
6515 case 0xeb: /* jmp Jb */
6516 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6517 tval
+= s
->pc
- s
->cs_base
;
6518 if (dflag
== MO_16
) {
6523 case 0x70 ... 0x7f: /* jcc Jb */
6524 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6526 case 0x180 ... 0x18f: /* jcc Jv */
6527 if (dflag
!= MO_16
) {
6528 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6530 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6533 next_eip
= s
->pc
- s
->cs_base
;
6535 if (dflag
== MO_16
) {
6539 gen_jcc(s
, b
, tval
, next_eip
);
6542 case 0x190 ... 0x19f: /* setcc Gv */
6543 modrm
= cpu_ldub_code(env
, s
->pc
++);
6544 gen_setcc1(s
, b
, cpu_T0
);
6545 gen_ldst_modrm(env
, s
, modrm
, MO_8
, OR_TMP0
, 1);
6547 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6548 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6552 modrm
= cpu_ldub_code(env
, s
->pc
++);
6553 reg
= ((modrm
>> 3) & 7) | rex_r
;
6554 gen_cmovcc1(env
, s
, ot
, b
, modrm
, reg
);
6557 /************************/
6559 case 0x9c: /* pushf */
6560 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_PUSHF
);
6561 if (s
->vm86
&& s
->iopl
!= 3) {
6562 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6564 gen_update_cc_op(s
);
6565 gen_helper_read_eflags(cpu_T0
, cpu_env
);
6566 gen_push_v(s
, cpu_T0
);
6569 case 0x9d: /* popf */
6570 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_POPF
);
6571 if (s
->vm86
&& s
->iopl
!= 3) {
6572 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6576 if (dflag
!= MO_16
) {
6577 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6578 tcg_const_i32((TF_MASK
| AC_MASK
|
6583 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6584 tcg_const_i32((TF_MASK
| AC_MASK
|
6586 IF_MASK
| IOPL_MASK
)
6590 if (s
->cpl
<= s
->iopl
) {
6591 if (dflag
!= MO_16
) {
6592 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6593 tcg_const_i32((TF_MASK
|
6599 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6600 tcg_const_i32((TF_MASK
|
6608 if (dflag
!= MO_16
) {
6609 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6610 tcg_const_i32((TF_MASK
| AC_MASK
|
6611 ID_MASK
| NT_MASK
)));
6613 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6614 tcg_const_i32((TF_MASK
| AC_MASK
|
6620 gen_pop_update(s
, ot
);
6621 set_cc_op(s
, CC_OP_EFLAGS
);
6622 /* abort translation because TF/AC flag may change */
6623 gen_jmp_im(s
->pc
- s
->cs_base
);
6627 case 0x9e: /* sahf */
6628 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6630 gen_op_mov_v_reg(MO_8
, cpu_T0
, R_AH
);
6631 gen_compute_eflags(s
);
6632 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, CC_O
);
6633 tcg_gen_andi_tl(cpu_T0
, cpu_T0
, CC_S
| CC_Z
| CC_A
| CC_P
| CC_C
);
6634 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, cpu_T0
);
6636 case 0x9f: /* lahf */
6637 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6639 gen_compute_eflags(s
);
6640 /* Note: gen_compute_eflags() only gives the condition codes */
6641 tcg_gen_ori_tl(cpu_T0
, cpu_cc_src
, 0x02);
6642 gen_op_mov_reg_v(MO_8
, R_AH
, cpu_T0
);
6644 case 0xf5: /* cmc */
6645 gen_compute_eflags(s
);
6646 tcg_gen_xori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6648 case 0xf8: /* clc */
6649 gen_compute_eflags(s
);
6650 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_C
);
6652 case 0xf9: /* stc */
6653 gen_compute_eflags(s
);
6654 tcg_gen_ori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6656 case 0xfc: /* cld */
6657 tcg_gen_movi_i32(cpu_tmp2_i32
, 1);
6658 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6660 case 0xfd: /* std */
6661 tcg_gen_movi_i32(cpu_tmp2_i32
, -1);
6662 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6665 /************************/
6666 /* bit operations */
6667 case 0x1ba: /* bt/bts/btr/btc Gv, im */
6669 modrm
= cpu_ldub_code(env
, s
->pc
++);
6670 op
= (modrm
>> 3) & 7;
6671 mod
= (modrm
>> 6) & 3;
6672 rm
= (modrm
& 7) | REX_B(s
);
6675 gen_lea_modrm(env
, s
, modrm
);
6676 if (!(s
->prefix
& PREFIX_LOCK
)) {
6677 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
6680 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
6683 val
= cpu_ldub_code(env
, s
->pc
++);
6684 tcg_gen_movi_tl(cpu_T1
, val
);
6689 case 0x1a3: /* bt Gv, Ev */
6692 case 0x1ab: /* bts */
6695 case 0x1b3: /* btr */
6698 case 0x1bb: /* btc */
6702 modrm
= cpu_ldub_code(env
, s
->pc
++);
6703 reg
= ((modrm
>> 3) & 7) | rex_r
;
6704 mod
= (modrm
>> 6) & 3;
6705 rm
= (modrm
& 7) | REX_B(s
);
6706 gen_op_mov_v_reg(MO_32
, cpu_T1
, reg
);
6708 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
6709 /* specific case: we need to add a displacement */
6710 gen_exts(ot
, cpu_T1
);
6711 tcg_gen_sari_tl(cpu_tmp0
, cpu_T1
, 3 + ot
);
6712 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, ot
);
6713 tcg_gen_add_tl(cpu_A0
, gen_lea_modrm_1(a
), cpu_tmp0
);
6714 gen_lea_v_seg(s
, s
->aflag
, cpu_A0
, a
.def_seg
, s
->override
);
6715 if (!(s
->prefix
& PREFIX_LOCK
)) {
6716 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
6719 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
6722 tcg_gen_andi_tl(cpu_T1
, cpu_T1
, (1 << (3 + ot
)) - 1);
6723 tcg_gen_movi_tl(cpu_tmp0
, 1);
6724 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T1
);
6725 if (s
->prefix
& PREFIX_LOCK
) {
6728 /* Needs no atomic ops; we surpressed the normal
6729 memory load for LOCK above so do it now. */
6730 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
6733 tcg_gen_atomic_fetch_or_tl(cpu_T0
, cpu_A0
, cpu_tmp0
,
6734 s
->mem_index
, ot
| MO_LE
);
6737 tcg_gen_not_tl(cpu_tmp0
, cpu_tmp0
);
6738 tcg_gen_atomic_fetch_and_tl(cpu_T0
, cpu_A0
, cpu_tmp0
,
6739 s
->mem_index
, ot
| MO_LE
);
6743 tcg_gen_atomic_fetch_xor_tl(cpu_T0
, cpu_A0
, cpu_tmp0
,
6744 s
->mem_index
, ot
| MO_LE
);
6747 tcg_gen_shr_tl(cpu_tmp4
, cpu_T0
, cpu_T1
);
6749 tcg_gen_shr_tl(cpu_tmp4
, cpu_T0
, cpu_T1
);
6752 /* Data already loaded; nothing to do. */
6755 tcg_gen_or_tl(cpu_T0
, cpu_T0
, cpu_tmp0
);
6758 tcg_gen_andc_tl(cpu_T0
, cpu_T0
, cpu_tmp0
);
6762 tcg_gen_xor_tl(cpu_T0
, cpu_T0
, cpu_tmp0
);
6767 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
6769 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
6774 /* Delay all CC updates until after the store above. Note that
6775 C is the result of the test, Z is unchanged, and the others
6776 are all undefined. */
6778 case CC_OP_MULB
... CC_OP_MULQ
:
6779 case CC_OP_ADDB
... CC_OP_ADDQ
:
6780 case CC_OP_ADCB
... CC_OP_ADCQ
:
6781 case CC_OP_SUBB
... CC_OP_SUBQ
:
6782 case CC_OP_SBBB
... CC_OP_SBBQ
:
6783 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
6784 case CC_OP_INCB
... CC_OP_INCQ
:
6785 case CC_OP_DECB
... CC_OP_DECQ
:
6786 case CC_OP_SHLB
... CC_OP_SHLQ
:
6787 case CC_OP_SARB
... CC_OP_SARQ
:
6788 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
6789 /* Z was going to be computed from the non-zero status of CC_DST.
6790 We can get that same Z value (and the new C value) by leaving
6791 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
6793 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
6794 set_cc_op(s
, ((s
->cc_op
- CC_OP_MULB
) & 3) + CC_OP_SARB
);
6797 /* Otherwise, generate EFLAGS and replace the C bit. */
6798 gen_compute_eflags(s
);
6799 tcg_gen_deposit_tl(cpu_cc_src
, cpu_cc_src
, cpu_tmp4
,
6804 case 0x1bc: /* bsf / tzcnt */
6805 case 0x1bd: /* bsr / lzcnt */
6807 modrm
= cpu_ldub_code(env
, s
->pc
++);
6808 reg
= ((modrm
>> 3) & 7) | rex_r
;
6809 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
6810 gen_extu(ot
, cpu_T0
);
6812 /* Note that lzcnt and tzcnt are in different extensions. */
6813 if ((prefixes
& PREFIX_REPZ
)
6815 ? s
->cpuid_ext3_features
& CPUID_EXT3_ABM
6816 : s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)) {
6818 /* For lzcnt/tzcnt, C bit is defined related to the input. */
6819 tcg_gen_mov_tl(cpu_cc_src
, cpu_T0
);
6821 /* For lzcnt, reduce the target_ulong result by the
6822 number of zeros that we expect to find at the top. */
6823 tcg_gen_clzi_tl(cpu_T0
, cpu_T0
, TARGET_LONG_BITS
);
6824 tcg_gen_subi_tl(cpu_T0
, cpu_T0
, TARGET_LONG_BITS
- size
);
6826 /* For tzcnt, a zero input must return the operand size. */
6827 tcg_gen_ctzi_tl(cpu_T0
, cpu_T0
, size
);
6829 /* For lzcnt/tzcnt, Z bit is defined related to the result. */
6830 gen_op_update1_cc();
6831 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
6833 /* For bsr/bsf, only the Z bit is defined and it is related
6834 to the input and not the result. */
6835 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
6836 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
6838 /* ??? The manual says that the output is undefined when the
6839 input is zero, but real hardware leaves it unchanged, and
6840 real programs appear to depend on that. Accomplish this
6841 by passing the output as the value to return upon zero. */
6843 /* For bsr, return the bit index of the first 1 bit,
6844 not the count of leading zeros. */
6845 tcg_gen_xori_tl(cpu_T1
, cpu_regs
[reg
], TARGET_LONG_BITS
- 1);
6846 tcg_gen_clz_tl(cpu_T0
, cpu_T0
, cpu_T1
);
6847 tcg_gen_xori_tl(cpu_T0
, cpu_T0
, TARGET_LONG_BITS
- 1);
6849 tcg_gen_ctz_tl(cpu_T0
, cpu_T0
, cpu_regs
[reg
]);
6852 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
6854 /************************/
6856 case 0x27: /* daa */
6859 gen_update_cc_op(s
);
6860 gen_helper_daa(cpu_env
);
6861 set_cc_op(s
, CC_OP_EFLAGS
);
6863 case 0x2f: /* das */
6866 gen_update_cc_op(s
);
6867 gen_helper_das(cpu_env
);
6868 set_cc_op(s
, CC_OP_EFLAGS
);
6870 case 0x37: /* aaa */
6873 gen_update_cc_op(s
);
6874 gen_helper_aaa(cpu_env
);
6875 set_cc_op(s
, CC_OP_EFLAGS
);
6877 case 0x3f: /* aas */
6880 gen_update_cc_op(s
);
6881 gen_helper_aas(cpu_env
);
6882 set_cc_op(s
, CC_OP_EFLAGS
);
6884 case 0xd4: /* aam */
6887 val
= cpu_ldub_code(env
, s
->pc
++);
6889 gen_exception(s
, EXCP00_DIVZ
, pc_start
- s
->cs_base
);
6891 gen_helper_aam(cpu_env
, tcg_const_i32(val
));
6892 set_cc_op(s
, CC_OP_LOGICB
);
6895 case 0xd5: /* aad */
6898 val
= cpu_ldub_code(env
, s
->pc
++);
6899 gen_helper_aad(cpu_env
, tcg_const_i32(val
));
6900 set_cc_op(s
, CC_OP_LOGICB
);
6902 /************************/
6904 case 0x90: /* nop */
6905 /* XXX: correct lock test for all insn */
6906 if (prefixes
& PREFIX_LOCK
) {
6909 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
6911 goto do_xchg_reg_eax
;
6913 if (prefixes
& PREFIX_REPZ
) {
6914 gen_update_cc_op(s
);
6915 gen_jmp_im(pc_start
- s
->cs_base
);
6916 gen_helper_pause(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
6917 s
->is_jmp
= DISAS_TB_JUMP
;
6920 case 0x9b: /* fwait */
6921 if ((s
->flags
& (HF_MP_MASK
| HF_TS_MASK
)) ==
6922 (HF_MP_MASK
| HF_TS_MASK
)) {
6923 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
6925 gen_helper_fwait(cpu_env
);
6928 case 0xcc: /* int3 */
6929 gen_interrupt(s
, EXCP03_INT3
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6931 case 0xcd: /* int N */
6932 val
= cpu_ldub_code(env
, s
->pc
++);
6933 if (s
->vm86
&& s
->iopl
!= 3) {
6934 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6936 gen_interrupt(s
, val
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6939 case 0xce: /* into */
6942 gen_update_cc_op(s
);
6943 gen_jmp_im(pc_start
- s
->cs_base
);
6944 gen_helper_into(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
6947 case 0xf1: /* icebp (undocumented, exits to external debugger) */
6948 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_ICEBP
);
6950 gen_debug(s
, pc_start
- s
->cs_base
);
6953 tb_flush(CPU(x86_env_get_cpu(env
)));
6954 qemu_set_log(CPU_LOG_INT
| CPU_LOG_TB_IN_ASM
);
6958 case 0xfa: /* cli */
6960 if (s
->cpl
<= s
->iopl
) {
6961 gen_helper_cli(cpu_env
);
6963 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6967 gen_helper_cli(cpu_env
);
6969 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6973 case 0xfb: /* sti */
6974 if (s
->vm86
? s
->iopl
== 3 : s
->cpl
<= s
->iopl
) {
6975 gen_helper_sti(cpu_env
);
6976 /* interruptions are enabled only the first insn after sti */
6977 gen_jmp_im(s
->pc
- s
->cs_base
);
6978 gen_eob_inhibit_irq(s
, true);
6980 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6983 case 0x62: /* bound */
6987 modrm
= cpu_ldub_code(env
, s
->pc
++);
6988 reg
= (modrm
>> 3) & 7;
6989 mod
= (modrm
>> 6) & 3;
6992 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
6993 gen_lea_modrm(env
, s
, modrm
);
6994 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
6996 gen_helper_boundw(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
6998 gen_helper_boundl(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
7001 case 0x1c8 ... 0x1cf: /* bswap reg */
7002 reg
= (b
& 7) | REX_B(s
);
7003 #ifdef TARGET_X86_64
7004 if (dflag
== MO_64
) {
7005 gen_op_mov_v_reg(MO_64
, cpu_T0
, reg
);
7006 tcg_gen_bswap64_i64(cpu_T0
, cpu_T0
);
7007 gen_op_mov_reg_v(MO_64
, reg
, cpu_T0
);
7011 gen_op_mov_v_reg(MO_32
, cpu_T0
, reg
);
7012 tcg_gen_ext32u_tl(cpu_T0
, cpu_T0
);
7013 tcg_gen_bswap32_tl(cpu_T0
, cpu_T0
);
7014 gen_op_mov_reg_v(MO_32
, reg
, cpu_T0
);
7017 case 0xd6: /* salc */
7020 gen_compute_eflags_c(s
, cpu_T0
);
7021 tcg_gen_neg_tl(cpu_T0
, cpu_T0
);
7022 gen_op_mov_reg_v(MO_8
, R_EAX
, cpu_T0
);
7024 case 0xe0: /* loopnz */
7025 case 0xe1: /* loopz */
7026 case 0xe2: /* loop */
7027 case 0xe3: /* jecxz */
7029 TCGLabel
*l1
, *l2
, *l3
;
7031 tval
= (int8_t)insn_get(env
, s
, MO_8
);
7032 next_eip
= s
->pc
- s
->cs_base
;
7034 if (dflag
== MO_16
) {
7038 l1
= gen_new_label();
7039 l2
= gen_new_label();
7040 l3
= gen_new_label();
7043 case 0: /* loopnz */
7045 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
7046 gen_op_jz_ecx(s
->aflag
, l3
);
7047 gen_jcc1(s
, (JCC_Z
<< 1) | (b
^ 1), l1
);
7050 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
7051 gen_op_jnz_ecx(s
->aflag
, l1
);
7055 gen_op_jz_ecx(s
->aflag
, l1
);
7060 gen_jmp_im(next_eip
);
7069 case 0x130: /* wrmsr */
7070 case 0x132: /* rdmsr */
7072 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7074 gen_update_cc_op(s
);
7075 gen_jmp_im(pc_start
- s
->cs_base
);
7077 gen_helper_rdmsr(cpu_env
);
7079 gen_helper_wrmsr(cpu_env
);
7083 case 0x131: /* rdtsc */
7084 gen_update_cc_op(s
);
7085 gen_jmp_im(pc_start
- s
->cs_base
);
7086 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7089 gen_helper_rdtsc(cpu_env
);
7090 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7092 gen_jmp(s
, s
->pc
- s
->cs_base
);
7095 case 0x133: /* rdpmc */
7096 gen_update_cc_op(s
);
7097 gen_jmp_im(pc_start
- s
->cs_base
);
7098 gen_helper_rdpmc(cpu_env
);
7100 case 0x134: /* sysenter */
7101 /* For Intel SYSENTER is valid on 64-bit */
7102 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7105 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7107 gen_helper_sysenter(cpu_env
);
7111 case 0x135: /* sysexit */
7112 /* For Intel SYSEXIT is valid on 64-bit */
7113 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7116 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7118 gen_helper_sysexit(cpu_env
, tcg_const_i32(dflag
- 1));
7122 #ifdef TARGET_X86_64
7123 case 0x105: /* syscall */
7124 /* XXX: is it usable in real mode ? */
7125 gen_update_cc_op(s
);
7126 gen_jmp_im(pc_start
- s
->cs_base
);
7127 gen_helper_syscall(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7128 /* TF handling for the syscall insn is different. The TF bit is checked
7129 after the syscall insn completes. This allows #DB to not be
7130 generated after one has entered CPL0 if TF is set in FMASK. */
7131 gen_eob_worker(s
, false, true);
7133 case 0x107: /* sysret */
7135 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7137 gen_helper_sysret(cpu_env
, tcg_const_i32(dflag
- 1));
7138 /* condition codes are modified only in long mode */
7140 set_cc_op(s
, CC_OP_EFLAGS
);
7142 /* TF handling for the sysret insn is different. The TF bit is
7143 checked after the sysret insn completes. This allows #DB to be
7144 generated "as if" the syscall insn in userspace has just
7146 gen_eob_worker(s
, false, true);
7150 case 0x1a2: /* cpuid */
7151 gen_update_cc_op(s
);
7152 gen_jmp_im(pc_start
- s
->cs_base
);
7153 gen_helper_cpuid(cpu_env
);
7155 case 0xf4: /* hlt */
7157 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7159 gen_update_cc_op(s
);
7160 gen_jmp_im(pc_start
- s
->cs_base
);
7161 gen_helper_hlt(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7162 s
->is_jmp
= DISAS_TB_JUMP
;
7166 modrm
= cpu_ldub_code(env
, s
->pc
++);
7167 mod
= (modrm
>> 6) & 3;
7168 op
= (modrm
>> 3) & 7;
7171 if (!s
->pe
|| s
->vm86
)
7173 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_READ
);
7174 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
,
7175 offsetof(CPUX86State
, ldt
.selector
));
7176 ot
= mod
== 3 ? dflag
: MO_16
;
7177 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7180 if (!s
->pe
|| s
->vm86
)
7183 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7185 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_WRITE
);
7186 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7187 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
7188 gen_helper_lldt(cpu_env
, cpu_tmp2_i32
);
7192 if (!s
->pe
|| s
->vm86
)
7194 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_READ
);
7195 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
,
7196 offsetof(CPUX86State
, tr
.selector
));
7197 ot
= mod
== 3 ? dflag
: MO_16
;
7198 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7201 if (!s
->pe
|| s
->vm86
)
7204 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7206 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_WRITE
);
7207 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7208 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
7209 gen_helper_ltr(cpu_env
, cpu_tmp2_i32
);
7214 if (!s
->pe
|| s
->vm86
)
7216 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7217 gen_update_cc_op(s
);
7219 gen_helper_verr(cpu_env
, cpu_T0
);
7221 gen_helper_verw(cpu_env
, cpu_T0
);
7223 set_cc_op(s
, CC_OP_EFLAGS
);
7231 modrm
= cpu_ldub_code(env
, s
->pc
++);
7233 CASE_MODRM_MEM_OP(0): /* sgdt */
7234 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_READ
);
7235 gen_lea_modrm(env
, s
, modrm
);
7236 tcg_gen_ld32u_tl(cpu_T0
,
7237 cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7238 gen_op_st_v(s
, MO_16
, cpu_T0
, cpu_A0
);
7239 gen_add_A0_im(s
, 2);
7240 tcg_gen_ld_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7241 if (dflag
== MO_16
) {
7242 tcg_gen_andi_tl(cpu_T0
, cpu_T0
, 0xffffff);
7244 gen_op_st_v(s
, CODE64(s
) + MO_32
, cpu_T0
, cpu_A0
);
7247 case 0xc8: /* monitor */
7248 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) || s
->cpl
!= 0) {
7251 gen_update_cc_op(s
);
7252 gen_jmp_im(pc_start
- s
->cs_base
);
7253 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EAX
]);
7254 gen_extu(s
->aflag
, cpu_A0
);
7255 gen_add_A0_ds_seg(s
);
7256 gen_helper_monitor(cpu_env
, cpu_A0
);
7259 case 0xc9: /* mwait */
7260 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) || s
->cpl
!= 0) {
7263 gen_update_cc_op(s
);
7264 gen_jmp_im(pc_start
- s
->cs_base
);
7265 gen_helper_mwait(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7269 case 0xca: /* clac */
7270 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
)
7274 gen_helper_clac(cpu_env
);
7275 gen_jmp_im(s
->pc
- s
->cs_base
);
7279 case 0xcb: /* stac */
7280 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
)
7284 gen_helper_stac(cpu_env
);
7285 gen_jmp_im(s
->pc
- s
->cs_base
);
7289 CASE_MODRM_MEM_OP(1): /* sidt */
7290 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_READ
);
7291 gen_lea_modrm(env
, s
, modrm
);
7292 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7293 gen_op_st_v(s
, MO_16
, cpu_T0
, cpu_A0
);
7294 gen_add_A0_im(s
, 2);
7295 tcg_gen_ld_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, idt
.base
));
7296 if (dflag
== MO_16
) {
7297 tcg_gen_andi_tl(cpu_T0
, cpu_T0
, 0xffffff);
7299 gen_op_st_v(s
, CODE64(s
) + MO_32
, cpu_T0
, cpu_A0
);
7302 case 0xd0: /* xgetbv */
7303 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
7304 || (s
->prefix
& (PREFIX_LOCK
| PREFIX_DATA
7305 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
7308 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_ECX
]);
7309 gen_helper_xgetbv(cpu_tmp1_i64
, cpu_env
, cpu_tmp2_i32
);
7310 tcg_gen_extr_i64_tl(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
], cpu_tmp1_i64
);
7313 case 0xd1: /* xsetbv */
7314 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
7315 || (s
->prefix
& (PREFIX_LOCK
| PREFIX_DATA
7316 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
7320 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7323 tcg_gen_concat_tl_i64(cpu_tmp1_i64
, cpu_regs
[R_EAX
],
7325 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_ECX
]);
7326 gen_helper_xsetbv(cpu_env
, cpu_tmp2_i32
, cpu_tmp1_i64
);
7327 /* End TB because translation flags may change. */
7328 gen_jmp_im(s
->pc
- s
->cs_base
);
7332 case 0xd8: /* VMRUN */
7333 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7337 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7340 gen_update_cc_op(s
);
7341 gen_jmp_im(pc_start
- s
->cs_base
);
7342 gen_helper_vmrun(cpu_env
, tcg_const_i32(s
->aflag
- 1),
7343 tcg_const_i32(s
->pc
- pc_start
));
7345 s
->is_jmp
= DISAS_TB_JUMP
;
7348 case 0xd9: /* VMMCALL */
7349 if (!(s
->flags
& HF_SVME_MASK
)) {
7352 gen_update_cc_op(s
);
7353 gen_jmp_im(pc_start
- s
->cs_base
);
7354 gen_helper_vmmcall(cpu_env
);
7357 case 0xda: /* VMLOAD */
7358 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7362 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7365 gen_update_cc_op(s
);
7366 gen_jmp_im(pc_start
- s
->cs_base
);
7367 gen_helper_vmload(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7370 case 0xdb: /* VMSAVE */
7371 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7375 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7378 gen_update_cc_op(s
);
7379 gen_jmp_im(pc_start
- s
->cs_base
);
7380 gen_helper_vmsave(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7383 case 0xdc: /* STGI */
7384 if ((!(s
->flags
& HF_SVME_MASK
)
7385 && !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
))
7390 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7393 gen_update_cc_op(s
);
7394 gen_jmp_im(pc_start
- s
->cs_base
);
7395 gen_helper_stgi(cpu_env
);
7398 case 0xdd: /* CLGI */
7399 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7403 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7406 gen_update_cc_op(s
);
7407 gen_jmp_im(pc_start
- s
->cs_base
);
7408 gen_helper_clgi(cpu_env
);
7411 case 0xde: /* SKINIT */
7412 if ((!(s
->flags
& HF_SVME_MASK
)
7413 && !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
))
7417 gen_update_cc_op(s
);
7418 gen_jmp_im(pc_start
- s
->cs_base
);
7419 gen_helper_skinit(cpu_env
);
7422 case 0xdf: /* INVLPGA */
7423 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7427 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7430 gen_update_cc_op(s
);
7431 gen_jmp_im(pc_start
- s
->cs_base
);
7432 gen_helper_invlpga(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7435 CASE_MODRM_MEM_OP(2): /* lgdt */
7437 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7440 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_WRITE
);
7441 gen_lea_modrm(env
, s
, modrm
);
7442 gen_op_ld_v(s
, MO_16
, cpu_T1
, cpu_A0
);
7443 gen_add_A0_im(s
, 2);
7444 gen_op_ld_v(s
, CODE64(s
) + MO_32
, cpu_T0
, cpu_A0
);
7445 if (dflag
== MO_16
) {
7446 tcg_gen_andi_tl(cpu_T0
, cpu_T0
, 0xffffff);
7448 tcg_gen_st_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7449 tcg_gen_st32_tl(cpu_T1
, cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7452 CASE_MODRM_MEM_OP(3): /* lidt */
7454 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7457 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_WRITE
);
7458 gen_lea_modrm(env
, s
, modrm
);
7459 gen_op_ld_v(s
, MO_16
, cpu_T1
, cpu_A0
);
7460 gen_add_A0_im(s
, 2);
7461 gen_op_ld_v(s
, CODE64(s
) + MO_32
, cpu_T0
, cpu_A0
);
7462 if (dflag
== MO_16
) {
7463 tcg_gen_andi_tl(cpu_T0
, cpu_T0
, 0xffffff);
7465 tcg_gen_st_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, idt
.base
));
7466 tcg_gen_st32_tl(cpu_T1
, cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7469 CASE_MODRM_OP(4): /* smsw */
7470 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_CR0
);
7471 tcg_gen_ld_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, cr
[0]));
7473 mod
= (modrm
>> 6) & 3;
7474 ot
= (mod
!= 3 ? MO_16
: s
->dflag
);
7478 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7480 case 0xee: /* rdpkru */
7481 if (prefixes
& PREFIX_LOCK
) {
7484 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_ECX
]);
7485 gen_helper_rdpkru(cpu_tmp1_i64
, cpu_env
, cpu_tmp2_i32
);
7486 tcg_gen_extr_i64_tl(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
], cpu_tmp1_i64
);
7488 case 0xef: /* wrpkru */
7489 if (prefixes
& PREFIX_LOCK
) {
7492 tcg_gen_concat_tl_i64(cpu_tmp1_i64
, cpu_regs
[R_EAX
],
7494 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_ECX
]);
7495 gen_helper_wrpkru(cpu_env
, cpu_tmp2_i32
, cpu_tmp1_i64
);
7497 CASE_MODRM_OP(6): /* lmsw */
7499 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7502 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7503 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7504 gen_helper_lmsw(cpu_env
, cpu_T0
);
7505 gen_jmp_im(s
->pc
- s
->cs_base
);
7509 CASE_MODRM_MEM_OP(7): /* invlpg */
7511 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7514 gen_update_cc_op(s
);
7515 gen_jmp_im(pc_start
- s
->cs_base
);
7516 gen_lea_modrm(env
, s
, modrm
);
7517 gen_helper_invlpg(cpu_env
, cpu_A0
);
7518 gen_jmp_im(s
->pc
- s
->cs_base
);
7522 case 0xf8: /* swapgs */
7523 #ifdef TARGET_X86_64
7526 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7528 tcg_gen_mov_tl(cpu_T0
, cpu_seg_base
[R_GS
]);
7529 tcg_gen_ld_tl(cpu_seg_base
[R_GS
], cpu_env
,
7530 offsetof(CPUX86State
, kernelgsbase
));
7531 tcg_gen_st_tl(cpu_T0
, cpu_env
,
7532 offsetof(CPUX86State
, kernelgsbase
));
7539 case 0xf9: /* rdtscp */
7540 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_RDTSCP
)) {
7543 gen_update_cc_op(s
);
7544 gen_jmp_im(pc_start
- s
->cs_base
);
7545 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7548 gen_helper_rdtscp(cpu_env
);
7549 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7551 gen_jmp(s
, s
->pc
- s
->cs_base
);
7560 case 0x108: /* invd */
7561 case 0x109: /* wbinvd */
7563 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7565 gen_svm_check_intercept(s
, pc_start
, (b
& 2) ? SVM_EXIT_INVD
: SVM_EXIT_WBINVD
);
7569 case 0x63: /* arpl or movslS (x86_64) */
7570 #ifdef TARGET_X86_64
7573 /* d_ot is the size of destination */
7576 modrm
= cpu_ldub_code(env
, s
->pc
++);
7577 reg
= ((modrm
>> 3) & 7) | rex_r
;
7578 mod
= (modrm
>> 6) & 3;
7579 rm
= (modrm
& 7) | REX_B(s
);
7582 gen_op_mov_v_reg(MO_32
, cpu_T0
, rm
);
7584 if (d_ot
== MO_64
) {
7585 tcg_gen_ext32s_tl(cpu_T0
, cpu_T0
);
7587 gen_op_mov_reg_v(d_ot
, reg
, cpu_T0
);
7589 gen_lea_modrm(env
, s
, modrm
);
7590 gen_op_ld_v(s
, MO_32
| MO_SIGN
, cpu_T0
, cpu_A0
);
7591 gen_op_mov_reg_v(d_ot
, reg
, cpu_T0
);
7597 TCGv t0
, t1
, t2
, a0
;
7599 if (!s
->pe
|| s
->vm86
)
7601 t0
= tcg_temp_local_new();
7602 t1
= tcg_temp_local_new();
7603 t2
= tcg_temp_local_new();
7605 modrm
= cpu_ldub_code(env
, s
->pc
++);
7606 reg
= (modrm
>> 3) & 7;
7607 mod
= (modrm
>> 6) & 3;
7610 gen_lea_modrm(env
, s
, modrm
);
7611 gen_op_ld_v(s
, ot
, t0
, cpu_A0
);
7612 a0
= tcg_temp_local_new();
7613 tcg_gen_mov_tl(a0
, cpu_A0
);
7615 gen_op_mov_v_reg(ot
, t0
, rm
);
7618 gen_op_mov_v_reg(ot
, t1
, reg
);
7619 tcg_gen_andi_tl(cpu_tmp0
, t0
, 3);
7620 tcg_gen_andi_tl(t1
, t1
, 3);
7621 tcg_gen_movi_tl(t2
, 0);
7622 label1
= gen_new_label();
7623 tcg_gen_brcond_tl(TCG_COND_GE
, cpu_tmp0
, t1
, label1
);
7624 tcg_gen_andi_tl(t0
, t0
, ~3);
7625 tcg_gen_or_tl(t0
, t0
, t1
);
7626 tcg_gen_movi_tl(t2
, CC_Z
);
7627 gen_set_label(label1
);
7629 gen_op_st_v(s
, ot
, t0
, a0
);
7632 gen_op_mov_reg_v(ot
, rm
, t0
);
7634 gen_compute_eflags(s
);
7635 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_Z
);
7636 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, t2
);
7642 case 0x102: /* lar */
7643 case 0x103: /* lsl */
7647 if (!s
->pe
|| s
->vm86
)
7649 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
7650 modrm
= cpu_ldub_code(env
, s
->pc
++);
7651 reg
= ((modrm
>> 3) & 7) | rex_r
;
7652 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7653 t0
= tcg_temp_local_new();
7654 gen_update_cc_op(s
);
7656 gen_helper_lar(t0
, cpu_env
, cpu_T0
);
7658 gen_helper_lsl(t0
, cpu_env
, cpu_T0
);
7660 tcg_gen_andi_tl(cpu_tmp0
, cpu_cc_src
, CC_Z
);
7661 label1
= gen_new_label();
7662 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
7663 gen_op_mov_reg_v(ot
, reg
, t0
);
7664 gen_set_label(label1
);
7665 set_cc_op(s
, CC_OP_EFLAGS
);
7670 modrm
= cpu_ldub_code(env
, s
->pc
++);
7671 mod
= (modrm
>> 6) & 3;
7672 op
= (modrm
>> 3) & 7;
7674 case 0: /* prefetchnta */
7675 case 1: /* prefetchnt0 */
7676 case 2: /* prefetchnt0 */
7677 case 3: /* prefetchnt0 */
7680 gen_nop_modrm(env
, s
, modrm
);
7681 /* nothing more to do */
7683 default: /* nop (multi byte) */
7684 gen_nop_modrm(env
, s
, modrm
);
7689 modrm
= cpu_ldub_code(env
, s
->pc
++);
7690 if (s
->flags
& HF_MPX_EN_MASK
) {
7691 mod
= (modrm
>> 6) & 3;
7692 reg
= ((modrm
>> 3) & 7) | rex_r
;
7693 if (prefixes
& PREFIX_REPZ
) {
7696 || (prefixes
& PREFIX_LOCK
)
7697 || s
->aflag
== MO_16
) {
7700 gen_bndck(env
, s
, modrm
, TCG_COND_LTU
, cpu_bndl
[reg
]);
7701 } else if (prefixes
& PREFIX_REPNZ
) {
7704 || (prefixes
& PREFIX_LOCK
)
7705 || s
->aflag
== MO_16
) {
7708 TCGv_i64 notu
= tcg_temp_new_i64();
7709 tcg_gen_not_i64(notu
, cpu_bndu
[reg
]);
7710 gen_bndck(env
, s
, modrm
, TCG_COND_GTU
, notu
);
7711 tcg_temp_free_i64(notu
);
7712 } else if (prefixes
& PREFIX_DATA
) {
7713 /* bndmov -- from reg/mem */
7714 if (reg
>= 4 || s
->aflag
== MO_16
) {
7718 int reg2
= (modrm
& 7) | REX_B(s
);
7719 if (reg2
>= 4 || (prefixes
& PREFIX_LOCK
)) {
7722 if (s
->flags
& HF_MPX_IU_MASK
) {
7723 tcg_gen_mov_i64(cpu_bndl
[reg
], cpu_bndl
[reg2
]);
7724 tcg_gen_mov_i64(cpu_bndu
[reg
], cpu_bndu
[reg2
]);
7727 gen_lea_modrm(env
, s
, modrm
);
7729 tcg_gen_qemu_ld_i64(cpu_bndl
[reg
], cpu_A0
,
7730 s
->mem_index
, MO_LEQ
);
7731 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, 8);
7732 tcg_gen_qemu_ld_i64(cpu_bndu
[reg
], cpu_A0
,
7733 s
->mem_index
, MO_LEQ
);
7735 tcg_gen_qemu_ld_i64(cpu_bndl
[reg
], cpu_A0
,
7736 s
->mem_index
, MO_LEUL
);
7737 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, 4);
7738 tcg_gen_qemu_ld_i64(cpu_bndu
[reg
], cpu_A0
,
7739 s
->mem_index
, MO_LEUL
);
7741 /* bnd registers are now in-use */
7742 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7744 } else if (mod
!= 3) {
7746 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7748 || (prefixes
& PREFIX_LOCK
)
7749 || s
->aflag
== MO_16
7754 tcg_gen_addi_tl(cpu_A0
, cpu_regs
[a
.base
], a
.disp
);
7756 tcg_gen_movi_tl(cpu_A0
, 0);
7758 gen_lea_v_seg(s
, s
->aflag
, cpu_A0
, a
.def_seg
, s
->override
);
7760 tcg_gen_mov_tl(cpu_T0
, cpu_regs
[a
.index
]);
7762 tcg_gen_movi_tl(cpu_T0
, 0);
7765 gen_helper_bndldx64(cpu_bndl
[reg
], cpu_env
, cpu_A0
, cpu_T0
);
7766 tcg_gen_ld_i64(cpu_bndu
[reg
], cpu_env
,
7767 offsetof(CPUX86State
, mmx_t0
.MMX_Q(0)));
7769 gen_helper_bndldx32(cpu_bndu
[reg
], cpu_env
, cpu_A0
, cpu_T0
);
7770 tcg_gen_ext32u_i64(cpu_bndl
[reg
], cpu_bndu
[reg
]);
7771 tcg_gen_shri_i64(cpu_bndu
[reg
], cpu_bndu
[reg
], 32);
7773 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7776 gen_nop_modrm(env
, s
, modrm
);
7779 modrm
= cpu_ldub_code(env
, s
->pc
++);
7780 if (s
->flags
& HF_MPX_EN_MASK
) {
7781 mod
= (modrm
>> 6) & 3;
7782 reg
= ((modrm
>> 3) & 7) | rex_r
;
7783 if (mod
!= 3 && (prefixes
& PREFIX_REPZ
)) {
7786 || (prefixes
& PREFIX_LOCK
)
7787 || s
->aflag
== MO_16
) {
7790 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7792 tcg_gen_extu_tl_i64(cpu_bndl
[reg
], cpu_regs
[a
.base
]);
7794 tcg_gen_ext32u_i64(cpu_bndl
[reg
], cpu_bndl
[reg
]);
7796 } else if (a
.base
== -1) {
7797 /* no base register has lower bound of 0 */
7798 tcg_gen_movi_i64(cpu_bndl
[reg
], 0);
7800 /* rip-relative generates #ud */
7803 tcg_gen_not_tl(cpu_A0
, gen_lea_modrm_1(a
));
7805 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
7807 tcg_gen_extu_tl_i64(cpu_bndu
[reg
], cpu_A0
);
7808 /* bnd registers are now in-use */
7809 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7811 } else if (prefixes
& PREFIX_REPNZ
) {
7814 || (prefixes
& PREFIX_LOCK
)
7815 || s
->aflag
== MO_16
) {
7818 gen_bndck(env
, s
, modrm
, TCG_COND_GTU
, cpu_bndu
[reg
]);
7819 } else if (prefixes
& PREFIX_DATA
) {
7820 /* bndmov -- to reg/mem */
7821 if (reg
>= 4 || s
->aflag
== MO_16
) {
7825 int reg2
= (modrm
& 7) | REX_B(s
);
7826 if (reg2
>= 4 || (prefixes
& PREFIX_LOCK
)) {
7829 if (s
->flags
& HF_MPX_IU_MASK
) {
7830 tcg_gen_mov_i64(cpu_bndl
[reg2
], cpu_bndl
[reg
]);
7831 tcg_gen_mov_i64(cpu_bndu
[reg2
], cpu_bndu
[reg
]);
7834 gen_lea_modrm(env
, s
, modrm
);
7836 tcg_gen_qemu_st_i64(cpu_bndl
[reg
], cpu_A0
,
7837 s
->mem_index
, MO_LEQ
);
7838 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, 8);
7839 tcg_gen_qemu_st_i64(cpu_bndu
[reg
], cpu_A0
,
7840 s
->mem_index
, MO_LEQ
);
7842 tcg_gen_qemu_st_i64(cpu_bndl
[reg
], cpu_A0
,
7843 s
->mem_index
, MO_LEUL
);
7844 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, 4);
7845 tcg_gen_qemu_st_i64(cpu_bndu
[reg
], cpu_A0
,
7846 s
->mem_index
, MO_LEUL
);
7849 } else if (mod
!= 3) {
7851 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7853 || (prefixes
& PREFIX_LOCK
)
7854 || s
->aflag
== MO_16
7859 tcg_gen_addi_tl(cpu_A0
, cpu_regs
[a
.base
], a
.disp
);
7861 tcg_gen_movi_tl(cpu_A0
, 0);
7863 gen_lea_v_seg(s
, s
->aflag
, cpu_A0
, a
.def_seg
, s
->override
);
7865 tcg_gen_mov_tl(cpu_T0
, cpu_regs
[a
.index
]);
7867 tcg_gen_movi_tl(cpu_T0
, 0);
7870 gen_helper_bndstx64(cpu_env
, cpu_A0
, cpu_T0
,
7871 cpu_bndl
[reg
], cpu_bndu
[reg
]);
7873 gen_helper_bndstx32(cpu_env
, cpu_A0
, cpu_T0
,
7874 cpu_bndl
[reg
], cpu_bndu
[reg
]);
7878 gen_nop_modrm(env
, s
, modrm
);
7880 case 0x119: case 0x11c ... 0x11f: /* nop (multi byte) */
7881 modrm
= cpu_ldub_code(env
, s
->pc
++);
7882 gen_nop_modrm(env
, s
, modrm
);
7884 case 0x120: /* mov reg, crN */
7885 case 0x122: /* mov crN, reg */
7887 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7889 modrm
= cpu_ldub_code(env
, s
->pc
++);
7890 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7891 * AMD documentation (24594.pdf) and testing of
7892 * intel 386 and 486 processors all show that the mod bits
7893 * are assumed to be 1's, regardless of actual values.
7895 rm
= (modrm
& 7) | REX_B(s
);
7896 reg
= ((modrm
>> 3) & 7) | rex_r
;
7901 if ((prefixes
& PREFIX_LOCK
) && (reg
== 0) &&
7902 (s
->cpuid_ext3_features
& CPUID_EXT3_CR8LEG
)) {
7911 gen_update_cc_op(s
);
7912 gen_jmp_im(pc_start
- s
->cs_base
);
7914 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
7915 gen_helper_write_crN(cpu_env
, tcg_const_i32(reg
),
7917 gen_jmp_im(s
->pc
- s
->cs_base
);
7920 gen_helper_read_crN(cpu_T0
, cpu_env
, tcg_const_i32(reg
));
7921 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
7929 case 0x121: /* mov reg, drN */
7930 case 0x123: /* mov drN, reg */
7932 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7934 modrm
= cpu_ldub_code(env
, s
->pc
++);
7935 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7936 * AMD documentation (24594.pdf) and testing of
7937 * intel 386 and 486 processors all show that the mod bits
7938 * are assumed to be 1's, regardless of actual values.
7940 rm
= (modrm
& 7) | REX_B(s
);
7941 reg
= ((modrm
>> 3) & 7) | rex_r
;
7950 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_DR0
+ reg
);
7951 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
7952 tcg_gen_movi_i32(cpu_tmp2_i32
, reg
);
7953 gen_helper_set_dr(cpu_env
, cpu_tmp2_i32
, cpu_T0
);
7954 gen_jmp_im(s
->pc
- s
->cs_base
);
7957 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_DR0
+ reg
);
7958 tcg_gen_movi_i32(cpu_tmp2_i32
, reg
);
7959 gen_helper_get_dr(cpu_T0
, cpu_env
, cpu_tmp2_i32
);
7960 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
7964 case 0x106: /* clts */
7966 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7968 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7969 gen_helper_clts(cpu_env
);
7970 /* abort block because static cpu state changed */
7971 gen_jmp_im(s
->pc
- s
->cs_base
);
7975 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
7976 case 0x1c3: /* MOVNTI reg, mem */
7977 if (!(s
->cpuid_features
& CPUID_SSE2
))
7979 ot
= mo_64_32(dflag
);
7980 modrm
= cpu_ldub_code(env
, s
->pc
++);
7981 mod
= (modrm
>> 6) & 3;
7984 reg
= ((modrm
>> 3) & 7) | rex_r
;
7985 /* generate a generic store */
7986 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
7989 modrm
= cpu_ldub_code(env
, s
->pc
++);
7991 CASE_MODRM_MEM_OP(0): /* fxsave */
7992 if (!(s
->cpuid_features
& CPUID_FXSR
)
7993 || (prefixes
& PREFIX_LOCK
)) {
7996 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
7997 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8000 gen_lea_modrm(env
, s
, modrm
);
8001 gen_helper_fxsave(cpu_env
, cpu_A0
);
8004 CASE_MODRM_MEM_OP(1): /* fxrstor */
8005 if (!(s
->cpuid_features
& CPUID_FXSR
)
8006 || (prefixes
& PREFIX_LOCK
)) {
8009 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
8010 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8013 gen_lea_modrm(env
, s
, modrm
);
8014 gen_helper_fxrstor(cpu_env
, cpu_A0
);
8017 CASE_MODRM_MEM_OP(2): /* ldmxcsr */
8018 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
)) {
8021 if (s
->flags
& HF_TS_MASK
) {
8022 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8025 gen_lea_modrm(env
, s
, modrm
);
8026 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
, s
->mem_index
, MO_LEUL
);
8027 gen_helper_ldmxcsr(cpu_env
, cpu_tmp2_i32
);
8030 CASE_MODRM_MEM_OP(3): /* stmxcsr */
8031 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
)) {
8034 if (s
->flags
& HF_TS_MASK
) {
8035 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8038 gen_lea_modrm(env
, s
, modrm
);
8039 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, mxcsr
));
8040 gen_op_st_v(s
, MO_32
, cpu_T0
, cpu_A0
);
8043 CASE_MODRM_MEM_OP(4): /* xsave */
8044 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8045 || (prefixes
& (PREFIX_LOCK
| PREFIX_DATA
8046 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
8049 gen_lea_modrm(env
, s
, modrm
);
8050 tcg_gen_concat_tl_i64(cpu_tmp1_i64
, cpu_regs
[R_EAX
],
8052 gen_helper_xsave(cpu_env
, cpu_A0
, cpu_tmp1_i64
);
8055 CASE_MODRM_MEM_OP(5): /* xrstor */
8056 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8057 || (prefixes
& (PREFIX_LOCK
| PREFIX_DATA
8058 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
8061 gen_lea_modrm(env
, s
, modrm
);
8062 tcg_gen_concat_tl_i64(cpu_tmp1_i64
, cpu_regs
[R_EAX
],
8064 gen_helper_xrstor(cpu_env
, cpu_A0
, cpu_tmp1_i64
);
8065 /* XRSTOR is how MPX is enabled, which changes how
8066 we translate. Thus we need to end the TB. */
8067 gen_update_cc_op(s
);
8068 gen_jmp_im(s
->pc
- s
->cs_base
);
8072 CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */
8073 if (prefixes
& PREFIX_LOCK
) {
8076 if (prefixes
& PREFIX_DATA
) {
8078 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLWB
)) {
8081 gen_nop_modrm(env
, s
, modrm
);
8084 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8085 || (s
->cpuid_xsave_features
& CPUID_XSAVE_XSAVEOPT
) == 0
8086 || (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
))) {
8089 gen_lea_modrm(env
, s
, modrm
);
8090 tcg_gen_concat_tl_i64(cpu_tmp1_i64
, cpu_regs
[R_EAX
],
8092 gen_helper_xsaveopt(cpu_env
, cpu_A0
, cpu_tmp1_i64
);
8096 CASE_MODRM_MEM_OP(7): /* clflush / clflushopt */
8097 if (prefixes
& PREFIX_LOCK
) {
8100 if (prefixes
& PREFIX_DATA
) {
8102 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLFLUSHOPT
)) {
8107 if ((s
->prefix
& (PREFIX_REPZ
| PREFIX_REPNZ
))
8108 || !(s
->cpuid_features
& CPUID_CLFLUSH
)) {
8112 gen_nop_modrm(env
, s
, modrm
);
8115 case 0xc0 ... 0xc7: /* rdfsbase (f3 0f ae /0) */
8116 case 0xc8 ... 0xc8: /* rdgsbase (f3 0f ae /1) */
8117 case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */
8118 case 0xd8 ... 0xd8: /* wrgsbase (f3 0f ae /3) */
8120 && (prefixes
& PREFIX_REPZ
)
8121 && !(prefixes
& PREFIX_LOCK
)
8122 && (s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_FSGSBASE
)) {
8123 TCGv base
, treg
, src
, dst
;
8125 /* Preserve hflags bits by testing CR4 at runtime. */
8126 tcg_gen_movi_i32(cpu_tmp2_i32
, CR4_FSGSBASE_MASK
);
8127 gen_helper_cr4_testbit(cpu_env
, cpu_tmp2_i32
);
8129 base
= cpu_seg_base
[modrm
& 8 ? R_GS
: R_FS
];
8130 treg
= cpu_regs
[(modrm
& 7) | REX_B(s
)];
8134 dst
= base
, src
= treg
;
8137 dst
= treg
, src
= base
;
8140 if (s
->dflag
== MO_32
) {
8141 tcg_gen_ext32u_tl(dst
, src
);
8143 tcg_gen_mov_tl(dst
, src
);
8149 case 0xf8: /* sfence / pcommit */
8150 if (prefixes
& PREFIX_DATA
) {
8152 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_PCOMMIT
)
8153 || (prefixes
& PREFIX_LOCK
)) {
8159 case 0xf9 ... 0xff: /* sfence */
8160 if (!(s
->cpuid_features
& CPUID_SSE
)
8161 || (prefixes
& PREFIX_LOCK
)) {
8164 tcg_gen_mb(TCG_MO_ST_ST
| TCG_BAR_SC
);
8166 case 0xe8 ... 0xef: /* lfence */
8167 if (!(s
->cpuid_features
& CPUID_SSE
)
8168 || (prefixes
& PREFIX_LOCK
)) {
8171 tcg_gen_mb(TCG_MO_LD_LD
| TCG_BAR_SC
);
8173 case 0xf0 ... 0xf7: /* mfence */
8174 if (!(s
->cpuid_features
& CPUID_SSE2
)
8175 || (prefixes
& PREFIX_LOCK
)) {
8178 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8186 case 0x10d: /* 3DNow! prefetch(w) */
8187 modrm
= cpu_ldub_code(env
, s
->pc
++);
8188 mod
= (modrm
>> 6) & 3;
8191 gen_nop_modrm(env
, s
, modrm
);
8193 case 0x1aa: /* rsm */
8194 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_RSM
);
8195 if (!(s
->flags
& HF_SMM_MASK
))
8197 gen_update_cc_op(s
);
8198 gen_jmp_im(s
->pc
- s
->cs_base
);
8199 gen_helper_rsm(cpu_env
);
8202 case 0x1b8: /* SSE4.2 popcnt */
8203 if ((prefixes
& (PREFIX_REPZ
| PREFIX_LOCK
| PREFIX_REPNZ
)) !=
8206 if (!(s
->cpuid_ext_features
& CPUID_EXT_POPCNT
))
8209 modrm
= cpu_ldub_code(env
, s
->pc
++);
8210 reg
= ((modrm
>> 3) & 7) | rex_r
;
8212 if (s
->prefix
& PREFIX_DATA
) {
8215 ot
= mo_64_32(dflag
);
8218 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
8219 gen_extu(ot
, cpu_T0
);
8220 tcg_gen_mov_tl(cpu_cc_src
, cpu_T0
);
8221 tcg_gen_ctpop_tl(cpu_T0
, cpu_T0
);
8222 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
8224 set_cc_op(s
, CC_OP_POPCNT
);
8226 case 0x10e ... 0x10f:
8227 /* 3DNow! instructions, ignore prefixes */
8228 s
->prefix
&= ~(PREFIX_REPZ
| PREFIX_REPNZ
| PREFIX_DATA
);
8229 case 0x110 ... 0x117:
8230 case 0x128 ... 0x12f:
8231 case 0x138 ... 0x13a:
8232 case 0x150 ... 0x179:
8233 case 0x17c ... 0x17f:
8235 case 0x1c4 ... 0x1c6:
8236 case 0x1d0 ... 0x1fe:
8237 gen_sse(env
, s
, b
, pc_start
, rex_r
);
8244 gen_illegal_opcode(s
);
8247 gen_unknown_opcode(env
, s
);
8251 void tcg_x86_init(void)
8253 static const char reg_names
[CPU_NB_REGS
][4] = {
8254 #ifdef TARGET_X86_64
8282 static const char seg_base_names
[6][8] = {
8290 static const char bnd_regl_names
[4][8] = {
8291 "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb"
8293 static const char bnd_regu_names
[4][8] = {
8294 "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub"
8297 static bool initialized
;
8304 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
8305 tcg_ctx
.tcg_env
= cpu_env
;
8306 cpu_cc_op
= tcg_global_mem_new_i32(cpu_env
,
8307 offsetof(CPUX86State
, cc_op
), "cc_op");
8308 cpu_cc_dst
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_dst
),
8310 cpu_cc_src
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_src
),
8312 cpu_cc_src2
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_src2
),
8315 for (i
= 0; i
< CPU_NB_REGS
; ++i
) {
8316 cpu_regs
[i
] = tcg_global_mem_new(cpu_env
,
8317 offsetof(CPUX86State
, regs
[i
]),
8321 for (i
= 0; i
< 6; ++i
) {
8323 = tcg_global_mem_new(cpu_env
,
8324 offsetof(CPUX86State
, segs
[i
].base
),
8328 for (i
= 0; i
< 4; ++i
) {
8330 = tcg_global_mem_new_i64(cpu_env
,
8331 offsetof(CPUX86State
, bnd_regs
[i
].lb
),
8334 = tcg_global_mem_new_i64(cpu_env
,
8335 offsetof(CPUX86State
, bnd_regs
[i
].ub
),
8340 /* generate intermediate code for basic block 'tb'. */
8341 void gen_intermediate_code(CPUX86State
*env
, TranslationBlock
*tb
)
8343 X86CPU
*cpu
= x86_env_get_cpu(env
);
8344 CPUState
*cs
= CPU(cpu
);
8345 DisasContext dc1
, *dc
= &dc1
;
8346 target_ulong pc_ptr
;
8348 target_ulong pc_start
;
8349 target_ulong cs_base
;
8353 /* generate intermediate code */
8355 cs_base
= tb
->cs_base
;
8358 dc
->pe
= (flags
>> HF_PE_SHIFT
) & 1;
8359 dc
->code32
= (flags
>> HF_CS32_SHIFT
) & 1;
8360 dc
->ss32
= (flags
>> HF_SS32_SHIFT
) & 1;
8361 dc
->addseg
= (flags
>> HF_ADDSEG_SHIFT
) & 1;
8363 dc
->vm86
= (flags
>> VM_SHIFT
) & 1;
8364 dc
->cpl
= (flags
>> HF_CPL_SHIFT
) & 3;
8365 dc
->iopl
= (flags
>> IOPL_SHIFT
) & 3;
8366 dc
->tf
= (flags
>> TF_SHIFT
) & 1;
8367 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
8368 dc
->cc_op
= CC_OP_DYNAMIC
;
8369 dc
->cc_op_dirty
= false;
8370 dc
->cs_base
= cs_base
;
8372 dc
->popl_esp_hack
= 0;
8373 /* select memory access functions */
8375 #ifdef CONFIG_SOFTMMU
8376 dc
->mem_index
= cpu_mmu_index(env
, false);
8378 dc
->cpuid_features
= env
->features
[FEAT_1_EDX
];
8379 dc
->cpuid_ext_features
= env
->features
[FEAT_1_ECX
];
8380 dc
->cpuid_ext2_features
= env
->features
[FEAT_8000_0001_EDX
];
8381 dc
->cpuid_ext3_features
= env
->features
[FEAT_8000_0001_ECX
];
8382 dc
->cpuid_7_0_ebx_features
= env
->features
[FEAT_7_0_EBX
];
8383 dc
->cpuid_xsave_features
= env
->features
[FEAT_XSAVE
];
8384 #ifdef TARGET_X86_64
8385 dc
->lma
= (flags
>> HF_LMA_SHIFT
) & 1;
8386 dc
->code64
= (flags
>> HF_CS64_SHIFT
) & 1;
8389 dc
->jmp_opt
= !(dc
->tf
|| cs
->singlestep_enabled
||
8390 (flags
& HF_INHIBIT_IRQ_MASK
));
8391 /* Do not optimize repz jumps at all in icount mode, because
8392 rep movsS instructions are execured with different paths
8393 in !repz_opt and repz_opt modes. The first one was used
8394 always except single step mode. And this setting
8395 disables jumps optimization and control paths become
8396 equivalent in run and single step modes.
8397 Now there will be no jump optimization for repz in
8398 record/replay modes and there will always be an
8399 additional step for ecx=0 when icount is enabled.
8401 dc
->repz_opt
= !dc
->jmp_opt
&& !(tb
->cflags
& CF_USE_ICOUNT
);
8403 /* check addseg logic */
8404 if (!dc
->addseg
&& (dc
->vm86
|| !dc
->pe
|| !dc
->code32
))
8405 printf("ERROR addseg\n");
8408 cpu_T0
= tcg_temp_new();
8409 cpu_T1
= tcg_temp_new();
8410 cpu_A0
= tcg_temp_new();
8412 cpu_tmp0
= tcg_temp_new();
8413 cpu_tmp1_i64
= tcg_temp_new_i64();
8414 cpu_tmp2_i32
= tcg_temp_new_i32();
8415 cpu_tmp3_i32
= tcg_temp_new_i32();
8416 cpu_tmp4
= tcg_temp_new();
8417 cpu_ptr0
= tcg_temp_new_ptr();
8418 cpu_ptr1
= tcg_temp_new_ptr();
8419 cpu_cc_srcT
= tcg_temp_local_new();
8421 dc
->is_jmp
= DISAS_NEXT
;
8424 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
8425 if (max_insns
== 0) {
8426 max_insns
= CF_COUNT_MASK
;
8428 if (max_insns
> TCG_MAX_INSNS
) {
8429 max_insns
= TCG_MAX_INSNS
;
8434 #if defined(CONFIG_USER_ONLY) && defined(TARGET_X86_64)
8435 /* Detect vsyscall */
8436 if (unlikely(pc_ptr
>= TARGET_VSYSCALL_START
8437 && pc_ptr
< TARGET_VSYSCALL_END
)) {
8438 gen_helper_vsyscall(cpu_env
);
8443 tcg_gen_insn_start(pc_ptr
, dc
->cc_op
);
8446 /* If RF is set, suppress an internally generated breakpoint. */
8447 if (unlikely(cpu_breakpoint_test(cs
, pc_ptr
,
8448 tb
->flags
& HF_RF_MASK
8449 ? BP_GDB
: BP_ANY
))) {
8450 gen_debug(dc
, pc_ptr
- dc
->cs_base
);
8451 /* The address covered by the breakpoint must be included in
8452 [tb->pc, tb->pc + tb->size) in order to for it to be
8453 properly cleared -- thus we increment the PC here so that
8454 the logic setting tb->size below does the right thing. */
8456 goto done_generating
;
8458 if (num_insns
== max_insns
&& (tb
->cflags
& CF_LAST_IO
)) {
8462 pc_ptr
= disas_insn(env
, dc
, pc_ptr
);
8463 /* stop translation if indicated */
8466 /* if single step mode, we generate only one instruction and
8467 generate an exception */
8468 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
8469 the flag and abort the translation to give the irqs a
8470 change to be happen */
8471 if (dc
->tf
|| dc
->singlestep_enabled
||
8472 (flags
& HF_INHIBIT_IRQ_MASK
)) {
8473 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8477 /* Do not cross the boundary of the pages in icount mode,
8478 it can cause an exception. Do it only when boundary is
8479 crossed by the first instruction in the block.
8480 If current instruction already crossed the bound - it's ok,
8481 because an exception hasn't stopped this code.
8483 if ((tb
->cflags
& CF_USE_ICOUNT
)
8484 && ((pc_ptr
& TARGET_PAGE_MASK
)
8485 != ((pc_ptr
+ TARGET_MAX_INSN_SIZE
- 1) & TARGET_PAGE_MASK
)
8486 || (pc_ptr
& ~TARGET_PAGE_MASK
) == 0)) {
8487 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8491 /* if too long translation, stop generation too */
8492 if (tcg_op_buf_full() ||
8493 (pc_ptr
- pc_start
) >= (TARGET_PAGE_SIZE
- 32) ||
8494 num_insns
>= max_insns
) {
8495 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8500 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8505 if (tb
->cflags
& CF_LAST_IO
)
8508 gen_tb_end(tb
, num_insns
);
8511 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)
8512 && qemu_log_in_addr_range(pc_start
)) {
8515 qemu_log("----------------\n");
8516 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
8517 #ifdef TARGET_X86_64
8522 disas_flags
= !dc
->code32
;
8523 log_target_disas(cs
, pc_start
, pc_ptr
- pc_start
, disas_flags
);
8529 tb
->size
= pc_ptr
- pc_start
;
8530 tb
->icount
= num_insns
;
8533 void restore_state_to_opc(CPUX86State
*env
, TranslationBlock
*tb
,
8536 int cc_op
= data
[1];
8537 env
->eip
= data
[0] - tb
->cs_base
;
8538 if (cc_op
!= CC_OP_DYNAMIC
) {