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"
27 #include "exec/translator.h"
29 #include "exec/helper-proto.h"
30 #include "exec/helper-gen.h"
32 #include "trace-tcg.h"
35 #define PREFIX_REPZ 0x01
36 #define PREFIX_REPNZ 0x02
37 #define PREFIX_LOCK 0x04
38 #define PREFIX_DATA 0x08
39 #define PREFIX_ADR 0x10
40 #define PREFIX_VEX 0x20
43 #define CODE64(s) ((s)->code64)
44 #define REX_X(s) ((s)->rex_x)
45 #define REX_B(s) ((s)->rex_b)
60 /* For a switch indexed by MODRM, match all memory operands for a given OP. */
61 #define CASE_MODRM_MEM_OP(OP) \
62 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
63 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
64 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7
66 #define CASE_MODRM_OP(OP) \
67 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
68 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
69 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7: \
70 case (3 << 6) | (OP << 3) | 0 ... (3 << 6) | (OP << 3) | 7
72 //#define MACRO_TEST 1
74 /* global register indexes */
75 static TCGv cpu_cc_dst
, cpu_cc_src
, cpu_cc_src2
;
76 static TCGv_i32 cpu_cc_op
;
77 static TCGv cpu_regs
[CPU_NB_REGS
];
78 static TCGv cpu_seg_base
[6];
79 static TCGv_i64 cpu_bndl
[4];
80 static TCGv_i64 cpu_bndu
[4];
83 /* local register indexes (only used inside old micro ops) */
84 static TCGv cpu_tmp0
, cpu_tmp4
;
85 static TCGv_ptr cpu_ptr0
, cpu_ptr1
;
86 static TCGv_i32 cpu_tmp2_i32
, cpu_tmp3_i32
;
87 static TCGv_i64 cpu_tmp1_i64
;
89 #include "exec/gen-icount.h"
92 static int x86_64_hregs
;
95 typedef struct DisasContext
{
96 DisasContextBase base
;
98 /* current insn context */
99 int override
; /* -1 if no override */
103 target_ulong pc_start
;
104 target_ulong pc
; /* pc = eip + cs_base */
105 /* current block context */
106 target_ulong cs_base
; /* base of CS segment */
107 int pe
; /* protected mode */
108 int code32
; /* 32 bit code segment */
110 int lma
; /* long mode active */
111 int code64
; /* 64 bit code segment */
114 int vex_l
; /* vex vector length */
115 int vex_v
; /* vex vvvv register, without 1's complement. */
116 int ss32
; /* 32 bit stack segment */
117 CCOp cc_op
; /* current CC operation */
119 int addseg
; /* non zero if either DS/ES/SS have a non zero base */
120 int f_st
; /* currently unused */
121 int vm86
; /* vm86 mode */
124 int tf
; /* TF cpu flag */
125 int jmp_opt
; /* use direct block chaining for direct jumps */
126 int repz_opt
; /* optimize jumps within repz instructions */
127 int mem_index
; /* select memory access functions */
128 uint64_t flags
; /* all execution flags */
129 int popl_esp_hack
; /* for correct popl with esp base handling */
130 int rip_offset
; /* only used in x86_64, but left for simplicity */
132 int cpuid_ext_features
;
133 int cpuid_ext2_features
;
134 int cpuid_ext3_features
;
135 int cpuid_7_0_ebx_features
;
136 int cpuid_xsave_features
;
138 /* TCG local temps */
146 static void gen_eob(DisasContext
*s
);
147 static void gen_jr(DisasContext
*s
, TCGv dest
);
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(s
->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(s
->A0
, s
->A0
, val
);
401 tcg_gen_ext32u_tl(s
->A0
, s
->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(DisasContext
*s
, TCGMemOp size
, int reg
)
418 tcg_gen_add_tl(cpu_tmp0
, cpu_regs
[reg
], s
->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
, s
->T0
, s
->A0
);
437 gen_op_mov_reg_v(idx
, d
, s
->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(s
->A0
, a0
);
464 if (ovr_seg
< 0 && s
->addseg
) {
468 tcg_gen_ext32u_tl(s
->A0
, a0
);
474 tcg_gen_ext16u_tl(s
->A0
, a0
);
489 TCGv seg
= cpu_seg_base
[ovr_seg
];
491 if (aflag
== MO_64
) {
492 tcg_gen_add_tl(s
->A0
, a0
, seg
);
493 } else if (CODE64(s
)) {
494 tcg_gen_ext32u_tl(s
->A0
, a0
);
495 tcg_gen_add_tl(s
->A0
, s
->A0
, seg
);
497 tcg_gen_add_tl(s
->A0
, a0
, seg
);
498 tcg_gen_ext32u_tl(s
->A0
, s
->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(DisasContext
*s
, TCGMemOp ot
)
515 tcg_gen_ld32s_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, df
));
516 tcg_gen_shli_tl(s
->T0
, s
->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
, s
->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
, s
->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
, s
->T0
, s
->A0
);
645 gen_string_movl_A0_EDI(s
);
646 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
647 gen_op_movl_T0_Dshift(s
, ot
);
648 gen_op_add_reg_T0(s
, s
->aflag
, R_ESI
);
649 gen_op_add_reg_T0(s
, s
->aflag
, R_EDI
);
652 static void gen_op_update1_cc(DisasContext
*s
)
654 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
657 static void gen_op_update2_cc(DisasContext
*s
)
659 tcg_gen_mov_tl(cpu_cc_src
, cpu_T1
);
660 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
663 static void gen_op_update3_cc(DisasContext
*s
, 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
, s
->T0
);
670 static inline void gen_op_testl_T0_T1_cc(DisasContext
*s
)
672 tcg_gen_and_tl(cpu_cc_dst
, s
->T0
, cpu_T1
);
675 static void gen_op_update_neg_cc(DisasContext
*s
)
677 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
678 tcg_gen_neg_tl(cpu_cc_src
, s
->T0
);
679 tcg_gen_movi_tl(s
->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
= t1
== cpu_cc_src
? cpu_tmp0
: reg
;
750 tcg_gen_mov_tl(t0
, s
->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
, s
->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
, s
->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 (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 (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
, s
->T0
);
1028 if (cc
.mask
!= -1) {
1029 tcg_gen_andi_tl(s
->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
, s
->T0
);
1046 gen_update_cc_op(s
);
1047 if (cc
.mask
!= -1) {
1048 tcg_gen_andi_tl(s
->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
, s
->T0
, R_EAX
);
1075 gen_string_movl_A0_EDI(s
);
1076 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
1077 gen_op_movl_T0_Dshift(s
, ot
);
1078 gen_op_add_reg_T0(s
, 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
, s
->T0
, s
->A0
);
1085 gen_op_mov_reg_v(ot
, R_EAX
, s
->T0
);
1086 gen_op_movl_T0_Dshift(s
, ot
);
1087 gen_op_add_reg_T0(s
, 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
, s
->A0
);
1094 gen_op(s
, OP_CMPL
, ot
, R_EAX
);
1095 gen_op_movl_T0_Dshift(s
, ot
);
1096 gen_op_add_reg_T0(s
, 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
, s
->A0
);
1103 gen_string_movl_A0_ESI(s
);
1104 gen_op(s
, OP_CMPL
, ot
, OR_TMP0
);
1105 gen_op_movl_T0_Dshift(s
, ot
);
1106 gen_op_add_reg_T0(s
, s
->aflag
, R_ESI
);
1107 gen_op_add_reg_T0(s
, 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 (tb_cflags(s
->base
.tb
) & 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(s
->T0
, 0);
1132 gen_op_st_v(s
, ot
, s
->T0
, s
->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
, s
->T0
, cpu_tmp2_i32
);
1136 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
1137 gen_op_movl_T0_Dshift(s
, ot
);
1138 gen_op_add_reg_T0(s
, s
->aflag
, R_EDI
);
1139 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
1140 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
1145 static inline void gen_outs(DisasContext
*s
, TCGMemOp ot
)
1147 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
1150 gen_string_movl_A0_ESI(s
);
1151 gen_op_ld_v(s
, ot
, s
->T0
, s
->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
, s
->T0
);
1156 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1157 gen_op_movl_T0_Dshift(s
, ot
);
1158 gen_op_add_reg_T0(s
, s
->aflag
, R_ESI
);
1159 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
1160 if (tb_cflags(s
->base
.tb
) & 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
, s1
->T0
, d
);
1270 } else if (!(s1
->prefix
& PREFIX_LOCK
)) {
1271 gen_op_ld_v(s1
, ot
, s1
->T0
, s1
->A0
);
1275 gen_compute_eflags_c(s1
, cpu_tmp4
);
1276 if (s1
->prefix
& PREFIX_LOCK
) {
1277 tcg_gen_add_tl(s1
->T0
, cpu_tmp4
, cpu_T1
);
1278 tcg_gen_atomic_add_fetch_tl(s1
->T0
, s1
->A0
, s1
->T0
,
1279 s1
->mem_index
, ot
| MO_LE
);
1281 tcg_gen_add_tl(s1
->T0
, s1
->T0
, cpu_T1
);
1282 tcg_gen_add_tl(s1
->T0
, s1
->T0
, cpu_tmp4
);
1283 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1285 gen_op_update3_cc(s1
, 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(s1
->T0
, cpu_T1
, cpu_tmp4
);
1292 tcg_gen_neg_tl(s1
->T0
, s1
->T0
);
1293 tcg_gen_atomic_add_fetch_tl(s1
->T0
, s1
->A0
, s1
->T0
,
1294 s1
->mem_index
, ot
| MO_LE
);
1296 tcg_gen_sub_tl(s1
->T0
, s1
->T0
, cpu_T1
);
1297 tcg_gen_sub_tl(s1
->T0
, s1
->T0
, cpu_tmp4
);
1298 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1300 gen_op_update3_cc(s1
, cpu_tmp4
);
1301 set_cc_op(s1
, CC_OP_SBBB
+ ot
);
1304 if (s1
->prefix
& PREFIX_LOCK
) {
1305 tcg_gen_atomic_add_fetch_tl(s1
->T0
, s1
->A0
, cpu_T1
,
1306 s1
->mem_index
, ot
| MO_LE
);
1308 tcg_gen_add_tl(s1
->T0
, s1
->T0
, cpu_T1
);
1309 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1311 gen_op_update2_cc(s1
);
1312 set_cc_op(s1
, CC_OP_ADDB
+ ot
);
1315 if (s1
->prefix
& PREFIX_LOCK
) {
1316 tcg_gen_neg_tl(s1
->T0
, cpu_T1
);
1317 tcg_gen_atomic_fetch_add_tl(s1
->cc_srcT
, s1
->A0
, s1
->T0
,
1318 s1
->mem_index
, ot
| MO_LE
);
1319 tcg_gen_sub_tl(s1
->T0
, s1
->cc_srcT
, cpu_T1
);
1321 tcg_gen_mov_tl(s1
->cc_srcT
, s1
->T0
);
1322 tcg_gen_sub_tl(s1
->T0
, s1
->T0
, cpu_T1
);
1323 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1325 gen_op_update2_cc(s1
);
1326 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1330 if (s1
->prefix
& PREFIX_LOCK
) {
1331 tcg_gen_atomic_and_fetch_tl(s1
->T0
, s1
->A0
, cpu_T1
,
1332 s1
->mem_index
, ot
| MO_LE
);
1334 tcg_gen_and_tl(s1
->T0
, s1
->T0
, cpu_T1
);
1335 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1337 gen_op_update1_cc(s1
);
1338 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1341 if (s1
->prefix
& PREFIX_LOCK
) {
1342 tcg_gen_atomic_or_fetch_tl(s1
->T0
, s1
->A0
, cpu_T1
,
1343 s1
->mem_index
, ot
| MO_LE
);
1345 tcg_gen_or_tl(s1
->T0
, s1
->T0
, cpu_T1
);
1346 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1348 gen_op_update1_cc(s1
);
1349 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1352 if (s1
->prefix
& PREFIX_LOCK
) {
1353 tcg_gen_atomic_xor_fetch_tl(s1
->T0
, s1
->A0
, cpu_T1
,
1354 s1
->mem_index
, ot
| MO_LE
);
1356 tcg_gen_xor_tl(s1
->T0
, s1
->T0
, cpu_T1
);
1357 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1359 gen_op_update1_cc(s1
);
1360 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1363 tcg_gen_mov_tl(cpu_cc_src
, cpu_T1
);
1364 tcg_gen_mov_tl(s1
->cc_srcT
, s1
->T0
);
1365 tcg_gen_sub_tl(cpu_cc_dst
, s1
->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(s1
->T0
, c
> 0 ? 1 : -1);
1376 tcg_gen_atomic_add_fetch_tl(s1
->T0
, s1
->A0
, s1
->T0
,
1377 s1
->mem_index
, ot
| MO_LE
);
1380 gen_op_mov_v_reg(ot
, s1
->T0
, d
);
1382 gen_op_ld_v(s1
, ot
, s1
->T0
, s1
->A0
);
1384 tcg_gen_addi_tl(s1
->T0
, s1
->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
, s1
->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
, s
->T0
, s
->A0
);
1447 gen_op_mov_v_reg(ot
, s
->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
, s
->T0
);
1456 tcg_gen_sar_tl(cpu_tmp0
, s
->T0
, cpu_tmp0
);
1457 tcg_gen_sar_tl(s
->T0
, s
->T0
, cpu_T1
);
1459 gen_extu(ot
, s
->T0
);
1460 tcg_gen_shr_tl(cpu_tmp0
, s
->T0
, cpu_tmp0
);
1461 tcg_gen_shr_tl(s
->T0
, s
->T0
, cpu_T1
);
1464 tcg_gen_shl_tl(cpu_tmp0
, s
->T0
, cpu_tmp0
);
1465 tcg_gen_shl_tl(s
->T0
, s
->T0
, cpu_T1
);
1469 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1471 gen_shift_flags(s
, ot
, s
->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
, s
->T0
, s
->A0
);
1483 gen_op_mov_v_reg(ot
, s
->T0
, op1
);
1489 gen_exts(ot
, s
->T0
);
1490 tcg_gen_sari_tl(cpu_tmp4
, s
->T0
, op2
- 1);
1491 tcg_gen_sari_tl(s
->T0
, s
->T0
, op2
);
1493 gen_extu(ot
, s
->T0
);
1494 tcg_gen_shri_tl(cpu_tmp4
, s
->T0
, op2
- 1);
1495 tcg_gen_shri_tl(s
->T0
, s
->T0
, op2
);
1498 tcg_gen_shli_tl(cpu_tmp4
, s
->T0
, op2
- 1);
1499 tcg_gen_shli_tl(s
->T0
, s
->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
, s
->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
, s
->T0
, s
->A0
);
1523 gen_op_mov_v_reg(ot
, s
->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(s
->T0
, s
->T0
);
1532 tcg_gen_muli_tl(s
->T0
, s
->T0
, 0x01010101);
1535 /* Replicate the 16-bit input so that a 32-bit rotate works. */
1536 tcg_gen_deposit_tl(s
->T0
, s
->T0
, s
->T0
, 16, 16);
1539 #ifdef TARGET_X86_64
1541 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->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(s
->T0
, cpu_tmp2_i32
);
1553 tcg_gen_rotr_tl(s
->T0
, s
->T0
, cpu_T1
);
1555 tcg_gen_rotl_tl(s
->T0
, s
->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
, s
->T0
, mask
- 1);
1572 tcg_gen_shri_tl(cpu_cc_dst
, s
->T0
, mask
);
1573 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1575 tcg_gen_shri_tl(cpu_cc_src2
, s
->T0
, mask
);
1576 tcg_gen_andi_tl(cpu_cc_dst
, s
->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
, s
->T0
, s
->A0
);
1609 gen_op_mov_v_reg(ot
, s
->T0
, op1
);
1615 #ifdef TARGET_X86_64
1617 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->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(s
->T0
, cpu_tmp2_i32
);
1628 tcg_gen_rotri_tl(s
->T0
, s
->T0
, op2
);
1630 tcg_gen_rotli_tl(s
->T0
, s
->T0
, op2
);
1641 shift
= mask
+ 1 - shift
;
1643 gen_extu(ot
, s
->T0
);
1644 tcg_gen_shli_tl(cpu_tmp0
, s
->T0
, shift
);
1645 tcg_gen_shri_tl(s
->T0
, s
->T0
, mask
+ 1 - shift
);
1646 tcg_gen_or_tl(s
->T0
, s
->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
, s
->T0
, mask
- 1);
1664 tcg_gen_shri_tl(cpu_cc_dst
, s
->T0
, mask
);
1665 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1667 tcg_gen_shri_tl(cpu_cc_src2
, s
->T0
, mask
);
1668 tcg_gen_andi_tl(cpu_cc_dst
, s
->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
, s
->T0
, s
->A0
);
1687 gen_op_mov_v_reg(ot
, s
->T0
, op1
);
1692 gen_helper_rcrb(s
->T0
, cpu_env
, s
->T0
, cpu_T1
);
1695 gen_helper_rcrw(s
->T0
, cpu_env
, s
->T0
, cpu_T1
);
1698 gen_helper_rcrl(s
->T0
, cpu_env
, s
->T0
, cpu_T1
);
1700 #ifdef TARGET_X86_64
1702 gen_helper_rcrq(s
->T0
, cpu_env
, s
->T0
, cpu_T1
);
1711 gen_helper_rclb(s
->T0
, cpu_env
, s
->T0
, cpu_T1
);
1714 gen_helper_rclw(s
->T0
, cpu_env
, s
->T0
, cpu_T1
);
1717 gen_helper_rcll(s
->T0
, cpu_env
, s
->T0
, cpu_T1
);
1719 #ifdef TARGET_X86_64
1721 gen_helper_rclq(s
->T0
, cpu_env
, s
->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
, s
->T0
, s
->A0
);
1743 gen_op_mov_v_reg(ot
, s
->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
, s
->T0
, cpu_T1
, 16, 16);
1756 tcg_gen_mov_tl(cpu_T1
, s
->T0
);
1757 tcg_gen_mov_tl(s
->T0
, cpu_tmp0
);
1759 tcg_gen_deposit_tl(cpu_T1
, s
->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(s
->T0
, s
->T0
, cpu_T1
);
1768 tcg_gen_shr_i64(cpu_tmp0
, s
->T0
, cpu_tmp0
);
1769 tcg_gen_shr_i64(s
->T0
, s
->T0
, count
);
1771 tcg_gen_concat_tl_i64(s
->T0
, cpu_T1
, s
->T0
);
1772 tcg_gen_shl_i64(cpu_tmp0
, s
->T0
, cpu_tmp0
);
1773 tcg_gen_shl_i64(s
->T0
, s
->T0
, count
);
1774 tcg_gen_shri_i64(cpu_tmp0
, cpu_tmp0
, 32);
1775 tcg_gen_shri_i64(s
->T0
, s
->T0
, 32);
1780 tcg_gen_subi_tl(cpu_tmp0
, count
, 1);
1782 tcg_gen_shr_tl(cpu_tmp0
, s
->T0
, cpu_tmp0
);
1784 tcg_gen_subfi_tl(cpu_tmp4
, mask
+ 1, count
);
1785 tcg_gen_shr_tl(s
->T0
, s
->T0
, count
);
1786 tcg_gen_shl_tl(cpu_T1
, cpu_T1
, cpu_tmp4
);
1788 tcg_gen_shl_tl(cpu_tmp0
, s
->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(s
->T0
, s
->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(s
->T0
, s
->T0
, cpu_T1
);
1808 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1810 gen_shift_flags(s
, ot
, s
->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 #define X86_MAX_INSN_LENGTH 15
1873 static uint64_t advance_pc(CPUX86State
*env
, DisasContext
*s
, int num_bytes
)
1875 uint64_t pc
= s
->pc
;
1878 if (unlikely(s
->pc
- s
->pc_start
> X86_MAX_INSN_LENGTH
)) {
1879 /* If the instruction's 16th byte is on a different page than the 1st, a
1880 * page fault on the second page wins over the general protection fault
1881 * caused by the instruction being too long.
1882 * This can happen even if the operand is only one byte long!
1884 if (((s
->pc
- 1) ^ (pc
- 1)) & TARGET_PAGE_MASK
) {
1885 volatile uint8_t unused
=
1886 cpu_ldub_code(env
, (s
->pc
- 1) & TARGET_PAGE_MASK
);
1889 siglongjmp(s
->jmpbuf
, 1);
1895 static inline uint8_t x86_ldub_code(CPUX86State
*env
, DisasContext
*s
)
1897 return cpu_ldub_code(env
, advance_pc(env
, s
, 1));
1900 static inline int16_t x86_ldsw_code(CPUX86State
*env
, DisasContext
*s
)
1902 return cpu_ldsw_code(env
, advance_pc(env
, s
, 2));
1905 static inline uint16_t x86_lduw_code(CPUX86State
*env
, DisasContext
*s
)
1907 return cpu_lduw_code(env
, advance_pc(env
, s
, 2));
1910 static inline uint32_t x86_ldl_code(CPUX86State
*env
, DisasContext
*s
)
1912 return cpu_ldl_code(env
, advance_pc(env
, s
, 4));
1915 #ifdef TARGET_X86_64
1916 static inline uint64_t x86_ldq_code(CPUX86State
*env
, DisasContext
*s
)
1918 return cpu_ldq_code(env
, advance_pc(env
, s
, 8));
1922 /* Decompose an address. */
1924 typedef struct AddressParts
{
1932 static AddressParts
gen_lea_modrm_0(CPUX86State
*env
, DisasContext
*s
,
1935 int def_seg
, base
, index
, scale
, mod
, rm
;
1944 mod
= (modrm
>> 6) & 3;
1946 base
= rm
| REX_B(s
);
1949 /* Normally filtered out earlier, but including this path
1950 simplifies multi-byte nop, as well as bndcl, bndcu, bndcn. */
1959 int code
= x86_ldub_code(env
, s
);
1960 scale
= (code
>> 6) & 3;
1961 index
= ((code
>> 3) & 7) | REX_X(s
);
1963 index
= -1; /* no index */
1965 base
= (code
& 7) | REX_B(s
);
1971 if ((base
& 7) == 5) {
1973 disp
= (int32_t)x86_ldl_code(env
, s
);
1974 if (CODE64(s
) && !havesib
) {
1976 disp
+= s
->pc
+ s
->rip_offset
;
1981 disp
= (int8_t)x86_ldub_code(env
, s
);
1985 disp
= (int32_t)x86_ldl_code(env
, s
);
1989 /* For correct popl handling with esp. */
1990 if (base
== R_ESP
&& s
->popl_esp_hack
) {
1991 disp
+= s
->popl_esp_hack
;
1993 if (base
== R_EBP
|| base
== R_ESP
) {
2002 disp
= x86_lduw_code(env
, s
);
2005 } else if (mod
== 1) {
2006 disp
= (int8_t)x86_ldub_code(env
, s
);
2008 disp
= (int16_t)x86_lduw_code(env
, s
);
2052 return (AddressParts
){ def_seg
, base
, index
, scale
, disp
};
2055 /* Compute the address, with a minimum number of TCG ops. */
2056 static TCGv
gen_lea_modrm_1(DisasContext
*s
, AddressParts a
)
2062 ea
= cpu_regs
[a
.index
];
2064 tcg_gen_shli_tl(s
->A0
, cpu_regs
[a
.index
], a
.scale
);
2068 tcg_gen_add_tl(s
->A0
, ea
, cpu_regs
[a
.base
]);
2071 } else if (a
.base
>= 0) {
2072 ea
= cpu_regs
[a
.base
];
2075 tcg_gen_movi_tl(s
->A0
, a
.disp
);
2077 } else if (a
.disp
!= 0) {
2078 tcg_gen_addi_tl(s
->A0
, ea
, a
.disp
);
2085 static void gen_lea_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2087 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
2088 TCGv ea
= gen_lea_modrm_1(s
, a
);
2089 gen_lea_v_seg(s
, s
->aflag
, ea
, a
.def_seg
, s
->override
);
2092 static void gen_nop_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2094 (void)gen_lea_modrm_0(env
, s
, modrm
);
2097 /* Used for BNDCL, BNDCU, BNDCN. */
2098 static void gen_bndck(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2099 TCGCond cond
, TCGv_i64 bndv
)
2101 TCGv ea
= gen_lea_modrm_1(s
, gen_lea_modrm_0(env
, s
, modrm
));
2103 tcg_gen_extu_tl_i64(cpu_tmp1_i64
, ea
);
2105 tcg_gen_ext32u_i64(cpu_tmp1_i64
, cpu_tmp1_i64
);
2107 tcg_gen_setcond_i64(cond
, cpu_tmp1_i64
, cpu_tmp1_i64
, bndv
);
2108 tcg_gen_extrl_i64_i32(cpu_tmp2_i32
, cpu_tmp1_i64
);
2109 gen_helper_bndck(cpu_env
, cpu_tmp2_i32
);
2112 /* used for LEA and MOV AX, mem */
2113 static void gen_add_A0_ds_seg(DisasContext
*s
)
2115 gen_lea_v_seg(s
, s
->aflag
, s
->A0
, R_DS
, s
->override
);
2118 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2120 static void gen_ldst_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2121 TCGMemOp ot
, int reg
, int is_store
)
2125 mod
= (modrm
>> 6) & 3;
2126 rm
= (modrm
& 7) | REX_B(s
);
2130 gen_op_mov_v_reg(ot
, s
->T0
, reg
);
2131 gen_op_mov_reg_v(ot
, rm
, s
->T0
);
2133 gen_op_mov_v_reg(ot
, s
->T0
, rm
);
2135 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
2138 gen_lea_modrm(env
, s
, modrm
);
2141 gen_op_mov_v_reg(ot
, s
->T0
, reg
);
2142 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
2144 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
2146 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
2151 static inline uint32_t insn_get(CPUX86State
*env
, DisasContext
*s
, TCGMemOp ot
)
2157 ret
= x86_ldub_code(env
, s
);
2160 ret
= x86_lduw_code(env
, s
);
2163 #ifdef TARGET_X86_64
2166 ret
= x86_ldl_code(env
, s
);
2174 static inline int insn_const_size(TCGMemOp ot
)
2183 static inline bool use_goto_tb(DisasContext
*s
, target_ulong pc
)
2185 #ifndef CONFIG_USER_ONLY
2186 return (pc
& TARGET_PAGE_MASK
) == (s
->base
.tb
->pc
& TARGET_PAGE_MASK
) ||
2187 (pc
& TARGET_PAGE_MASK
) == (s
->pc_start
& TARGET_PAGE_MASK
);
2193 static inline void gen_goto_tb(DisasContext
*s
, int tb_num
, target_ulong eip
)
2195 target_ulong pc
= s
->cs_base
+ eip
;
2197 if (use_goto_tb(s
, pc
)) {
2198 /* jump to same page: we can use a direct jump */
2199 tcg_gen_goto_tb(tb_num
);
2201 tcg_gen_exit_tb(s
->base
.tb
, tb_num
);
2202 s
->base
.is_jmp
= DISAS_NORETURN
;
2204 /* jump to another page */
2206 gen_jr(s
, cpu_tmp0
);
2210 static inline void gen_jcc(DisasContext
*s
, int b
,
2211 target_ulong val
, target_ulong next_eip
)
2216 l1
= gen_new_label();
2219 gen_goto_tb(s
, 0, next_eip
);
2222 gen_goto_tb(s
, 1, val
);
2224 l1
= gen_new_label();
2225 l2
= gen_new_label();
2228 gen_jmp_im(next_eip
);
2238 static void gen_cmovcc1(CPUX86State
*env
, DisasContext
*s
, TCGMemOp ot
, int b
,
2243 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
2245 cc
= gen_prepare_cc(s
, b
, cpu_T1
);
2246 if (cc
.mask
!= -1) {
2247 TCGv t0
= tcg_temp_new();
2248 tcg_gen_andi_tl(t0
, cc
.reg
, cc
.mask
);
2252 cc
.reg2
= tcg_const_tl(cc
.imm
);
2255 tcg_gen_movcond_tl(cc
.cond
, s
->T0
, cc
.reg
, cc
.reg2
,
2256 s
->T0
, cpu_regs
[reg
]);
2257 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
2259 if (cc
.mask
!= -1) {
2260 tcg_temp_free(cc
.reg
);
2263 tcg_temp_free(cc
.reg2
);
2267 static inline void gen_op_movl_T0_seg(DisasContext
*s
, int seg_reg
)
2269 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
2270 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2273 static inline void gen_op_movl_seg_T0_vm(DisasContext
*s
, int seg_reg
)
2275 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
2276 tcg_gen_st32_tl(s
->T0
, cpu_env
,
2277 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2278 tcg_gen_shli_tl(cpu_seg_base
[seg_reg
], s
->T0
, 4);
2281 /* move T0 to seg_reg and compute if the CPU state may change. Never
2282 call this function with seg_reg == R_CS */
2283 static void gen_movl_seg_T0(DisasContext
*s
, int seg_reg
)
2285 if (s
->pe
&& !s
->vm86
) {
2286 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
2287 gen_helper_load_seg(cpu_env
, tcg_const_i32(seg_reg
), cpu_tmp2_i32
);
2288 /* abort translation because the addseg value may change or
2289 because ss32 may change. For R_SS, translation must always
2290 stop as a special handling must be done to disable hardware
2291 interrupts for the next instruction */
2292 if (seg_reg
== R_SS
|| (s
->code32
&& seg_reg
< R_FS
)) {
2293 s
->base
.is_jmp
= DISAS_TOO_MANY
;
2296 gen_op_movl_seg_T0_vm(s
, seg_reg
);
2297 if (seg_reg
== R_SS
) {
2298 s
->base
.is_jmp
= DISAS_TOO_MANY
;
2303 static inline int svm_is_rep(int prefixes
)
2305 return ((prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) ? 8 : 0);
2309 gen_svm_check_intercept_param(DisasContext
*s
, target_ulong pc_start
,
2310 uint32_t type
, uint64_t param
)
2312 /* no SVM activated; fast case */
2313 if (likely(!(s
->flags
& HF_SVMI_MASK
)))
2315 gen_update_cc_op(s
);
2316 gen_jmp_im(pc_start
- s
->cs_base
);
2317 gen_helper_svm_check_intercept_param(cpu_env
, tcg_const_i32(type
),
2318 tcg_const_i64(param
));
2322 gen_svm_check_intercept(DisasContext
*s
, target_ulong pc_start
, uint64_t type
)
2324 gen_svm_check_intercept_param(s
, pc_start
, type
, 0);
2327 static inline void gen_stack_update(DisasContext
*s
, int addend
)
2329 gen_op_add_reg_im(mo_stacksize(s
), R_ESP
, addend
);
2332 /* Generate a push. It depends on ss32, addseg and dflag. */
2333 static void gen_push_v(DisasContext
*s
, TCGv val
)
2335 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2336 TCGMemOp a_ot
= mo_stacksize(s
);
2337 int size
= 1 << d_ot
;
2338 TCGv new_esp
= s
->A0
;
2340 tcg_gen_subi_tl(s
->A0
, cpu_regs
[R_ESP
], size
);
2345 tcg_gen_mov_tl(new_esp
, s
->A0
);
2347 gen_lea_v_seg(s
, a_ot
, s
->A0
, R_SS
, -1);
2350 gen_op_st_v(s
, d_ot
, val
, s
->A0
);
2351 gen_op_mov_reg_v(a_ot
, R_ESP
, new_esp
);
2354 /* two step pop is necessary for precise exceptions */
2355 static TCGMemOp
gen_pop_T0(DisasContext
*s
)
2357 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2359 gen_lea_v_seg(s
, mo_stacksize(s
), cpu_regs
[R_ESP
], R_SS
, -1);
2360 gen_op_ld_v(s
, d_ot
, s
->T0
, s
->A0
);
2365 static inline void gen_pop_update(DisasContext
*s
, TCGMemOp ot
)
2367 gen_stack_update(s
, 1 << ot
);
2370 static inline void gen_stack_A0(DisasContext
*s
)
2372 gen_lea_v_seg(s
, s
->ss32
? MO_32
: MO_16
, cpu_regs
[R_ESP
], R_SS
, -1);
2375 static void gen_pusha(DisasContext
*s
)
2377 TCGMemOp s_ot
= s
->ss32
? MO_32
: MO_16
;
2378 TCGMemOp d_ot
= s
->dflag
;
2379 int size
= 1 << d_ot
;
2382 for (i
= 0; i
< 8; i
++) {
2383 tcg_gen_addi_tl(s
->A0
, cpu_regs
[R_ESP
], (i
- 8) * size
);
2384 gen_lea_v_seg(s
, s_ot
, s
->A0
, R_SS
, -1);
2385 gen_op_st_v(s
, d_ot
, cpu_regs
[7 - i
], s
->A0
);
2388 gen_stack_update(s
, -8 * size
);
2391 static void gen_popa(DisasContext
*s
)
2393 TCGMemOp s_ot
= s
->ss32
? MO_32
: MO_16
;
2394 TCGMemOp d_ot
= s
->dflag
;
2395 int size
= 1 << d_ot
;
2398 for (i
= 0; i
< 8; i
++) {
2399 /* ESP is not reloaded */
2400 if (7 - i
== R_ESP
) {
2403 tcg_gen_addi_tl(s
->A0
, cpu_regs
[R_ESP
], i
* size
);
2404 gen_lea_v_seg(s
, s_ot
, s
->A0
, R_SS
, -1);
2405 gen_op_ld_v(s
, d_ot
, s
->T0
, s
->A0
);
2406 gen_op_mov_reg_v(d_ot
, 7 - i
, s
->T0
);
2409 gen_stack_update(s
, 8 * size
);
2412 static void gen_enter(DisasContext
*s
, int esp_addend
, int level
)
2414 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2415 TCGMemOp a_ot
= CODE64(s
) ? MO_64
: s
->ss32
? MO_32
: MO_16
;
2416 int size
= 1 << d_ot
;
2418 /* Push BP; compute FrameTemp into T1. */
2419 tcg_gen_subi_tl(cpu_T1
, cpu_regs
[R_ESP
], size
);
2420 gen_lea_v_seg(s
, a_ot
, cpu_T1
, R_SS
, -1);
2421 gen_op_st_v(s
, d_ot
, cpu_regs
[R_EBP
], s
->A0
);
2427 /* Copy level-1 pointers from the previous frame. */
2428 for (i
= 1; i
< level
; ++i
) {
2429 tcg_gen_subi_tl(s
->A0
, cpu_regs
[R_EBP
], size
* i
);
2430 gen_lea_v_seg(s
, a_ot
, s
->A0
, R_SS
, -1);
2431 gen_op_ld_v(s
, d_ot
, cpu_tmp0
, s
->A0
);
2433 tcg_gen_subi_tl(s
->A0
, cpu_T1
, size
* i
);
2434 gen_lea_v_seg(s
, a_ot
, s
->A0
, R_SS
, -1);
2435 gen_op_st_v(s
, d_ot
, cpu_tmp0
, s
->A0
);
2438 /* Push the current FrameTemp as the last level. */
2439 tcg_gen_subi_tl(s
->A0
, cpu_T1
, size
* level
);
2440 gen_lea_v_seg(s
, a_ot
, s
->A0
, R_SS
, -1);
2441 gen_op_st_v(s
, d_ot
, cpu_T1
, s
->A0
);
2444 /* Copy the FrameTemp value to EBP. */
2445 gen_op_mov_reg_v(a_ot
, R_EBP
, cpu_T1
);
2447 /* Compute the final value of ESP. */
2448 tcg_gen_subi_tl(cpu_T1
, cpu_T1
, esp_addend
+ size
* level
);
2449 gen_op_mov_reg_v(a_ot
, R_ESP
, cpu_T1
);
2452 static void gen_leave(DisasContext
*s
)
2454 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2455 TCGMemOp a_ot
= mo_stacksize(s
);
2457 gen_lea_v_seg(s
, a_ot
, cpu_regs
[R_EBP
], R_SS
, -1);
2458 gen_op_ld_v(s
, d_ot
, s
->T0
, s
->A0
);
2460 tcg_gen_addi_tl(cpu_T1
, cpu_regs
[R_EBP
], 1 << d_ot
);
2462 gen_op_mov_reg_v(d_ot
, R_EBP
, s
->T0
);
2463 gen_op_mov_reg_v(a_ot
, R_ESP
, cpu_T1
);
2466 static void gen_exception(DisasContext
*s
, int trapno
, target_ulong cur_eip
)
2468 gen_update_cc_op(s
);
2469 gen_jmp_im(cur_eip
);
2470 gen_helper_raise_exception(cpu_env
, tcg_const_i32(trapno
));
2471 s
->base
.is_jmp
= DISAS_NORETURN
;
2474 /* Generate #UD for the current instruction. The assumption here is that
2475 the instruction is known, but it isn't allowed in the current cpu mode. */
2476 static void gen_illegal_opcode(DisasContext
*s
)
2478 gen_exception(s
, EXCP06_ILLOP
, s
->pc_start
- s
->cs_base
);
2481 /* Similarly, except that the assumption here is that we don't decode
2482 the instruction at all -- either a missing opcode, an unimplemented
2483 feature, or just a bogus instruction stream. */
2484 static void gen_unknown_opcode(CPUX86State
*env
, DisasContext
*s
)
2486 gen_illegal_opcode(s
);
2488 if (qemu_loglevel_mask(LOG_UNIMP
)) {
2489 target_ulong pc
= s
->pc_start
, end
= s
->pc
;
2491 qemu_log("ILLOPC: " TARGET_FMT_lx
":", pc
);
2492 for (; pc
< end
; ++pc
) {
2493 qemu_log(" %02x", cpu_ldub_code(env
, pc
));
2500 /* an interrupt is different from an exception because of the
2502 static void gen_interrupt(DisasContext
*s
, int intno
,
2503 target_ulong cur_eip
, target_ulong next_eip
)
2505 gen_update_cc_op(s
);
2506 gen_jmp_im(cur_eip
);
2507 gen_helper_raise_interrupt(cpu_env
, tcg_const_i32(intno
),
2508 tcg_const_i32(next_eip
- cur_eip
));
2509 s
->base
.is_jmp
= DISAS_NORETURN
;
2512 static void gen_debug(DisasContext
*s
, target_ulong cur_eip
)
2514 gen_update_cc_op(s
);
2515 gen_jmp_im(cur_eip
);
2516 gen_helper_debug(cpu_env
);
2517 s
->base
.is_jmp
= DISAS_NORETURN
;
2520 static void gen_set_hflag(DisasContext
*s
, uint32_t mask
)
2522 if ((s
->flags
& mask
) == 0) {
2523 TCGv_i32 t
= tcg_temp_new_i32();
2524 tcg_gen_ld_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2525 tcg_gen_ori_i32(t
, t
, mask
);
2526 tcg_gen_st_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2527 tcg_temp_free_i32(t
);
2532 static void gen_reset_hflag(DisasContext
*s
, uint32_t mask
)
2534 if (s
->flags
& mask
) {
2535 TCGv_i32 t
= tcg_temp_new_i32();
2536 tcg_gen_ld_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2537 tcg_gen_andi_i32(t
, t
, ~mask
);
2538 tcg_gen_st_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2539 tcg_temp_free_i32(t
);
2544 /* Clear BND registers during legacy branches. */
2545 static void gen_bnd_jmp(DisasContext
*s
)
2547 /* Clear the registers only if BND prefix is missing, MPX is enabled,
2548 and if the BNDREGs are known to be in use (non-zero) already.
2549 The helper itself will check BNDPRESERVE at runtime. */
2550 if ((s
->prefix
& PREFIX_REPNZ
) == 0
2551 && (s
->flags
& HF_MPX_EN_MASK
) != 0
2552 && (s
->flags
& HF_MPX_IU_MASK
) != 0) {
2553 gen_helper_bnd_jmp(cpu_env
);
2557 /* Generate an end of block. Trace exception is also generated if needed.
2558 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set.
2559 If RECHECK_TF, emit a rechecking helper for #DB, ignoring the state of
2560 S->TF. This is used by the syscall/sysret insns. */
2562 do_gen_eob_worker(DisasContext
*s
, bool inhibit
, bool recheck_tf
, bool jr
)
2564 gen_update_cc_op(s
);
2566 /* If several instructions disable interrupts, only the first does it. */
2567 if (inhibit
&& !(s
->flags
& HF_INHIBIT_IRQ_MASK
)) {
2568 gen_set_hflag(s
, HF_INHIBIT_IRQ_MASK
);
2570 gen_reset_hflag(s
, HF_INHIBIT_IRQ_MASK
);
2573 if (s
->base
.tb
->flags
& HF_RF_MASK
) {
2574 gen_helper_reset_rf(cpu_env
);
2576 if (s
->base
.singlestep_enabled
) {
2577 gen_helper_debug(cpu_env
);
2578 } else if (recheck_tf
) {
2579 gen_helper_rechecking_single_step(cpu_env
);
2580 tcg_gen_exit_tb(NULL
, 0);
2582 gen_helper_single_step(cpu_env
);
2584 tcg_gen_lookup_and_goto_ptr();
2586 tcg_gen_exit_tb(NULL
, 0);
2588 s
->base
.is_jmp
= DISAS_NORETURN
;
2592 gen_eob_worker(DisasContext
*s
, bool inhibit
, bool recheck_tf
)
2594 do_gen_eob_worker(s
, inhibit
, recheck_tf
, false);
2598 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set. */
2599 static void gen_eob_inhibit_irq(DisasContext
*s
, bool inhibit
)
2601 gen_eob_worker(s
, inhibit
, false);
2604 /* End of block, resetting the inhibit irq flag. */
2605 static void gen_eob(DisasContext
*s
)
2607 gen_eob_worker(s
, false, false);
2610 /* Jump to register */
2611 static void gen_jr(DisasContext
*s
, TCGv dest
)
2613 do_gen_eob_worker(s
, false, false, true);
2616 /* generate a jump to eip. No segment change must happen before as a
2617 direct call to the next block may occur */
2618 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
)
2620 gen_update_cc_op(s
);
2621 set_cc_op(s
, CC_OP_DYNAMIC
);
2623 gen_goto_tb(s
, tb_num
, eip
);
2630 static void gen_jmp(DisasContext
*s
, target_ulong eip
)
2632 gen_jmp_tb(s
, eip
, 0);
2635 static inline void gen_ldq_env_A0(DisasContext
*s
, int offset
)
2637 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, s
->A0
, s
->mem_index
, MO_LEQ
);
2638 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2641 static inline void gen_stq_env_A0(DisasContext
*s
, int offset
)
2643 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2644 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, s
->A0
, s
->mem_index
, MO_LEQ
);
2647 static inline void gen_ldo_env_A0(DisasContext
*s
, int offset
)
2649 int mem_index
= s
->mem_index
;
2650 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, s
->A0
, mem_index
, MO_LEQ
);
2651 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2652 tcg_gen_addi_tl(cpu_tmp0
, s
->A0
, 8);
2653 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
, MO_LEQ
);
2654 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2657 static inline void gen_sto_env_A0(DisasContext
*s
, int offset
)
2659 int mem_index
= s
->mem_index
;
2660 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2661 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, s
->A0
, mem_index
, MO_LEQ
);
2662 tcg_gen_addi_tl(cpu_tmp0
, s
->A0
, 8);
2663 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2664 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
, MO_LEQ
);
2667 static inline void gen_op_movo(int d_offset
, int s_offset
)
2669 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2670 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2671 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2672 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2675 static inline void gen_op_movq(int d_offset
, int s_offset
)
2677 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
);
2678 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2681 static inline void gen_op_movl(int d_offset
, int s_offset
)
2683 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
, s_offset
);
2684 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, d_offset
);
2687 static inline void gen_op_movq_env_0(int d_offset
)
2689 tcg_gen_movi_i64(cpu_tmp1_i64
, 0);
2690 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2693 typedef void (*SSEFunc_i_ep
)(TCGv_i32 val
, TCGv_ptr env
, TCGv_ptr reg
);
2694 typedef void (*SSEFunc_l_ep
)(TCGv_i64 val
, TCGv_ptr env
, TCGv_ptr reg
);
2695 typedef void (*SSEFunc_0_epi
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i32 val
);
2696 typedef void (*SSEFunc_0_epl
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i64 val
);
2697 typedef void (*SSEFunc_0_epp
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
);
2698 typedef void (*SSEFunc_0_eppi
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2700 typedef void (*SSEFunc_0_ppi
)(TCGv_ptr reg_a
, TCGv_ptr reg_b
, TCGv_i32 val
);
2701 typedef void (*SSEFunc_0_eppt
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2704 #define SSE_SPECIAL ((void *)1)
2705 #define SSE_DUMMY ((void *)2)
2707 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2708 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2709 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2711 static const SSEFunc_0_epp sse_op_table1
[256][4] = {
2712 /* 3DNow! extensions */
2713 [0x0e] = { SSE_DUMMY
}, /* femms */
2714 [0x0f] = { SSE_DUMMY
}, /* pf... */
2715 /* pure SSE operations */
2716 [0x10] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2717 [0x11] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2718 [0x12] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd, movsldup, movddup */
2719 [0x13] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd */
2720 [0x14] = { gen_helper_punpckldq_xmm
, gen_helper_punpcklqdq_xmm
},
2721 [0x15] = { gen_helper_punpckhdq_xmm
, gen_helper_punpckhqdq_xmm
},
2722 [0x16] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd, movshdup */
2723 [0x17] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd */
2725 [0x28] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2726 [0x29] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2727 [0x2a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2728 [0x2b] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movntps, movntpd, movntss, movntsd */
2729 [0x2c] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2730 [0x2d] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2731 [0x2e] = { gen_helper_ucomiss
, gen_helper_ucomisd
},
2732 [0x2f] = { gen_helper_comiss
, gen_helper_comisd
},
2733 [0x50] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movmskps, movmskpd */
2734 [0x51] = SSE_FOP(sqrt
),
2735 [0x52] = { gen_helper_rsqrtps
, NULL
, gen_helper_rsqrtss
, NULL
},
2736 [0x53] = { gen_helper_rcpps
, NULL
, gen_helper_rcpss
, NULL
},
2737 [0x54] = { gen_helper_pand_xmm
, gen_helper_pand_xmm
}, /* andps, andpd */
2738 [0x55] = { gen_helper_pandn_xmm
, gen_helper_pandn_xmm
}, /* andnps, andnpd */
2739 [0x56] = { gen_helper_por_xmm
, gen_helper_por_xmm
}, /* orps, orpd */
2740 [0x57] = { gen_helper_pxor_xmm
, gen_helper_pxor_xmm
}, /* xorps, xorpd */
2741 [0x58] = SSE_FOP(add
),
2742 [0x59] = SSE_FOP(mul
),
2743 [0x5a] = { gen_helper_cvtps2pd
, gen_helper_cvtpd2ps
,
2744 gen_helper_cvtss2sd
, gen_helper_cvtsd2ss
},
2745 [0x5b] = { gen_helper_cvtdq2ps
, gen_helper_cvtps2dq
, gen_helper_cvttps2dq
},
2746 [0x5c] = SSE_FOP(sub
),
2747 [0x5d] = SSE_FOP(min
),
2748 [0x5e] = SSE_FOP(div
),
2749 [0x5f] = SSE_FOP(max
),
2751 [0xc2] = SSE_FOP(cmpeq
),
2752 [0xc6] = { (SSEFunc_0_epp
)gen_helper_shufps
,
2753 (SSEFunc_0_epp
)gen_helper_shufpd
}, /* XXX: casts */
2755 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */
2756 [0x38] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2757 [0x3a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2759 /* MMX ops and their SSE extensions */
2760 [0x60] = MMX_OP2(punpcklbw
),
2761 [0x61] = MMX_OP2(punpcklwd
),
2762 [0x62] = MMX_OP2(punpckldq
),
2763 [0x63] = MMX_OP2(packsswb
),
2764 [0x64] = MMX_OP2(pcmpgtb
),
2765 [0x65] = MMX_OP2(pcmpgtw
),
2766 [0x66] = MMX_OP2(pcmpgtl
),
2767 [0x67] = MMX_OP2(packuswb
),
2768 [0x68] = MMX_OP2(punpckhbw
),
2769 [0x69] = MMX_OP2(punpckhwd
),
2770 [0x6a] = MMX_OP2(punpckhdq
),
2771 [0x6b] = MMX_OP2(packssdw
),
2772 [0x6c] = { NULL
, gen_helper_punpcklqdq_xmm
},
2773 [0x6d] = { NULL
, gen_helper_punpckhqdq_xmm
},
2774 [0x6e] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movd mm, ea */
2775 [0x6f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, , movqdu */
2776 [0x70] = { (SSEFunc_0_epp
)gen_helper_pshufw_mmx
,
2777 (SSEFunc_0_epp
)gen_helper_pshufd_xmm
,
2778 (SSEFunc_0_epp
)gen_helper_pshufhw_xmm
,
2779 (SSEFunc_0_epp
)gen_helper_pshuflw_xmm
}, /* XXX: casts */
2780 [0x71] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftw */
2781 [0x72] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftd */
2782 [0x73] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftq */
2783 [0x74] = MMX_OP2(pcmpeqb
),
2784 [0x75] = MMX_OP2(pcmpeqw
),
2785 [0x76] = MMX_OP2(pcmpeql
),
2786 [0x77] = { SSE_DUMMY
}, /* emms */
2787 [0x78] = { NULL
, SSE_SPECIAL
, NULL
, SSE_SPECIAL
}, /* extrq_i, insertq_i */
2788 [0x79] = { NULL
, gen_helper_extrq_r
, NULL
, gen_helper_insertq_r
},
2789 [0x7c] = { NULL
, gen_helper_haddpd
, NULL
, gen_helper_haddps
},
2790 [0x7d] = { NULL
, gen_helper_hsubpd
, NULL
, gen_helper_hsubps
},
2791 [0x7e] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movd, movd, , movq */
2792 [0x7f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, movdqu */
2793 [0xc4] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pinsrw */
2794 [0xc5] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pextrw */
2795 [0xd0] = { NULL
, gen_helper_addsubpd
, NULL
, gen_helper_addsubps
},
2796 [0xd1] = MMX_OP2(psrlw
),
2797 [0xd2] = MMX_OP2(psrld
),
2798 [0xd3] = MMX_OP2(psrlq
),
2799 [0xd4] = MMX_OP2(paddq
),
2800 [0xd5] = MMX_OP2(pmullw
),
2801 [0xd6] = { NULL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2802 [0xd7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pmovmskb */
2803 [0xd8] = MMX_OP2(psubusb
),
2804 [0xd9] = MMX_OP2(psubusw
),
2805 [0xda] = MMX_OP2(pminub
),
2806 [0xdb] = MMX_OP2(pand
),
2807 [0xdc] = MMX_OP2(paddusb
),
2808 [0xdd] = MMX_OP2(paddusw
),
2809 [0xde] = MMX_OP2(pmaxub
),
2810 [0xdf] = MMX_OP2(pandn
),
2811 [0xe0] = MMX_OP2(pavgb
),
2812 [0xe1] = MMX_OP2(psraw
),
2813 [0xe2] = MMX_OP2(psrad
),
2814 [0xe3] = MMX_OP2(pavgw
),
2815 [0xe4] = MMX_OP2(pmulhuw
),
2816 [0xe5] = MMX_OP2(pmulhw
),
2817 [0xe6] = { NULL
, gen_helper_cvttpd2dq
, gen_helper_cvtdq2pd
, gen_helper_cvtpd2dq
},
2818 [0xe7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movntq, movntq */
2819 [0xe8] = MMX_OP2(psubsb
),
2820 [0xe9] = MMX_OP2(psubsw
),
2821 [0xea] = MMX_OP2(pminsw
),
2822 [0xeb] = MMX_OP2(por
),
2823 [0xec] = MMX_OP2(paddsb
),
2824 [0xed] = MMX_OP2(paddsw
),
2825 [0xee] = MMX_OP2(pmaxsw
),
2826 [0xef] = MMX_OP2(pxor
),
2827 [0xf0] = { NULL
, NULL
, NULL
, SSE_SPECIAL
}, /* lddqu */
2828 [0xf1] = MMX_OP2(psllw
),
2829 [0xf2] = MMX_OP2(pslld
),
2830 [0xf3] = MMX_OP2(psllq
),
2831 [0xf4] = MMX_OP2(pmuludq
),
2832 [0xf5] = MMX_OP2(pmaddwd
),
2833 [0xf6] = MMX_OP2(psadbw
),
2834 [0xf7] = { (SSEFunc_0_epp
)gen_helper_maskmov_mmx
,
2835 (SSEFunc_0_epp
)gen_helper_maskmov_xmm
}, /* XXX: casts */
2836 [0xf8] = MMX_OP2(psubb
),
2837 [0xf9] = MMX_OP2(psubw
),
2838 [0xfa] = MMX_OP2(psubl
),
2839 [0xfb] = MMX_OP2(psubq
),
2840 [0xfc] = MMX_OP2(paddb
),
2841 [0xfd] = MMX_OP2(paddw
),
2842 [0xfe] = MMX_OP2(paddl
),
2845 static const SSEFunc_0_epp sse_op_table2
[3 * 8][2] = {
2846 [0 + 2] = MMX_OP2(psrlw
),
2847 [0 + 4] = MMX_OP2(psraw
),
2848 [0 + 6] = MMX_OP2(psllw
),
2849 [8 + 2] = MMX_OP2(psrld
),
2850 [8 + 4] = MMX_OP2(psrad
),
2851 [8 + 6] = MMX_OP2(pslld
),
2852 [16 + 2] = MMX_OP2(psrlq
),
2853 [16 + 3] = { NULL
, gen_helper_psrldq_xmm
},
2854 [16 + 6] = MMX_OP2(psllq
),
2855 [16 + 7] = { NULL
, gen_helper_pslldq_xmm
},
2858 static const SSEFunc_0_epi sse_op_table3ai
[] = {
2859 gen_helper_cvtsi2ss
,
2863 #ifdef TARGET_X86_64
2864 static const SSEFunc_0_epl sse_op_table3aq
[] = {
2865 gen_helper_cvtsq2ss
,
2870 static const SSEFunc_i_ep sse_op_table3bi
[] = {
2871 gen_helper_cvttss2si
,
2872 gen_helper_cvtss2si
,
2873 gen_helper_cvttsd2si
,
2877 #ifdef TARGET_X86_64
2878 static const SSEFunc_l_ep sse_op_table3bq
[] = {
2879 gen_helper_cvttss2sq
,
2880 gen_helper_cvtss2sq
,
2881 gen_helper_cvttsd2sq
,
2886 static const SSEFunc_0_epp sse_op_table4
[8][4] = {
2897 static const SSEFunc_0_epp sse_op_table5
[256] = {
2898 [0x0c] = gen_helper_pi2fw
,
2899 [0x0d] = gen_helper_pi2fd
,
2900 [0x1c] = gen_helper_pf2iw
,
2901 [0x1d] = gen_helper_pf2id
,
2902 [0x8a] = gen_helper_pfnacc
,
2903 [0x8e] = gen_helper_pfpnacc
,
2904 [0x90] = gen_helper_pfcmpge
,
2905 [0x94] = gen_helper_pfmin
,
2906 [0x96] = gen_helper_pfrcp
,
2907 [0x97] = gen_helper_pfrsqrt
,
2908 [0x9a] = gen_helper_pfsub
,
2909 [0x9e] = gen_helper_pfadd
,
2910 [0xa0] = gen_helper_pfcmpgt
,
2911 [0xa4] = gen_helper_pfmax
,
2912 [0xa6] = gen_helper_movq
, /* pfrcpit1; no need to actually increase precision */
2913 [0xa7] = gen_helper_movq
, /* pfrsqit1 */
2914 [0xaa] = gen_helper_pfsubr
,
2915 [0xae] = gen_helper_pfacc
,
2916 [0xb0] = gen_helper_pfcmpeq
,
2917 [0xb4] = gen_helper_pfmul
,
2918 [0xb6] = gen_helper_movq
, /* pfrcpit2 */
2919 [0xb7] = gen_helper_pmulhrw_mmx
,
2920 [0xbb] = gen_helper_pswapd
,
2921 [0xbf] = gen_helper_pavgb_mmx
/* pavgusb */
2924 struct SSEOpHelper_epp
{
2925 SSEFunc_0_epp op
[2];
2929 struct SSEOpHelper_eppi
{
2930 SSEFunc_0_eppi op
[2];
2934 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
2935 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
2936 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
2937 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
2938 #define PCLMULQDQ_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, \
2939 CPUID_EXT_PCLMULQDQ }
2940 #define AESNI_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_AES }
2942 static const struct SSEOpHelper_epp sse_op_table6
[256] = {
2943 [0x00] = SSSE3_OP(pshufb
),
2944 [0x01] = SSSE3_OP(phaddw
),
2945 [0x02] = SSSE3_OP(phaddd
),
2946 [0x03] = SSSE3_OP(phaddsw
),
2947 [0x04] = SSSE3_OP(pmaddubsw
),
2948 [0x05] = SSSE3_OP(phsubw
),
2949 [0x06] = SSSE3_OP(phsubd
),
2950 [0x07] = SSSE3_OP(phsubsw
),
2951 [0x08] = SSSE3_OP(psignb
),
2952 [0x09] = SSSE3_OP(psignw
),
2953 [0x0a] = SSSE3_OP(psignd
),
2954 [0x0b] = SSSE3_OP(pmulhrsw
),
2955 [0x10] = SSE41_OP(pblendvb
),
2956 [0x14] = SSE41_OP(blendvps
),
2957 [0x15] = SSE41_OP(blendvpd
),
2958 [0x17] = SSE41_OP(ptest
),
2959 [0x1c] = SSSE3_OP(pabsb
),
2960 [0x1d] = SSSE3_OP(pabsw
),
2961 [0x1e] = SSSE3_OP(pabsd
),
2962 [0x20] = SSE41_OP(pmovsxbw
),
2963 [0x21] = SSE41_OP(pmovsxbd
),
2964 [0x22] = SSE41_OP(pmovsxbq
),
2965 [0x23] = SSE41_OP(pmovsxwd
),
2966 [0x24] = SSE41_OP(pmovsxwq
),
2967 [0x25] = SSE41_OP(pmovsxdq
),
2968 [0x28] = SSE41_OP(pmuldq
),
2969 [0x29] = SSE41_OP(pcmpeqq
),
2970 [0x2a] = SSE41_SPECIAL
, /* movntqda */
2971 [0x2b] = SSE41_OP(packusdw
),
2972 [0x30] = SSE41_OP(pmovzxbw
),
2973 [0x31] = SSE41_OP(pmovzxbd
),
2974 [0x32] = SSE41_OP(pmovzxbq
),
2975 [0x33] = SSE41_OP(pmovzxwd
),
2976 [0x34] = SSE41_OP(pmovzxwq
),
2977 [0x35] = SSE41_OP(pmovzxdq
),
2978 [0x37] = SSE42_OP(pcmpgtq
),
2979 [0x38] = SSE41_OP(pminsb
),
2980 [0x39] = SSE41_OP(pminsd
),
2981 [0x3a] = SSE41_OP(pminuw
),
2982 [0x3b] = SSE41_OP(pminud
),
2983 [0x3c] = SSE41_OP(pmaxsb
),
2984 [0x3d] = SSE41_OP(pmaxsd
),
2985 [0x3e] = SSE41_OP(pmaxuw
),
2986 [0x3f] = SSE41_OP(pmaxud
),
2987 [0x40] = SSE41_OP(pmulld
),
2988 [0x41] = SSE41_OP(phminposuw
),
2989 [0xdb] = AESNI_OP(aesimc
),
2990 [0xdc] = AESNI_OP(aesenc
),
2991 [0xdd] = AESNI_OP(aesenclast
),
2992 [0xde] = AESNI_OP(aesdec
),
2993 [0xdf] = AESNI_OP(aesdeclast
),
2996 static const struct SSEOpHelper_eppi sse_op_table7
[256] = {
2997 [0x08] = SSE41_OP(roundps
),
2998 [0x09] = SSE41_OP(roundpd
),
2999 [0x0a] = SSE41_OP(roundss
),
3000 [0x0b] = SSE41_OP(roundsd
),
3001 [0x0c] = SSE41_OP(blendps
),
3002 [0x0d] = SSE41_OP(blendpd
),
3003 [0x0e] = SSE41_OP(pblendw
),
3004 [0x0f] = SSSE3_OP(palignr
),
3005 [0x14] = SSE41_SPECIAL
, /* pextrb */
3006 [0x15] = SSE41_SPECIAL
, /* pextrw */
3007 [0x16] = SSE41_SPECIAL
, /* pextrd/pextrq */
3008 [0x17] = SSE41_SPECIAL
, /* extractps */
3009 [0x20] = SSE41_SPECIAL
, /* pinsrb */
3010 [0x21] = SSE41_SPECIAL
, /* insertps */
3011 [0x22] = SSE41_SPECIAL
, /* pinsrd/pinsrq */
3012 [0x40] = SSE41_OP(dpps
),
3013 [0x41] = SSE41_OP(dppd
),
3014 [0x42] = SSE41_OP(mpsadbw
),
3015 [0x44] = PCLMULQDQ_OP(pclmulqdq
),
3016 [0x60] = SSE42_OP(pcmpestrm
),
3017 [0x61] = SSE42_OP(pcmpestri
),
3018 [0x62] = SSE42_OP(pcmpistrm
),
3019 [0x63] = SSE42_OP(pcmpistri
),
3020 [0xdf] = AESNI_OP(aeskeygenassist
),
3023 static void gen_sse(CPUX86State
*env
, DisasContext
*s
, int b
,
3024 target_ulong pc_start
, int rex_r
)
3026 int b1
, op1_offset
, op2_offset
, is_xmm
, val
;
3027 int modrm
, mod
, rm
, reg
;
3028 SSEFunc_0_epp sse_fn_epp
;
3029 SSEFunc_0_eppi sse_fn_eppi
;
3030 SSEFunc_0_ppi sse_fn_ppi
;
3031 SSEFunc_0_eppt sse_fn_eppt
;
3035 if (s
->prefix
& PREFIX_DATA
)
3037 else if (s
->prefix
& PREFIX_REPZ
)
3039 else if (s
->prefix
& PREFIX_REPNZ
)
3043 sse_fn_epp
= sse_op_table1
[b
][b1
];
3047 if ((b
<= 0x5f && b
>= 0x10) || b
== 0xc6 || b
== 0xc2) {
3057 /* simple MMX/SSE operation */
3058 if (s
->flags
& HF_TS_MASK
) {
3059 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
3062 if (s
->flags
& HF_EM_MASK
) {
3064 gen_illegal_opcode(s
);
3068 && !(s
->flags
& HF_OSFXSR_MASK
)
3069 && ((b
!= 0x38 && b
!= 0x3a) || (s
->prefix
& PREFIX_DATA
))) {
3073 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
)) {
3074 /* If we were fully decoding this we might use illegal_op. */
3078 gen_helper_emms(cpu_env
);
3083 gen_helper_emms(cpu_env
);
3086 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3087 the static cpu state) */
3089 gen_helper_enter_mmx(cpu_env
);
3092 modrm
= x86_ldub_code(env
, s
);
3093 reg
= ((modrm
>> 3) & 7);
3096 mod
= (modrm
>> 6) & 3;
3097 if (sse_fn_epp
== SSE_SPECIAL
) {
3100 case 0x0e7: /* movntq */
3104 gen_lea_modrm(env
, s
, modrm
);
3105 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3107 case 0x1e7: /* movntdq */
3108 case 0x02b: /* movntps */
3109 case 0x12b: /* movntps */
3112 gen_lea_modrm(env
, s
, modrm
);
3113 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3115 case 0x3f0: /* lddqu */
3118 gen_lea_modrm(env
, s
, modrm
);
3119 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3121 case 0x22b: /* movntss */
3122 case 0x32b: /* movntsd */
3125 gen_lea_modrm(env
, s
, modrm
);
3127 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3128 xmm_regs
[reg
].ZMM_Q(0)));
3130 tcg_gen_ld32u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
3131 xmm_regs
[reg
].ZMM_L(0)));
3132 gen_op_st_v(s
, MO_32
, s
->T0
, s
->A0
);
3135 case 0x6e: /* movd mm, ea */
3136 #ifdef TARGET_X86_64
3137 if (s
->dflag
== MO_64
) {
3138 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3139 tcg_gen_st_tl(s
->T0
, cpu_env
,
3140 offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3144 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3145 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3146 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3147 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
3148 gen_helper_movl_mm_T0_mmx(cpu_ptr0
, cpu_tmp2_i32
);
3151 case 0x16e: /* movd xmm, ea */
3152 #ifdef TARGET_X86_64
3153 if (s
->dflag
== MO_64
) {
3154 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3155 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3156 offsetof(CPUX86State
,xmm_regs
[reg
]));
3157 gen_helper_movq_mm_T0_xmm(cpu_ptr0
, s
->T0
);
3161 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3162 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3163 offsetof(CPUX86State
,xmm_regs
[reg
]));
3164 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
3165 gen_helper_movl_mm_T0_xmm(cpu_ptr0
, cpu_tmp2_i32
);
3168 case 0x6f: /* movq mm, ea */
3170 gen_lea_modrm(env
, s
, modrm
);
3171 gen_ldq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3174 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
3175 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3176 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
3177 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3180 case 0x010: /* movups */
3181 case 0x110: /* movupd */
3182 case 0x028: /* movaps */
3183 case 0x128: /* movapd */
3184 case 0x16f: /* movdqa xmm, ea */
3185 case 0x26f: /* movdqu xmm, ea */
3187 gen_lea_modrm(env
, s
, modrm
);
3188 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3190 rm
= (modrm
& 7) | REX_B(s
);
3191 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[reg
]),
3192 offsetof(CPUX86State
,xmm_regs
[rm
]));
3195 case 0x210: /* movss xmm, ea */
3197 gen_lea_modrm(env
, s
, modrm
);
3198 gen_op_ld_v(s
, MO_32
, s
->T0
, s
->A0
);
3199 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3200 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(0)));
3201 tcg_gen_movi_tl(s
->T0
, 0);
3202 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3203 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(1)));
3204 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3205 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(2)));
3206 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3207 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(3)));
3209 rm
= (modrm
& 7) | REX_B(s
);
3210 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)),
3211 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)));
3214 case 0x310: /* movsd xmm, ea */
3216 gen_lea_modrm(env
, s
, modrm
);
3217 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3218 xmm_regs
[reg
].ZMM_Q(0)));
3219 tcg_gen_movi_tl(s
->T0
, 0);
3220 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3221 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(2)));
3222 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3223 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(3)));
3225 rm
= (modrm
& 7) | REX_B(s
);
3226 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3227 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3230 case 0x012: /* movlps */
3231 case 0x112: /* movlpd */
3233 gen_lea_modrm(env
, s
, modrm
);
3234 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3235 xmm_regs
[reg
].ZMM_Q(0)));
3238 rm
= (modrm
& 7) | REX_B(s
);
3239 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3240 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(1)));
3243 case 0x212: /* movsldup */
3245 gen_lea_modrm(env
, s
, modrm
);
3246 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3248 rm
= (modrm
& 7) | REX_B(s
);
3249 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)),
3250 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)));
3251 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)),
3252 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(2)));
3254 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)),
3255 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3256 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)),
3257 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)));
3259 case 0x312: /* movddup */
3261 gen_lea_modrm(env
, s
, modrm
);
3262 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3263 xmm_regs
[reg
].ZMM_Q(0)));
3265 rm
= (modrm
& 7) | REX_B(s
);
3266 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3267 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3269 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)),
3270 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3272 case 0x016: /* movhps */
3273 case 0x116: /* movhpd */
3275 gen_lea_modrm(env
, s
, modrm
);
3276 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3277 xmm_regs
[reg
].ZMM_Q(1)));
3280 rm
= (modrm
& 7) | REX_B(s
);
3281 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)),
3282 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3285 case 0x216: /* movshdup */
3287 gen_lea_modrm(env
, s
, modrm
);
3288 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3290 rm
= (modrm
& 7) | REX_B(s
);
3291 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)),
3292 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(1)));
3293 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)),
3294 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(3)));
3296 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)),
3297 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)));
3298 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)),
3299 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)));
3304 int bit_index
, field_length
;
3306 if (b1
== 1 && reg
!= 0)
3308 field_length
= x86_ldub_code(env
, s
) & 0x3F;
3309 bit_index
= x86_ldub_code(env
, s
) & 0x3F;
3310 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3311 offsetof(CPUX86State
,xmm_regs
[reg
]));
3313 gen_helper_extrq_i(cpu_env
, cpu_ptr0
,
3314 tcg_const_i32(bit_index
),
3315 tcg_const_i32(field_length
));
3317 gen_helper_insertq_i(cpu_env
, cpu_ptr0
,
3318 tcg_const_i32(bit_index
),
3319 tcg_const_i32(field_length
));
3322 case 0x7e: /* movd ea, mm */
3323 #ifdef TARGET_X86_64
3324 if (s
->dflag
== MO_64
) {
3325 tcg_gen_ld_i64(s
->T0
, cpu_env
,
3326 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3327 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3331 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
3332 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_L(0)));
3333 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3336 case 0x17e: /* movd ea, xmm */
3337 #ifdef TARGET_X86_64
3338 if (s
->dflag
== MO_64
) {
3339 tcg_gen_ld_i64(s
->T0
, cpu_env
,
3340 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3341 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3345 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
3346 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3347 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3350 case 0x27e: /* movq xmm, ea */
3352 gen_lea_modrm(env
, s
, modrm
);
3353 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3354 xmm_regs
[reg
].ZMM_Q(0)));
3356 rm
= (modrm
& 7) | REX_B(s
);
3357 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3358 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3360 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)));
3362 case 0x7f: /* movq ea, mm */
3364 gen_lea_modrm(env
, s
, modrm
);
3365 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3368 gen_op_movq(offsetof(CPUX86State
,fpregs
[rm
].mmx
),
3369 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3372 case 0x011: /* movups */
3373 case 0x111: /* movupd */
3374 case 0x029: /* movaps */
3375 case 0x129: /* movapd */
3376 case 0x17f: /* movdqa ea, xmm */
3377 case 0x27f: /* movdqu ea, xmm */
3379 gen_lea_modrm(env
, s
, modrm
);
3380 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3382 rm
= (modrm
& 7) | REX_B(s
);
3383 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[rm
]),
3384 offsetof(CPUX86State
,xmm_regs
[reg
]));
3387 case 0x211: /* movss ea, xmm */
3389 gen_lea_modrm(env
, s
, modrm
);
3390 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
3391 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(0)));
3392 gen_op_st_v(s
, MO_32
, s
->T0
, s
->A0
);
3394 rm
= (modrm
& 7) | REX_B(s
);
3395 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)),
3396 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3399 case 0x311: /* movsd ea, xmm */
3401 gen_lea_modrm(env
, s
, modrm
);
3402 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3403 xmm_regs
[reg
].ZMM_Q(0)));
3405 rm
= (modrm
& 7) | REX_B(s
);
3406 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)),
3407 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3410 case 0x013: /* movlps */
3411 case 0x113: /* movlpd */
3413 gen_lea_modrm(env
, s
, modrm
);
3414 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3415 xmm_regs
[reg
].ZMM_Q(0)));
3420 case 0x017: /* movhps */
3421 case 0x117: /* movhpd */
3423 gen_lea_modrm(env
, s
, modrm
);
3424 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3425 xmm_regs
[reg
].ZMM_Q(1)));
3430 case 0x71: /* shift mm, im */
3433 case 0x171: /* shift xmm, im */
3439 val
= x86_ldub_code(env
, s
);
3441 tcg_gen_movi_tl(s
->T0
, val
);
3442 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3443 offsetof(CPUX86State
, xmm_t0
.ZMM_L(0)));
3444 tcg_gen_movi_tl(s
->T0
, 0);
3445 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3446 offsetof(CPUX86State
, xmm_t0
.ZMM_L(1)));
3447 op1_offset
= offsetof(CPUX86State
,xmm_t0
);
3449 tcg_gen_movi_tl(s
->T0
, val
);
3450 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3451 offsetof(CPUX86State
, mmx_t0
.MMX_L(0)));
3452 tcg_gen_movi_tl(s
->T0
, 0);
3453 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3454 offsetof(CPUX86State
, mmx_t0
.MMX_L(1)));
3455 op1_offset
= offsetof(CPUX86State
,mmx_t0
);
3457 sse_fn_epp
= sse_op_table2
[((b
- 1) & 3) * 8 +
3458 (((modrm
>> 3)) & 7)][b1
];
3463 rm
= (modrm
& 7) | REX_B(s
);
3464 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3467 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3469 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3470 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op1_offset
);
3471 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3473 case 0x050: /* movmskps */
3474 rm
= (modrm
& 7) | REX_B(s
);
3475 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3476 offsetof(CPUX86State
,xmm_regs
[rm
]));
3477 gen_helper_movmskps(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3478 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3480 case 0x150: /* movmskpd */
3481 rm
= (modrm
& 7) | REX_B(s
);
3482 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3483 offsetof(CPUX86State
,xmm_regs
[rm
]));
3484 gen_helper_movmskpd(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3485 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3487 case 0x02a: /* cvtpi2ps */
3488 case 0x12a: /* cvtpi2pd */
3489 gen_helper_enter_mmx(cpu_env
);
3491 gen_lea_modrm(env
, s
, modrm
);
3492 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3493 gen_ldq_env_A0(s
, op2_offset
);
3496 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3498 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3499 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3500 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3503 gen_helper_cvtpi2ps(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3507 gen_helper_cvtpi2pd(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3511 case 0x22a: /* cvtsi2ss */
3512 case 0x32a: /* cvtsi2sd */
3513 ot
= mo_64_32(s
->dflag
);
3514 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3515 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3516 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3518 SSEFunc_0_epi sse_fn_epi
= sse_op_table3ai
[(b
>> 8) & 1];
3519 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
3520 sse_fn_epi(cpu_env
, cpu_ptr0
, cpu_tmp2_i32
);
3522 #ifdef TARGET_X86_64
3523 SSEFunc_0_epl sse_fn_epl
= sse_op_table3aq
[(b
>> 8) & 1];
3524 sse_fn_epl(cpu_env
, cpu_ptr0
, s
->T0
);
3530 case 0x02c: /* cvttps2pi */
3531 case 0x12c: /* cvttpd2pi */
3532 case 0x02d: /* cvtps2pi */
3533 case 0x12d: /* cvtpd2pi */
3534 gen_helper_enter_mmx(cpu_env
);
3536 gen_lea_modrm(env
, s
, modrm
);
3537 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3538 gen_ldo_env_A0(s
, op2_offset
);
3540 rm
= (modrm
& 7) | REX_B(s
);
3541 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3543 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
);
3544 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3545 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3548 gen_helper_cvttps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3551 gen_helper_cvttpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3554 gen_helper_cvtps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3557 gen_helper_cvtpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3561 case 0x22c: /* cvttss2si */
3562 case 0x32c: /* cvttsd2si */
3563 case 0x22d: /* cvtss2si */
3564 case 0x32d: /* cvtsd2si */
3565 ot
= mo_64_32(s
->dflag
);
3567 gen_lea_modrm(env
, s
, modrm
);
3569 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.ZMM_Q(0)));
3571 gen_op_ld_v(s
, MO_32
, s
->T0
, s
->A0
);
3572 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3573 offsetof(CPUX86State
, xmm_t0
.ZMM_L(0)));
3575 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3577 rm
= (modrm
& 7) | REX_B(s
);
3578 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3580 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3582 SSEFunc_i_ep sse_fn_i_ep
=
3583 sse_op_table3bi
[((b
>> 7) & 2) | (b
& 1)];
3584 sse_fn_i_ep(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3585 tcg_gen_extu_i32_tl(s
->T0
, cpu_tmp2_i32
);
3587 #ifdef TARGET_X86_64
3588 SSEFunc_l_ep sse_fn_l_ep
=
3589 sse_op_table3bq
[((b
>> 7) & 2) | (b
& 1)];
3590 sse_fn_l_ep(s
->T0
, cpu_env
, cpu_ptr0
);
3595 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
3597 case 0xc4: /* pinsrw */
3600 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
3601 val
= x86_ldub_code(env
, s
);
3604 tcg_gen_st16_tl(s
->T0
, cpu_env
,
3605 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_W(val
)));
3608 tcg_gen_st16_tl(s
->T0
, cpu_env
,
3609 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_W(val
)));
3612 case 0xc5: /* pextrw */
3616 ot
= mo_64_32(s
->dflag
);
3617 val
= x86_ldub_code(env
, s
);
3620 rm
= (modrm
& 7) | REX_B(s
);
3621 tcg_gen_ld16u_tl(s
->T0
, cpu_env
,
3622 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_W(val
)));
3626 tcg_gen_ld16u_tl(s
->T0
, cpu_env
,
3627 offsetof(CPUX86State
,fpregs
[rm
].mmx
.MMX_W(val
)));
3629 reg
= ((modrm
>> 3) & 7) | rex_r
;
3630 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
3632 case 0x1d6: /* movq ea, xmm */
3634 gen_lea_modrm(env
, s
, modrm
);
3635 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3636 xmm_regs
[reg
].ZMM_Q(0)));
3638 rm
= (modrm
& 7) | REX_B(s
);
3639 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)),
3640 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3641 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(1)));
3644 case 0x2d6: /* movq2dq */
3645 gen_helper_enter_mmx(cpu_env
);
3647 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3648 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3649 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)));
3651 case 0x3d6: /* movdq2q */
3652 gen_helper_enter_mmx(cpu_env
);
3653 rm
= (modrm
& 7) | REX_B(s
);
3654 gen_op_movq(offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
),
3655 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3657 case 0xd7: /* pmovmskb */
3662 rm
= (modrm
& 7) | REX_B(s
);
3663 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[rm
]));
3664 gen_helper_pmovmskb_xmm(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3667 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3668 gen_helper_pmovmskb_mmx(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3670 reg
= ((modrm
>> 3) & 7) | rex_r
;
3671 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3677 if ((b
& 0xf0) == 0xf0) {
3680 modrm
= x86_ldub_code(env
, s
);
3682 reg
= ((modrm
>> 3) & 7) | rex_r
;
3683 mod
= (modrm
>> 6) & 3;
3688 sse_fn_epp
= sse_op_table6
[b
].op
[b1
];
3692 if (!(s
->cpuid_ext_features
& sse_op_table6
[b
].ext_mask
))
3696 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3698 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
3700 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3701 gen_lea_modrm(env
, s
, modrm
);
3703 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3704 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3705 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3706 gen_ldq_env_A0(s
, op2_offset
+
3707 offsetof(ZMMReg
, ZMM_Q(0)));
3709 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3710 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3711 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, s
->A0
,
3712 s
->mem_index
, MO_LEUL
);
3713 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, op2_offset
+
3714 offsetof(ZMMReg
, ZMM_L(0)));
3716 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3717 tcg_gen_qemu_ld_tl(cpu_tmp0
, s
->A0
,
3718 s
->mem_index
, MO_LEUW
);
3719 tcg_gen_st16_tl(cpu_tmp0
, cpu_env
, op2_offset
+
3720 offsetof(ZMMReg
, ZMM_W(0)));
3722 case 0x2a: /* movntqda */
3723 gen_ldo_env_A0(s
, op1_offset
);
3726 gen_ldo_env_A0(s
, op2_offset
);
3730 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
3732 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3734 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3735 gen_lea_modrm(env
, s
, modrm
);
3736 gen_ldq_env_A0(s
, op2_offset
);
3739 if (sse_fn_epp
== SSE_SPECIAL
) {
3743 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3744 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3745 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3748 set_cc_op(s
, CC_OP_EFLAGS
);
3755 /* Various integer extensions at 0f 38 f[0-f]. */
3756 b
= modrm
| (b1
<< 8);
3757 modrm
= x86_ldub_code(env
, s
);
3758 reg
= ((modrm
>> 3) & 7) | rex_r
;
3761 case 0x3f0: /* crc32 Gd,Eb */
3762 case 0x3f1: /* crc32 Gd,Ey */
3764 if (!(s
->cpuid_ext_features
& CPUID_EXT_SSE42
)) {
3767 if ((b
& 0xff) == 0xf0) {
3769 } else if (s
->dflag
!= MO_64
) {
3770 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3775 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[reg
]);
3776 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3777 gen_helper_crc32(s
->T0
, cpu_tmp2_i32
,
3778 s
->T0
, tcg_const_i32(8 << ot
));
3780 ot
= mo_64_32(s
->dflag
);
3781 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
3784 case 0x1f0: /* crc32 or movbe */
3786 /* For these insns, the f3 prefix is supposed to have priority
3787 over the 66 prefix, but that's not what we implement above
3789 if (s
->prefix
& PREFIX_REPNZ
) {
3793 case 0x0f0: /* movbe Gy,My */
3794 case 0x0f1: /* movbe My,Gy */
3795 if (!(s
->cpuid_ext_features
& CPUID_EXT_MOVBE
)) {
3798 if (s
->dflag
!= MO_64
) {
3799 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3804 gen_lea_modrm(env
, s
, modrm
);
3806 tcg_gen_qemu_ld_tl(s
->T0
, s
->A0
,
3807 s
->mem_index
, ot
| MO_BE
);
3808 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
3810 tcg_gen_qemu_st_tl(cpu_regs
[reg
], s
->A0
,
3811 s
->mem_index
, ot
| MO_BE
);
3815 case 0x0f2: /* andn Gy, By, Ey */
3816 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3817 || !(s
->prefix
& PREFIX_VEX
)
3821 ot
= mo_64_32(s
->dflag
);
3822 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3823 tcg_gen_andc_tl(s
->T0
, s
->T0
, cpu_regs
[s
->vex_v
]);
3824 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
3825 gen_op_update1_cc(s
);
3826 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3829 case 0x0f7: /* bextr Gy, Ey, By */
3830 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3831 || !(s
->prefix
& PREFIX_VEX
)
3835 ot
= mo_64_32(s
->dflag
);
3839 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3840 /* Extract START, and shift the operand.
3841 Shifts larger than operand size get zeros. */
3842 tcg_gen_ext8u_tl(s
->A0
, cpu_regs
[s
->vex_v
]);
3843 tcg_gen_shr_tl(s
->T0
, s
->T0
, s
->A0
);
3845 bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3846 zero
= tcg_const_tl(0);
3847 tcg_gen_movcond_tl(TCG_COND_LEU
, s
->T0
, s
->A0
, bound
,
3849 tcg_temp_free(zero
);
3851 /* Extract the LEN into a mask. Lengths larger than
3852 operand size get all ones. */
3853 tcg_gen_extract_tl(s
->A0
, cpu_regs
[s
->vex_v
], 8, 8);
3854 tcg_gen_movcond_tl(TCG_COND_LEU
, s
->A0
, s
->A0
, bound
,
3856 tcg_temp_free(bound
);
3857 tcg_gen_movi_tl(cpu_T1
, 1);
3858 tcg_gen_shl_tl(cpu_T1
, cpu_T1
, s
->A0
);
3859 tcg_gen_subi_tl(cpu_T1
, cpu_T1
, 1);
3860 tcg_gen_and_tl(s
->T0
, s
->T0
, cpu_T1
);
3862 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
3863 gen_op_update1_cc(s
);
3864 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3868 case 0x0f5: /* bzhi Gy, Ey, By */
3869 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3870 || !(s
->prefix
& PREFIX_VEX
)
3874 ot
= mo_64_32(s
->dflag
);
3875 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3876 tcg_gen_ext8u_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3878 TCGv bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3879 /* Note that since we're using BMILG (in order to get O
3880 cleared) we need to store the inverse into C. */
3881 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_cc_src
,
3883 tcg_gen_movcond_tl(TCG_COND_GT
, cpu_T1
, cpu_T1
,
3884 bound
, bound
, cpu_T1
);
3885 tcg_temp_free(bound
);
3887 tcg_gen_movi_tl(s
->A0
, -1);
3888 tcg_gen_shl_tl(s
->A0
, s
->A0
, cpu_T1
);
3889 tcg_gen_andc_tl(s
->T0
, s
->T0
, s
->A0
);
3890 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
3891 gen_op_update1_cc(s
);
3892 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
3895 case 0x3f6: /* mulx By, Gy, rdx, Ey */
3896 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3897 || !(s
->prefix
& PREFIX_VEX
)
3901 ot
= mo_64_32(s
->dflag
);
3902 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3905 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
3906 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EDX
]);
3907 tcg_gen_mulu2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
3908 cpu_tmp2_i32
, cpu_tmp3_i32
);
3909 tcg_gen_extu_i32_tl(cpu_regs
[s
->vex_v
], cpu_tmp2_i32
);
3910 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp3_i32
);
3912 #ifdef TARGET_X86_64
3914 tcg_gen_mulu2_i64(s
->T0
, cpu_T1
,
3915 s
->T0
, cpu_regs
[R_EDX
]);
3916 tcg_gen_mov_i64(cpu_regs
[s
->vex_v
], s
->T0
);
3917 tcg_gen_mov_i64(cpu_regs
[reg
], cpu_T1
);
3923 case 0x3f5: /* pdep Gy, By, Ey */
3924 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3925 || !(s
->prefix
& PREFIX_VEX
)
3929 ot
= mo_64_32(s
->dflag
);
3930 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3931 /* Note that by zero-extending the mask operand, we
3932 automatically handle zero-extending the result. */
3934 tcg_gen_mov_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3936 tcg_gen_ext32u_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3938 gen_helper_pdep(cpu_regs
[reg
], s
->T0
, cpu_T1
);
3941 case 0x2f5: /* pext Gy, By, Ey */
3942 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3943 || !(s
->prefix
& PREFIX_VEX
)
3947 ot
= mo_64_32(s
->dflag
);
3948 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3949 /* Note that by zero-extending the mask operand, we
3950 automatically handle zero-extending the result. */
3952 tcg_gen_mov_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3954 tcg_gen_ext32u_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3956 gen_helper_pext(cpu_regs
[reg
], s
->T0
, cpu_T1
);
3959 case 0x1f6: /* adcx Gy, Ey */
3960 case 0x2f6: /* adox Gy, Ey */
3961 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_ADX
)) {
3964 TCGv carry_in
, carry_out
, zero
;
3967 ot
= mo_64_32(s
->dflag
);
3968 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3970 /* Re-use the carry-out from a previous round. */
3972 carry_out
= (b
== 0x1f6 ? cpu_cc_dst
: cpu_cc_src2
);
3976 carry_in
= cpu_cc_dst
;
3977 end_op
= CC_OP_ADCX
;
3979 end_op
= CC_OP_ADCOX
;
3984 end_op
= CC_OP_ADCOX
;
3986 carry_in
= cpu_cc_src2
;
3987 end_op
= CC_OP_ADOX
;
3991 end_op
= CC_OP_ADCOX
;
3992 carry_in
= carry_out
;
3995 end_op
= (b
== 0x1f6 ? CC_OP_ADCX
: CC_OP_ADOX
);
3998 /* If we can't reuse carry-out, get it out of EFLAGS. */
4000 if (s
->cc_op
!= CC_OP_ADCX
&& s
->cc_op
!= CC_OP_ADOX
) {
4001 gen_compute_eflags(s
);
4003 carry_in
= cpu_tmp0
;
4004 tcg_gen_extract_tl(carry_in
, cpu_cc_src
,
4005 ctz32(b
== 0x1f6 ? CC_C
: CC_O
), 1);
4009 #ifdef TARGET_X86_64
4011 /* If we know TL is 64-bit, and we want a 32-bit
4012 result, just do everything in 64-bit arithmetic. */
4013 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_regs
[reg
]);
4014 tcg_gen_ext32u_i64(s
->T0
, s
->T0
);
4015 tcg_gen_add_i64(s
->T0
, s
->T0
, cpu_regs
[reg
]);
4016 tcg_gen_add_i64(s
->T0
, s
->T0
, carry_in
);
4017 tcg_gen_ext32u_i64(cpu_regs
[reg
], s
->T0
);
4018 tcg_gen_shri_i64(carry_out
, s
->T0
, 32);
4022 /* Otherwise compute the carry-out in two steps. */
4023 zero
= tcg_const_tl(0);
4024 tcg_gen_add2_tl(s
->T0
, carry_out
,
4027 tcg_gen_add2_tl(cpu_regs
[reg
], carry_out
,
4028 cpu_regs
[reg
], carry_out
,
4030 tcg_temp_free(zero
);
4033 set_cc_op(s
, end_op
);
4037 case 0x1f7: /* shlx Gy, Ey, By */
4038 case 0x2f7: /* sarx Gy, Ey, By */
4039 case 0x3f7: /* shrx Gy, Ey, By */
4040 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4041 || !(s
->prefix
& PREFIX_VEX
)
4045 ot
= mo_64_32(s
->dflag
);
4046 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4048 tcg_gen_andi_tl(cpu_T1
, cpu_regs
[s
->vex_v
], 63);
4050 tcg_gen_andi_tl(cpu_T1
, cpu_regs
[s
->vex_v
], 31);
4053 tcg_gen_shl_tl(s
->T0
, s
->T0
, cpu_T1
);
4054 } else if (b
== 0x2f7) {
4056 tcg_gen_ext32s_tl(s
->T0
, s
->T0
);
4058 tcg_gen_sar_tl(s
->T0
, s
->T0
, cpu_T1
);
4061 tcg_gen_ext32u_tl(s
->T0
, s
->T0
);
4063 tcg_gen_shr_tl(s
->T0
, s
->T0
, cpu_T1
);
4065 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
4071 case 0x3f3: /* Group 17 */
4072 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
4073 || !(s
->prefix
& PREFIX_VEX
)
4077 ot
= mo_64_32(s
->dflag
);
4078 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4080 tcg_gen_mov_tl(cpu_cc_src
, s
->T0
);
4082 case 1: /* blsr By,Ey */
4083 tcg_gen_subi_tl(cpu_T1
, s
->T0
, 1);
4084 tcg_gen_and_tl(s
->T0
, s
->T0
, cpu_T1
);
4086 case 2: /* blsmsk By,Ey */
4087 tcg_gen_subi_tl(cpu_T1
, s
->T0
, 1);
4088 tcg_gen_xor_tl(s
->T0
, s
->T0
, cpu_T1
);
4090 case 3: /* blsi By, Ey */
4091 tcg_gen_neg_tl(cpu_T1
, s
->T0
);
4092 tcg_gen_and_tl(s
->T0
, s
->T0
, cpu_T1
);
4097 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
4098 gen_op_mov_reg_v(ot
, s
->vex_v
, s
->T0
);
4099 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4110 modrm
= x86_ldub_code(env
, s
);
4112 reg
= ((modrm
>> 3) & 7) | rex_r
;
4113 mod
= (modrm
>> 6) & 3;
4118 sse_fn_eppi
= sse_op_table7
[b
].op
[b1
];
4122 if (!(s
->cpuid_ext_features
& sse_op_table7
[b
].ext_mask
))
4127 if (sse_fn_eppi
== SSE_SPECIAL
) {
4128 ot
= mo_64_32(s
->dflag
);
4129 rm
= (modrm
& 7) | REX_B(s
);
4131 gen_lea_modrm(env
, s
, modrm
);
4132 reg
= ((modrm
>> 3) & 7) | rex_r
;
4133 val
= x86_ldub_code(env
, s
);
4135 case 0x14: /* pextrb */
4136 tcg_gen_ld8u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
4137 xmm_regs
[reg
].ZMM_B(val
& 15)));
4139 gen_op_mov_reg_v(ot
, rm
, s
->T0
);
4141 tcg_gen_qemu_st_tl(s
->T0
, s
->A0
,
4142 s
->mem_index
, MO_UB
);
4145 case 0x15: /* pextrw */
4146 tcg_gen_ld16u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
4147 xmm_regs
[reg
].ZMM_W(val
& 7)));
4149 gen_op_mov_reg_v(ot
, rm
, s
->T0
);
4151 tcg_gen_qemu_st_tl(s
->T0
, s
->A0
,
4152 s
->mem_index
, MO_LEUW
);
4156 if (ot
== MO_32
) { /* pextrd */
4157 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4158 offsetof(CPUX86State
,
4159 xmm_regs
[reg
].ZMM_L(val
& 3)));
4161 tcg_gen_extu_i32_tl(cpu_regs
[rm
], cpu_tmp2_i32
);
4163 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, s
->A0
,
4164 s
->mem_index
, MO_LEUL
);
4166 } else { /* pextrq */
4167 #ifdef TARGET_X86_64
4168 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
4169 offsetof(CPUX86State
,
4170 xmm_regs
[reg
].ZMM_Q(val
& 1)));
4172 tcg_gen_mov_i64(cpu_regs
[rm
], cpu_tmp1_i64
);
4174 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, s
->A0
,
4175 s
->mem_index
, MO_LEQ
);
4182 case 0x17: /* extractps */
4183 tcg_gen_ld32u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
4184 xmm_regs
[reg
].ZMM_L(val
& 3)));
4186 gen_op_mov_reg_v(ot
, rm
, s
->T0
);
4188 tcg_gen_qemu_st_tl(s
->T0
, s
->A0
,
4189 s
->mem_index
, MO_LEUL
);
4192 case 0x20: /* pinsrb */
4194 gen_op_mov_v_reg(MO_32
, s
->T0
, rm
);
4196 tcg_gen_qemu_ld_tl(s
->T0
, s
->A0
,
4197 s
->mem_index
, MO_UB
);
4199 tcg_gen_st8_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
4200 xmm_regs
[reg
].ZMM_B(val
& 15)));
4202 case 0x21: /* insertps */
4204 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4205 offsetof(CPUX86State
,xmm_regs
[rm
]
4206 .ZMM_L((val
>> 6) & 3)));
4208 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, s
->A0
,
4209 s
->mem_index
, MO_LEUL
);
4211 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4212 offsetof(CPUX86State
,xmm_regs
[reg
]
4213 .ZMM_L((val
>> 4) & 3)));
4215 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4216 cpu_env
, offsetof(CPUX86State
,
4217 xmm_regs
[reg
].ZMM_L(0)));
4219 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4220 cpu_env
, offsetof(CPUX86State
,
4221 xmm_regs
[reg
].ZMM_L(1)));
4223 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4224 cpu_env
, offsetof(CPUX86State
,
4225 xmm_regs
[reg
].ZMM_L(2)));
4227 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4228 cpu_env
, offsetof(CPUX86State
,
4229 xmm_regs
[reg
].ZMM_L(3)));
4232 if (ot
== MO_32
) { /* pinsrd */
4234 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[rm
]);
4236 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, s
->A0
,
4237 s
->mem_index
, MO_LEUL
);
4239 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4240 offsetof(CPUX86State
,
4241 xmm_regs
[reg
].ZMM_L(val
& 3)));
4242 } else { /* pinsrq */
4243 #ifdef TARGET_X86_64
4245 gen_op_mov_v_reg(ot
, cpu_tmp1_i64
, rm
);
4247 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, s
->A0
,
4248 s
->mem_index
, MO_LEQ
);
4250 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
4251 offsetof(CPUX86State
,
4252 xmm_regs
[reg
].ZMM_Q(val
& 1)));
4263 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4265 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
4267 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4268 gen_lea_modrm(env
, s
, modrm
);
4269 gen_ldo_env_A0(s
, op2_offset
);
4272 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4274 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4276 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4277 gen_lea_modrm(env
, s
, modrm
);
4278 gen_ldq_env_A0(s
, op2_offset
);
4281 val
= x86_ldub_code(env
, s
);
4283 if ((b
& 0xfc) == 0x60) { /* pcmpXstrX */
4284 set_cc_op(s
, CC_OP_EFLAGS
);
4286 if (s
->dflag
== MO_64
) {
4287 /* The helper must use entire 64-bit gp registers */
4292 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4293 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4294 sse_fn_eppi(cpu_env
, cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4298 /* Various integer extensions at 0f 3a f[0-f]. */
4299 b
= modrm
| (b1
<< 8);
4300 modrm
= x86_ldub_code(env
, s
);
4301 reg
= ((modrm
>> 3) & 7) | rex_r
;
4304 case 0x3f0: /* rorx Gy,Ey, Ib */
4305 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4306 || !(s
->prefix
& PREFIX_VEX
)
4310 ot
= mo_64_32(s
->dflag
);
4311 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4312 b
= x86_ldub_code(env
, s
);
4314 tcg_gen_rotri_tl(s
->T0
, s
->T0
, b
& 63);
4316 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
4317 tcg_gen_rotri_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, b
& 31);
4318 tcg_gen_extu_i32_tl(s
->T0
, cpu_tmp2_i32
);
4320 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
4330 gen_unknown_opcode(env
, s
);
4334 /* generic MMX or SSE operation */
4336 case 0x70: /* pshufx insn */
4337 case 0xc6: /* pshufx insn */
4338 case 0xc2: /* compare insns */
4345 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4349 gen_lea_modrm(env
, s
, modrm
);
4350 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4356 /* Most sse scalar operations. */
4359 } else if (b1
== 3) {
4364 case 0x2e: /* ucomis[sd] */
4365 case 0x2f: /* comis[sd] */
4377 gen_op_ld_v(s
, MO_32
, s
->T0
, s
->A0
);
4378 tcg_gen_st32_tl(s
->T0
, cpu_env
,
4379 offsetof(CPUX86State
,xmm_t0
.ZMM_L(0)));
4383 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.ZMM_D(0)));
4386 /* 128 bit access */
4387 gen_ldo_env_A0(s
, op2_offset
);
4391 rm
= (modrm
& 7) | REX_B(s
);
4392 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
4395 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4397 gen_lea_modrm(env
, s
, modrm
);
4398 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4399 gen_ldq_env_A0(s
, op2_offset
);
4402 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4406 case 0x0f: /* 3DNow! data insns */
4407 val
= x86_ldub_code(env
, s
);
4408 sse_fn_epp
= sse_op_table5
[val
];
4412 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
)) {
4415 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4416 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4417 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4419 case 0x70: /* pshufx insn */
4420 case 0xc6: /* pshufx insn */
4421 val
= x86_ldub_code(env
, s
);
4422 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4423 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4424 /* XXX: introduce a new table? */
4425 sse_fn_ppi
= (SSEFunc_0_ppi
)sse_fn_epp
;
4426 sse_fn_ppi(cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4430 val
= x86_ldub_code(env
, s
);
4433 sse_fn_epp
= sse_op_table4
[val
][b1
];
4435 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4436 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4437 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4440 /* maskmov : we must prepare A0 */
4443 tcg_gen_mov_tl(s
->A0
, cpu_regs
[R_EDI
]);
4444 gen_extu(s
->aflag
, s
->A0
);
4445 gen_add_A0_ds_seg(s
);
4447 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4448 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4449 /* XXX: introduce a new table? */
4450 sse_fn_eppt
= (SSEFunc_0_eppt
)sse_fn_epp
;
4451 sse_fn_eppt(cpu_env
, cpu_ptr0
, cpu_ptr1
, s
->A0
);
4454 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4455 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4456 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4459 if (b
== 0x2e || b
== 0x2f) {
4460 set_cc_op(s
, CC_OP_EFLAGS
);
4465 /* convert one instruction. s->base.is_jmp is set if the translation must
4466 be stopped. Return the next pc value */
4467 static target_ulong
disas_insn(DisasContext
*s
, CPUState
*cpu
)
4469 CPUX86State
*env
= cpu
->env_ptr
;
4472 TCGMemOp ot
, aflag
, dflag
;
4473 int modrm
, reg
, rm
, mod
, op
, opreg
, val
;
4474 target_ulong next_eip
, tval
;
4476 target_ulong pc_start
= s
->base
.pc_next
;
4478 s
->pc_start
= s
->pc
= pc_start
;
4480 #ifdef TARGET_X86_64
4485 s
->rip_offset
= 0; /* for relative ip address */
4488 if (sigsetjmp(s
->jmpbuf
, 0) != 0) {
4489 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
4498 b
= x86_ldub_code(env
, s
);
4499 /* Collect prefixes. */
4502 prefixes
|= PREFIX_REPZ
;
4505 prefixes
|= PREFIX_REPNZ
;
4508 prefixes
|= PREFIX_LOCK
;
4529 prefixes
|= PREFIX_DATA
;
4532 prefixes
|= PREFIX_ADR
;
4534 #ifdef TARGET_X86_64
4538 rex_w
= (b
>> 3) & 1;
4539 rex_r
= (b
& 0x4) << 1;
4540 s
->rex_x
= (b
& 0x2) << 2;
4541 REX_B(s
) = (b
& 0x1) << 3;
4542 x86_64_hregs
= 1; /* select uniform byte register addressing */
4547 case 0xc5: /* 2-byte VEX */
4548 case 0xc4: /* 3-byte VEX */
4549 /* VEX prefixes cannot be used except in 32-bit mode.
4550 Otherwise the instruction is LES or LDS. */
4551 if (s
->code32
&& !s
->vm86
) {
4552 static const int pp_prefix
[4] = {
4553 0, PREFIX_DATA
, PREFIX_REPZ
, PREFIX_REPNZ
4555 int vex3
, vex2
= x86_ldub_code(env
, s
);
4557 if (!CODE64(s
) && (vex2
& 0xc0) != 0xc0) {
4558 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4559 otherwise the instruction is LES or LDS. */
4560 s
->pc
--; /* rewind the advance_pc() x86_ldub_code() did */
4564 /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
4565 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
4566 | PREFIX_LOCK
| PREFIX_DATA
)) {
4569 #ifdef TARGET_X86_64
4574 rex_r
= (~vex2
>> 4) & 8;
4576 /* 2-byte VEX prefix: RVVVVlpp, implied 0f leading opcode byte */
4578 b
= x86_ldub_code(env
, s
) | 0x100;
4580 /* 3-byte VEX prefix: RXBmmmmm wVVVVlpp */
4581 #ifdef TARGET_X86_64
4582 s
->rex_x
= (~vex2
>> 3) & 8;
4583 s
->rex_b
= (~vex2
>> 2) & 8;
4585 vex3
= x86_ldub_code(env
, s
);
4586 rex_w
= (vex3
>> 7) & 1;
4587 switch (vex2
& 0x1f) {
4588 case 0x01: /* Implied 0f leading opcode bytes. */
4589 b
= x86_ldub_code(env
, s
) | 0x100;
4591 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4594 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4597 default: /* Reserved for future use. */
4601 s
->vex_v
= (~vex3
>> 3) & 0xf;
4602 s
->vex_l
= (vex3
>> 2) & 1;
4603 prefixes
|= pp_prefix
[vex3
& 3] | PREFIX_VEX
;
4608 /* Post-process prefixes. */
4610 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit
4611 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4612 over 0x66 if both are present. */
4613 dflag
= (rex_w
> 0 ? MO_64
: prefixes
& PREFIX_DATA
? MO_16
: MO_32
);
4614 /* In 64-bit mode, 0x67 selects 32-bit addressing. */
4615 aflag
= (prefixes
& PREFIX_ADR
? MO_32
: MO_64
);
4617 /* In 16/32-bit mode, 0x66 selects the opposite data size. */
4618 if (s
->code32
^ ((prefixes
& PREFIX_DATA
) != 0)) {
4623 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */
4624 if (s
->code32
^ ((prefixes
& PREFIX_ADR
) != 0)) {
4631 s
->prefix
= prefixes
;
4635 /* now check op code */
4639 /**************************/
4640 /* extended op code */
4641 b
= x86_ldub_code(env
, s
) | 0x100;
4644 /**************************/
4659 ot
= mo_b_d(b
, dflag
);
4662 case 0: /* OP Ev, Gv */
4663 modrm
= x86_ldub_code(env
, s
);
4664 reg
= ((modrm
>> 3) & 7) | rex_r
;
4665 mod
= (modrm
>> 6) & 3;
4666 rm
= (modrm
& 7) | REX_B(s
);
4668 gen_lea_modrm(env
, s
, modrm
);
4670 } else if (op
== OP_XORL
&& rm
== reg
) {
4672 /* xor reg, reg optimisation */
4673 set_cc_op(s
, CC_OP_CLR
);
4674 tcg_gen_movi_tl(s
->T0
, 0);
4675 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
4680 gen_op_mov_v_reg(ot
, cpu_T1
, reg
);
4681 gen_op(s
, op
, ot
, opreg
);
4683 case 1: /* OP Gv, Ev */
4684 modrm
= x86_ldub_code(env
, s
);
4685 mod
= (modrm
>> 6) & 3;
4686 reg
= ((modrm
>> 3) & 7) | rex_r
;
4687 rm
= (modrm
& 7) | REX_B(s
);
4689 gen_lea_modrm(env
, s
, modrm
);
4690 gen_op_ld_v(s
, ot
, cpu_T1
, s
->A0
);
4691 } else if (op
== OP_XORL
&& rm
== reg
) {
4694 gen_op_mov_v_reg(ot
, cpu_T1
, rm
);
4696 gen_op(s
, op
, ot
, reg
);
4698 case 2: /* OP A, Iv */
4699 val
= insn_get(env
, s
, ot
);
4700 tcg_gen_movi_tl(cpu_T1
, val
);
4701 gen_op(s
, op
, ot
, OR_EAX
);
4711 case 0x80: /* GRP1 */
4717 ot
= mo_b_d(b
, dflag
);
4719 modrm
= x86_ldub_code(env
, s
);
4720 mod
= (modrm
>> 6) & 3;
4721 rm
= (modrm
& 7) | REX_B(s
);
4722 op
= (modrm
>> 3) & 7;
4728 s
->rip_offset
= insn_const_size(ot
);
4729 gen_lea_modrm(env
, s
, modrm
);
4740 val
= insn_get(env
, s
, ot
);
4743 val
= (int8_t)insn_get(env
, s
, MO_8
);
4746 tcg_gen_movi_tl(cpu_T1
, val
);
4747 gen_op(s
, op
, ot
, opreg
);
4751 /**************************/
4752 /* inc, dec, and other misc arith */
4753 case 0x40 ... 0x47: /* inc Gv */
4755 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), 1);
4757 case 0x48 ... 0x4f: /* dec Gv */
4759 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), -1);
4761 case 0xf6: /* GRP3 */
4763 ot
= mo_b_d(b
, dflag
);
4765 modrm
= x86_ldub_code(env
, s
);
4766 mod
= (modrm
>> 6) & 3;
4767 rm
= (modrm
& 7) | REX_B(s
);
4768 op
= (modrm
>> 3) & 7;
4771 s
->rip_offset
= insn_const_size(ot
);
4773 gen_lea_modrm(env
, s
, modrm
);
4774 /* For those below that handle locked memory, don't load here. */
4775 if (!(s
->prefix
& PREFIX_LOCK
)
4777 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
4780 gen_op_mov_v_reg(ot
, s
->T0
, rm
);
4785 val
= insn_get(env
, s
, ot
);
4786 tcg_gen_movi_tl(cpu_T1
, val
);
4787 gen_op_testl_T0_T1_cc(s
);
4788 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4791 if (s
->prefix
& PREFIX_LOCK
) {
4795 tcg_gen_movi_tl(s
->T0
, ~0);
4796 tcg_gen_atomic_xor_fetch_tl(s
->T0
, s
->A0
, s
->T0
,
4797 s
->mem_index
, ot
| MO_LE
);
4799 tcg_gen_not_tl(s
->T0
, s
->T0
);
4801 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
4803 gen_op_mov_reg_v(ot
, rm
, s
->T0
);
4808 if (s
->prefix
& PREFIX_LOCK
) {
4810 TCGv a0
, t0
, t1
, t2
;
4815 a0
= tcg_temp_local_new();
4816 t0
= tcg_temp_local_new();
4817 label1
= gen_new_label();
4819 tcg_gen_mov_tl(a0
, s
->A0
);
4820 tcg_gen_mov_tl(t0
, s
->T0
);
4822 gen_set_label(label1
);
4823 t1
= tcg_temp_new();
4824 t2
= tcg_temp_new();
4825 tcg_gen_mov_tl(t2
, t0
);
4826 tcg_gen_neg_tl(t1
, t0
);
4827 tcg_gen_atomic_cmpxchg_tl(t0
, a0
, t0
, t1
,
4828 s
->mem_index
, ot
| MO_LE
);
4830 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t2
, label1
);
4834 tcg_gen_mov_tl(s
->T0
, t0
);
4837 tcg_gen_neg_tl(s
->T0
, s
->T0
);
4839 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
4841 gen_op_mov_reg_v(ot
, rm
, s
->T0
);
4844 gen_op_update_neg_cc(s
);
4845 set_cc_op(s
, CC_OP_SUBB
+ ot
);
4850 gen_op_mov_v_reg(MO_8
, cpu_T1
, R_EAX
);
4851 tcg_gen_ext8u_tl(s
->T0
, s
->T0
);
4852 tcg_gen_ext8u_tl(cpu_T1
, cpu_T1
);
4853 /* XXX: use 32 bit mul which could be faster */
4854 tcg_gen_mul_tl(s
->T0
, s
->T0
, cpu_T1
);
4855 gen_op_mov_reg_v(MO_16
, R_EAX
, s
->T0
);
4856 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
4857 tcg_gen_andi_tl(cpu_cc_src
, s
->T0
, 0xff00);
4858 set_cc_op(s
, CC_OP_MULB
);
4861 gen_op_mov_v_reg(MO_16
, cpu_T1
, R_EAX
);
4862 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
4863 tcg_gen_ext16u_tl(cpu_T1
, cpu_T1
);
4864 /* XXX: use 32 bit mul which could be faster */
4865 tcg_gen_mul_tl(s
->T0
, s
->T0
, cpu_T1
);
4866 gen_op_mov_reg_v(MO_16
, R_EAX
, s
->T0
);
4867 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
4868 tcg_gen_shri_tl(s
->T0
, s
->T0
, 16);
4869 gen_op_mov_reg_v(MO_16
, R_EDX
, s
->T0
);
4870 tcg_gen_mov_tl(cpu_cc_src
, s
->T0
);
4871 set_cc_op(s
, CC_OP_MULW
);
4875 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
4876 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
4877 tcg_gen_mulu2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4878 cpu_tmp2_i32
, cpu_tmp3_i32
);
4879 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
4880 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
4881 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4882 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4883 set_cc_op(s
, CC_OP_MULL
);
4885 #ifdef TARGET_X86_64
4887 tcg_gen_mulu2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4888 s
->T0
, cpu_regs
[R_EAX
]);
4889 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4890 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4891 set_cc_op(s
, CC_OP_MULQ
);
4899 gen_op_mov_v_reg(MO_8
, cpu_T1
, R_EAX
);
4900 tcg_gen_ext8s_tl(s
->T0
, s
->T0
);
4901 tcg_gen_ext8s_tl(cpu_T1
, cpu_T1
);
4902 /* XXX: use 32 bit mul which could be faster */
4903 tcg_gen_mul_tl(s
->T0
, s
->T0
, cpu_T1
);
4904 gen_op_mov_reg_v(MO_16
, R_EAX
, s
->T0
);
4905 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
4906 tcg_gen_ext8s_tl(cpu_tmp0
, s
->T0
);
4907 tcg_gen_sub_tl(cpu_cc_src
, s
->T0
, cpu_tmp0
);
4908 set_cc_op(s
, CC_OP_MULB
);
4911 gen_op_mov_v_reg(MO_16
, cpu_T1
, R_EAX
);
4912 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
4913 tcg_gen_ext16s_tl(cpu_T1
, cpu_T1
);
4914 /* XXX: use 32 bit mul which could be faster */
4915 tcg_gen_mul_tl(s
->T0
, s
->T0
, cpu_T1
);
4916 gen_op_mov_reg_v(MO_16
, R_EAX
, s
->T0
);
4917 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
4918 tcg_gen_ext16s_tl(cpu_tmp0
, s
->T0
);
4919 tcg_gen_sub_tl(cpu_cc_src
, s
->T0
, cpu_tmp0
);
4920 tcg_gen_shri_tl(s
->T0
, s
->T0
, 16);
4921 gen_op_mov_reg_v(MO_16
, R_EDX
, s
->T0
);
4922 set_cc_op(s
, CC_OP_MULW
);
4926 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
4927 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
4928 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4929 cpu_tmp2_i32
, cpu_tmp3_i32
);
4930 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
4931 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
4932 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
4933 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4934 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
4935 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
4936 set_cc_op(s
, CC_OP_MULL
);
4938 #ifdef TARGET_X86_64
4940 tcg_gen_muls2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4941 s
->T0
, cpu_regs
[R_EAX
]);
4942 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4943 tcg_gen_sari_tl(cpu_cc_src
, cpu_regs
[R_EAX
], 63);
4944 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_regs
[R_EDX
]);
4945 set_cc_op(s
, CC_OP_MULQ
);
4953 gen_helper_divb_AL(cpu_env
, s
->T0
);
4956 gen_helper_divw_AX(cpu_env
, s
->T0
);
4960 gen_helper_divl_EAX(cpu_env
, s
->T0
);
4962 #ifdef TARGET_X86_64
4964 gen_helper_divq_EAX(cpu_env
, s
->T0
);
4972 gen_helper_idivb_AL(cpu_env
, s
->T0
);
4975 gen_helper_idivw_AX(cpu_env
, s
->T0
);
4979 gen_helper_idivl_EAX(cpu_env
, s
->T0
);
4981 #ifdef TARGET_X86_64
4983 gen_helper_idivq_EAX(cpu_env
, s
->T0
);
4993 case 0xfe: /* GRP4 */
4994 case 0xff: /* GRP5 */
4995 ot
= mo_b_d(b
, dflag
);
4997 modrm
= x86_ldub_code(env
, s
);
4998 mod
= (modrm
>> 6) & 3;
4999 rm
= (modrm
& 7) | REX_B(s
);
5000 op
= (modrm
>> 3) & 7;
5001 if (op
>= 2 && b
== 0xfe) {
5005 if (op
== 2 || op
== 4) {
5006 /* operand size for jumps is 64 bit */
5008 } else if (op
== 3 || op
== 5) {
5009 ot
= dflag
!= MO_16
? MO_32
+ (rex_w
== 1) : MO_16
;
5010 } else if (op
== 6) {
5011 /* default push size is 64 bit */
5012 ot
= mo_pushpop(s
, dflag
);
5016 gen_lea_modrm(env
, s
, modrm
);
5017 if (op
>= 2 && op
!= 3 && op
!= 5)
5018 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
5020 gen_op_mov_v_reg(ot
, s
->T0
, rm
);
5024 case 0: /* inc Ev */
5029 gen_inc(s
, ot
, opreg
, 1);
5031 case 1: /* dec Ev */
5036 gen_inc(s
, ot
, opreg
, -1);
5038 case 2: /* call Ev */
5039 /* XXX: optimize if memory (no 'and' is necessary) */
5040 if (dflag
== MO_16
) {
5041 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
5043 next_eip
= s
->pc
- s
->cs_base
;
5044 tcg_gen_movi_tl(cpu_T1
, next_eip
);
5045 gen_push_v(s
, cpu_T1
);
5046 gen_op_jmp_v(s
->T0
);
5050 case 3: /* lcall Ev */
5051 gen_op_ld_v(s
, ot
, cpu_T1
, s
->A0
);
5052 gen_add_A0_im(s
, 1 << ot
);
5053 gen_op_ld_v(s
, MO_16
, s
->T0
, s
->A0
);
5055 if (s
->pe
&& !s
->vm86
) {
5056 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
5057 gen_helper_lcall_protected(cpu_env
, cpu_tmp2_i32
, cpu_T1
,
5058 tcg_const_i32(dflag
- 1),
5059 tcg_const_tl(s
->pc
- s
->cs_base
));
5061 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
5062 gen_helper_lcall_real(cpu_env
, cpu_tmp2_i32
, cpu_T1
,
5063 tcg_const_i32(dflag
- 1),
5064 tcg_const_i32(s
->pc
- s
->cs_base
));
5066 tcg_gen_ld_tl(cpu_tmp4
, cpu_env
, offsetof(CPUX86State
, eip
));
5067 gen_jr(s
, cpu_tmp4
);
5069 case 4: /* jmp Ev */
5070 if (dflag
== MO_16
) {
5071 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
5073 gen_op_jmp_v(s
->T0
);
5077 case 5: /* ljmp Ev */
5078 gen_op_ld_v(s
, ot
, cpu_T1
, s
->A0
);
5079 gen_add_A0_im(s
, 1 << ot
);
5080 gen_op_ld_v(s
, MO_16
, s
->T0
, s
->A0
);
5082 if (s
->pe
&& !s
->vm86
) {
5083 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
5084 gen_helper_ljmp_protected(cpu_env
, cpu_tmp2_i32
, cpu_T1
,
5085 tcg_const_tl(s
->pc
- s
->cs_base
));
5087 gen_op_movl_seg_T0_vm(s
, R_CS
);
5088 gen_op_jmp_v(cpu_T1
);
5090 tcg_gen_ld_tl(cpu_tmp4
, cpu_env
, offsetof(CPUX86State
, eip
));
5091 gen_jr(s
, cpu_tmp4
);
5093 case 6: /* push Ev */
5094 gen_push_v(s
, s
->T0
);
5101 case 0x84: /* test Ev, Gv */
5103 ot
= mo_b_d(b
, dflag
);
5105 modrm
= x86_ldub_code(env
, s
);
5106 reg
= ((modrm
>> 3) & 7) | rex_r
;
5108 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5109 gen_op_mov_v_reg(ot
, cpu_T1
, reg
);
5110 gen_op_testl_T0_T1_cc(s
);
5111 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5114 case 0xa8: /* test eAX, Iv */
5116 ot
= mo_b_d(b
, dflag
);
5117 val
= insn_get(env
, s
, ot
);
5119 gen_op_mov_v_reg(ot
, s
->T0
, OR_EAX
);
5120 tcg_gen_movi_tl(cpu_T1
, val
);
5121 gen_op_testl_T0_T1_cc(s
);
5122 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5125 case 0x98: /* CWDE/CBW */
5127 #ifdef TARGET_X86_64
5129 gen_op_mov_v_reg(MO_32
, s
->T0
, R_EAX
);
5130 tcg_gen_ext32s_tl(s
->T0
, s
->T0
);
5131 gen_op_mov_reg_v(MO_64
, R_EAX
, s
->T0
);
5135 gen_op_mov_v_reg(MO_16
, s
->T0
, R_EAX
);
5136 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5137 gen_op_mov_reg_v(MO_32
, R_EAX
, s
->T0
);
5140 gen_op_mov_v_reg(MO_8
, s
->T0
, R_EAX
);
5141 tcg_gen_ext8s_tl(s
->T0
, s
->T0
);
5142 gen_op_mov_reg_v(MO_16
, R_EAX
, s
->T0
);
5148 case 0x99: /* CDQ/CWD */
5150 #ifdef TARGET_X86_64
5152 gen_op_mov_v_reg(MO_64
, s
->T0
, R_EAX
);
5153 tcg_gen_sari_tl(s
->T0
, s
->T0
, 63);
5154 gen_op_mov_reg_v(MO_64
, R_EDX
, s
->T0
);
5158 gen_op_mov_v_reg(MO_32
, s
->T0
, R_EAX
);
5159 tcg_gen_ext32s_tl(s
->T0
, s
->T0
);
5160 tcg_gen_sari_tl(s
->T0
, s
->T0
, 31);
5161 gen_op_mov_reg_v(MO_32
, R_EDX
, s
->T0
);
5164 gen_op_mov_v_reg(MO_16
, s
->T0
, R_EAX
);
5165 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5166 tcg_gen_sari_tl(s
->T0
, s
->T0
, 15);
5167 gen_op_mov_reg_v(MO_16
, R_EDX
, s
->T0
);
5173 case 0x1af: /* imul Gv, Ev */
5174 case 0x69: /* imul Gv, Ev, I */
5177 modrm
= x86_ldub_code(env
, s
);
5178 reg
= ((modrm
>> 3) & 7) | rex_r
;
5180 s
->rip_offset
= insn_const_size(ot
);
5183 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5185 val
= insn_get(env
, s
, ot
);
5186 tcg_gen_movi_tl(cpu_T1
, val
);
5187 } else if (b
== 0x6b) {
5188 val
= (int8_t)insn_get(env
, s
, MO_8
);
5189 tcg_gen_movi_tl(cpu_T1
, val
);
5191 gen_op_mov_v_reg(ot
, cpu_T1
, reg
);
5194 #ifdef TARGET_X86_64
5196 tcg_gen_muls2_i64(cpu_regs
[reg
], cpu_T1
, s
->T0
, cpu_T1
);
5197 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5198 tcg_gen_sari_tl(cpu_cc_src
, cpu_cc_dst
, 63);
5199 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_T1
);
5203 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
5204 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T1
);
5205 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
5206 cpu_tmp2_i32
, cpu_tmp3_i32
);
5207 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
5208 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
5209 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5210 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
5211 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
5214 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5215 tcg_gen_ext16s_tl(cpu_T1
, cpu_T1
);
5216 /* XXX: use 32 bit mul which could be faster */
5217 tcg_gen_mul_tl(s
->T0
, s
->T0
, cpu_T1
);
5218 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
5219 tcg_gen_ext16s_tl(cpu_tmp0
, s
->T0
);
5220 tcg_gen_sub_tl(cpu_cc_src
, s
->T0
, cpu_tmp0
);
5221 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
5224 set_cc_op(s
, CC_OP_MULB
+ ot
);
5227 case 0x1c1: /* xadd Ev, Gv */
5228 ot
= mo_b_d(b
, dflag
);
5229 modrm
= x86_ldub_code(env
, s
);
5230 reg
= ((modrm
>> 3) & 7) | rex_r
;
5231 mod
= (modrm
>> 6) & 3;
5232 gen_op_mov_v_reg(ot
, s
->T0
, reg
);
5234 rm
= (modrm
& 7) | REX_B(s
);
5235 gen_op_mov_v_reg(ot
, cpu_T1
, rm
);
5236 tcg_gen_add_tl(s
->T0
, s
->T0
, cpu_T1
);
5237 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
5238 gen_op_mov_reg_v(ot
, rm
, s
->T0
);
5240 gen_lea_modrm(env
, s
, modrm
);
5241 if (s
->prefix
& PREFIX_LOCK
) {
5242 tcg_gen_atomic_fetch_add_tl(cpu_T1
, s
->A0
, s
->T0
,
5243 s
->mem_index
, ot
| MO_LE
);
5244 tcg_gen_add_tl(s
->T0
, s
->T0
, cpu_T1
);
5246 gen_op_ld_v(s
, ot
, cpu_T1
, s
->A0
);
5247 tcg_gen_add_tl(s
->T0
, s
->T0
, cpu_T1
);
5248 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
5250 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
5252 gen_op_update2_cc(s
);
5253 set_cc_op(s
, CC_OP_ADDB
+ ot
);
5256 case 0x1b1: /* cmpxchg Ev, Gv */
5258 TCGv oldv
, newv
, cmpv
;
5260 ot
= mo_b_d(b
, dflag
);
5261 modrm
= x86_ldub_code(env
, s
);
5262 reg
= ((modrm
>> 3) & 7) | rex_r
;
5263 mod
= (modrm
>> 6) & 3;
5264 oldv
= tcg_temp_new();
5265 newv
= tcg_temp_new();
5266 cmpv
= tcg_temp_new();
5267 gen_op_mov_v_reg(ot
, newv
, reg
);
5268 tcg_gen_mov_tl(cmpv
, cpu_regs
[R_EAX
]);
5270 if (s
->prefix
& PREFIX_LOCK
) {
5274 gen_lea_modrm(env
, s
, modrm
);
5275 tcg_gen_atomic_cmpxchg_tl(oldv
, s
->A0
, cmpv
, newv
,
5276 s
->mem_index
, ot
| MO_LE
);
5277 gen_op_mov_reg_v(ot
, R_EAX
, oldv
);
5280 rm
= (modrm
& 7) | REX_B(s
);
5281 gen_op_mov_v_reg(ot
, oldv
, rm
);
5283 gen_lea_modrm(env
, s
, modrm
);
5284 gen_op_ld_v(s
, ot
, oldv
, s
->A0
);
5285 rm
= 0; /* avoid warning */
5289 /* store value = (old == cmp ? new : old); */
5290 tcg_gen_movcond_tl(TCG_COND_EQ
, newv
, oldv
, cmpv
, newv
, oldv
);
5292 gen_op_mov_reg_v(ot
, R_EAX
, oldv
);
5293 gen_op_mov_reg_v(ot
, rm
, newv
);
5295 /* Perform an unconditional store cycle like physical cpu;
5296 must be before changing accumulator to ensure
5297 idempotency if the store faults and the instruction
5299 gen_op_st_v(s
, ot
, newv
, s
->A0
);
5300 gen_op_mov_reg_v(ot
, R_EAX
, oldv
);
5303 tcg_gen_mov_tl(cpu_cc_src
, oldv
);
5304 tcg_gen_mov_tl(s
->cc_srcT
, cmpv
);
5305 tcg_gen_sub_tl(cpu_cc_dst
, cmpv
, oldv
);
5306 set_cc_op(s
, CC_OP_SUBB
+ ot
);
5307 tcg_temp_free(oldv
);
5308 tcg_temp_free(newv
);
5309 tcg_temp_free(cmpv
);
5312 case 0x1c7: /* cmpxchg8b */
5313 modrm
= x86_ldub_code(env
, s
);
5314 mod
= (modrm
>> 6) & 3;
5315 if ((mod
== 3) || ((modrm
& 0x38) != 0x8))
5317 #ifdef TARGET_X86_64
5318 if (dflag
== MO_64
) {
5319 if (!(s
->cpuid_ext_features
& CPUID_EXT_CX16
))
5321 gen_lea_modrm(env
, s
, modrm
);
5322 if ((s
->prefix
& PREFIX_LOCK
) && (tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
5323 gen_helper_cmpxchg16b(cpu_env
, s
->A0
);
5325 gen_helper_cmpxchg16b_unlocked(cpu_env
, s
->A0
);
5330 if (!(s
->cpuid_features
& CPUID_CX8
))
5332 gen_lea_modrm(env
, s
, modrm
);
5333 if ((s
->prefix
& PREFIX_LOCK
) && (tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
5334 gen_helper_cmpxchg8b(cpu_env
, s
->A0
);
5336 gen_helper_cmpxchg8b_unlocked(cpu_env
, s
->A0
);
5339 set_cc_op(s
, CC_OP_EFLAGS
);
5342 /**************************/
5344 case 0x50 ... 0x57: /* push */
5345 gen_op_mov_v_reg(MO_32
, s
->T0
, (b
& 7) | REX_B(s
));
5346 gen_push_v(s
, s
->T0
);
5348 case 0x58 ... 0x5f: /* pop */
5350 /* NOTE: order is important for pop %sp */
5351 gen_pop_update(s
, ot
);
5352 gen_op_mov_reg_v(ot
, (b
& 7) | REX_B(s
), s
->T0
);
5354 case 0x60: /* pusha */
5359 case 0x61: /* popa */
5364 case 0x68: /* push Iv */
5366 ot
= mo_pushpop(s
, dflag
);
5368 val
= insn_get(env
, s
, ot
);
5370 val
= (int8_t)insn_get(env
, s
, MO_8
);
5371 tcg_gen_movi_tl(s
->T0
, val
);
5372 gen_push_v(s
, s
->T0
);
5374 case 0x8f: /* pop Ev */
5375 modrm
= x86_ldub_code(env
, s
);
5376 mod
= (modrm
>> 6) & 3;
5379 /* NOTE: order is important for pop %sp */
5380 gen_pop_update(s
, ot
);
5381 rm
= (modrm
& 7) | REX_B(s
);
5382 gen_op_mov_reg_v(ot
, rm
, s
->T0
);
5384 /* NOTE: order is important too for MMU exceptions */
5385 s
->popl_esp_hack
= 1 << ot
;
5386 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5387 s
->popl_esp_hack
= 0;
5388 gen_pop_update(s
, ot
);
5391 case 0xc8: /* enter */
5394 val
= x86_lduw_code(env
, s
);
5395 level
= x86_ldub_code(env
, s
);
5396 gen_enter(s
, val
, level
);
5399 case 0xc9: /* leave */
5402 case 0x06: /* push es */
5403 case 0x0e: /* push cs */
5404 case 0x16: /* push ss */
5405 case 0x1e: /* push ds */
5408 gen_op_movl_T0_seg(s
, b
>> 3);
5409 gen_push_v(s
, s
->T0
);
5411 case 0x1a0: /* push fs */
5412 case 0x1a8: /* push gs */
5413 gen_op_movl_T0_seg(s
, (b
>> 3) & 7);
5414 gen_push_v(s
, s
->T0
);
5416 case 0x07: /* pop es */
5417 case 0x17: /* pop ss */
5418 case 0x1f: /* pop ds */
5423 gen_movl_seg_T0(s
, reg
);
5424 gen_pop_update(s
, ot
);
5425 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5426 if (s
->base
.is_jmp
) {
5427 gen_jmp_im(s
->pc
- s
->cs_base
);
5430 gen_eob_inhibit_irq(s
, true);
5436 case 0x1a1: /* pop fs */
5437 case 0x1a9: /* pop gs */
5439 gen_movl_seg_T0(s
, (b
>> 3) & 7);
5440 gen_pop_update(s
, ot
);
5441 if (s
->base
.is_jmp
) {
5442 gen_jmp_im(s
->pc
- s
->cs_base
);
5447 /**************************/
5450 case 0x89: /* mov Gv, Ev */
5451 ot
= mo_b_d(b
, dflag
);
5452 modrm
= x86_ldub_code(env
, s
);
5453 reg
= ((modrm
>> 3) & 7) | rex_r
;
5455 /* generate a generic store */
5456 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
5459 case 0xc7: /* mov Ev, Iv */
5460 ot
= mo_b_d(b
, dflag
);
5461 modrm
= x86_ldub_code(env
, s
);
5462 mod
= (modrm
>> 6) & 3;
5464 s
->rip_offset
= insn_const_size(ot
);
5465 gen_lea_modrm(env
, s
, modrm
);
5467 val
= insn_get(env
, s
, ot
);
5468 tcg_gen_movi_tl(s
->T0
, val
);
5470 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
5472 gen_op_mov_reg_v(ot
, (modrm
& 7) | REX_B(s
), s
->T0
);
5476 case 0x8b: /* mov Ev, Gv */
5477 ot
= mo_b_d(b
, dflag
);
5478 modrm
= x86_ldub_code(env
, s
);
5479 reg
= ((modrm
>> 3) & 7) | rex_r
;
5481 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5482 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
5484 case 0x8e: /* mov seg, Gv */
5485 modrm
= x86_ldub_code(env
, s
);
5486 reg
= (modrm
>> 3) & 7;
5487 if (reg
>= 6 || reg
== R_CS
)
5489 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
5490 gen_movl_seg_T0(s
, reg
);
5491 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5492 if (s
->base
.is_jmp
) {
5493 gen_jmp_im(s
->pc
- s
->cs_base
);
5496 gen_eob_inhibit_irq(s
, true);
5502 case 0x8c: /* mov Gv, seg */
5503 modrm
= x86_ldub_code(env
, s
);
5504 reg
= (modrm
>> 3) & 7;
5505 mod
= (modrm
>> 6) & 3;
5508 gen_op_movl_T0_seg(s
, reg
);
5509 ot
= mod
== 3 ? dflag
: MO_16
;
5510 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5513 case 0x1b6: /* movzbS Gv, Eb */
5514 case 0x1b7: /* movzwS Gv, Eb */
5515 case 0x1be: /* movsbS Gv, Eb */
5516 case 0x1bf: /* movswS Gv, Eb */
5521 /* d_ot is the size of destination */
5523 /* ot is the size of source */
5524 ot
= (b
& 1) + MO_8
;
5525 /* s_ot is the sign+size of source */
5526 s_ot
= b
& 8 ? MO_SIGN
| ot
: ot
;
5528 modrm
= x86_ldub_code(env
, s
);
5529 reg
= ((modrm
>> 3) & 7) | rex_r
;
5530 mod
= (modrm
>> 6) & 3;
5531 rm
= (modrm
& 7) | REX_B(s
);
5534 if (s_ot
== MO_SB
&& byte_reg_is_xH(rm
)) {
5535 tcg_gen_sextract_tl(s
->T0
, cpu_regs
[rm
- 4], 8, 8);
5537 gen_op_mov_v_reg(ot
, s
->T0
, rm
);
5540 tcg_gen_ext8u_tl(s
->T0
, s
->T0
);
5543 tcg_gen_ext8s_tl(s
->T0
, s
->T0
);
5546 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
5550 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5554 gen_op_mov_reg_v(d_ot
, reg
, s
->T0
);
5556 gen_lea_modrm(env
, s
, modrm
);
5557 gen_op_ld_v(s
, s_ot
, s
->T0
, s
->A0
);
5558 gen_op_mov_reg_v(d_ot
, reg
, s
->T0
);
5563 case 0x8d: /* lea */
5564 modrm
= x86_ldub_code(env
, s
);
5565 mod
= (modrm
>> 6) & 3;
5568 reg
= ((modrm
>> 3) & 7) | rex_r
;
5570 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
5571 TCGv ea
= gen_lea_modrm_1(s
, a
);
5572 gen_lea_v_seg(s
, s
->aflag
, ea
, -1, -1);
5573 gen_op_mov_reg_v(dflag
, reg
, s
->A0
);
5577 case 0xa0: /* mov EAX, Ov */
5579 case 0xa2: /* mov Ov, EAX */
5582 target_ulong offset_addr
;
5584 ot
= mo_b_d(b
, dflag
);
5586 #ifdef TARGET_X86_64
5588 offset_addr
= x86_ldq_code(env
, s
);
5592 offset_addr
= insn_get(env
, s
, s
->aflag
);
5595 tcg_gen_movi_tl(s
->A0
, offset_addr
);
5596 gen_add_A0_ds_seg(s
);
5598 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
5599 gen_op_mov_reg_v(ot
, R_EAX
, s
->T0
);
5601 gen_op_mov_v_reg(ot
, s
->T0
, R_EAX
);
5602 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
5606 case 0xd7: /* xlat */
5607 tcg_gen_mov_tl(s
->A0
, cpu_regs
[R_EBX
]);
5608 tcg_gen_ext8u_tl(s
->T0
, cpu_regs
[R_EAX
]);
5609 tcg_gen_add_tl(s
->A0
, s
->A0
, s
->T0
);
5610 gen_extu(s
->aflag
, s
->A0
);
5611 gen_add_A0_ds_seg(s
);
5612 gen_op_ld_v(s
, MO_8
, s
->T0
, s
->A0
);
5613 gen_op_mov_reg_v(MO_8
, R_EAX
, s
->T0
);
5615 case 0xb0 ... 0xb7: /* mov R, Ib */
5616 val
= insn_get(env
, s
, MO_8
);
5617 tcg_gen_movi_tl(s
->T0
, val
);
5618 gen_op_mov_reg_v(MO_8
, (b
& 7) | REX_B(s
), s
->T0
);
5620 case 0xb8 ... 0xbf: /* mov R, Iv */
5621 #ifdef TARGET_X86_64
5622 if (dflag
== MO_64
) {
5625 tmp
= x86_ldq_code(env
, s
);
5626 reg
= (b
& 7) | REX_B(s
);
5627 tcg_gen_movi_tl(s
->T0
, tmp
);
5628 gen_op_mov_reg_v(MO_64
, reg
, s
->T0
);
5633 val
= insn_get(env
, s
, ot
);
5634 reg
= (b
& 7) | REX_B(s
);
5635 tcg_gen_movi_tl(s
->T0
, val
);
5636 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
5640 case 0x91 ... 0x97: /* xchg R, EAX */
5643 reg
= (b
& 7) | REX_B(s
);
5647 case 0x87: /* xchg Ev, Gv */
5648 ot
= mo_b_d(b
, dflag
);
5649 modrm
= x86_ldub_code(env
, s
);
5650 reg
= ((modrm
>> 3) & 7) | rex_r
;
5651 mod
= (modrm
>> 6) & 3;
5653 rm
= (modrm
& 7) | REX_B(s
);
5655 gen_op_mov_v_reg(ot
, s
->T0
, reg
);
5656 gen_op_mov_v_reg(ot
, cpu_T1
, rm
);
5657 gen_op_mov_reg_v(ot
, rm
, s
->T0
);
5658 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
5660 gen_lea_modrm(env
, s
, modrm
);
5661 gen_op_mov_v_reg(ot
, s
->T0
, reg
);
5662 /* for xchg, lock is implicit */
5663 tcg_gen_atomic_xchg_tl(cpu_T1
, s
->A0
, s
->T0
,
5664 s
->mem_index
, ot
| MO_LE
);
5665 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
5668 case 0xc4: /* les Gv */
5669 /* In CODE64 this is VEX3; see above. */
5672 case 0xc5: /* lds Gv */
5673 /* In CODE64 this is VEX2; see above. */
5676 case 0x1b2: /* lss Gv */
5679 case 0x1b4: /* lfs Gv */
5682 case 0x1b5: /* lgs Gv */
5685 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
5686 modrm
= x86_ldub_code(env
, s
);
5687 reg
= ((modrm
>> 3) & 7) | rex_r
;
5688 mod
= (modrm
>> 6) & 3;
5691 gen_lea_modrm(env
, s
, modrm
);
5692 gen_op_ld_v(s
, ot
, cpu_T1
, s
->A0
);
5693 gen_add_A0_im(s
, 1 << ot
);
5694 /* load the segment first to handle exceptions properly */
5695 gen_op_ld_v(s
, MO_16
, s
->T0
, s
->A0
);
5696 gen_movl_seg_T0(s
, op
);
5697 /* then put the data */
5698 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
5699 if (s
->base
.is_jmp
) {
5700 gen_jmp_im(s
->pc
- s
->cs_base
);
5705 /************************/
5713 ot
= mo_b_d(b
, dflag
);
5714 modrm
= x86_ldub_code(env
, s
);
5715 mod
= (modrm
>> 6) & 3;
5716 op
= (modrm
>> 3) & 7;
5722 gen_lea_modrm(env
, s
, modrm
);
5725 opreg
= (modrm
& 7) | REX_B(s
);
5730 gen_shift(s
, op
, ot
, opreg
, OR_ECX
);
5733 shift
= x86_ldub_code(env
, s
);
5735 gen_shifti(s
, op
, ot
, opreg
, shift
);
5750 case 0x1a4: /* shld imm */
5754 case 0x1a5: /* shld cl */
5758 case 0x1ac: /* shrd imm */
5762 case 0x1ad: /* shrd cl */
5767 modrm
= x86_ldub_code(env
, s
);
5768 mod
= (modrm
>> 6) & 3;
5769 rm
= (modrm
& 7) | REX_B(s
);
5770 reg
= ((modrm
>> 3) & 7) | rex_r
;
5772 gen_lea_modrm(env
, s
, modrm
);
5777 gen_op_mov_v_reg(ot
, cpu_T1
, reg
);
5780 TCGv imm
= tcg_const_tl(x86_ldub_code(env
, s
));
5781 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, imm
);
5784 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, cpu_regs
[R_ECX
]);
5788 /************************/
5791 if (s
->flags
& (HF_EM_MASK
| HF_TS_MASK
)) {
5792 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5793 /* XXX: what to do if illegal op ? */
5794 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
5797 modrm
= x86_ldub_code(env
, s
);
5798 mod
= (modrm
>> 6) & 3;
5800 op
= ((b
& 7) << 3) | ((modrm
>> 3) & 7);
5803 gen_lea_modrm(env
, s
, modrm
);
5805 case 0x00 ... 0x07: /* fxxxs */
5806 case 0x10 ... 0x17: /* fixxxl */
5807 case 0x20 ... 0x27: /* fxxxl */
5808 case 0x30 ... 0x37: /* fixxx */
5815 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, s
->A0
,
5816 s
->mem_index
, MO_LEUL
);
5817 gen_helper_flds_FT0(cpu_env
, cpu_tmp2_i32
);
5820 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, s
->A0
,
5821 s
->mem_index
, MO_LEUL
);
5822 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
5825 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, s
->A0
,
5826 s
->mem_index
, MO_LEQ
);
5827 gen_helper_fldl_FT0(cpu_env
, cpu_tmp1_i64
);
5831 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, s
->A0
,
5832 s
->mem_index
, MO_LESW
);
5833 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
5837 gen_helper_fp_arith_ST0_FT0(op1
);
5839 /* fcomp needs pop */
5840 gen_helper_fpop(cpu_env
);
5844 case 0x08: /* flds */
5845 case 0x0a: /* fsts */
5846 case 0x0b: /* fstps */
5847 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5848 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5849 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5854 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, s
->A0
,
5855 s
->mem_index
, MO_LEUL
);
5856 gen_helper_flds_ST0(cpu_env
, cpu_tmp2_i32
);
5859 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, s
->A0
,
5860 s
->mem_index
, MO_LEUL
);
5861 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
5864 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, s
->A0
,
5865 s
->mem_index
, MO_LEQ
);
5866 gen_helper_fldl_ST0(cpu_env
, cpu_tmp1_i64
);
5870 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, s
->A0
,
5871 s
->mem_index
, MO_LESW
);
5872 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
5877 /* XXX: the corresponding CPUID bit must be tested ! */
5880 gen_helper_fisttl_ST0(cpu_tmp2_i32
, cpu_env
);
5881 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, s
->A0
,
5882 s
->mem_index
, MO_LEUL
);
5885 gen_helper_fisttll_ST0(cpu_tmp1_i64
, cpu_env
);
5886 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, s
->A0
,
5887 s
->mem_index
, MO_LEQ
);
5891 gen_helper_fistt_ST0(cpu_tmp2_i32
, cpu_env
);
5892 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, s
->A0
,
5893 s
->mem_index
, MO_LEUW
);
5896 gen_helper_fpop(cpu_env
);
5901 gen_helper_fsts_ST0(cpu_tmp2_i32
, cpu_env
);
5902 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, s
->A0
,
5903 s
->mem_index
, MO_LEUL
);
5906 gen_helper_fistl_ST0(cpu_tmp2_i32
, cpu_env
);
5907 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, s
->A0
,
5908 s
->mem_index
, MO_LEUL
);
5911 gen_helper_fstl_ST0(cpu_tmp1_i64
, cpu_env
);
5912 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, s
->A0
,
5913 s
->mem_index
, MO_LEQ
);
5917 gen_helper_fist_ST0(cpu_tmp2_i32
, cpu_env
);
5918 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, s
->A0
,
5919 s
->mem_index
, MO_LEUW
);
5923 gen_helper_fpop(cpu_env
);
5927 case 0x0c: /* fldenv mem */
5928 gen_helper_fldenv(cpu_env
, s
->A0
, tcg_const_i32(dflag
- 1));
5930 case 0x0d: /* fldcw mem */
5931 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, s
->A0
,
5932 s
->mem_index
, MO_LEUW
);
5933 gen_helper_fldcw(cpu_env
, cpu_tmp2_i32
);
5935 case 0x0e: /* fnstenv mem */
5936 gen_helper_fstenv(cpu_env
, s
->A0
, tcg_const_i32(dflag
- 1));
5938 case 0x0f: /* fnstcw mem */
5939 gen_helper_fnstcw(cpu_tmp2_i32
, cpu_env
);
5940 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, s
->A0
,
5941 s
->mem_index
, MO_LEUW
);
5943 case 0x1d: /* fldt mem */
5944 gen_helper_fldt_ST0(cpu_env
, s
->A0
);
5946 case 0x1f: /* fstpt mem */
5947 gen_helper_fstt_ST0(cpu_env
, s
->A0
);
5948 gen_helper_fpop(cpu_env
);
5950 case 0x2c: /* frstor mem */
5951 gen_helper_frstor(cpu_env
, s
->A0
, tcg_const_i32(dflag
- 1));
5953 case 0x2e: /* fnsave mem */
5954 gen_helper_fsave(cpu_env
, s
->A0
, tcg_const_i32(dflag
- 1));
5956 case 0x2f: /* fnstsw mem */
5957 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
5958 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, s
->A0
,
5959 s
->mem_index
, MO_LEUW
);
5961 case 0x3c: /* fbld */
5962 gen_helper_fbld_ST0(cpu_env
, s
->A0
);
5964 case 0x3e: /* fbstp */
5965 gen_helper_fbst_ST0(cpu_env
, s
->A0
);
5966 gen_helper_fpop(cpu_env
);
5968 case 0x3d: /* fildll */
5969 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, s
->A0
, s
->mem_index
, MO_LEQ
);
5970 gen_helper_fildll_ST0(cpu_env
, cpu_tmp1_i64
);
5972 case 0x3f: /* fistpll */
5973 gen_helper_fistll_ST0(cpu_tmp1_i64
, cpu_env
);
5974 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, s
->A0
, s
->mem_index
, MO_LEQ
);
5975 gen_helper_fpop(cpu_env
);
5981 /* register float ops */
5985 case 0x08: /* fld sti */
5986 gen_helper_fpush(cpu_env
);
5987 gen_helper_fmov_ST0_STN(cpu_env
,
5988 tcg_const_i32((opreg
+ 1) & 7));
5990 case 0x09: /* fxchg sti */
5991 case 0x29: /* fxchg4 sti, undocumented op */
5992 case 0x39: /* fxchg7 sti, undocumented op */
5993 gen_helper_fxchg_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
5995 case 0x0a: /* grp d9/2 */
5998 /* check exceptions (FreeBSD FPU probe) */
5999 gen_helper_fwait(cpu_env
);
6005 case 0x0c: /* grp d9/4 */
6008 gen_helper_fchs_ST0(cpu_env
);
6011 gen_helper_fabs_ST0(cpu_env
);
6014 gen_helper_fldz_FT0(cpu_env
);
6015 gen_helper_fcom_ST0_FT0(cpu_env
);
6018 gen_helper_fxam_ST0(cpu_env
);
6024 case 0x0d: /* grp d9/5 */
6028 gen_helper_fpush(cpu_env
);
6029 gen_helper_fld1_ST0(cpu_env
);
6032 gen_helper_fpush(cpu_env
);
6033 gen_helper_fldl2t_ST0(cpu_env
);
6036 gen_helper_fpush(cpu_env
);
6037 gen_helper_fldl2e_ST0(cpu_env
);
6040 gen_helper_fpush(cpu_env
);
6041 gen_helper_fldpi_ST0(cpu_env
);
6044 gen_helper_fpush(cpu_env
);
6045 gen_helper_fldlg2_ST0(cpu_env
);
6048 gen_helper_fpush(cpu_env
);
6049 gen_helper_fldln2_ST0(cpu_env
);
6052 gen_helper_fpush(cpu_env
);
6053 gen_helper_fldz_ST0(cpu_env
);
6060 case 0x0e: /* grp d9/6 */
6063 gen_helper_f2xm1(cpu_env
);
6066 gen_helper_fyl2x(cpu_env
);
6069 gen_helper_fptan(cpu_env
);
6071 case 3: /* fpatan */
6072 gen_helper_fpatan(cpu_env
);
6074 case 4: /* fxtract */
6075 gen_helper_fxtract(cpu_env
);
6077 case 5: /* fprem1 */
6078 gen_helper_fprem1(cpu_env
);
6080 case 6: /* fdecstp */
6081 gen_helper_fdecstp(cpu_env
);
6084 case 7: /* fincstp */
6085 gen_helper_fincstp(cpu_env
);
6089 case 0x0f: /* grp d9/7 */
6092 gen_helper_fprem(cpu_env
);
6094 case 1: /* fyl2xp1 */
6095 gen_helper_fyl2xp1(cpu_env
);
6098 gen_helper_fsqrt(cpu_env
);
6100 case 3: /* fsincos */
6101 gen_helper_fsincos(cpu_env
);
6103 case 5: /* fscale */
6104 gen_helper_fscale(cpu_env
);
6106 case 4: /* frndint */
6107 gen_helper_frndint(cpu_env
);
6110 gen_helper_fsin(cpu_env
);
6114 gen_helper_fcos(cpu_env
);
6118 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6119 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6120 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6126 gen_helper_fp_arith_STN_ST0(op1
, opreg
);
6128 gen_helper_fpop(cpu_env
);
6130 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6131 gen_helper_fp_arith_ST0_FT0(op1
);
6135 case 0x02: /* fcom */
6136 case 0x22: /* fcom2, undocumented op */
6137 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6138 gen_helper_fcom_ST0_FT0(cpu_env
);
6140 case 0x03: /* fcomp */
6141 case 0x23: /* fcomp3, undocumented op */
6142 case 0x32: /* fcomp5, undocumented op */
6143 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6144 gen_helper_fcom_ST0_FT0(cpu_env
);
6145 gen_helper_fpop(cpu_env
);
6147 case 0x15: /* da/5 */
6149 case 1: /* fucompp */
6150 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6151 gen_helper_fucom_ST0_FT0(cpu_env
);
6152 gen_helper_fpop(cpu_env
);
6153 gen_helper_fpop(cpu_env
);
6161 case 0: /* feni (287 only, just do nop here) */
6163 case 1: /* fdisi (287 only, just do nop here) */
6166 gen_helper_fclex(cpu_env
);
6168 case 3: /* fninit */
6169 gen_helper_fninit(cpu_env
);
6171 case 4: /* fsetpm (287 only, just do nop here) */
6177 case 0x1d: /* fucomi */
6178 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6181 gen_update_cc_op(s
);
6182 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6183 gen_helper_fucomi_ST0_FT0(cpu_env
);
6184 set_cc_op(s
, CC_OP_EFLAGS
);
6186 case 0x1e: /* fcomi */
6187 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6190 gen_update_cc_op(s
);
6191 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6192 gen_helper_fcomi_ST0_FT0(cpu_env
);
6193 set_cc_op(s
, CC_OP_EFLAGS
);
6195 case 0x28: /* ffree sti */
6196 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6198 case 0x2a: /* fst sti */
6199 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6201 case 0x2b: /* fstp sti */
6202 case 0x0b: /* fstp1 sti, undocumented op */
6203 case 0x3a: /* fstp8 sti, undocumented op */
6204 case 0x3b: /* fstp9 sti, undocumented op */
6205 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6206 gen_helper_fpop(cpu_env
);
6208 case 0x2c: /* fucom st(i) */
6209 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6210 gen_helper_fucom_ST0_FT0(cpu_env
);
6212 case 0x2d: /* fucomp st(i) */
6213 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6214 gen_helper_fucom_ST0_FT0(cpu_env
);
6215 gen_helper_fpop(cpu_env
);
6217 case 0x33: /* de/3 */
6219 case 1: /* fcompp */
6220 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6221 gen_helper_fcom_ST0_FT0(cpu_env
);
6222 gen_helper_fpop(cpu_env
);
6223 gen_helper_fpop(cpu_env
);
6229 case 0x38: /* ffreep sti, undocumented op */
6230 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6231 gen_helper_fpop(cpu_env
);
6233 case 0x3c: /* df/4 */
6236 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
6237 tcg_gen_extu_i32_tl(s
->T0
, cpu_tmp2_i32
);
6238 gen_op_mov_reg_v(MO_16
, R_EAX
, s
->T0
);
6244 case 0x3d: /* fucomip */
6245 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6248 gen_update_cc_op(s
);
6249 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6250 gen_helper_fucomi_ST0_FT0(cpu_env
);
6251 gen_helper_fpop(cpu_env
);
6252 set_cc_op(s
, CC_OP_EFLAGS
);
6254 case 0x3e: /* fcomip */
6255 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6258 gen_update_cc_op(s
);
6259 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6260 gen_helper_fcomi_ST0_FT0(cpu_env
);
6261 gen_helper_fpop(cpu_env
);
6262 set_cc_op(s
, CC_OP_EFLAGS
);
6264 case 0x10 ... 0x13: /* fcmovxx */
6269 static const uint8_t fcmov_cc
[8] = {
6276 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6279 op1
= fcmov_cc
[op
& 3] | (((op
>> 3) & 1) ^ 1);
6280 l1
= gen_new_label();
6281 gen_jcc1_noeob(s
, op1
, l1
);
6282 gen_helper_fmov_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6291 /************************/
6294 case 0xa4: /* movsS */
6296 ot
= mo_b_d(b
, dflag
);
6297 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6298 gen_repz_movs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6304 case 0xaa: /* stosS */
6306 ot
= mo_b_d(b
, dflag
);
6307 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6308 gen_repz_stos(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6313 case 0xac: /* lodsS */
6315 ot
= mo_b_d(b
, dflag
);
6316 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6317 gen_repz_lods(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6322 case 0xae: /* scasS */
6324 ot
= mo_b_d(b
, dflag
);
6325 if (prefixes
& PREFIX_REPNZ
) {
6326 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6327 } else if (prefixes
& PREFIX_REPZ
) {
6328 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6334 case 0xa6: /* cmpsS */
6336 ot
= mo_b_d(b
, dflag
);
6337 if (prefixes
& PREFIX_REPNZ
) {
6338 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6339 } else if (prefixes
& PREFIX_REPZ
) {
6340 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6345 case 0x6c: /* insS */
6347 ot
= mo_b_d32(b
, dflag
);
6348 tcg_gen_ext16u_tl(s
->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
) | 4);
6351 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6352 gen_repz_ins(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6355 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6356 gen_jmp(s
, s
->pc
- s
->cs_base
);
6360 case 0x6e: /* outsS */
6362 ot
= mo_b_d32(b
, dflag
);
6363 tcg_gen_ext16u_tl(s
->T0
, cpu_regs
[R_EDX
]);
6364 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6365 svm_is_rep(prefixes
) | 4);
6366 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6367 gen_repz_outs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6370 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6371 gen_jmp(s
, s
->pc
- s
->cs_base
);
6376 /************************/
6381 ot
= mo_b_d32(b
, dflag
);
6382 val
= x86_ldub_code(env
, s
);
6383 tcg_gen_movi_tl(s
->T0
, val
);
6384 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6385 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6386 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6389 tcg_gen_movi_i32(cpu_tmp2_i32
, val
);
6390 gen_helper_in_func(ot
, cpu_T1
, cpu_tmp2_i32
);
6391 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T1
);
6392 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6393 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6395 gen_jmp(s
, s
->pc
- s
->cs_base
);
6400 ot
= mo_b_d32(b
, dflag
);
6401 val
= x86_ldub_code(env
, s
);
6402 tcg_gen_movi_tl(s
->T0
, val
);
6403 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6404 svm_is_rep(prefixes
));
6405 gen_op_mov_v_reg(ot
, cpu_T1
, R_EAX
);
6407 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6410 tcg_gen_movi_i32(cpu_tmp2_i32
, val
);
6411 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T1
);
6412 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6413 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6414 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6416 gen_jmp(s
, s
->pc
- s
->cs_base
);
6421 ot
= mo_b_d32(b
, dflag
);
6422 tcg_gen_ext16u_tl(s
->T0
, cpu_regs
[R_EDX
]);
6423 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6424 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6425 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6428 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
6429 gen_helper_in_func(ot
, cpu_T1
, cpu_tmp2_i32
);
6430 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T1
);
6431 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6432 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6434 gen_jmp(s
, s
->pc
- s
->cs_base
);
6439 ot
= mo_b_d32(b
, dflag
);
6440 tcg_gen_ext16u_tl(s
->T0
, cpu_regs
[R_EDX
]);
6441 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6442 svm_is_rep(prefixes
));
6443 gen_op_mov_v_reg(ot
, cpu_T1
, R_EAX
);
6445 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6448 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
6449 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T1
);
6450 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6451 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6452 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6454 gen_jmp(s
, s
->pc
- s
->cs_base
);
6458 /************************/
6460 case 0xc2: /* ret im */
6461 val
= x86_ldsw_code(env
, s
);
6463 gen_stack_update(s
, val
+ (1 << ot
));
6464 /* Note that gen_pop_T0 uses a zero-extending load. */
6465 gen_op_jmp_v(s
->T0
);
6469 case 0xc3: /* ret */
6471 gen_pop_update(s
, ot
);
6472 /* Note that gen_pop_T0 uses a zero-extending load. */
6473 gen_op_jmp_v(s
->T0
);
6477 case 0xca: /* lret im */
6478 val
= x86_ldsw_code(env
, s
);
6480 if (s
->pe
&& !s
->vm86
) {
6481 gen_update_cc_op(s
);
6482 gen_jmp_im(pc_start
- s
->cs_base
);
6483 gen_helper_lret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6484 tcg_const_i32(val
));
6488 gen_op_ld_v(s
, dflag
, s
->T0
, s
->A0
);
6489 /* NOTE: keeping EIP updated is not a problem in case of
6491 gen_op_jmp_v(s
->T0
);
6493 gen_add_A0_im(s
, 1 << dflag
);
6494 gen_op_ld_v(s
, dflag
, s
->T0
, s
->A0
);
6495 gen_op_movl_seg_T0_vm(s
, R_CS
);
6496 /* add stack offset */
6497 gen_stack_update(s
, val
+ (2 << dflag
));
6501 case 0xcb: /* lret */
6504 case 0xcf: /* iret */
6505 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IRET
);
6508 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6509 set_cc_op(s
, CC_OP_EFLAGS
);
6510 } else if (s
->vm86
) {
6512 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6514 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6515 set_cc_op(s
, CC_OP_EFLAGS
);
6518 gen_helper_iret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6519 tcg_const_i32(s
->pc
- s
->cs_base
));
6520 set_cc_op(s
, CC_OP_EFLAGS
);
6524 case 0xe8: /* call im */
6526 if (dflag
!= MO_16
) {
6527 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6529 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6531 next_eip
= s
->pc
- s
->cs_base
;
6533 if (dflag
== MO_16
) {
6535 } else if (!CODE64(s
)) {
6538 tcg_gen_movi_tl(s
->T0
, next_eip
);
6539 gen_push_v(s
, s
->T0
);
6544 case 0x9a: /* lcall im */
6546 unsigned int selector
, offset
;
6551 offset
= insn_get(env
, s
, ot
);
6552 selector
= insn_get(env
, s
, MO_16
);
6554 tcg_gen_movi_tl(s
->T0
, selector
);
6555 tcg_gen_movi_tl(cpu_T1
, offset
);
6558 case 0xe9: /* jmp im */
6559 if (dflag
!= MO_16
) {
6560 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6562 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6564 tval
+= s
->pc
- s
->cs_base
;
6565 if (dflag
== MO_16
) {
6567 } else if (!CODE64(s
)) {
6573 case 0xea: /* ljmp im */
6575 unsigned int selector
, offset
;
6580 offset
= insn_get(env
, s
, ot
);
6581 selector
= insn_get(env
, s
, MO_16
);
6583 tcg_gen_movi_tl(s
->T0
, selector
);
6584 tcg_gen_movi_tl(cpu_T1
, offset
);
6587 case 0xeb: /* jmp Jb */
6588 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6589 tval
+= s
->pc
- s
->cs_base
;
6590 if (dflag
== MO_16
) {
6595 case 0x70 ... 0x7f: /* jcc Jb */
6596 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6598 case 0x180 ... 0x18f: /* jcc Jv */
6599 if (dflag
!= MO_16
) {
6600 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6602 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6605 next_eip
= s
->pc
- s
->cs_base
;
6607 if (dflag
== MO_16
) {
6611 gen_jcc(s
, b
, tval
, next_eip
);
6614 case 0x190 ... 0x19f: /* setcc Gv */
6615 modrm
= x86_ldub_code(env
, s
);
6616 gen_setcc1(s
, b
, s
->T0
);
6617 gen_ldst_modrm(env
, s
, modrm
, MO_8
, OR_TMP0
, 1);
6619 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6620 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6624 modrm
= x86_ldub_code(env
, s
);
6625 reg
= ((modrm
>> 3) & 7) | rex_r
;
6626 gen_cmovcc1(env
, s
, ot
, b
, modrm
, reg
);
6629 /************************/
6631 case 0x9c: /* pushf */
6632 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_PUSHF
);
6633 if (s
->vm86
&& s
->iopl
!= 3) {
6634 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6636 gen_update_cc_op(s
);
6637 gen_helper_read_eflags(s
->T0
, cpu_env
);
6638 gen_push_v(s
, s
->T0
);
6641 case 0x9d: /* popf */
6642 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_POPF
);
6643 if (s
->vm86
&& s
->iopl
!= 3) {
6644 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6648 if (dflag
!= MO_16
) {
6649 gen_helper_write_eflags(cpu_env
, s
->T0
,
6650 tcg_const_i32((TF_MASK
| AC_MASK
|
6655 gen_helper_write_eflags(cpu_env
, s
->T0
,
6656 tcg_const_i32((TF_MASK
| AC_MASK
|
6658 IF_MASK
| IOPL_MASK
)
6662 if (s
->cpl
<= s
->iopl
) {
6663 if (dflag
!= MO_16
) {
6664 gen_helper_write_eflags(cpu_env
, s
->T0
,
6665 tcg_const_i32((TF_MASK
|
6671 gen_helper_write_eflags(cpu_env
, s
->T0
,
6672 tcg_const_i32((TF_MASK
|
6680 if (dflag
!= MO_16
) {
6681 gen_helper_write_eflags(cpu_env
, s
->T0
,
6682 tcg_const_i32((TF_MASK
| AC_MASK
|
6683 ID_MASK
| NT_MASK
)));
6685 gen_helper_write_eflags(cpu_env
, s
->T0
,
6686 tcg_const_i32((TF_MASK
| AC_MASK
|
6692 gen_pop_update(s
, ot
);
6693 set_cc_op(s
, CC_OP_EFLAGS
);
6694 /* abort translation because TF/AC flag may change */
6695 gen_jmp_im(s
->pc
- s
->cs_base
);
6699 case 0x9e: /* sahf */
6700 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6702 gen_op_mov_v_reg(MO_8
, s
->T0
, R_AH
);
6703 gen_compute_eflags(s
);
6704 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, CC_O
);
6705 tcg_gen_andi_tl(s
->T0
, s
->T0
, CC_S
| CC_Z
| CC_A
| CC_P
| CC_C
);
6706 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, s
->T0
);
6708 case 0x9f: /* lahf */
6709 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6711 gen_compute_eflags(s
);
6712 /* Note: gen_compute_eflags() only gives the condition codes */
6713 tcg_gen_ori_tl(s
->T0
, cpu_cc_src
, 0x02);
6714 gen_op_mov_reg_v(MO_8
, R_AH
, s
->T0
);
6716 case 0xf5: /* cmc */
6717 gen_compute_eflags(s
);
6718 tcg_gen_xori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6720 case 0xf8: /* clc */
6721 gen_compute_eflags(s
);
6722 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_C
);
6724 case 0xf9: /* stc */
6725 gen_compute_eflags(s
);
6726 tcg_gen_ori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6728 case 0xfc: /* cld */
6729 tcg_gen_movi_i32(cpu_tmp2_i32
, 1);
6730 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6732 case 0xfd: /* std */
6733 tcg_gen_movi_i32(cpu_tmp2_i32
, -1);
6734 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6737 /************************/
6738 /* bit operations */
6739 case 0x1ba: /* bt/bts/btr/btc Gv, im */
6741 modrm
= x86_ldub_code(env
, s
);
6742 op
= (modrm
>> 3) & 7;
6743 mod
= (modrm
>> 6) & 3;
6744 rm
= (modrm
& 7) | REX_B(s
);
6747 gen_lea_modrm(env
, s
, modrm
);
6748 if (!(s
->prefix
& PREFIX_LOCK
)) {
6749 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
6752 gen_op_mov_v_reg(ot
, s
->T0
, rm
);
6755 val
= x86_ldub_code(env
, s
);
6756 tcg_gen_movi_tl(cpu_T1
, val
);
6761 case 0x1a3: /* bt Gv, Ev */
6764 case 0x1ab: /* bts */
6767 case 0x1b3: /* btr */
6770 case 0x1bb: /* btc */
6774 modrm
= x86_ldub_code(env
, s
);
6775 reg
= ((modrm
>> 3) & 7) | rex_r
;
6776 mod
= (modrm
>> 6) & 3;
6777 rm
= (modrm
& 7) | REX_B(s
);
6778 gen_op_mov_v_reg(MO_32
, cpu_T1
, reg
);
6780 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
6781 /* specific case: we need to add a displacement */
6782 gen_exts(ot
, cpu_T1
);
6783 tcg_gen_sari_tl(cpu_tmp0
, cpu_T1
, 3 + ot
);
6784 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, ot
);
6785 tcg_gen_add_tl(s
->A0
, gen_lea_modrm_1(s
, a
), cpu_tmp0
);
6786 gen_lea_v_seg(s
, s
->aflag
, s
->A0
, a
.def_seg
, s
->override
);
6787 if (!(s
->prefix
& PREFIX_LOCK
)) {
6788 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
6791 gen_op_mov_v_reg(ot
, s
->T0
, rm
);
6794 tcg_gen_andi_tl(cpu_T1
, cpu_T1
, (1 << (3 + ot
)) - 1);
6795 tcg_gen_movi_tl(cpu_tmp0
, 1);
6796 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T1
);
6797 if (s
->prefix
& PREFIX_LOCK
) {
6800 /* Needs no atomic ops; we surpressed the normal
6801 memory load for LOCK above so do it now. */
6802 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
6805 tcg_gen_atomic_fetch_or_tl(s
->T0
, s
->A0
, cpu_tmp0
,
6806 s
->mem_index
, ot
| MO_LE
);
6809 tcg_gen_not_tl(cpu_tmp0
, cpu_tmp0
);
6810 tcg_gen_atomic_fetch_and_tl(s
->T0
, s
->A0
, cpu_tmp0
,
6811 s
->mem_index
, ot
| MO_LE
);
6815 tcg_gen_atomic_fetch_xor_tl(s
->T0
, s
->A0
, cpu_tmp0
,
6816 s
->mem_index
, ot
| MO_LE
);
6819 tcg_gen_shr_tl(cpu_tmp4
, s
->T0
, cpu_T1
);
6821 tcg_gen_shr_tl(cpu_tmp4
, s
->T0
, cpu_T1
);
6824 /* Data already loaded; nothing to do. */
6827 tcg_gen_or_tl(s
->T0
, s
->T0
, cpu_tmp0
);
6830 tcg_gen_andc_tl(s
->T0
, s
->T0
, cpu_tmp0
);
6834 tcg_gen_xor_tl(s
->T0
, s
->T0
, cpu_tmp0
);
6839 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
6841 gen_op_mov_reg_v(ot
, rm
, s
->T0
);
6846 /* Delay all CC updates until after the store above. Note that
6847 C is the result of the test, Z is unchanged, and the others
6848 are all undefined. */
6850 case CC_OP_MULB
... CC_OP_MULQ
:
6851 case CC_OP_ADDB
... CC_OP_ADDQ
:
6852 case CC_OP_ADCB
... CC_OP_ADCQ
:
6853 case CC_OP_SUBB
... CC_OP_SUBQ
:
6854 case CC_OP_SBBB
... CC_OP_SBBQ
:
6855 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
6856 case CC_OP_INCB
... CC_OP_INCQ
:
6857 case CC_OP_DECB
... CC_OP_DECQ
:
6858 case CC_OP_SHLB
... CC_OP_SHLQ
:
6859 case CC_OP_SARB
... CC_OP_SARQ
:
6860 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
6861 /* Z was going to be computed from the non-zero status of CC_DST.
6862 We can get that same Z value (and the new C value) by leaving
6863 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
6865 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
6866 set_cc_op(s
, ((s
->cc_op
- CC_OP_MULB
) & 3) + CC_OP_SARB
);
6869 /* Otherwise, generate EFLAGS and replace the C bit. */
6870 gen_compute_eflags(s
);
6871 tcg_gen_deposit_tl(cpu_cc_src
, cpu_cc_src
, cpu_tmp4
,
6876 case 0x1bc: /* bsf / tzcnt */
6877 case 0x1bd: /* bsr / lzcnt */
6879 modrm
= x86_ldub_code(env
, s
);
6880 reg
= ((modrm
>> 3) & 7) | rex_r
;
6881 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
6882 gen_extu(ot
, s
->T0
);
6884 /* Note that lzcnt and tzcnt are in different extensions. */
6885 if ((prefixes
& PREFIX_REPZ
)
6887 ? s
->cpuid_ext3_features
& CPUID_EXT3_ABM
6888 : s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)) {
6890 /* For lzcnt/tzcnt, C bit is defined related to the input. */
6891 tcg_gen_mov_tl(cpu_cc_src
, s
->T0
);
6893 /* For lzcnt, reduce the target_ulong result by the
6894 number of zeros that we expect to find at the top. */
6895 tcg_gen_clzi_tl(s
->T0
, s
->T0
, TARGET_LONG_BITS
);
6896 tcg_gen_subi_tl(s
->T0
, s
->T0
, TARGET_LONG_BITS
- size
);
6898 /* For tzcnt, a zero input must return the operand size. */
6899 tcg_gen_ctzi_tl(s
->T0
, s
->T0
, size
);
6901 /* For lzcnt/tzcnt, Z bit is defined related to the result. */
6902 gen_op_update1_cc(s
);
6903 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
6905 /* For bsr/bsf, only the Z bit is defined and it is related
6906 to the input and not the result. */
6907 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
6908 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
6910 /* ??? The manual says that the output is undefined when the
6911 input is zero, but real hardware leaves it unchanged, and
6912 real programs appear to depend on that. Accomplish this
6913 by passing the output as the value to return upon zero. */
6915 /* For bsr, return the bit index of the first 1 bit,
6916 not the count of leading zeros. */
6917 tcg_gen_xori_tl(cpu_T1
, cpu_regs
[reg
], TARGET_LONG_BITS
- 1);
6918 tcg_gen_clz_tl(s
->T0
, s
->T0
, cpu_T1
);
6919 tcg_gen_xori_tl(s
->T0
, s
->T0
, TARGET_LONG_BITS
- 1);
6921 tcg_gen_ctz_tl(s
->T0
, s
->T0
, cpu_regs
[reg
]);
6924 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
6926 /************************/
6928 case 0x27: /* daa */
6931 gen_update_cc_op(s
);
6932 gen_helper_daa(cpu_env
);
6933 set_cc_op(s
, CC_OP_EFLAGS
);
6935 case 0x2f: /* das */
6938 gen_update_cc_op(s
);
6939 gen_helper_das(cpu_env
);
6940 set_cc_op(s
, CC_OP_EFLAGS
);
6942 case 0x37: /* aaa */
6945 gen_update_cc_op(s
);
6946 gen_helper_aaa(cpu_env
);
6947 set_cc_op(s
, CC_OP_EFLAGS
);
6949 case 0x3f: /* aas */
6952 gen_update_cc_op(s
);
6953 gen_helper_aas(cpu_env
);
6954 set_cc_op(s
, CC_OP_EFLAGS
);
6956 case 0xd4: /* aam */
6959 val
= x86_ldub_code(env
, s
);
6961 gen_exception(s
, EXCP00_DIVZ
, pc_start
- s
->cs_base
);
6963 gen_helper_aam(cpu_env
, tcg_const_i32(val
));
6964 set_cc_op(s
, CC_OP_LOGICB
);
6967 case 0xd5: /* aad */
6970 val
= x86_ldub_code(env
, s
);
6971 gen_helper_aad(cpu_env
, tcg_const_i32(val
));
6972 set_cc_op(s
, CC_OP_LOGICB
);
6974 /************************/
6976 case 0x90: /* nop */
6977 /* XXX: correct lock test for all insn */
6978 if (prefixes
& PREFIX_LOCK
) {
6981 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
6983 goto do_xchg_reg_eax
;
6985 if (prefixes
& PREFIX_REPZ
) {
6986 gen_update_cc_op(s
);
6987 gen_jmp_im(pc_start
- s
->cs_base
);
6988 gen_helper_pause(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
6989 s
->base
.is_jmp
= DISAS_NORETURN
;
6992 case 0x9b: /* fwait */
6993 if ((s
->flags
& (HF_MP_MASK
| HF_TS_MASK
)) ==
6994 (HF_MP_MASK
| HF_TS_MASK
)) {
6995 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
6997 gen_helper_fwait(cpu_env
);
7000 case 0xcc: /* int3 */
7001 gen_interrupt(s
, EXCP03_INT3
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
7003 case 0xcd: /* int N */
7004 val
= x86_ldub_code(env
, s
);
7005 if (s
->vm86
&& s
->iopl
!= 3) {
7006 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7008 gen_interrupt(s
, val
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
7011 case 0xce: /* into */
7014 gen_update_cc_op(s
);
7015 gen_jmp_im(pc_start
- s
->cs_base
);
7016 gen_helper_into(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7019 case 0xf1: /* icebp (undocumented, exits to external debugger) */
7020 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_ICEBP
);
7022 gen_debug(s
, pc_start
- s
->cs_base
);
7025 tb_flush(CPU(x86_env_get_cpu(env
)));
7026 qemu_set_log(CPU_LOG_INT
| CPU_LOG_TB_IN_ASM
);
7030 case 0xfa: /* cli */
7032 if (s
->cpl
<= s
->iopl
) {
7033 gen_helper_cli(cpu_env
);
7035 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7039 gen_helper_cli(cpu_env
);
7041 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7045 case 0xfb: /* sti */
7046 if (s
->vm86
? s
->iopl
== 3 : s
->cpl
<= s
->iopl
) {
7047 gen_helper_sti(cpu_env
);
7048 /* interruptions are enabled only the first insn after sti */
7049 gen_jmp_im(s
->pc
- s
->cs_base
);
7050 gen_eob_inhibit_irq(s
, true);
7052 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7055 case 0x62: /* bound */
7059 modrm
= x86_ldub_code(env
, s
);
7060 reg
= (modrm
>> 3) & 7;
7061 mod
= (modrm
>> 6) & 3;
7064 gen_op_mov_v_reg(ot
, s
->T0
, reg
);
7065 gen_lea_modrm(env
, s
, modrm
);
7066 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
7068 gen_helper_boundw(cpu_env
, s
->A0
, cpu_tmp2_i32
);
7070 gen_helper_boundl(cpu_env
, s
->A0
, cpu_tmp2_i32
);
7073 case 0x1c8 ... 0x1cf: /* bswap reg */
7074 reg
= (b
& 7) | REX_B(s
);
7075 #ifdef TARGET_X86_64
7076 if (dflag
== MO_64
) {
7077 gen_op_mov_v_reg(MO_64
, s
->T0
, reg
);
7078 tcg_gen_bswap64_i64(s
->T0
, s
->T0
);
7079 gen_op_mov_reg_v(MO_64
, reg
, s
->T0
);
7083 gen_op_mov_v_reg(MO_32
, s
->T0
, reg
);
7084 tcg_gen_ext32u_tl(s
->T0
, s
->T0
);
7085 tcg_gen_bswap32_tl(s
->T0
, s
->T0
);
7086 gen_op_mov_reg_v(MO_32
, reg
, s
->T0
);
7089 case 0xd6: /* salc */
7092 gen_compute_eflags_c(s
, s
->T0
);
7093 tcg_gen_neg_tl(s
->T0
, s
->T0
);
7094 gen_op_mov_reg_v(MO_8
, R_EAX
, s
->T0
);
7096 case 0xe0: /* loopnz */
7097 case 0xe1: /* loopz */
7098 case 0xe2: /* loop */
7099 case 0xe3: /* jecxz */
7101 TCGLabel
*l1
, *l2
, *l3
;
7103 tval
= (int8_t)insn_get(env
, s
, MO_8
);
7104 next_eip
= s
->pc
- s
->cs_base
;
7106 if (dflag
== MO_16
) {
7110 l1
= gen_new_label();
7111 l2
= gen_new_label();
7112 l3
= gen_new_label();
7115 case 0: /* loopnz */
7117 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
7118 gen_op_jz_ecx(s
->aflag
, l3
);
7119 gen_jcc1(s
, (JCC_Z
<< 1) | (b
^ 1), l1
);
7122 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
7123 gen_op_jnz_ecx(s
->aflag
, l1
);
7127 gen_op_jz_ecx(s
->aflag
, l1
);
7132 gen_jmp_im(next_eip
);
7141 case 0x130: /* wrmsr */
7142 case 0x132: /* rdmsr */
7144 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7146 gen_update_cc_op(s
);
7147 gen_jmp_im(pc_start
- s
->cs_base
);
7149 gen_helper_rdmsr(cpu_env
);
7151 gen_helper_wrmsr(cpu_env
);
7155 case 0x131: /* rdtsc */
7156 gen_update_cc_op(s
);
7157 gen_jmp_im(pc_start
- s
->cs_base
);
7158 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7161 gen_helper_rdtsc(cpu_env
);
7162 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7164 gen_jmp(s
, s
->pc
- s
->cs_base
);
7167 case 0x133: /* rdpmc */
7168 gen_update_cc_op(s
);
7169 gen_jmp_im(pc_start
- s
->cs_base
);
7170 gen_helper_rdpmc(cpu_env
);
7172 case 0x134: /* sysenter */
7173 /* For Intel SYSENTER is valid on 64-bit */
7174 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7177 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7179 gen_helper_sysenter(cpu_env
);
7183 case 0x135: /* sysexit */
7184 /* For Intel SYSEXIT is valid on 64-bit */
7185 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7188 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7190 gen_helper_sysexit(cpu_env
, tcg_const_i32(dflag
- 1));
7194 #ifdef TARGET_X86_64
7195 case 0x105: /* syscall */
7196 /* XXX: is it usable in real mode ? */
7197 gen_update_cc_op(s
);
7198 gen_jmp_im(pc_start
- s
->cs_base
);
7199 gen_helper_syscall(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7200 /* TF handling for the syscall insn is different. The TF bit is checked
7201 after the syscall insn completes. This allows #DB to not be
7202 generated after one has entered CPL0 if TF is set in FMASK. */
7203 gen_eob_worker(s
, false, true);
7205 case 0x107: /* sysret */
7207 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7209 gen_helper_sysret(cpu_env
, tcg_const_i32(dflag
- 1));
7210 /* condition codes are modified only in long mode */
7212 set_cc_op(s
, CC_OP_EFLAGS
);
7214 /* TF handling for the sysret insn is different. The TF bit is
7215 checked after the sysret insn completes. This allows #DB to be
7216 generated "as if" the syscall insn in userspace has just
7218 gen_eob_worker(s
, false, true);
7222 case 0x1a2: /* cpuid */
7223 gen_update_cc_op(s
);
7224 gen_jmp_im(pc_start
- s
->cs_base
);
7225 gen_helper_cpuid(cpu_env
);
7227 case 0xf4: /* hlt */
7229 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7231 gen_update_cc_op(s
);
7232 gen_jmp_im(pc_start
- s
->cs_base
);
7233 gen_helper_hlt(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7234 s
->base
.is_jmp
= DISAS_NORETURN
;
7238 modrm
= x86_ldub_code(env
, s
);
7239 mod
= (modrm
>> 6) & 3;
7240 op
= (modrm
>> 3) & 7;
7243 if (!s
->pe
|| s
->vm86
)
7245 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_READ
);
7246 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
7247 offsetof(CPUX86State
, ldt
.selector
));
7248 ot
= mod
== 3 ? dflag
: MO_16
;
7249 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7252 if (!s
->pe
|| s
->vm86
)
7255 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7257 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_WRITE
);
7258 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7259 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
7260 gen_helper_lldt(cpu_env
, cpu_tmp2_i32
);
7264 if (!s
->pe
|| s
->vm86
)
7266 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_READ
);
7267 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
7268 offsetof(CPUX86State
, tr
.selector
));
7269 ot
= mod
== 3 ? dflag
: MO_16
;
7270 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7273 if (!s
->pe
|| s
->vm86
)
7276 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7278 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_WRITE
);
7279 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7280 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
7281 gen_helper_ltr(cpu_env
, cpu_tmp2_i32
);
7286 if (!s
->pe
|| s
->vm86
)
7288 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7289 gen_update_cc_op(s
);
7291 gen_helper_verr(cpu_env
, s
->T0
);
7293 gen_helper_verw(cpu_env
, s
->T0
);
7295 set_cc_op(s
, CC_OP_EFLAGS
);
7303 modrm
= x86_ldub_code(env
, s
);
7305 CASE_MODRM_MEM_OP(0): /* sgdt */
7306 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_READ
);
7307 gen_lea_modrm(env
, s
, modrm
);
7308 tcg_gen_ld32u_tl(s
->T0
,
7309 cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7310 gen_op_st_v(s
, MO_16
, s
->T0
, s
->A0
);
7311 gen_add_A0_im(s
, 2);
7312 tcg_gen_ld_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7313 if (dflag
== MO_16
) {
7314 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xffffff);
7316 gen_op_st_v(s
, CODE64(s
) + MO_32
, s
->T0
, s
->A0
);
7319 case 0xc8: /* monitor */
7320 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) || s
->cpl
!= 0) {
7323 gen_update_cc_op(s
);
7324 gen_jmp_im(pc_start
- s
->cs_base
);
7325 tcg_gen_mov_tl(s
->A0
, cpu_regs
[R_EAX
]);
7326 gen_extu(s
->aflag
, s
->A0
);
7327 gen_add_A0_ds_seg(s
);
7328 gen_helper_monitor(cpu_env
, s
->A0
);
7331 case 0xc9: /* mwait */
7332 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) || s
->cpl
!= 0) {
7335 gen_update_cc_op(s
);
7336 gen_jmp_im(pc_start
- s
->cs_base
);
7337 gen_helper_mwait(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7341 case 0xca: /* clac */
7342 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
)
7346 gen_helper_clac(cpu_env
);
7347 gen_jmp_im(s
->pc
- s
->cs_base
);
7351 case 0xcb: /* stac */
7352 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
)
7356 gen_helper_stac(cpu_env
);
7357 gen_jmp_im(s
->pc
- s
->cs_base
);
7361 CASE_MODRM_MEM_OP(1): /* sidt */
7362 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_READ
);
7363 gen_lea_modrm(env
, s
, modrm
);
7364 tcg_gen_ld32u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7365 gen_op_st_v(s
, MO_16
, s
->T0
, s
->A0
);
7366 gen_add_A0_im(s
, 2);
7367 tcg_gen_ld_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, idt
.base
));
7368 if (dflag
== MO_16
) {
7369 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xffffff);
7371 gen_op_st_v(s
, CODE64(s
) + MO_32
, s
->T0
, s
->A0
);
7374 case 0xd0: /* xgetbv */
7375 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
7376 || (s
->prefix
& (PREFIX_LOCK
| PREFIX_DATA
7377 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
7380 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_ECX
]);
7381 gen_helper_xgetbv(cpu_tmp1_i64
, cpu_env
, cpu_tmp2_i32
);
7382 tcg_gen_extr_i64_tl(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
], cpu_tmp1_i64
);
7385 case 0xd1: /* xsetbv */
7386 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
7387 || (s
->prefix
& (PREFIX_LOCK
| PREFIX_DATA
7388 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
7392 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7395 tcg_gen_concat_tl_i64(cpu_tmp1_i64
, cpu_regs
[R_EAX
],
7397 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_ECX
]);
7398 gen_helper_xsetbv(cpu_env
, cpu_tmp2_i32
, cpu_tmp1_i64
);
7399 /* End TB because translation flags may change. */
7400 gen_jmp_im(s
->pc
- s
->cs_base
);
7404 case 0xd8: /* VMRUN */
7405 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7409 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7412 gen_update_cc_op(s
);
7413 gen_jmp_im(pc_start
- s
->cs_base
);
7414 gen_helper_vmrun(cpu_env
, tcg_const_i32(s
->aflag
- 1),
7415 tcg_const_i32(s
->pc
- pc_start
));
7416 tcg_gen_exit_tb(NULL
, 0);
7417 s
->base
.is_jmp
= DISAS_NORETURN
;
7420 case 0xd9: /* VMMCALL */
7421 if (!(s
->flags
& HF_SVME_MASK
)) {
7424 gen_update_cc_op(s
);
7425 gen_jmp_im(pc_start
- s
->cs_base
);
7426 gen_helper_vmmcall(cpu_env
);
7429 case 0xda: /* VMLOAD */
7430 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7434 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7437 gen_update_cc_op(s
);
7438 gen_jmp_im(pc_start
- s
->cs_base
);
7439 gen_helper_vmload(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7442 case 0xdb: /* VMSAVE */
7443 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7447 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7450 gen_update_cc_op(s
);
7451 gen_jmp_im(pc_start
- s
->cs_base
);
7452 gen_helper_vmsave(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7455 case 0xdc: /* STGI */
7456 if ((!(s
->flags
& HF_SVME_MASK
)
7457 && !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
))
7462 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7465 gen_update_cc_op(s
);
7466 gen_helper_stgi(cpu_env
);
7467 gen_jmp_im(s
->pc
- s
->cs_base
);
7471 case 0xdd: /* CLGI */
7472 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7476 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7479 gen_update_cc_op(s
);
7480 gen_jmp_im(pc_start
- s
->cs_base
);
7481 gen_helper_clgi(cpu_env
);
7484 case 0xde: /* SKINIT */
7485 if ((!(s
->flags
& HF_SVME_MASK
)
7486 && !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
))
7490 gen_update_cc_op(s
);
7491 gen_jmp_im(pc_start
- s
->cs_base
);
7492 gen_helper_skinit(cpu_env
);
7495 case 0xdf: /* INVLPGA */
7496 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7500 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7503 gen_update_cc_op(s
);
7504 gen_jmp_im(pc_start
- s
->cs_base
);
7505 gen_helper_invlpga(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7508 CASE_MODRM_MEM_OP(2): /* lgdt */
7510 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7513 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_WRITE
);
7514 gen_lea_modrm(env
, s
, modrm
);
7515 gen_op_ld_v(s
, MO_16
, cpu_T1
, s
->A0
);
7516 gen_add_A0_im(s
, 2);
7517 gen_op_ld_v(s
, CODE64(s
) + MO_32
, s
->T0
, s
->A0
);
7518 if (dflag
== MO_16
) {
7519 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xffffff);
7521 tcg_gen_st_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7522 tcg_gen_st32_tl(cpu_T1
, cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7525 CASE_MODRM_MEM_OP(3): /* lidt */
7527 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7530 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_WRITE
);
7531 gen_lea_modrm(env
, s
, modrm
);
7532 gen_op_ld_v(s
, MO_16
, cpu_T1
, s
->A0
);
7533 gen_add_A0_im(s
, 2);
7534 gen_op_ld_v(s
, CODE64(s
) + MO_32
, s
->T0
, s
->A0
);
7535 if (dflag
== MO_16
) {
7536 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xffffff);
7538 tcg_gen_st_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, idt
.base
));
7539 tcg_gen_st32_tl(cpu_T1
, cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7542 CASE_MODRM_OP(4): /* smsw */
7543 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_CR0
);
7544 tcg_gen_ld_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, cr
[0]));
7546 mod
= (modrm
>> 6) & 3;
7547 ot
= (mod
!= 3 ? MO_16
: s
->dflag
);
7551 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7553 case 0xee: /* rdpkru */
7554 if (prefixes
& PREFIX_LOCK
) {
7557 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_ECX
]);
7558 gen_helper_rdpkru(cpu_tmp1_i64
, cpu_env
, cpu_tmp2_i32
);
7559 tcg_gen_extr_i64_tl(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
], cpu_tmp1_i64
);
7561 case 0xef: /* wrpkru */
7562 if (prefixes
& PREFIX_LOCK
) {
7565 tcg_gen_concat_tl_i64(cpu_tmp1_i64
, cpu_regs
[R_EAX
],
7567 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_ECX
]);
7568 gen_helper_wrpkru(cpu_env
, cpu_tmp2_i32
, cpu_tmp1_i64
);
7570 CASE_MODRM_OP(6): /* lmsw */
7572 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7575 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7576 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7577 gen_helper_lmsw(cpu_env
, s
->T0
);
7578 gen_jmp_im(s
->pc
- s
->cs_base
);
7582 CASE_MODRM_MEM_OP(7): /* invlpg */
7584 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7587 gen_update_cc_op(s
);
7588 gen_jmp_im(pc_start
- s
->cs_base
);
7589 gen_lea_modrm(env
, s
, modrm
);
7590 gen_helper_invlpg(cpu_env
, s
->A0
);
7591 gen_jmp_im(s
->pc
- s
->cs_base
);
7595 case 0xf8: /* swapgs */
7596 #ifdef TARGET_X86_64
7599 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7601 tcg_gen_mov_tl(s
->T0
, cpu_seg_base
[R_GS
]);
7602 tcg_gen_ld_tl(cpu_seg_base
[R_GS
], cpu_env
,
7603 offsetof(CPUX86State
, kernelgsbase
));
7604 tcg_gen_st_tl(s
->T0
, cpu_env
,
7605 offsetof(CPUX86State
, kernelgsbase
));
7612 case 0xf9: /* rdtscp */
7613 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_RDTSCP
)) {
7616 gen_update_cc_op(s
);
7617 gen_jmp_im(pc_start
- s
->cs_base
);
7618 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7621 gen_helper_rdtscp(cpu_env
);
7622 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7624 gen_jmp(s
, s
->pc
- s
->cs_base
);
7633 case 0x108: /* invd */
7634 case 0x109: /* wbinvd */
7636 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7638 gen_svm_check_intercept(s
, pc_start
, (b
& 2) ? SVM_EXIT_INVD
: SVM_EXIT_WBINVD
);
7642 case 0x63: /* arpl or movslS (x86_64) */
7643 #ifdef TARGET_X86_64
7646 /* d_ot is the size of destination */
7649 modrm
= x86_ldub_code(env
, s
);
7650 reg
= ((modrm
>> 3) & 7) | rex_r
;
7651 mod
= (modrm
>> 6) & 3;
7652 rm
= (modrm
& 7) | REX_B(s
);
7655 gen_op_mov_v_reg(MO_32
, s
->T0
, rm
);
7657 if (d_ot
== MO_64
) {
7658 tcg_gen_ext32s_tl(s
->T0
, s
->T0
);
7660 gen_op_mov_reg_v(d_ot
, reg
, s
->T0
);
7662 gen_lea_modrm(env
, s
, modrm
);
7663 gen_op_ld_v(s
, MO_32
| MO_SIGN
, s
->T0
, s
->A0
);
7664 gen_op_mov_reg_v(d_ot
, reg
, s
->T0
);
7670 TCGv t0
, t1
, t2
, a0
;
7672 if (!s
->pe
|| s
->vm86
)
7674 t0
= tcg_temp_local_new();
7675 t1
= tcg_temp_local_new();
7676 t2
= tcg_temp_local_new();
7678 modrm
= x86_ldub_code(env
, s
);
7679 reg
= (modrm
>> 3) & 7;
7680 mod
= (modrm
>> 6) & 3;
7683 gen_lea_modrm(env
, s
, modrm
);
7684 gen_op_ld_v(s
, ot
, t0
, s
->A0
);
7685 a0
= tcg_temp_local_new();
7686 tcg_gen_mov_tl(a0
, s
->A0
);
7688 gen_op_mov_v_reg(ot
, t0
, rm
);
7691 gen_op_mov_v_reg(ot
, t1
, reg
);
7692 tcg_gen_andi_tl(cpu_tmp0
, t0
, 3);
7693 tcg_gen_andi_tl(t1
, t1
, 3);
7694 tcg_gen_movi_tl(t2
, 0);
7695 label1
= gen_new_label();
7696 tcg_gen_brcond_tl(TCG_COND_GE
, cpu_tmp0
, t1
, label1
);
7697 tcg_gen_andi_tl(t0
, t0
, ~3);
7698 tcg_gen_or_tl(t0
, t0
, t1
);
7699 tcg_gen_movi_tl(t2
, CC_Z
);
7700 gen_set_label(label1
);
7702 gen_op_st_v(s
, ot
, t0
, a0
);
7705 gen_op_mov_reg_v(ot
, rm
, t0
);
7707 gen_compute_eflags(s
);
7708 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_Z
);
7709 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, t2
);
7715 case 0x102: /* lar */
7716 case 0x103: /* lsl */
7720 if (!s
->pe
|| s
->vm86
)
7722 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
7723 modrm
= x86_ldub_code(env
, s
);
7724 reg
= ((modrm
>> 3) & 7) | rex_r
;
7725 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7726 t0
= tcg_temp_local_new();
7727 gen_update_cc_op(s
);
7729 gen_helper_lar(t0
, cpu_env
, s
->T0
);
7731 gen_helper_lsl(t0
, cpu_env
, s
->T0
);
7733 tcg_gen_andi_tl(cpu_tmp0
, cpu_cc_src
, CC_Z
);
7734 label1
= gen_new_label();
7735 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
7736 gen_op_mov_reg_v(ot
, reg
, t0
);
7737 gen_set_label(label1
);
7738 set_cc_op(s
, CC_OP_EFLAGS
);
7743 modrm
= x86_ldub_code(env
, s
);
7744 mod
= (modrm
>> 6) & 3;
7745 op
= (modrm
>> 3) & 7;
7747 case 0: /* prefetchnta */
7748 case 1: /* prefetchnt0 */
7749 case 2: /* prefetchnt0 */
7750 case 3: /* prefetchnt0 */
7753 gen_nop_modrm(env
, s
, modrm
);
7754 /* nothing more to do */
7756 default: /* nop (multi byte) */
7757 gen_nop_modrm(env
, s
, modrm
);
7762 modrm
= x86_ldub_code(env
, s
);
7763 if (s
->flags
& HF_MPX_EN_MASK
) {
7764 mod
= (modrm
>> 6) & 3;
7765 reg
= ((modrm
>> 3) & 7) | rex_r
;
7766 if (prefixes
& PREFIX_REPZ
) {
7769 || (prefixes
& PREFIX_LOCK
)
7770 || s
->aflag
== MO_16
) {
7773 gen_bndck(env
, s
, modrm
, TCG_COND_LTU
, cpu_bndl
[reg
]);
7774 } else if (prefixes
& PREFIX_REPNZ
) {
7777 || (prefixes
& PREFIX_LOCK
)
7778 || s
->aflag
== MO_16
) {
7781 TCGv_i64 notu
= tcg_temp_new_i64();
7782 tcg_gen_not_i64(notu
, cpu_bndu
[reg
]);
7783 gen_bndck(env
, s
, modrm
, TCG_COND_GTU
, notu
);
7784 tcg_temp_free_i64(notu
);
7785 } else if (prefixes
& PREFIX_DATA
) {
7786 /* bndmov -- from reg/mem */
7787 if (reg
>= 4 || s
->aflag
== MO_16
) {
7791 int reg2
= (modrm
& 7) | REX_B(s
);
7792 if (reg2
>= 4 || (prefixes
& PREFIX_LOCK
)) {
7795 if (s
->flags
& HF_MPX_IU_MASK
) {
7796 tcg_gen_mov_i64(cpu_bndl
[reg
], cpu_bndl
[reg2
]);
7797 tcg_gen_mov_i64(cpu_bndu
[reg
], cpu_bndu
[reg2
]);
7800 gen_lea_modrm(env
, s
, modrm
);
7802 tcg_gen_qemu_ld_i64(cpu_bndl
[reg
], s
->A0
,
7803 s
->mem_index
, MO_LEQ
);
7804 tcg_gen_addi_tl(s
->A0
, s
->A0
, 8);
7805 tcg_gen_qemu_ld_i64(cpu_bndu
[reg
], s
->A0
,
7806 s
->mem_index
, MO_LEQ
);
7808 tcg_gen_qemu_ld_i64(cpu_bndl
[reg
], s
->A0
,
7809 s
->mem_index
, MO_LEUL
);
7810 tcg_gen_addi_tl(s
->A0
, s
->A0
, 4);
7811 tcg_gen_qemu_ld_i64(cpu_bndu
[reg
], s
->A0
,
7812 s
->mem_index
, MO_LEUL
);
7814 /* bnd registers are now in-use */
7815 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7817 } else if (mod
!= 3) {
7819 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7821 || (prefixes
& PREFIX_LOCK
)
7822 || s
->aflag
== MO_16
7827 tcg_gen_addi_tl(s
->A0
, cpu_regs
[a
.base
], a
.disp
);
7829 tcg_gen_movi_tl(s
->A0
, 0);
7831 gen_lea_v_seg(s
, s
->aflag
, s
->A0
, a
.def_seg
, s
->override
);
7833 tcg_gen_mov_tl(s
->T0
, cpu_regs
[a
.index
]);
7835 tcg_gen_movi_tl(s
->T0
, 0);
7838 gen_helper_bndldx64(cpu_bndl
[reg
], cpu_env
, s
->A0
, s
->T0
);
7839 tcg_gen_ld_i64(cpu_bndu
[reg
], cpu_env
,
7840 offsetof(CPUX86State
, mmx_t0
.MMX_Q(0)));
7842 gen_helper_bndldx32(cpu_bndu
[reg
], cpu_env
, s
->A0
, s
->T0
);
7843 tcg_gen_ext32u_i64(cpu_bndl
[reg
], cpu_bndu
[reg
]);
7844 tcg_gen_shri_i64(cpu_bndu
[reg
], cpu_bndu
[reg
], 32);
7846 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7849 gen_nop_modrm(env
, s
, modrm
);
7852 modrm
= x86_ldub_code(env
, s
);
7853 if (s
->flags
& HF_MPX_EN_MASK
) {
7854 mod
= (modrm
>> 6) & 3;
7855 reg
= ((modrm
>> 3) & 7) | rex_r
;
7856 if (mod
!= 3 && (prefixes
& PREFIX_REPZ
)) {
7859 || (prefixes
& PREFIX_LOCK
)
7860 || s
->aflag
== MO_16
) {
7863 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7865 tcg_gen_extu_tl_i64(cpu_bndl
[reg
], cpu_regs
[a
.base
]);
7867 tcg_gen_ext32u_i64(cpu_bndl
[reg
], cpu_bndl
[reg
]);
7869 } else if (a
.base
== -1) {
7870 /* no base register has lower bound of 0 */
7871 tcg_gen_movi_i64(cpu_bndl
[reg
], 0);
7873 /* rip-relative generates #ud */
7876 tcg_gen_not_tl(s
->A0
, gen_lea_modrm_1(s
, a
));
7878 tcg_gen_ext32u_tl(s
->A0
, s
->A0
);
7880 tcg_gen_extu_tl_i64(cpu_bndu
[reg
], s
->A0
);
7881 /* bnd registers are now in-use */
7882 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7884 } else if (prefixes
& PREFIX_REPNZ
) {
7887 || (prefixes
& PREFIX_LOCK
)
7888 || s
->aflag
== MO_16
) {
7891 gen_bndck(env
, s
, modrm
, TCG_COND_GTU
, cpu_bndu
[reg
]);
7892 } else if (prefixes
& PREFIX_DATA
) {
7893 /* bndmov -- to reg/mem */
7894 if (reg
>= 4 || s
->aflag
== MO_16
) {
7898 int reg2
= (modrm
& 7) | REX_B(s
);
7899 if (reg2
>= 4 || (prefixes
& PREFIX_LOCK
)) {
7902 if (s
->flags
& HF_MPX_IU_MASK
) {
7903 tcg_gen_mov_i64(cpu_bndl
[reg2
], cpu_bndl
[reg
]);
7904 tcg_gen_mov_i64(cpu_bndu
[reg2
], cpu_bndu
[reg
]);
7907 gen_lea_modrm(env
, s
, modrm
);
7909 tcg_gen_qemu_st_i64(cpu_bndl
[reg
], s
->A0
,
7910 s
->mem_index
, MO_LEQ
);
7911 tcg_gen_addi_tl(s
->A0
, s
->A0
, 8);
7912 tcg_gen_qemu_st_i64(cpu_bndu
[reg
], s
->A0
,
7913 s
->mem_index
, MO_LEQ
);
7915 tcg_gen_qemu_st_i64(cpu_bndl
[reg
], s
->A0
,
7916 s
->mem_index
, MO_LEUL
);
7917 tcg_gen_addi_tl(s
->A0
, s
->A0
, 4);
7918 tcg_gen_qemu_st_i64(cpu_bndu
[reg
], s
->A0
,
7919 s
->mem_index
, MO_LEUL
);
7922 } else if (mod
!= 3) {
7924 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7926 || (prefixes
& PREFIX_LOCK
)
7927 || s
->aflag
== MO_16
7932 tcg_gen_addi_tl(s
->A0
, cpu_regs
[a
.base
], a
.disp
);
7934 tcg_gen_movi_tl(s
->A0
, 0);
7936 gen_lea_v_seg(s
, s
->aflag
, s
->A0
, a
.def_seg
, s
->override
);
7938 tcg_gen_mov_tl(s
->T0
, cpu_regs
[a
.index
]);
7940 tcg_gen_movi_tl(s
->T0
, 0);
7943 gen_helper_bndstx64(cpu_env
, s
->A0
, s
->T0
,
7944 cpu_bndl
[reg
], cpu_bndu
[reg
]);
7946 gen_helper_bndstx32(cpu_env
, s
->A0
, s
->T0
,
7947 cpu_bndl
[reg
], cpu_bndu
[reg
]);
7951 gen_nop_modrm(env
, s
, modrm
);
7953 case 0x119: case 0x11c ... 0x11f: /* nop (multi byte) */
7954 modrm
= x86_ldub_code(env
, s
);
7955 gen_nop_modrm(env
, s
, modrm
);
7957 case 0x120: /* mov reg, crN */
7958 case 0x122: /* mov crN, reg */
7960 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7962 modrm
= x86_ldub_code(env
, s
);
7963 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7964 * AMD documentation (24594.pdf) and testing of
7965 * intel 386 and 486 processors all show that the mod bits
7966 * are assumed to be 1's, regardless of actual values.
7968 rm
= (modrm
& 7) | REX_B(s
);
7969 reg
= ((modrm
>> 3) & 7) | rex_r
;
7974 if ((prefixes
& PREFIX_LOCK
) && (reg
== 0) &&
7975 (s
->cpuid_ext3_features
& CPUID_EXT3_CR8LEG
)) {
7984 gen_update_cc_op(s
);
7985 gen_jmp_im(pc_start
- s
->cs_base
);
7987 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7990 gen_op_mov_v_reg(ot
, s
->T0
, rm
);
7991 gen_helper_write_crN(cpu_env
, tcg_const_i32(reg
),
7993 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7996 gen_jmp_im(s
->pc
- s
->cs_base
);
7999 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
8002 gen_helper_read_crN(s
->T0
, cpu_env
, tcg_const_i32(reg
));
8003 gen_op_mov_reg_v(ot
, rm
, s
->T0
);
8004 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
8014 case 0x121: /* mov reg, drN */
8015 case 0x123: /* mov drN, reg */
8017 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
8019 modrm
= x86_ldub_code(env
, s
);
8020 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
8021 * AMD documentation (24594.pdf) and testing of
8022 * intel 386 and 486 processors all show that the mod bits
8023 * are assumed to be 1's, regardless of actual values.
8025 rm
= (modrm
& 7) | REX_B(s
);
8026 reg
= ((modrm
>> 3) & 7) | rex_r
;
8035 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_DR0
+ reg
);
8036 gen_op_mov_v_reg(ot
, s
->T0
, rm
);
8037 tcg_gen_movi_i32(cpu_tmp2_i32
, reg
);
8038 gen_helper_set_dr(cpu_env
, cpu_tmp2_i32
, s
->T0
);
8039 gen_jmp_im(s
->pc
- s
->cs_base
);
8042 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_DR0
+ reg
);
8043 tcg_gen_movi_i32(cpu_tmp2_i32
, reg
);
8044 gen_helper_get_dr(s
->T0
, cpu_env
, cpu_tmp2_i32
);
8045 gen_op_mov_reg_v(ot
, rm
, s
->T0
);
8049 case 0x106: /* clts */
8051 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
8053 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
8054 gen_helper_clts(cpu_env
);
8055 /* abort block because static cpu state changed */
8056 gen_jmp_im(s
->pc
- s
->cs_base
);
8060 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
8061 case 0x1c3: /* MOVNTI reg, mem */
8062 if (!(s
->cpuid_features
& CPUID_SSE2
))
8064 ot
= mo_64_32(dflag
);
8065 modrm
= x86_ldub_code(env
, s
);
8066 mod
= (modrm
>> 6) & 3;
8069 reg
= ((modrm
>> 3) & 7) | rex_r
;
8070 /* generate a generic store */
8071 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
8074 modrm
= x86_ldub_code(env
, s
);
8076 CASE_MODRM_MEM_OP(0): /* fxsave */
8077 if (!(s
->cpuid_features
& CPUID_FXSR
)
8078 || (prefixes
& PREFIX_LOCK
)) {
8081 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
8082 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8085 gen_lea_modrm(env
, s
, modrm
);
8086 gen_helper_fxsave(cpu_env
, s
->A0
);
8089 CASE_MODRM_MEM_OP(1): /* fxrstor */
8090 if (!(s
->cpuid_features
& CPUID_FXSR
)
8091 || (prefixes
& PREFIX_LOCK
)) {
8094 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
8095 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8098 gen_lea_modrm(env
, s
, modrm
);
8099 gen_helper_fxrstor(cpu_env
, s
->A0
);
8102 CASE_MODRM_MEM_OP(2): /* ldmxcsr */
8103 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
)) {
8106 if (s
->flags
& HF_TS_MASK
) {
8107 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8110 gen_lea_modrm(env
, s
, modrm
);
8111 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, s
->A0
, s
->mem_index
, MO_LEUL
);
8112 gen_helper_ldmxcsr(cpu_env
, cpu_tmp2_i32
);
8115 CASE_MODRM_MEM_OP(3): /* stmxcsr */
8116 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
)) {
8119 if (s
->flags
& HF_TS_MASK
) {
8120 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8123 gen_lea_modrm(env
, s
, modrm
);
8124 tcg_gen_ld32u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, mxcsr
));
8125 gen_op_st_v(s
, MO_32
, s
->T0
, s
->A0
);
8128 CASE_MODRM_MEM_OP(4): /* xsave */
8129 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8130 || (prefixes
& (PREFIX_LOCK
| PREFIX_DATA
8131 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
8134 gen_lea_modrm(env
, s
, modrm
);
8135 tcg_gen_concat_tl_i64(cpu_tmp1_i64
, cpu_regs
[R_EAX
],
8137 gen_helper_xsave(cpu_env
, s
->A0
, cpu_tmp1_i64
);
8140 CASE_MODRM_MEM_OP(5): /* xrstor */
8141 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8142 || (prefixes
& (PREFIX_LOCK
| PREFIX_DATA
8143 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
8146 gen_lea_modrm(env
, s
, modrm
);
8147 tcg_gen_concat_tl_i64(cpu_tmp1_i64
, cpu_regs
[R_EAX
],
8149 gen_helper_xrstor(cpu_env
, s
->A0
, cpu_tmp1_i64
);
8150 /* XRSTOR is how MPX is enabled, which changes how
8151 we translate. Thus we need to end the TB. */
8152 gen_update_cc_op(s
);
8153 gen_jmp_im(s
->pc
- s
->cs_base
);
8157 CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */
8158 if (prefixes
& PREFIX_LOCK
) {
8161 if (prefixes
& PREFIX_DATA
) {
8163 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLWB
)) {
8166 gen_nop_modrm(env
, s
, modrm
);
8169 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8170 || (s
->cpuid_xsave_features
& CPUID_XSAVE_XSAVEOPT
) == 0
8171 || (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
))) {
8174 gen_lea_modrm(env
, s
, modrm
);
8175 tcg_gen_concat_tl_i64(cpu_tmp1_i64
, cpu_regs
[R_EAX
],
8177 gen_helper_xsaveopt(cpu_env
, s
->A0
, cpu_tmp1_i64
);
8181 CASE_MODRM_MEM_OP(7): /* clflush / clflushopt */
8182 if (prefixes
& PREFIX_LOCK
) {
8185 if (prefixes
& PREFIX_DATA
) {
8187 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLFLUSHOPT
)) {
8192 if ((s
->prefix
& (PREFIX_REPZ
| PREFIX_REPNZ
))
8193 || !(s
->cpuid_features
& CPUID_CLFLUSH
)) {
8197 gen_nop_modrm(env
, s
, modrm
);
8200 case 0xc0 ... 0xc7: /* rdfsbase (f3 0f ae /0) */
8201 case 0xc8 ... 0xcf: /* rdgsbase (f3 0f ae /1) */
8202 case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */
8203 case 0xd8 ... 0xdf: /* wrgsbase (f3 0f ae /3) */
8205 && (prefixes
& PREFIX_REPZ
)
8206 && !(prefixes
& PREFIX_LOCK
)
8207 && (s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_FSGSBASE
)) {
8208 TCGv base
, treg
, src
, dst
;
8210 /* Preserve hflags bits by testing CR4 at runtime. */
8211 tcg_gen_movi_i32(cpu_tmp2_i32
, CR4_FSGSBASE_MASK
);
8212 gen_helper_cr4_testbit(cpu_env
, cpu_tmp2_i32
);
8214 base
= cpu_seg_base
[modrm
& 8 ? R_GS
: R_FS
];
8215 treg
= cpu_regs
[(modrm
& 7) | REX_B(s
)];
8219 dst
= base
, src
= treg
;
8222 dst
= treg
, src
= base
;
8225 if (s
->dflag
== MO_32
) {
8226 tcg_gen_ext32u_tl(dst
, src
);
8228 tcg_gen_mov_tl(dst
, src
);
8234 case 0xf8: /* sfence / pcommit */
8235 if (prefixes
& PREFIX_DATA
) {
8237 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_PCOMMIT
)
8238 || (prefixes
& PREFIX_LOCK
)) {
8244 case 0xf9 ... 0xff: /* sfence */
8245 if (!(s
->cpuid_features
& CPUID_SSE
)
8246 || (prefixes
& PREFIX_LOCK
)) {
8249 tcg_gen_mb(TCG_MO_ST_ST
| TCG_BAR_SC
);
8251 case 0xe8 ... 0xef: /* lfence */
8252 if (!(s
->cpuid_features
& CPUID_SSE
)
8253 || (prefixes
& PREFIX_LOCK
)) {
8256 tcg_gen_mb(TCG_MO_LD_LD
| TCG_BAR_SC
);
8258 case 0xf0 ... 0xf7: /* mfence */
8259 if (!(s
->cpuid_features
& CPUID_SSE2
)
8260 || (prefixes
& PREFIX_LOCK
)) {
8263 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8271 case 0x10d: /* 3DNow! prefetch(w) */
8272 modrm
= x86_ldub_code(env
, s
);
8273 mod
= (modrm
>> 6) & 3;
8276 gen_nop_modrm(env
, s
, modrm
);
8278 case 0x1aa: /* rsm */
8279 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_RSM
);
8280 if (!(s
->flags
& HF_SMM_MASK
))
8282 gen_update_cc_op(s
);
8283 gen_jmp_im(s
->pc
- s
->cs_base
);
8284 gen_helper_rsm(cpu_env
);
8287 case 0x1b8: /* SSE4.2 popcnt */
8288 if ((prefixes
& (PREFIX_REPZ
| PREFIX_LOCK
| PREFIX_REPNZ
)) !=
8291 if (!(s
->cpuid_ext_features
& CPUID_EXT_POPCNT
))
8294 modrm
= x86_ldub_code(env
, s
);
8295 reg
= ((modrm
>> 3) & 7) | rex_r
;
8297 if (s
->prefix
& PREFIX_DATA
) {
8300 ot
= mo_64_32(dflag
);
8303 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
8304 gen_extu(ot
, s
->T0
);
8305 tcg_gen_mov_tl(cpu_cc_src
, s
->T0
);
8306 tcg_gen_ctpop_tl(s
->T0
, s
->T0
);
8307 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
8309 set_cc_op(s
, CC_OP_POPCNT
);
8311 case 0x10e ... 0x10f:
8312 /* 3DNow! instructions, ignore prefixes */
8313 s
->prefix
&= ~(PREFIX_REPZ
| PREFIX_REPNZ
| PREFIX_DATA
);
8315 case 0x110 ... 0x117:
8316 case 0x128 ... 0x12f:
8317 case 0x138 ... 0x13a:
8318 case 0x150 ... 0x179:
8319 case 0x17c ... 0x17f:
8321 case 0x1c4 ... 0x1c6:
8322 case 0x1d0 ... 0x1fe:
8323 gen_sse(env
, s
, b
, pc_start
, rex_r
);
8330 gen_illegal_opcode(s
);
8333 gen_unknown_opcode(env
, s
);
8337 void tcg_x86_init(void)
8339 static const char reg_names
[CPU_NB_REGS
][4] = {
8340 #ifdef TARGET_X86_64
8368 static const char seg_base_names
[6][8] = {
8376 static const char bnd_regl_names
[4][8] = {
8377 "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb"
8379 static const char bnd_regu_names
[4][8] = {
8380 "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub"
8384 cpu_cc_op
= tcg_global_mem_new_i32(cpu_env
,
8385 offsetof(CPUX86State
, cc_op
), "cc_op");
8386 cpu_cc_dst
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_dst
),
8388 cpu_cc_src
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_src
),
8390 cpu_cc_src2
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_src2
),
8393 for (i
= 0; i
< CPU_NB_REGS
; ++i
) {
8394 cpu_regs
[i
] = tcg_global_mem_new(cpu_env
,
8395 offsetof(CPUX86State
, regs
[i
]),
8399 for (i
= 0; i
< 6; ++i
) {
8401 = tcg_global_mem_new(cpu_env
,
8402 offsetof(CPUX86State
, segs
[i
].base
),
8406 for (i
= 0; i
< 4; ++i
) {
8408 = tcg_global_mem_new_i64(cpu_env
,
8409 offsetof(CPUX86State
, bnd_regs
[i
].lb
),
8412 = tcg_global_mem_new_i64(cpu_env
,
8413 offsetof(CPUX86State
, bnd_regs
[i
].ub
),
8418 static void i386_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cpu
)
8420 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8421 CPUX86State
*env
= cpu
->env_ptr
;
8422 uint32_t flags
= dc
->base
.tb
->flags
;
8423 target_ulong cs_base
= dc
->base
.tb
->cs_base
;
8425 dc
->pe
= (flags
>> HF_PE_SHIFT
) & 1;
8426 dc
->code32
= (flags
>> HF_CS32_SHIFT
) & 1;
8427 dc
->ss32
= (flags
>> HF_SS32_SHIFT
) & 1;
8428 dc
->addseg
= (flags
>> HF_ADDSEG_SHIFT
) & 1;
8430 dc
->vm86
= (flags
>> VM_SHIFT
) & 1;
8431 dc
->cpl
= (flags
>> HF_CPL_SHIFT
) & 3;
8432 dc
->iopl
= (flags
>> IOPL_SHIFT
) & 3;
8433 dc
->tf
= (flags
>> TF_SHIFT
) & 1;
8434 dc
->cc_op
= CC_OP_DYNAMIC
;
8435 dc
->cc_op_dirty
= false;
8436 dc
->cs_base
= cs_base
;
8437 dc
->popl_esp_hack
= 0;
8438 /* select memory access functions */
8440 #ifdef CONFIG_SOFTMMU
8441 dc
->mem_index
= cpu_mmu_index(env
, false);
8443 dc
->cpuid_features
= env
->features
[FEAT_1_EDX
];
8444 dc
->cpuid_ext_features
= env
->features
[FEAT_1_ECX
];
8445 dc
->cpuid_ext2_features
= env
->features
[FEAT_8000_0001_EDX
];
8446 dc
->cpuid_ext3_features
= env
->features
[FEAT_8000_0001_ECX
];
8447 dc
->cpuid_7_0_ebx_features
= env
->features
[FEAT_7_0_EBX
];
8448 dc
->cpuid_xsave_features
= env
->features
[FEAT_XSAVE
];
8449 #ifdef TARGET_X86_64
8450 dc
->lma
= (flags
>> HF_LMA_SHIFT
) & 1;
8451 dc
->code64
= (flags
>> HF_CS64_SHIFT
) & 1;
8454 dc
->jmp_opt
= !(dc
->tf
|| dc
->base
.singlestep_enabled
||
8455 (flags
& HF_INHIBIT_IRQ_MASK
));
8456 /* Do not optimize repz jumps at all in icount mode, because
8457 rep movsS instructions are execured with different paths
8458 in !repz_opt and repz_opt modes. The first one was used
8459 always except single step mode. And this setting
8460 disables jumps optimization and control paths become
8461 equivalent in run and single step modes.
8462 Now there will be no jump optimization for repz in
8463 record/replay modes and there will always be an
8464 additional step for ecx=0 when icount is enabled.
8466 dc
->repz_opt
= !dc
->jmp_opt
&& !(tb_cflags(dc
->base
.tb
) & CF_USE_ICOUNT
);
8468 /* check addseg logic */
8469 if (!dc
->addseg
&& (dc
->vm86
|| !dc
->pe
|| !dc
->code32
))
8470 printf("ERROR addseg\n");
8473 dc
->T0
= tcg_temp_new();
8474 cpu_T1
= tcg_temp_new();
8475 dc
->A0
= tcg_temp_new();
8477 cpu_tmp0
= tcg_temp_new();
8478 cpu_tmp1_i64
= tcg_temp_new_i64();
8479 cpu_tmp2_i32
= tcg_temp_new_i32();
8480 cpu_tmp3_i32
= tcg_temp_new_i32();
8481 cpu_tmp4
= tcg_temp_new();
8482 cpu_ptr0
= tcg_temp_new_ptr();
8483 cpu_ptr1
= tcg_temp_new_ptr();
8484 dc
->cc_srcT
= tcg_temp_local_new();
8487 static void i386_tr_tb_start(DisasContextBase
*db
, CPUState
*cpu
)
8491 static void i386_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
8493 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8495 tcg_gen_insn_start(dc
->base
.pc_next
, dc
->cc_op
);
8498 static bool i386_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cpu
,
8499 const CPUBreakpoint
*bp
)
8501 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8502 /* If RF is set, suppress an internally generated breakpoint. */
8503 int flags
= dc
->base
.tb
->flags
& HF_RF_MASK
? BP_GDB
: BP_ANY
;
8504 if (bp
->flags
& flags
) {
8505 gen_debug(dc
, dc
->base
.pc_next
- dc
->cs_base
);
8506 dc
->base
.is_jmp
= DISAS_NORETURN
;
8507 /* The address covered by the breakpoint must be included in
8508 [tb->pc, tb->pc + tb->size) in order to for it to be
8509 properly cleared -- thus we increment the PC here so that
8510 the generic logic setting tb->size later does the right thing. */
8511 dc
->base
.pc_next
+= 1;
8518 static void i386_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
8520 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8521 target_ulong pc_next
= disas_insn(dc
, cpu
);
8523 if (dc
->tf
|| (dc
->base
.tb
->flags
& HF_INHIBIT_IRQ_MASK
)) {
8524 /* if single step mode, we generate only one instruction and
8525 generate an exception */
8526 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
8527 the flag and abort the translation to give the irqs a
8529 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
8530 } else if ((tb_cflags(dc
->base
.tb
) & CF_USE_ICOUNT
)
8531 && ((dc
->base
.pc_next
& TARGET_PAGE_MASK
)
8532 != ((dc
->base
.pc_next
+ TARGET_MAX_INSN_SIZE
- 1)
8534 || (dc
->base
.pc_next
& ~TARGET_PAGE_MASK
) == 0)) {
8535 /* Do not cross the boundary of the pages in icount mode,
8536 it can cause an exception. Do it only when boundary is
8537 crossed by the first instruction in the block.
8538 If current instruction already crossed the bound - it's ok,
8539 because an exception hasn't stopped this code.
8541 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
8542 } else if ((pc_next
- dc
->base
.pc_first
) >= (TARGET_PAGE_SIZE
- 32)) {
8543 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
8546 dc
->base
.pc_next
= pc_next
;
8549 static void i386_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cpu
)
8551 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8553 if (dc
->base
.is_jmp
== DISAS_TOO_MANY
) {
8554 gen_jmp_im(dc
->base
.pc_next
- dc
->cs_base
);
8559 static void i386_tr_disas_log(const DisasContextBase
*dcbase
,
8562 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8564 qemu_log("IN: %s\n", lookup_symbol(dc
->base
.pc_first
));
8565 log_target_disas(cpu
, dc
->base
.pc_first
, dc
->base
.tb
->size
);
8568 static const TranslatorOps i386_tr_ops
= {
8569 .init_disas_context
= i386_tr_init_disas_context
,
8570 .tb_start
= i386_tr_tb_start
,
8571 .insn_start
= i386_tr_insn_start
,
8572 .breakpoint_check
= i386_tr_breakpoint_check
,
8573 .translate_insn
= i386_tr_translate_insn
,
8574 .tb_stop
= i386_tr_tb_stop
,
8575 .disas_log
= i386_tr_disas_log
,
8578 /* generate intermediate code for basic block 'tb'. */
8579 void gen_intermediate_code(CPUState
*cpu
, TranslationBlock
*tb
)
8583 translator_loop(&i386_tr_ops
, &dc
.base
, cpu
, tb
);
8586 void restore_state_to_opc(CPUX86State
*env
, TranslationBlock
*tb
,
8589 int cc_op
= data
[1];
8590 env
->eip
= data
[0] - tb
->cs_base
;
8591 if (cc_op
!= CC_OP_DYNAMIC
) {