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"
25 #include "tcg/tcg-op.h"
26 #include "exec/cpu_ldst.h"
27 #include "exec/translator.h"
29 #include "exec/helper-proto.h"
30 #include "exec/helper-gen.h"
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];
82 #include "exec/gen-icount.h"
84 typedef struct DisasContext
{
85 DisasContextBase base
;
87 /* current insn context */
88 int override
; /* -1 if no override */
92 target_ulong pc_start
;
93 target_ulong pc
; /* pc = eip + cs_base */
94 /* current block context */
95 target_ulong cs_base
; /* base of CS segment */
96 int pe
; /* protected mode */
97 int code32
; /* 32 bit code segment */
99 int lma
; /* long mode active */
100 int code64
; /* 64 bit code segment */
103 int vex_l
; /* vex vector length */
104 int vex_v
; /* vex vvvv register, without 1's complement. */
105 int ss32
; /* 32 bit stack segment */
106 CCOp cc_op
; /* current CC operation */
111 int addseg
; /* non zero if either DS/ES/SS have a non zero base */
112 int f_st
; /* currently unused */
113 int vm86
; /* vm86 mode */
116 int tf
; /* TF cpu flag */
117 int jmp_opt
; /* use direct block chaining for direct jumps */
118 int repz_opt
; /* optimize jumps within repz instructions */
119 int mem_index
; /* select memory access functions */
120 uint64_t flags
; /* all execution flags */
121 int popl_esp_hack
; /* for correct popl with esp base handling */
122 int rip_offset
; /* only used in x86_64, but left for simplicity */
124 int cpuid_ext_features
;
125 int cpuid_ext2_features
;
126 int cpuid_ext3_features
;
127 int cpuid_7_0_ebx_features
;
128 int cpuid_xsave_features
;
130 /* TCG local temps */
136 /* TCG local register indexes (only used inside old micro ops) */
148 static void gen_eob(DisasContext
*s
);
149 static void gen_jr(DisasContext
*s
, TCGv dest
);
150 static void gen_jmp(DisasContext
*s
, target_ulong eip
);
151 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
);
152 static void gen_op(DisasContext
*s1
, int op
, MemOp ot
, int d
);
154 /* i386 arith/logic operations */
174 OP_SHL1
, /* undocumented */
190 /* I386 int registers */
191 OR_EAX
, /* MUST be even numbered */
200 OR_TMP0
= 16, /* temporary operand register */
202 OR_A0
, /* temporary register used when doing address evaluation */
212 /* Bit set if the global variable is live after setting CC_OP to X. */
213 static const uint8_t cc_op_live
[CC_OP_NB
] = {
214 [CC_OP_DYNAMIC
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
215 [CC_OP_EFLAGS
] = USES_CC_SRC
,
216 [CC_OP_MULB
... CC_OP_MULQ
] = USES_CC_DST
| USES_CC_SRC
,
217 [CC_OP_ADDB
... CC_OP_ADDQ
] = USES_CC_DST
| USES_CC_SRC
,
218 [CC_OP_ADCB
... CC_OP_ADCQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
219 [CC_OP_SUBB
... CC_OP_SUBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRCT
,
220 [CC_OP_SBBB
... CC_OP_SBBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
221 [CC_OP_LOGICB
... CC_OP_LOGICQ
] = USES_CC_DST
,
222 [CC_OP_INCB
... CC_OP_INCQ
] = USES_CC_DST
| USES_CC_SRC
,
223 [CC_OP_DECB
... CC_OP_DECQ
] = USES_CC_DST
| USES_CC_SRC
,
224 [CC_OP_SHLB
... CC_OP_SHLQ
] = USES_CC_DST
| USES_CC_SRC
,
225 [CC_OP_SARB
... CC_OP_SARQ
] = USES_CC_DST
| USES_CC_SRC
,
226 [CC_OP_BMILGB
... CC_OP_BMILGQ
] = USES_CC_DST
| USES_CC_SRC
,
227 [CC_OP_ADCX
] = USES_CC_DST
| USES_CC_SRC
,
228 [CC_OP_ADOX
] = USES_CC_SRC
| USES_CC_SRC2
,
229 [CC_OP_ADCOX
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
231 [CC_OP_POPCNT
] = USES_CC_SRC
,
234 static void set_cc_op(DisasContext
*s
, CCOp op
)
238 if (s
->cc_op
== op
) {
242 /* Discard CC computation that will no longer be used. */
243 dead
= cc_op_live
[s
->cc_op
] & ~cc_op_live
[op
];
244 if (dead
& USES_CC_DST
) {
245 tcg_gen_discard_tl(cpu_cc_dst
);
247 if (dead
& USES_CC_SRC
) {
248 tcg_gen_discard_tl(cpu_cc_src
);
250 if (dead
& USES_CC_SRC2
) {
251 tcg_gen_discard_tl(cpu_cc_src2
);
253 if (dead
& USES_CC_SRCT
) {
254 tcg_gen_discard_tl(s
->cc_srcT
);
257 if (op
== CC_OP_DYNAMIC
) {
258 /* The DYNAMIC setting is translator only, and should never be
259 stored. Thus we always consider it clean. */
260 s
->cc_op_dirty
= false;
262 /* Discard any computed CC_OP value (see shifts). */
263 if (s
->cc_op
== CC_OP_DYNAMIC
) {
264 tcg_gen_discard_i32(cpu_cc_op
);
266 s
->cc_op_dirty
= true;
271 static void gen_update_cc_op(DisasContext
*s
)
273 if (s
->cc_op_dirty
) {
274 tcg_gen_movi_i32(cpu_cc_op
, s
->cc_op
);
275 s
->cc_op_dirty
= false;
281 #define NB_OP_SIZES 4
283 #else /* !TARGET_X86_64 */
285 #define NB_OP_SIZES 3
287 #endif /* !TARGET_X86_64 */
289 #if defined(HOST_WORDS_BIGENDIAN)
290 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
291 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
292 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
293 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
294 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
296 #define REG_B_OFFSET 0
297 #define REG_H_OFFSET 1
298 #define REG_W_OFFSET 0
299 #define REG_L_OFFSET 0
300 #define REG_LH_OFFSET 4
303 /* In instruction encodings for byte register accesses the
304 * register number usually indicates "low 8 bits of register N";
305 * however there are some special cases where N 4..7 indicates
306 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
307 * true for this special case, false otherwise.
309 static inline bool byte_reg_is_xH(DisasContext
*s
, int reg
)
315 if (reg
>= 8 || s
->x86_64_hregs
) {
322 /* Select the size of a push/pop operation. */
323 static inline MemOp
mo_pushpop(DisasContext
*s
, MemOp ot
)
326 return ot
== MO_16
? MO_16
: MO_64
;
332 /* Select the size of the stack pointer. */
333 static inline MemOp
mo_stacksize(DisasContext
*s
)
335 return CODE64(s
) ? MO_64
: s
->ss32
? MO_32
: MO_16
;
338 /* Select only size 64 else 32. Used for SSE operand sizes. */
339 static inline MemOp
mo_64_32(MemOp ot
)
342 return ot
== MO_64
? MO_64
: MO_32
;
348 /* Select size 8 if lsb of B is clear, else OT. Used for decoding
349 byte vs word opcodes. */
350 static inline MemOp
mo_b_d(int b
, MemOp ot
)
352 return b
& 1 ? ot
: MO_8
;
355 /* Select size 8 if lsb of B is clear, else OT capped at 32.
356 Used for decoding operand size of port opcodes. */
357 static inline MemOp
mo_b_d32(int b
, MemOp ot
)
359 return b
& 1 ? (ot
== MO_16
? MO_16
: MO_32
) : MO_8
;
362 static void gen_op_mov_reg_v(DisasContext
*s
, MemOp ot
, int reg
, TCGv t0
)
366 if (!byte_reg_is_xH(s
, reg
)) {
367 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 8);
369 tcg_gen_deposit_tl(cpu_regs
[reg
- 4], cpu_regs
[reg
- 4], t0
, 8, 8);
373 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 16);
376 /* For x86_64, this sets the higher half of register to zero.
377 For i386, this is equivalent to a mov. */
378 tcg_gen_ext32u_tl(cpu_regs
[reg
], t0
);
382 tcg_gen_mov_tl(cpu_regs
[reg
], t0
);
391 void gen_op_mov_v_reg(DisasContext
*s
, MemOp ot
, TCGv t0
, int reg
)
393 if (ot
== MO_8
&& byte_reg_is_xH(s
, reg
)) {
394 tcg_gen_extract_tl(t0
, cpu_regs
[reg
- 4], 8, 8);
396 tcg_gen_mov_tl(t0
, cpu_regs
[reg
]);
400 static void gen_add_A0_im(DisasContext
*s
, int val
)
402 tcg_gen_addi_tl(s
->A0
, s
->A0
, val
);
404 tcg_gen_ext32u_tl(s
->A0
, s
->A0
);
408 static inline void gen_op_jmp_v(TCGv dest
)
410 tcg_gen_st_tl(dest
, cpu_env
, offsetof(CPUX86State
, eip
));
414 void gen_op_add_reg_im(DisasContext
*s
, MemOp size
, int reg
, int32_t val
)
416 tcg_gen_addi_tl(s
->tmp0
, cpu_regs
[reg
], val
);
417 gen_op_mov_reg_v(s
, size
, reg
, s
->tmp0
);
420 static inline void gen_op_add_reg_T0(DisasContext
*s
, MemOp size
, int reg
)
422 tcg_gen_add_tl(s
->tmp0
, cpu_regs
[reg
], s
->T0
);
423 gen_op_mov_reg_v(s
, size
, reg
, s
->tmp0
);
426 static inline void gen_op_ld_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
428 tcg_gen_qemu_ld_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
431 static inline void gen_op_st_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
433 tcg_gen_qemu_st_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
436 static inline void gen_op_st_rm_T0_A0(DisasContext
*s
, int idx
, int d
)
439 gen_op_st_v(s
, idx
, s
->T0
, s
->A0
);
441 gen_op_mov_reg_v(s
, idx
, d
, s
->T0
);
445 static inline void gen_jmp_im(DisasContext
*s
, target_ulong pc
)
447 tcg_gen_movi_tl(s
->tmp0
, pc
);
448 gen_op_jmp_v(s
->tmp0
);
451 /* Compute SEG:REG into A0. SEG is selected from the override segment
452 (OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to
453 indicate no override. */
454 static void gen_lea_v_seg(DisasContext
*s
, MemOp aflag
, TCGv a0
,
455 int def_seg
, int ovr_seg
)
461 tcg_gen_mov_tl(s
->A0
, a0
);
468 if (ovr_seg
< 0 && s
->addseg
) {
472 tcg_gen_ext32u_tl(s
->A0
, a0
);
478 tcg_gen_ext16u_tl(s
->A0
, a0
);
493 TCGv seg
= cpu_seg_base
[ovr_seg
];
495 if (aflag
== MO_64
) {
496 tcg_gen_add_tl(s
->A0
, a0
, seg
);
497 } else if (CODE64(s
)) {
498 tcg_gen_ext32u_tl(s
->A0
, a0
);
499 tcg_gen_add_tl(s
->A0
, s
->A0
, seg
);
501 tcg_gen_add_tl(s
->A0
, a0
, seg
);
502 tcg_gen_ext32u_tl(s
->A0
, s
->A0
);
507 static inline void gen_string_movl_A0_ESI(DisasContext
*s
)
509 gen_lea_v_seg(s
, s
->aflag
, cpu_regs
[R_ESI
], R_DS
, s
->override
);
512 static inline void gen_string_movl_A0_EDI(DisasContext
*s
)
514 gen_lea_v_seg(s
, s
->aflag
, cpu_regs
[R_EDI
], R_ES
, -1);
517 static inline void gen_op_movl_T0_Dshift(DisasContext
*s
, MemOp ot
)
519 tcg_gen_ld32s_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, df
));
520 tcg_gen_shli_tl(s
->T0
, s
->T0
, ot
);
523 static TCGv
gen_ext_tl(TCGv dst
, TCGv src
, MemOp size
, bool sign
)
528 tcg_gen_ext8s_tl(dst
, src
);
530 tcg_gen_ext8u_tl(dst
, src
);
535 tcg_gen_ext16s_tl(dst
, src
);
537 tcg_gen_ext16u_tl(dst
, src
);
543 tcg_gen_ext32s_tl(dst
, src
);
545 tcg_gen_ext32u_tl(dst
, src
);
554 static void gen_extu(MemOp ot
, TCGv reg
)
556 gen_ext_tl(reg
, reg
, ot
, false);
559 static void gen_exts(MemOp ot
, TCGv reg
)
561 gen_ext_tl(reg
, reg
, ot
, true);
565 void gen_op_jnz_ecx(DisasContext
*s
, MemOp size
, TCGLabel
*label1
)
567 tcg_gen_mov_tl(s
->tmp0
, cpu_regs
[R_ECX
]);
568 gen_extu(size
, s
->tmp0
);
569 tcg_gen_brcondi_tl(TCG_COND_NE
, s
->tmp0
, 0, label1
);
573 void gen_op_jz_ecx(DisasContext
*s
, MemOp size
, TCGLabel
*label1
)
575 tcg_gen_mov_tl(s
->tmp0
, cpu_regs
[R_ECX
]);
576 gen_extu(size
, s
->tmp0
);
577 tcg_gen_brcondi_tl(TCG_COND_EQ
, s
->tmp0
, 0, label1
);
580 static void gen_helper_in_func(MemOp ot
, TCGv v
, TCGv_i32 n
)
584 gen_helper_inb(v
, cpu_env
, n
);
587 gen_helper_inw(v
, cpu_env
, n
);
590 gen_helper_inl(v
, cpu_env
, n
);
597 static void gen_helper_out_func(MemOp ot
, TCGv_i32 v
, TCGv_i32 n
)
601 gen_helper_outb(cpu_env
, v
, n
);
604 gen_helper_outw(cpu_env
, v
, n
);
607 gen_helper_outl(cpu_env
, v
, n
);
614 static void gen_check_io(DisasContext
*s
, MemOp ot
, target_ulong cur_eip
,
617 target_ulong next_eip
;
619 if (s
->pe
&& (s
->cpl
> s
->iopl
|| s
->vm86
)) {
620 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
623 gen_helper_check_iob(cpu_env
, s
->tmp2_i32
);
626 gen_helper_check_iow(cpu_env
, s
->tmp2_i32
);
629 gen_helper_check_iol(cpu_env
, s
->tmp2_i32
);
635 if(s
->flags
& HF_GUEST_MASK
) {
637 gen_jmp_im(s
, cur_eip
);
638 svm_flags
|= (1 << (4 + ot
));
639 next_eip
= s
->pc
- s
->cs_base
;
640 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
641 gen_helper_svm_check_io(cpu_env
, s
->tmp2_i32
,
642 tcg_const_i32(svm_flags
),
643 tcg_const_i32(next_eip
- cur_eip
));
647 static inline void gen_movs(DisasContext
*s
, MemOp ot
)
649 gen_string_movl_A0_ESI(s
);
650 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
651 gen_string_movl_A0_EDI(s
);
652 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
653 gen_op_movl_T0_Dshift(s
, ot
);
654 gen_op_add_reg_T0(s
, s
->aflag
, R_ESI
);
655 gen_op_add_reg_T0(s
, s
->aflag
, R_EDI
);
658 static void gen_op_update1_cc(DisasContext
*s
)
660 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
663 static void gen_op_update2_cc(DisasContext
*s
)
665 tcg_gen_mov_tl(cpu_cc_src
, s
->T1
);
666 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
669 static void gen_op_update3_cc(DisasContext
*s
, TCGv reg
)
671 tcg_gen_mov_tl(cpu_cc_src2
, reg
);
672 tcg_gen_mov_tl(cpu_cc_src
, s
->T1
);
673 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
676 static inline void gen_op_testl_T0_T1_cc(DisasContext
*s
)
678 tcg_gen_and_tl(cpu_cc_dst
, s
->T0
, s
->T1
);
681 static void gen_op_update_neg_cc(DisasContext
*s
)
683 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
684 tcg_gen_neg_tl(cpu_cc_src
, s
->T0
);
685 tcg_gen_movi_tl(s
->cc_srcT
, 0);
688 /* compute all eflags to cc_src */
689 static void gen_compute_eflags(DisasContext
*s
)
691 TCGv zero
, dst
, src1
, src2
;
694 if (s
->cc_op
== CC_OP_EFLAGS
) {
697 if (s
->cc_op
== CC_OP_CLR
) {
698 tcg_gen_movi_tl(cpu_cc_src
, CC_Z
| CC_P
);
699 set_cc_op(s
, CC_OP_EFLAGS
);
708 /* Take care to not read values that are not live. */
709 live
= cc_op_live
[s
->cc_op
] & ~USES_CC_SRCT
;
710 dead
= live
^ (USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
);
712 zero
= tcg_const_tl(0);
713 if (dead
& USES_CC_DST
) {
716 if (dead
& USES_CC_SRC
) {
719 if (dead
& USES_CC_SRC2
) {
725 gen_helper_cc_compute_all(cpu_cc_src
, dst
, src1
, src2
, cpu_cc_op
);
726 set_cc_op(s
, CC_OP_EFLAGS
);
733 typedef struct CCPrepare
{
743 /* compute eflags.C to reg */
744 static CCPrepare
gen_prepare_eflags_c(DisasContext
*s
, TCGv reg
)
750 case CC_OP_SUBB
... CC_OP_SUBQ
:
751 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
752 size
= s
->cc_op
- CC_OP_SUBB
;
753 t1
= gen_ext_tl(s
->tmp0
, cpu_cc_src
, size
, false);
754 /* If no temporary was used, be careful not to alias t1 and t0. */
755 t0
= t1
== cpu_cc_src
? s
->tmp0
: reg
;
756 tcg_gen_mov_tl(t0
, s
->cc_srcT
);
760 case CC_OP_ADDB
... CC_OP_ADDQ
:
761 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
762 size
= s
->cc_op
- CC_OP_ADDB
;
763 t1
= gen_ext_tl(s
->tmp0
, cpu_cc_src
, size
, false);
764 t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
766 return (CCPrepare
) { .cond
= TCG_COND_LTU
, .reg
= t0
,
767 .reg2
= t1
, .mask
= -1, .use_reg2
= true };
769 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
772 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
774 case CC_OP_INCB
... CC_OP_INCQ
:
775 case CC_OP_DECB
... CC_OP_DECQ
:
776 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
777 .mask
= -1, .no_setcond
= true };
779 case CC_OP_SHLB
... CC_OP_SHLQ
:
780 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
781 size
= s
->cc_op
- CC_OP_SHLB
;
782 shift
= (8 << size
) - 1;
783 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
784 .mask
= (target_ulong
)1 << shift
};
786 case CC_OP_MULB
... CC_OP_MULQ
:
787 return (CCPrepare
) { .cond
= TCG_COND_NE
,
788 .reg
= cpu_cc_src
, .mask
= -1 };
790 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
791 size
= s
->cc_op
- CC_OP_BMILGB
;
792 t0
= gen_ext_tl(reg
, cpu_cc_src
, size
, false);
793 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
797 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_dst
,
798 .mask
= -1, .no_setcond
= true };
801 case CC_OP_SARB
... CC_OP_SARQ
:
803 return (CCPrepare
) { .cond
= TCG_COND_NE
,
804 .reg
= cpu_cc_src
, .mask
= CC_C
};
807 /* The need to compute only C from CC_OP_DYNAMIC is important
808 in efficiently implementing e.g. INC at the start of a TB. */
810 gen_helper_cc_compute_c(reg
, cpu_cc_dst
, cpu_cc_src
,
811 cpu_cc_src2
, cpu_cc_op
);
812 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
813 .mask
= -1, .no_setcond
= true };
817 /* compute eflags.P to reg */
818 static CCPrepare
gen_prepare_eflags_p(DisasContext
*s
, TCGv reg
)
820 gen_compute_eflags(s
);
821 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
825 /* compute eflags.S to reg */
826 static CCPrepare
gen_prepare_eflags_s(DisasContext
*s
, TCGv reg
)
830 gen_compute_eflags(s
);
836 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
840 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
843 MemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
844 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, true);
845 return (CCPrepare
) { .cond
= TCG_COND_LT
, .reg
= t0
, .mask
= -1 };
850 /* compute eflags.O to reg */
851 static CCPrepare
gen_prepare_eflags_o(DisasContext
*s
, TCGv reg
)
856 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src2
,
857 .mask
= -1, .no_setcond
= true };
860 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
862 gen_compute_eflags(s
);
863 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
868 /* compute eflags.Z to reg */
869 static CCPrepare
gen_prepare_eflags_z(DisasContext
*s
, TCGv reg
)
873 gen_compute_eflags(s
);
879 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
882 return (CCPrepare
) { .cond
= TCG_COND_ALWAYS
, .mask
= -1 };
884 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= cpu_cc_src
,
888 MemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
889 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
890 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
895 /* perform a conditional store into register 'reg' according to jump opcode
896 value 'b'. In the fast case, T0 is guaranted not to be used. */
897 static CCPrepare
gen_prepare_cc(DisasContext
*s
, int b
, TCGv reg
)
899 int inv
, jcc_op
, cond
;
905 jcc_op
= (b
>> 1) & 7;
908 case CC_OP_SUBB
... CC_OP_SUBQ
:
909 /* We optimize relational operators for the cmp/jcc case. */
910 size
= s
->cc_op
- CC_OP_SUBB
;
913 tcg_gen_mov_tl(s
->tmp4
, s
->cc_srcT
);
914 gen_extu(size
, s
->tmp4
);
915 t0
= gen_ext_tl(s
->tmp0
, cpu_cc_src
, size
, false);
916 cc
= (CCPrepare
) { .cond
= TCG_COND_LEU
, .reg
= s
->tmp4
,
917 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
926 tcg_gen_mov_tl(s
->tmp4
, s
->cc_srcT
);
927 gen_exts(size
, s
->tmp4
);
928 t0
= gen_ext_tl(s
->tmp0
, cpu_cc_src
, size
, true);
929 cc
= (CCPrepare
) { .cond
= cond
, .reg
= s
->tmp4
,
930 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
940 /* This actually generates good code for JC, JZ and JS. */
943 cc
= gen_prepare_eflags_o(s
, reg
);
946 cc
= gen_prepare_eflags_c(s
, reg
);
949 cc
= gen_prepare_eflags_z(s
, reg
);
952 gen_compute_eflags(s
);
953 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
954 .mask
= CC_Z
| CC_C
};
957 cc
= gen_prepare_eflags_s(s
, reg
);
960 cc
= gen_prepare_eflags_p(s
, reg
);
963 gen_compute_eflags(s
);
964 if (reg
== cpu_cc_src
) {
967 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
968 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
969 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
974 gen_compute_eflags(s
);
975 if (reg
== cpu_cc_src
) {
978 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
979 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
980 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
981 .mask
= CC_S
| CC_Z
};
988 cc
.cond
= tcg_invert_cond(cc
.cond
);
993 static void gen_setcc1(DisasContext
*s
, int b
, TCGv reg
)
995 CCPrepare cc
= gen_prepare_cc(s
, b
, reg
);
998 if (cc
.cond
== TCG_COND_EQ
) {
999 tcg_gen_xori_tl(reg
, cc
.reg
, 1);
1001 tcg_gen_mov_tl(reg
, cc
.reg
);
1006 if (cc
.cond
== TCG_COND_NE
&& !cc
.use_reg2
&& cc
.imm
== 0 &&
1007 cc
.mask
!= 0 && (cc
.mask
& (cc
.mask
- 1)) == 0) {
1008 tcg_gen_shri_tl(reg
, cc
.reg
, ctztl(cc
.mask
));
1009 tcg_gen_andi_tl(reg
, reg
, 1);
1012 if (cc
.mask
!= -1) {
1013 tcg_gen_andi_tl(reg
, cc
.reg
, cc
.mask
);
1017 tcg_gen_setcond_tl(cc
.cond
, reg
, cc
.reg
, cc
.reg2
);
1019 tcg_gen_setcondi_tl(cc
.cond
, reg
, cc
.reg
, cc
.imm
);
1023 static inline void gen_compute_eflags_c(DisasContext
*s
, TCGv reg
)
1025 gen_setcc1(s
, JCC_B
<< 1, reg
);
1028 /* generate a conditional jump to label 'l1' according to jump opcode
1029 value 'b'. In the fast case, T0 is guaranted not to be used. */
1030 static inline void gen_jcc1_noeob(DisasContext
*s
, int b
, TCGLabel
*l1
)
1032 CCPrepare cc
= gen_prepare_cc(s
, b
, s
->T0
);
1034 if (cc
.mask
!= -1) {
1035 tcg_gen_andi_tl(s
->T0
, cc
.reg
, cc
.mask
);
1039 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1041 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1045 /* Generate a conditional jump to label 'l1' according to jump opcode
1046 value 'b'. In the fast case, T0 is guaranted not to be used.
1047 A translation block must end soon. */
1048 static inline void gen_jcc1(DisasContext
*s
, int b
, TCGLabel
*l1
)
1050 CCPrepare cc
= gen_prepare_cc(s
, b
, s
->T0
);
1052 gen_update_cc_op(s
);
1053 if (cc
.mask
!= -1) {
1054 tcg_gen_andi_tl(s
->T0
, cc
.reg
, cc
.mask
);
1057 set_cc_op(s
, CC_OP_DYNAMIC
);
1059 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1061 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1065 /* XXX: does not work with gdbstub "ice" single step - not a
1067 static TCGLabel
*gen_jz_ecx_string(DisasContext
*s
, target_ulong next_eip
)
1069 TCGLabel
*l1
= gen_new_label();
1070 TCGLabel
*l2
= gen_new_label();
1071 gen_op_jnz_ecx(s
, s
->aflag
, l1
);
1073 gen_jmp_tb(s
, next_eip
, 1);
1078 static inline void gen_stos(DisasContext
*s
, MemOp ot
)
1080 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, R_EAX
);
1081 gen_string_movl_A0_EDI(s
);
1082 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
1083 gen_op_movl_T0_Dshift(s
, ot
);
1084 gen_op_add_reg_T0(s
, s
->aflag
, R_EDI
);
1087 static inline void gen_lods(DisasContext
*s
, MemOp ot
)
1089 gen_string_movl_A0_ESI(s
);
1090 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1091 gen_op_mov_reg_v(s
, ot
, R_EAX
, s
->T0
);
1092 gen_op_movl_T0_Dshift(s
, ot
);
1093 gen_op_add_reg_T0(s
, s
->aflag
, R_ESI
);
1096 static inline void gen_scas(DisasContext
*s
, MemOp ot
)
1098 gen_string_movl_A0_EDI(s
);
1099 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
1100 gen_op(s
, OP_CMPL
, ot
, R_EAX
);
1101 gen_op_movl_T0_Dshift(s
, ot
);
1102 gen_op_add_reg_T0(s
, s
->aflag
, R_EDI
);
1105 static inline void gen_cmps(DisasContext
*s
, MemOp ot
)
1107 gen_string_movl_A0_EDI(s
);
1108 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
1109 gen_string_movl_A0_ESI(s
);
1110 gen_op(s
, OP_CMPL
, ot
, OR_TMP0
);
1111 gen_op_movl_T0_Dshift(s
, ot
);
1112 gen_op_add_reg_T0(s
, s
->aflag
, R_ESI
);
1113 gen_op_add_reg_T0(s
, s
->aflag
, R_EDI
);
1116 static void gen_bpt_io(DisasContext
*s
, TCGv_i32 t_port
, int ot
)
1118 if (s
->flags
& HF_IOBPT_MASK
) {
1119 TCGv_i32 t_size
= tcg_const_i32(1 << ot
);
1120 TCGv t_next
= tcg_const_tl(s
->pc
- s
->cs_base
);
1122 gen_helper_bpt_io(cpu_env
, t_port
, t_size
, t_next
);
1123 tcg_temp_free_i32(t_size
);
1124 tcg_temp_free(t_next
);
1129 static inline void gen_ins(DisasContext
*s
, MemOp ot
)
1131 gen_string_movl_A0_EDI(s
);
1132 /* Note: we must do this dummy write first to be restartable in
1133 case of page fault. */
1134 tcg_gen_movi_tl(s
->T0
, 0);
1135 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
1136 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_EDX
]);
1137 tcg_gen_andi_i32(s
->tmp2_i32
, s
->tmp2_i32
, 0xffff);
1138 gen_helper_in_func(ot
, s
->T0
, s
->tmp2_i32
);
1139 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
1140 gen_op_movl_T0_Dshift(s
, ot
);
1141 gen_op_add_reg_T0(s
, s
->aflag
, R_EDI
);
1142 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
1145 static inline void gen_outs(DisasContext
*s
, MemOp ot
)
1147 gen_string_movl_A0_ESI(s
);
1148 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1150 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_EDX
]);
1151 tcg_gen_andi_i32(s
->tmp2_i32
, s
->tmp2_i32
, 0xffff);
1152 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, s
->T0
);
1153 gen_helper_out_func(ot
, s
->tmp2_i32
, s
->tmp3_i32
);
1154 gen_op_movl_T0_Dshift(s
, ot
);
1155 gen_op_add_reg_T0(s
, s
->aflag
, R_ESI
);
1156 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
1159 /* same method as Valgrind : we generate jumps to current or next
1161 #define GEN_REPZ(op) \
1162 static inline void gen_repz_ ## op(DisasContext *s, MemOp ot, \
1163 target_ulong cur_eip, target_ulong next_eip) \
1166 gen_update_cc_op(s); \
1167 l2 = gen_jz_ecx_string(s, next_eip); \
1168 gen_ ## op(s, ot); \
1169 gen_op_add_reg_im(s, s->aflag, R_ECX, -1); \
1170 /* a loop would cause two single step exceptions if ECX = 1 \
1171 before rep string_insn */ \
1173 gen_op_jz_ecx(s, s->aflag, l2); \
1174 gen_jmp(s, cur_eip); \
1177 #define GEN_REPZ2(op) \
1178 static inline void gen_repz_ ## op(DisasContext *s, MemOp ot, \
1179 target_ulong cur_eip, \
1180 target_ulong next_eip, \
1184 gen_update_cc_op(s); \
1185 l2 = gen_jz_ecx_string(s, next_eip); \
1186 gen_ ## op(s, ot); \
1187 gen_op_add_reg_im(s, s->aflag, R_ECX, -1); \
1188 gen_update_cc_op(s); \
1189 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
1191 gen_op_jz_ecx(s, s->aflag, l2); \
1192 gen_jmp(s, cur_eip); \
1203 static void gen_helper_fp_arith_ST0_FT0(int op
)
1207 gen_helper_fadd_ST0_FT0(cpu_env
);
1210 gen_helper_fmul_ST0_FT0(cpu_env
);
1213 gen_helper_fcom_ST0_FT0(cpu_env
);
1216 gen_helper_fcom_ST0_FT0(cpu_env
);
1219 gen_helper_fsub_ST0_FT0(cpu_env
);
1222 gen_helper_fsubr_ST0_FT0(cpu_env
);
1225 gen_helper_fdiv_ST0_FT0(cpu_env
);
1228 gen_helper_fdivr_ST0_FT0(cpu_env
);
1233 /* NOTE the exception in "r" op ordering */
1234 static void gen_helper_fp_arith_STN_ST0(int op
, int opreg
)
1236 TCGv_i32 tmp
= tcg_const_i32(opreg
);
1239 gen_helper_fadd_STN_ST0(cpu_env
, tmp
);
1242 gen_helper_fmul_STN_ST0(cpu_env
, tmp
);
1245 gen_helper_fsubr_STN_ST0(cpu_env
, tmp
);
1248 gen_helper_fsub_STN_ST0(cpu_env
, tmp
);
1251 gen_helper_fdivr_STN_ST0(cpu_env
, tmp
);
1254 gen_helper_fdiv_STN_ST0(cpu_env
, tmp
);
1259 static void gen_exception(DisasContext
*s
, int trapno
, target_ulong cur_eip
)
1261 gen_update_cc_op(s
);
1262 gen_jmp_im(s
, cur_eip
);
1263 gen_helper_raise_exception(cpu_env
, tcg_const_i32(trapno
));
1264 s
->base
.is_jmp
= DISAS_NORETURN
;
1267 /* Generate #UD for the current instruction. The assumption here is that
1268 the instruction is known, but it isn't allowed in the current cpu mode. */
1269 static void gen_illegal_opcode(DisasContext
*s
)
1271 gen_exception(s
, EXCP06_ILLOP
, s
->pc_start
- s
->cs_base
);
1274 /* if d == OR_TMP0, it means memory operand (address in A0) */
1275 static void gen_op(DisasContext
*s1
, int op
, MemOp ot
, int d
)
1278 if (s1
->prefix
& PREFIX_LOCK
) {
1279 /* Lock prefix when destination is not memory. */
1280 gen_illegal_opcode(s1
);
1283 gen_op_mov_v_reg(s1
, ot
, s1
->T0
, d
);
1284 } else if (!(s1
->prefix
& PREFIX_LOCK
)) {
1285 gen_op_ld_v(s1
, ot
, s1
->T0
, s1
->A0
);
1289 gen_compute_eflags_c(s1
, s1
->tmp4
);
1290 if (s1
->prefix
& PREFIX_LOCK
) {
1291 tcg_gen_add_tl(s1
->T0
, s1
->tmp4
, s1
->T1
);
1292 tcg_gen_atomic_add_fetch_tl(s1
->T0
, s1
->A0
, s1
->T0
,
1293 s1
->mem_index
, ot
| MO_LE
);
1295 tcg_gen_add_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1296 tcg_gen_add_tl(s1
->T0
, s1
->T0
, s1
->tmp4
);
1297 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1299 gen_op_update3_cc(s1
, s1
->tmp4
);
1300 set_cc_op(s1
, CC_OP_ADCB
+ ot
);
1303 gen_compute_eflags_c(s1
, s1
->tmp4
);
1304 if (s1
->prefix
& PREFIX_LOCK
) {
1305 tcg_gen_add_tl(s1
->T0
, s1
->T1
, s1
->tmp4
);
1306 tcg_gen_neg_tl(s1
->T0
, s1
->T0
);
1307 tcg_gen_atomic_add_fetch_tl(s1
->T0
, s1
->A0
, s1
->T0
,
1308 s1
->mem_index
, ot
| MO_LE
);
1310 tcg_gen_sub_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1311 tcg_gen_sub_tl(s1
->T0
, s1
->T0
, s1
->tmp4
);
1312 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1314 gen_op_update3_cc(s1
, s1
->tmp4
);
1315 set_cc_op(s1
, CC_OP_SBBB
+ ot
);
1318 if (s1
->prefix
& PREFIX_LOCK
) {
1319 tcg_gen_atomic_add_fetch_tl(s1
->T0
, s1
->A0
, s1
->T1
,
1320 s1
->mem_index
, ot
| MO_LE
);
1322 tcg_gen_add_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1323 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1325 gen_op_update2_cc(s1
);
1326 set_cc_op(s1
, CC_OP_ADDB
+ ot
);
1329 if (s1
->prefix
& PREFIX_LOCK
) {
1330 tcg_gen_neg_tl(s1
->T0
, s1
->T1
);
1331 tcg_gen_atomic_fetch_add_tl(s1
->cc_srcT
, s1
->A0
, s1
->T0
,
1332 s1
->mem_index
, ot
| MO_LE
);
1333 tcg_gen_sub_tl(s1
->T0
, s1
->cc_srcT
, s1
->T1
);
1335 tcg_gen_mov_tl(s1
->cc_srcT
, s1
->T0
);
1336 tcg_gen_sub_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1337 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1339 gen_op_update2_cc(s1
);
1340 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1344 if (s1
->prefix
& PREFIX_LOCK
) {
1345 tcg_gen_atomic_and_fetch_tl(s1
->T0
, s1
->A0
, s1
->T1
,
1346 s1
->mem_index
, ot
| MO_LE
);
1348 tcg_gen_and_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1349 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1351 gen_op_update1_cc(s1
);
1352 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1355 if (s1
->prefix
& PREFIX_LOCK
) {
1356 tcg_gen_atomic_or_fetch_tl(s1
->T0
, s1
->A0
, s1
->T1
,
1357 s1
->mem_index
, ot
| MO_LE
);
1359 tcg_gen_or_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1360 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1362 gen_op_update1_cc(s1
);
1363 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1366 if (s1
->prefix
& PREFIX_LOCK
) {
1367 tcg_gen_atomic_xor_fetch_tl(s1
->T0
, s1
->A0
, s1
->T1
,
1368 s1
->mem_index
, ot
| MO_LE
);
1370 tcg_gen_xor_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1371 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1373 gen_op_update1_cc(s1
);
1374 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1377 tcg_gen_mov_tl(cpu_cc_src
, s1
->T1
);
1378 tcg_gen_mov_tl(s1
->cc_srcT
, s1
->T0
);
1379 tcg_gen_sub_tl(cpu_cc_dst
, s1
->T0
, s1
->T1
);
1380 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1385 /* if d == OR_TMP0, it means memory operand (address in A0) */
1386 static void gen_inc(DisasContext
*s1
, MemOp ot
, int d
, int c
)
1388 if (s1
->prefix
& PREFIX_LOCK
) {
1390 /* Lock prefix when destination is not memory */
1391 gen_illegal_opcode(s1
);
1394 tcg_gen_movi_tl(s1
->T0
, c
> 0 ? 1 : -1);
1395 tcg_gen_atomic_add_fetch_tl(s1
->T0
, s1
->A0
, s1
->T0
,
1396 s1
->mem_index
, ot
| MO_LE
);
1399 gen_op_mov_v_reg(s1
, ot
, s1
->T0
, d
);
1401 gen_op_ld_v(s1
, ot
, s1
->T0
, s1
->A0
);
1403 tcg_gen_addi_tl(s1
->T0
, s1
->T0
, (c
> 0 ? 1 : -1));
1404 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1407 gen_compute_eflags_c(s1
, cpu_cc_src
);
1408 tcg_gen_mov_tl(cpu_cc_dst
, s1
->T0
);
1409 set_cc_op(s1
, (c
> 0 ? CC_OP_INCB
: CC_OP_DECB
) + ot
);
1412 static void gen_shift_flags(DisasContext
*s
, MemOp ot
, TCGv result
,
1413 TCGv shm1
, TCGv count
, bool is_right
)
1415 TCGv_i32 z32
, s32
, oldop
;
1418 /* Store the results into the CC variables. If we know that the
1419 variable must be dead, store unconditionally. Otherwise we'll
1420 need to not disrupt the current contents. */
1421 z_tl
= tcg_const_tl(0);
1422 if (cc_op_live
[s
->cc_op
] & USES_CC_DST
) {
1423 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_dst
, count
, z_tl
,
1424 result
, cpu_cc_dst
);
1426 tcg_gen_mov_tl(cpu_cc_dst
, result
);
1428 if (cc_op_live
[s
->cc_op
] & USES_CC_SRC
) {
1429 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_src
, count
, z_tl
,
1432 tcg_gen_mov_tl(cpu_cc_src
, shm1
);
1434 tcg_temp_free(z_tl
);
1436 /* Get the two potential CC_OP values into temporaries. */
1437 tcg_gen_movi_i32(s
->tmp2_i32
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1438 if (s
->cc_op
== CC_OP_DYNAMIC
) {
1441 tcg_gen_movi_i32(s
->tmp3_i32
, s
->cc_op
);
1442 oldop
= s
->tmp3_i32
;
1445 /* Conditionally store the CC_OP value. */
1446 z32
= tcg_const_i32(0);
1447 s32
= tcg_temp_new_i32();
1448 tcg_gen_trunc_tl_i32(s32
, count
);
1449 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, s32
, z32
, s
->tmp2_i32
, oldop
);
1450 tcg_temp_free_i32(z32
);
1451 tcg_temp_free_i32(s32
);
1453 /* The CC_OP value is no longer predictable. */
1454 set_cc_op(s
, CC_OP_DYNAMIC
);
1457 static void gen_shift_rm_T1(DisasContext
*s
, MemOp ot
, int op1
,
1458 int is_right
, int is_arith
)
1460 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1463 if (op1
== OR_TMP0
) {
1464 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1466 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1469 tcg_gen_andi_tl(s
->T1
, s
->T1
, mask
);
1470 tcg_gen_subi_tl(s
->tmp0
, s
->T1
, 1);
1474 gen_exts(ot
, s
->T0
);
1475 tcg_gen_sar_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1476 tcg_gen_sar_tl(s
->T0
, s
->T0
, s
->T1
);
1478 gen_extu(ot
, s
->T0
);
1479 tcg_gen_shr_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1480 tcg_gen_shr_tl(s
->T0
, s
->T0
, s
->T1
);
1483 tcg_gen_shl_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1484 tcg_gen_shl_tl(s
->T0
, s
->T0
, s
->T1
);
1488 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1490 gen_shift_flags(s
, ot
, s
->T0
, s
->tmp0
, s
->T1
, is_right
);
1493 static void gen_shift_rm_im(DisasContext
*s
, MemOp ot
, int op1
, int op2
,
1494 int is_right
, int is_arith
)
1496 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1500 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1502 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1508 gen_exts(ot
, s
->T0
);
1509 tcg_gen_sari_tl(s
->tmp4
, s
->T0
, op2
- 1);
1510 tcg_gen_sari_tl(s
->T0
, s
->T0
, op2
);
1512 gen_extu(ot
, s
->T0
);
1513 tcg_gen_shri_tl(s
->tmp4
, s
->T0
, op2
- 1);
1514 tcg_gen_shri_tl(s
->T0
, s
->T0
, op2
);
1517 tcg_gen_shli_tl(s
->tmp4
, s
->T0
, op2
- 1);
1518 tcg_gen_shli_tl(s
->T0
, s
->T0
, op2
);
1523 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1525 /* update eflags if non zero shift */
1527 tcg_gen_mov_tl(cpu_cc_src
, s
->tmp4
);
1528 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
1529 set_cc_op(s
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1533 static void gen_rot_rm_T1(DisasContext
*s
, MemOp ot
, int op1
, int is_right
)
1535 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1539 if (op1
== OR_TMP0
) {
1540 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1542 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1545 tcg_gen_andi_tl(s
->T1
, s
->T1
, mask
);
1549 /* Replicate the 8-bit input so that a 32-bit rotate works. */
1550 tcg_gen_ext8u_tl(s
->T0
, s
->T0
);
1551 tcg_gen_muli_tl(s
->T0
, s
->T0
, 0x01010101);
1554 /* Replicate the 16-bit input so that a 32-bit rotate works. */
1555 tcg_gen_deposit_tl(s
->T0
, s
->T0
, s
->T0
, 16, 16);
1558 #ifdef TARGET_X86_64
1560 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
1561 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, s
->T1
);
1563 tcg_gen_rotr_i32(s
->tmp2_i32
, s
->tmp2_i32
, s
->tmp3_i32
);
1565 tcg_gen_rotl_i32(s
->tmp2_i32
, s
->tmp2_i32
, s
->tmp3_i32
);
1567 tcg_gen_extu_i32_tl(s
->T0
, s
->tmp2_i32
);
1572 tcg_gen_rotr_tl(s
->T0
, s
->T0
, s
->T1
);
1574 tcg_gen_rotl_tl(s
->T0
, s
->T0
, s
->T1
);
1580 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1582 /* We'll need the flags computed into CC_SRC. */
1583 gen_compute_eflags(s
);
1585 /* The value that was "rotated out" is now present at the other end
1586 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1587 since we've computed the flags into CC_SRC, these variables are
1590 tcg_gen_shri_tl(cpu_cc_src2
, s
->T0
, mask
- 1);
1591 tcg_gen_shri_tl(cpu_cc_dst
, s
->T0
, mask
);
1592 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1594 tcg_gen_shri_tl(cpu_cc_src2
, s
->T0
, mask
);
1595 tcg_gen_andi_tl(cpu_cc_dst
, s
->T0
, 1);
1597 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1598 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1600 /* Now conditionally store the new CC_OP value. If the shift count
1601 is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1602 Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1603 exactly as we computed above. */
1604 t0
= tcg_const_i32(0);
1605 t1
= tcg_temp_new_i32();
1606 tcg_gen_trunc_tl_i32(t1
, s
->T1
);
1607 tcg_gen_movi_i32(s
->tmp2_i32
, CC_OP_ADCOX
);
1608 tcg_gen_movi_i32(s
->tmp3_i32
, CC_OP_EFLAGS
);
1609 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, t1
, t0
,
1610 s
->tmp2_i32
, s
->tmp3_i32
);
1611 tcg_temp_free_i32(t0
);
1612 tcg_temp_free_i32(t1
);
1614 /* The CC_OP value is no longer predictable. */
1615 set_cc_op(s
, CC_OP_DYNAMIC
);
1618 static void gen_rot_rm_im(DisasContext
*s
, MemOp ot
, int op1
, int op2
,
1621 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1625 if (op1
== OR_TMP0
) {
1626 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1628 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1634 #ifdef TARGET_X86_64
1636 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
1638 tcg_gen_rotri_i32(s
->tmp2_i32
, s
->tmp2_i32
, op2
);
1640 tcg_gen_rotli_i32(s
->tmp2_i32
, s
->tmp2_i32
, op2
);
1642 tcg_gen_extu_i32_tl(s
->T0
, s
->tmp2_i32
);
1647 tcg_gen_rotri_tl(s
->T0
, s
->T0
, op2
);
1649 tcg_gen_rotli_tl(s
->T0
, s
->T0
, op2
);
1660 shift
= mask
+ 1 - shift
;
1662 gen_extu(ot
, s
->T0
);
1663 tcg_gen_shli_tl(s
->tmp0
, s
->T0
, shift
);
1664 tcg_gen_shri_tl(s
->T0
, s
->T0
, mask
+ 1 - shift
);
1665 tcg_gen_or_tl(s
->T0
, s
->T0
, s
->tmp0
);
1671 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1674 /* Compute the flags into CC_SRC. */
1675 gen_compute_eflags(s
);
1677 /* The value that was "rotated out" is now present at the other end
1678 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1679 since we've computed the flags into CC_SRC, these variables are
1682 tcg_gen_shri_tl(cpu_cc_src2
, s
->T0
, mask
- 1);
1683 tcg_gen_shri_tl(cpu_cc_dst
, s
->T0
, mask
);
1684 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1686 tcg_gen_shri_tl(cpu_cc_src2
, s
->T0
, mask
);
1687 tcg_gen_andi_tl(cpu_cc_dst
, s
->T0
, 1);
1689 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1690 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1691 set_cc_op(s
, CC_OP_ADCOX
);
1695 /* XXX: add faster immediate = 1 case */
1696 static void gen_rotc_rm_T1(DisasContext
*s
, MemOp ot
, int op1
,
1699 gen_compute_eflags(s
);
1700 assert(s
->cc_op
== CC_OP_EFLAGS
);
1704 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1706 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1711 gen_helper_rcrb(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1714 gen_helper_rcrw(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1717 gen_helper_rcrl(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1719 #ifdef TARGET_X86_64
1721 gen_helper_rcrq(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1730 gen_helper_rclb(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1733 gen_helper_rclw(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1736 gen_helper_rcll(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1738 #ifdef TARGET_X86_64
1740 gen_helper_rclq(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1748 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1751 /* XXX: add faster immediate case */
1752 static void gen_shiftd_rm_T1(DisasContext
*s
, MemOp ot
, int op1
,
1753 bool is_right
, TCGv count_in
)
1755 target_ulong mask
= (ot
== MO_64
? 63 : 31);
1759 if (op1
== OR_TMP0
) {
1760 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1762 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1765 count
= tcg_temp_new();
1766 tcg_gen_andi_tl(count
, count_in
, mask
);
1770 /* Note: we implement the Intel behaviour for shift count > 16.
1771 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A
1772 portion by constructing it as a 32-bit value. */
1774 tcg_gen_deposit_tl(s
->tmp0
, s
->T0
, s
->T1
, 16, 16);
1775 tcg_gen_mov_tl(s
->T1
, s
->T0
);
1776 tcg_gen_mov_tl(s
->T0
, s
->tmp0
);
1778 tcg_gen_deposit_tl(s
->T1
, s
->T0
, s
->T1
, 16, 16);
1781 #ifdef TARGET_X86_64
1783 /* Concatenate the two 32-bit values and use a 64-bit shift. */
1784 tcg_gen_subi_tl(s
->tmp0
, count
, 1);
1786 tcg_gen_concat_tl_i64(s
->T0
, s
->T0
, s
->T1
);
1787 tcg_gen_shr_i64(s
->tmp0
, s
->T0
, s
->tmp0
);
1788 tcg_gen_shr_i64(s
->T0
, s
->T0
, count
);
1790 tcg_gen_concat_tl_i64(s
->T0
, s
->T1
, s
->T0
);
1791 tcg_gen_shl_i64(s
->tmp0
, s
->T0
, s
->tmp0
);
1792 tcg_gen_shl_i64(s
->T0
, s
->T0
, count
);
1793 tcg_gen_shri_i64(s
->tmp0
, s
->tmp0
, 32);
1794 tcg_gen_shri_i64(s
->T0
, s
->T0
, 32);
1799 tcg_gen_subi_tl(s
->tmp0
, count
, 1);
1801 tcg_gen_shr_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1803 tcg_gen_subfi_tl(s
->tmp4
, mask
+ 1, count
);
1804 tcg_gen_shr_tl(s
->T0
, s
->T0
, count
);
1805 tcg_gen_shl_tl(s
->T1
, s
->T1
, s
->tmp4
);
1807 tcg_gen_shl_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1809 /* Only needed if count > 16, for Intel behaviour. */
1810 tcg_gen_subfi_tl(s
->tmp4
, 33, count
);
1811 tcg_gen_shr_tl(s
->tmp4
, s
->T1
, s
->tmp4
);
1812 tcg_gen_or_tl(s
->tmp0
, s
->tmp0
, s
->tmp4
);
1815 tcg_gen_subfi_tl(s
->tmp4
, mask
+ 1, count
);
1816 tcg_gen_shl_tl(s
->T0
, s
->T0
, count
);
1817 tcg_gen_shr_tl(s
->T1
, s
->T1
, s
->tmp4
);
1819 tcg_gen_movi_tl(s
->tmp4
, 0);
1820 tcg_gen_movcond_tl(TCG_COND_EQ
, s
->T1
, count
, s
->tmp4
,
1822 tcg_gen_or_tl(s
->T0
, s
->T0
, s
->T1
);
1827 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1829 gen_shift_flags(s
, ot
, s
->T0
, s
->tmp0
, count
, is_right
);
1830 tcg_temp_free(count
);
1833 static void gen_shift(DisasContext
*s1
, int op
, MemOp ot
, int d
, int s
)
1836 gen_op_mov_v_reg(s1
, ot
, s1
->T1
, s
);
1839 gen_rot_rm_T1(s1
, ot
, d
, 0);
1842 gen_rot_rm_T1(s1
, ot
, d
, 1);
1846 gen_shift_rm_T1(s1
, ot
, d
, 0, 0);
1849 gen_shift_rm_T1(s1
, ot
, d
, 1, 0);
1852 gen_shift_rm_T1(s1
, ot
, d
, 1, 1);
1855 gen_rotc_rm_T1(s1
, ot
, d
, 0);
1858 gen_rotc_rm_T1(s1
, ot
, d
, 1);
1863 static void gen_shifti(DisasContext
*s1
, int op
, MemOp ot
, int d
, int c
)
1867 gen_rot_rm_im(s1
, ot
, d
, c
, 0);
1870 gen_rot_rm_im(s1
, ot
, d
, c
, 1);
1874 gen_shift_rm_im(s1
, ot
, d
, c
, 0, 0);
1877 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 0);
1880 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 1);
1883 /* currently not optimized */
1884 tcg_gen_movi_tl(s1
->T1
, c
);
1885 gen_shift(s1
, op
, ot
, d
, OR_TMP1
);
1890 #define X86_MAX_INSN_LENGTH 15
1892 static uint64_t advance_pc(CPUX86State
*env
, DisasContext
*s
, int num_bytes
)
1894 uint64_t pc
= s
->pc
;
1897 if (unlikely(s
->pc
- s
->pc_start
> X86_MAX_INSN_LENGTH
)) {
1898 /* If the instruction's 16th byte is on a different page than the 1st, a
1899 * page fault on the second page wins over the general protection fault
1900 * caused by the instruction being too long.
1901 * This can happen even if the operand is only one byte long!
1903 if (((s
->pc
- 1) ^ (pc
- 1)) & TARGET_PAGE_MASK
) {
1904 volatile uint8_t unused
=
1905 cpu_ldub_code(env
, (s
->pc
- 1) & TARGET_PAGE_MASK
);
1908 siglongjmp(s
->jmpbuf
, 1);
1914 static inline uint8_t x86_ldub_code(CPUX86State
*env
, DisasContext
*s
)
1916 return translator_ldub(env
, advance_pc(env
, s
, 1));
1919 static inline int16_t x86_ldsw_code(CPUX86State
*env
, DisasContext
*s
)
1921 return translator_ldsw(env
, advance_pc(env
, s
, 2));
1924 static inline uint16_t x86_lduw_code(CPUX86State
*env
, DisasContext
*s
)
1926 return translator_lduw(env
, advance_pc(env
, s
, 2));
1929 static inline uint32_t x86_ldl_code(CPUX86State
*env
, DisasContext
*s
)
1931 return translator_ldl(env
, advance_pc(env
, s
, 4));
1934 #ifdef TARGET_X86_64
1935 static inline uint64_t x86_ldq_code(CPUX86State
*env
, DisasContext
*s
)
1937 return translator_ldq(env
, advance_pc(env
, s
, 8));
1941 /* Decompose an address. */
1943 typedef struct AddressParts
{
1951 static AddressParts
gen_lea_modrm_0(CPUX86State
*env
, DisasContext
*s
,
1954 int def_seg
, base
, index
, scale
, mod
, rm
;
1963 mod
= (modrm
>> 6) & 3;
1965 base
= rm
| REX_B(s
);
1968 /* Normally filtered out earlier, but including this path
1969 simplifies multi-byte nop, as well as bndcl, bndcu, bndcn. */
1978 int code
= x86_ldub_code(env
, s
);
1979 scale
= (code
>> 6) & 3;
1980 index
= ((code
>> 3) & 7) | REX_X(s
);
1982 index
= -1; /* no index */
1984 base
= (code
& 7) | REX_B(s
);
1990 if ((base
& 7) == 5) {
1992 disp
= (int32_t)x86_ldl_code(env
, s
);
1993 if (CODE64(s
) && !havesib
) {
1995 disp
+= s
->pc
+ s
->rip_offset
;
2000 disp
= (int8_t)x86_ldub_code(env
, s
);
2004 disp
= (int32_t)x86_ldl_code(env
, s
);
2008 /* For correct popl handling with esp. */
2009 if (base
== R_ESP
&& s
->popl_esp_hack
) {
2010 disp
+= s
->popl_esp_hack
;
2012 if (base
== R_EBP
|| base
== R_ESP
) {
2021 disp
= x86_lduw_code(env
, s
);
2024 } else if (mod
== 1) {
2025 disp
= (int8_t)x86_ldub_code(env
, s
);
2027 disp
= (int16_t)x86_lduw_code(env
, s
);
2071 return (AddressParts
){ def_seg
, base
, index
, scale
, disp
};
2074 /* Compute the address, with a minimum number of TCG ops. */
2075 static TCGv
gen_lea_modrm_1(DisasContext
*s
, AddressParts a
)
2081 ea
= cpu_regs
[a
.index
];
2083 tcg_gen_shli_tl(s
->A0
, cpu_regs
[a
.index
], a
.scale
);
2087 tcg_gen_add_tl(s
->A0
, ea
, cpu_regs
[a
.base
]);
2090 } else if (a
.base
>= 0) {
2091 ea
= cpu_regs
[a
.base
];
2094 tcg_gen_movi_tl(s
->A0
, a
.disp
);
2096 } else if (a
.disp
!= 0) {
2097 tcg_gen_addi_tl(s
->A0
, ea
, a
.disp
);
2104 static void gen_lea_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2106 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
2107 TCGv ea
= gen_lea_modrm_1(s
, a
);
2108 gen_lea_v_seg(s
, s
->aflag
, ea
, a
.def_seg
, s
->override
);
2111 static void gen_nop_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2113 (void)gen_lea_modrm_0(env
, s
, modrm
);
2116 /* Used for BNDCL, BNDCU, BNDCN. */
2117 static void gen_bndck(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2118 TCGCond cond
, TCGv_i64 bndv
)
2120 TCGv ea
= gen_lea_modrm_1(s
, gen_lea_modrm_0(env
, s
, modrm
));
2122 tcg_gen_extu_tl_i64(s
->tmp1_i64
, ea
);
2124 tcg_gen_ext32u_i64(s
->tmp1_i64
, s
->tmp1_i64
);
2126 tcg_gen_setcond_i64(cond
, s
->tmp1_i64
, s
->tmp1_i64
, bndv
);
2127 tcg_gen_extrl_i64_i32(s
->tmp2_i32
, s
->tmp1_i64
);
2128 gen_helper_bndck(cpu_env
, s
->tmp2_i32
);
2131 /* used for LEA and MOV AX, mem */
2132 static void gen_add_A0_ds_seg(DisasContext
*s
)
2134 gen_lea_v_seg(s
, s
->aflag
, s
->A0
, R_DS
, s
->override
);
2137 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2139 static void gen_ldst_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2140 MemOp ot
, int reg
, int is_store
)
2144 mod
= (modrm
>> 6) & 3;
2145 rm
= (modrm
& 7) | REX_B(s
);
2149 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
2150 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
2152 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
2154 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
2157 gen_lea_modrm(env
, s
, modrm
);
2160 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
2161 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
2163 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
2165 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
2170 static inline uint32_t insn_get(CPUX86State
*env
, DisasContext
*s
, MemOp ot
)
2176 ret
= x86_ldub_code(env
, s
);
2179 ret
= x86_lduw_code(env
, s
);
2182 #ifdef TARGET_X86_64
2185 ret
= x86_ldl_code(env
, s
);
2193 static inline int insn_const_size(MemOp ot
)
2202 static inline bool use_goto_tb(DisasContext
*s
, target_ulong pc
)
2204 #ifndef CONFIG_USER_ONLY
2205 return (pc
& TARGET_PAGE_MASK
) == (s
->base
.tb
->pc
& TARGET_PAGE_MASK
) ||
2206 (pc
& TARGET_PAGE_MASK
) == (s
->pc_start
& TARGET_PAGE_MASK
);
2212 static inline void gen_goto_tb(DisasContext
*s
, int tb_num
, target_ulong eip
)
2214 target_ulong pc
= s
->cs_base
+ eip
;
2216 if (use_goto_tb(s
, pc
)) {
2217 /* jump to same page: we can use a direct jump */
2218 tcg_gen_goto_tb(tb_num
);
2220 tcg_gen_exit_tb(s
->base
.tb
, tb_num
);
2221 s
->base
.is_jmp
= DISAS_NORETURN
;
2223 /* jump to another page */
2229 static inline void gen_jcc(DisasContext
*s
, int b
,
2230 target_ulong val
, target_ulong next_eip
)
2235 l1
= gen_new_label();
2238 gen_goto_tb(s
, 0, next_eip
);
2241 gen_goto_tb(s
, 1, val
);
2243 l1
= gen_new_label();
2244 l2
= gen_new_label();
2247 gen_jmp_im(s
, next_eip
);
2257 static void gen_cmovcc1(CPUX86State
*env
, DisasContext
*s
, MemOp ot
, int b
,
2262 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
2264 cc
= gen_prepare_cc(s
, b
, s
->T1
);
2265 if (cc
.mask
!= -1) {
2266 TCGv t0
= tcg_temp_new();
2267 tcg_gen_andi_tl(t0
, cc
.reg
, cc
.mask
);
2271 cc
.reg2
= tcg_const_tl(cc
.imm
);
2274 tcg_gen_movcond_tl(cc
.cond
, s
->T0
, cc
.reg
, cc
.reg2
,
2275 s
->T0
, cpu_regs
[reg
]);
2276 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
2278 if (cc
.mask
!= -1) {
2279 tcg_temp_free(cc
.reg
);
2282 tcg_temp_free(cc
.reg2
);
2286 static inline void gen_op_movl_T0_seg(DisasContext
*s
, int seg_reg
)
2288 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
2289 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2292 static inline void gen_op_movl_seg_T0_vm(DisasContext
*s
, int seg_reg
)
2294 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
2295 tcg_gen_st32_tl(s
->T0
, cpu_env
,
2296 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2297 tcg_gen_shli_tl(cpu_seg_base
[seg_reg
], s
->T0
, 4);
2300 /* move T0 to seg_reg and compute if the CPU state may change. Never
2301 call this function with seg_reg == R_CS */
2302 static void gen_movl_seg_T0(DisasContext
*s
, int seg_reg
)
2304 if (s
->pe
&& !s
->vm86
) {
2305 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
2306 gen_helper_load_seg(cpu_env
, tcg_const_i32(seg_reg
), s
->tmp2_i32
);
2307 /* abort translation because the addseg value may change or
2308 because ss32 may change. For R_SS, translation must always
2309 stop as a special handling must be done to disable hardware
2310 interrupts for the next instruction */
2311 if (seg_reg
== R_SS
|| (s
->code32
&& seg_reg
< R_FS
)) {
2312 s
->base
.is_jmp
= DISAS_TOO_MANY
;
2315 gen_op_movl_seg_T0_vm(s
, seg_reg
);
2316 if (seg_reg
== R_SS
) {
2317 s
->base
.is_jmp
= DISAS_TOO_MANY
;
2322 static inline int svm_is_rep(int prefixes
)
2324 return ((prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) ? 8 : 0);
2328 gen_svm_check_intercept_param(DisasContext
*s
, target_ulong pc_start
,
2329 uint32_t type
, uint64_t param
)
2331 /* no SVM activated; fast case */
2332 if (likely(!(s
->flags
& HF_GUEST_MASK
)))
2334 gen_update_cc_op(s
);
2335 gen_jmp_im(s
, pc_start
- s
->cs_base
);
2336 gen_helper_svm_check_intercept_param(cpu_env
, tcg_const_i32(type
),
2337 tcg_const_i64(param
));
2341 gen_svm_check_intercept(DisasContext
*s
, target_ulong pc_start
, uint64_t type
)
2343 gen_svm_check_intercept_param(s
, pc_start
, type
, 0);
2346 static inline void gen_stack_update(DisasContext
*s
, int addend
)
2348 gen_op_add_reg_im(s
, mo_stacksize(s
), R_ESP
, addend
);
2351 /* Generate a push. It depends on ss32, addseg and dflag. */
2352 static void gen_push_v(DisasContext
*s
, TCGv val
)
2354 MemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2355 MemOp a_ot
= mo_stacksize(s
);
2356 int size
= 1 << d_ot
;
2357 TCGv new_esp
= s
->A0
;
2359 tcg_gen_subi_tl(s
->A0
, cpu_regs
[R_ESP
], size
);
2364 tcg_gen_mov_tl(new_esp
, s
->A0
);
2366 gen_lea_v_seg(s
, a_ot
, s
->A0
, R_SS
, -1);
2369 gen_op_st_v(s
, d_ot
, val
, s
->A0
);
2370 gen_op_mov_reg_v(s
, a_ot
, R_ESP
, new_esp
);
2373 /* two step pop is necessary for precise exceptions */
2374 static MemOp
gen_pop_T0(DisasContext
*s
)
2376 MemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2378 gen_lea_v_seg(s
, mo_stacksize(s
), cpu_regs
[R_ESP
], R_SS
, -1);
2379 gen_op_ld_v(s
, d_ot
, s
->T0
, s
->A0
);
2384 static inline void gen_pop_update(DisasContext
*s
, MemOp ot
)
2386 gen_stack_update(s
, 1 << ot
);
2389 static inline void gen_stack_A0(DisasContext
*s
)
2391 gen_lea_v_seg(s
, s
->ss32
? MO_32
: MO_16
, cpu_regs
[R_ESP
], R_SS
, -1);
2394 static void gen_pusha(DisasContext
*s
)
2396 MemOp s_ot
= s
->ss32
? MO_32
: MO_16
;
2397 MemOp d_ot
= s
->dflag
;
2398 int size
= 1 << d_ot
;
2401 for (i
= 0; i
< 8; i
++) {
2402 tcg_gen_addi_tl(s
->A0
, cpu_regs
[R_ESP
], (i
- 8) * size
);
2403 gen_lea_v_seg(s
, s_ot
, s
->A0
, R_SS
, -1);
2404 gen_op_st_v(s
, d_ot
, cpu_regs
[7 - i
], s
->A0
);
2407 gen_stack_update(s
, -8 * size
);
2410 static void gen_popa(DisasContext
*s
)
2412 MemOp s_ot
= s
->ss32
? MO_32
: MO_16
;
2413 MemOp d_ot
= s
->dflag
;
2414 int size
= 1 << d_ot
;
2417 for (i
= 0; i
< 8; i
++) {
2418 /* ESP is not reloaded */
2419 if (7 - i
== R_ESP
) {
2422 tcg_gen_addi_tl(s
->A0
, cpu_regs
[R_ESP
], i
* size
);
2423 gen_lea_v_seg(s
, s_ot
, s
->A0
, R_SS
, -1);
2424 gen_op_ld_v(s
, d_ot
, s
->T0
, s
->A0
);
2425 gen_op_mov_reg_v(s
, d_ot
, 7 - i
, s
->T0
);
2428 gen_stack_update(s
, 8 * size
);
2431 static void gen_enter(DisasContext
*s
, int esp_addend
, int level
)
2433 MemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2434 MemOp a_ot
= CODE64(s
) ? MO_64
: s
->ss32
? MO_32
: MO_16
;
2435 int size
= 1 << d_ot
;
2437 /* Push BP; compute FrameTemp into T1. */
2438 tcg_gen_subi_tl(s
->T1
, cpu_regs
[R_ESP
], size
);
2439 gen_lea_v_seg(s
, a_ot
, s
->T1
, R_SS
, -1);
2440 gen_op_st_v(s
, d_ot
, cpu_regs
[R_EBP
], s
->A0
);
2446 /* Copy level-1 pointers from the previous frame. */
2447 for (i
= 1; i
< level
; ++i
) {
2448 tcg_gen_subi_tl(s
->A0
, cpu_regs
[R_EBP
], size
* i
);
2449 gen_lea_v_seg(s
, a_ot
, s
->A0
, R_SS
, -1);
2450 gen_op_ld_v(s
, d_ot
, s
->tmp0
, s
->A0
);
2452 tcg_gen_subi_tl(s
->A0
, s
->T1
, size
* i
);
2453 gen_lea_v_seg(s
, a_ot
, s
->A0
, R_SS
, -1);
2454 gen_op_st_v(s
, d_ot
, s
->tmp0
, s
->A0
);
2457 /* Push the current FrameTemp as the last level. */
2458 tcg_gen_subi_tl(s
->A0
, s
->T1
, size
* level
);
2459 gen_lea_v_seg(s
, a_ot
, s
->A0
, R_SS
, -1);
2460 gen_op_st_v(s
, d_ot
, s
->T1
, s
->A0
);
2463 /* Copy the FrameTemp value to EBP. */
2464 gen_op_mov_reg_v(s
, a_ot
, R_EBP
, s
->T1
);
2466 /* Compute the final value of ESP. */
2467 tcg_gen_subi_tl(s
->T1
, s
->T1
, esp_addend
+ size
* level
);
2468 gen_op_mov_reg_v(s
, a_ot
, R_ESP
, s
->T1
);
2471 static void gen_leave(DisasContext
*s
)
2473 MemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2474 MemOp a_ot
= mo_stacksize(s
);
2476 gen_lea_v_seg(s
, a_ot
, cpu_regs
[R_EBP
], R_SS
, -1);
2477 gen_op_ld_v(s
, d_ot
, s
->T0
, s
->A0
);
2479 tcg_gen_addi_tl(s
->T1
, cpu_regs
[R_EBP
], 1 << d_ot
);
2481 gen_op_mov_reg_v(s
, d_ot
, R_EBP
, s
->T0
);
2482 gen_op_mov_reg_v(s
, a_ot
, R_ESP
, s
->T1
);
2485 /* Similarly, except that the assumption here is that we don't decode
2486 the instruction at all -- either a missing opcode, an unimplemented
2487 feature, or just a bogus instruction stream. */
2488 static void gen_unknown_opcode(CPUX86State
*env
, DisasContext
*s
)
2490 gen_illegal_opcode(s
);
2492 if (qemu_loglevel_mask(LOG_UNIMP
)) {
2493 FILE *logfile
= qemu_log_lock();
2494 target_ulong pc
= s
->pc_start
, end
= s
->pc
;
2496 qemu_log("ILLOPC: " TARGET_FMT_lx
":", pc
);
2497 for (; pc
< end
; ++pc
) {
2498 qemu_log(" %02x", cpu_ldub_code(env
, pc
));
2501 qemu_log_unlock(logfile
);
2505 /* an interrupt is different from an exception because of the
2507 static void gen_interrupt(DisasContext
*s
, int intno
,
2508 target_ulong cur_eip
, target_ulong next_eip
)
2510 gen_update_cc_op(s
);
2511 gen_jmp_im(s
, cur_eip
);
2512 gen_helper_raise_interrupt(cpu_env
, tcg_const_i32(intno
),
2513 tcg_const_i32(next_eip
- cur_eip
));
2514 s
->base
.is_jmp
= DISAS_NORETURN
;
2517 static void gen_debug(DisasContext
*s
, target_ulong cur_eip
)
2519 gen_update_cc_op(s
);
2520 gen_jmp_im(s
, cur_eip
);
2521 gen_helper_debug(cpu_env
);
2522 s
->base
.is_jmp
= DISAS_NORETURN
;
2525 static void gen_set_hflag(DisasContext
*s
, uint32_t mask
)
2527 if ((s
->flags
& mask
) == 0) {
2528 TCGv_i32 t
= tcg_temp_new_i32();
2529 tcg_gen_ld_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2530 tcg_gen_ori_i32(t
, t
, mask
);
2531 tcg_gen_st_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2532 tcg_temp_free_i32(t
);
2537 static void gen_reset_hflag(DisasContext
*s
, uint32_t mask
)
2539 if (s
->flags
& mask
) {
2540 TCGv_i32 t
= tcg_temp_new_i32();
2541 tcg_gen_ld_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2542 tcg_gen_andi_i32(t
, t
, ~mask
);
2543 tcg_gen_st_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2544 tcg_temp_free_i32(t
);
2549 /* Clear BND registers during legacy branches. */
2550 static void gen_bnd_jmp(DisasContext
*s
)
2552 /* Clear the registers only if BND prefix is missing, MPX is enabled,
2553 and if the BNDREGs are known to be in use (non-zero) already.
2554 The helper itself will check BNDPRESERVE at runtime. */
2555 if ((s
->prefix
& PREFIX_REPNZ
) == 0
2556 && (s
->flags
& HF_MPX_EN_MASK
) != 0
2557 && (s
->flags
& HF_MPX_IU_MASK
) != 0) {
2558 gen_helper_bnd_jmp(cpu_env
);
2562 /* Generate an end of block. Trace exception is also generated if needed.
2563 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set.
2564 If RECHECK_TF, emit a rechecking helper for #DB, ignoring the state of
2565 S->TF. This is used by the syscall/sysret insns. */
2567 do_gen_eob_worker(DisasContext
*s
, bool inhibit
, bool recheck_tf
, bool jr
)
2569 gen_update_cc_op(s
);
2571 /* If several instructions disable interrupts, only the first does it. */
2572 if (inhibit
&& !(s
->flags
& HF_INHIBIT_IRQ_MASK
)) {
2573 gen_set_hflag(s
, HF_INHIBIT_IRQ_MASK
);
2575 gen_reset_hflag(s
, HF_INHIBIT_IRQ_MASK
);
2578 if (s
->base
.tb
->flags
& HF_RF_MASK
) {
2579 gen_helper_reset_rf(cpu_env
);
2581 if (s
->base
.singlestep_enabled
) {
2582 gen_helper_debug(cpu_env
);
2583 } else if (recheck_tf
) {
2584 gen_helper_rechecking_single_step(cpu_env
);
2585 tcg_gen_exit_tb(NULL
, 0);
2587 gen_helper_single_step(cpu_env
);
2589 tcg_gen_lookup_and_goto_ptr();
2591 tcg_gen_exit_tb(NULL
, 0);
2593 s
->base
.is_jmp
= DISAS_NORETURN
;
2597 gen_eob_worker(DisasContext
*s
, bool inhibit
, bool recheck_tf
)
2599 do_gen_eob_worker(s
, inhibit
, recheck_tf
, false);
2603 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set. */
2604 static void gen_eob_inhibit_irq(DisasContext
*s
, bool inhibit
)
2606 gen_eob_worker(s
, inhibit
, false);
2609 /* End of block, resetting the inhibit irq flag. */
2610 static void gen_eob(DisasContext
*s
)
2612 gen_eob_worker(s
, false, false);
2615 /* Jump to register */
2616 static void gen_jr(DisasContext
*s
, TCGv dest
)
2618 do_gen_eob_worker(s
, false, false, true);
2621 /* generate a jump to eip. No segment change must happen before as a
2622 direct call to the next block may occur */
2623 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
)
2625 gen_update_cc_op(s
);
2626 set_cc_op(s
, CC_OP_DYNAMIC
);
2628 gen_goto_tb(s
, tb_num
, eip
);
2635 static void gen_jmp(DisasContext
*s
, target_ulong eip
)
2637 gen_jmp_tb(s
, eip
, 0);
2640 static inline void gen_ldq_env_A0(DisasContext
*s
, int offset
)
2642 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
, s
->mem_index
, MO_LEQ
);
2643 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, offset
);
2646 static inline void gen_stq_env_A0(DisasContext
*s
, int offset
)
2648 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, offset
);
2649 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
, s
->mem_index
, MO_LEQ
);
2652 static inline void gen_ldo_env_A0(DisasContext
*s
, int offset
)
2654 int mem_index
= s
->mem_index
;
2655 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
, mem_index
, MO_LEQ
);
2656 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2657 tcg_gen_addi_tl(s
->tmp0
, s
->A0
, 8);
2658 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->tmp0
, mem_index
, MO_LEQ
);
2659 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2662 static inline void gen_sto_env_A0(DisasContext
*s
, int offset
)
2664 int mem_index
= s
->mem_index
;
2665 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2666 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
, mem_index
, MO_LEQ
);
2667 tcg_gen_addi_tl(s
->tmp0
, s
->A0
, 8);
2668 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2669 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->tmp0
, mem_index
, MO_LEQ
);
2672 static inline void gen_op_movo(DisasContext
*s
, int d_offset
, int s_offset
)
2674 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, s_offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2675 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, d_offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2676 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, s_offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2677 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, d_offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2680 static inline void gen_op_movq(DisasContext
*s
, int d_offset
, int s_offset
)
2682 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, s_offset
);
2683 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, d_offset
);
2686 static inline void gen_op_movl(DisasContext
*s
, int d_offset
, int s_offset
)
2688 tcg_gen_ld_i32(s
->tmp2_i32
, cpu_env
, s_offset
);
2689 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
, d_offset
);
2692 static inline void gen_op_movq_env_0(DisasContext
*s
, int d_offset
)
2694 tcg_gen_movi_i64(s
->tmp1_i64
, 0);
2695 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, d_offset
);
2698 typedef void (*SSEFunc_i_ep
)(TCGv_i32 val
, TCGv_ptr env
, TCGv_ptr reg
);
2699 typedef void (*SSEFunc_l_ep
)(TCGv_i64 val
, TCGv_ptr env
, TCGv_ptr reg
);
2700 typedef void (*SSEFunc_0_epi
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i32 val
);
2701 typedef void (*SSEFunc_0_epl
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i64 val
);
2702 typedef void (*SSEFunc_0_epp
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
);
2703 typedef void (*SSEFunc_0_eppi
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2705 typedef void (*SSEFunc_0_ppi
)(TCGv_ptr reg_a
, TCGv_ptr reg_b
, TCGv_i32 val
);
2706 typedef void (*SSEFunc_0_eppt
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2709 #define SSE_SPECIAL ((void *)1)
2710 #define SSE_DUMMY ((void *)2)
2712 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2713 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2714 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2716 static const SSEFunc_0_epp sse_op_table1
[256][4] = {
2717 /* 3DNow! extensions */
2718 [0x0e] = { SSE_DUMMY
}, /* femms */
2719 [0x0f] = { SSE_DUMMY
}, /* pf... */
2720 /* pure SSE operations */
2721 [0x10] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2722 [0x11] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2723 [0x12] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd, movsldup, movddup */
2724 [0x13] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd */
2725 [0x14] = { gen_helper_punpckldq_xmm
, gen_helper_punpcklqdq_xmm
},
2726 [0x15] = { gen_helper_punpckhdq_xmm
, gen_helper_punpckhqdq_xmm
},
2727 [0x16] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd, movshdup */
2728 [0x17] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd */
2730 [0x28] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2731 [0x29] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2732 [0x2a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2733 [0x2b] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movntps, movntpd, movntss, movntsd */
2734 [0x2c] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2735 [0x2d] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2736 [0x2e] = { gen_helper_ucomiss
, gen_helper_ucomisd
},
2737 [0x2f] = { gen_helper_comiss
, gen_helper_comisd
},
2738 [0x50] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movmskps, movmskpd */
2739 [0x51] = SSE_FOP(sqrt
),
2740 [0x52] = { gen_helper_rsqrtps
, NULL
, gen_helper_rsqrtss
, NULL
},
2741 [0x53] = { gen_helper_rcpps
, NULL
, gen_helper_rcpss
, NULL
},
2742 [0x54] = { gen_helper_pand_xmm
, gen_helper_pand_xmm
}, /* andps, andpd */
2743 [0x55] = { gen_helper_pandn_xmm
, gen_helper_pandn_xmm
}, /* andnps, andnpd */
2744 [0x56] = { gen_helper_por_xmm
, gen_helper_por_xmm
}, /* orps, orpd */
2745 [0x57] = { gen_helper_pxor_xmm
, gen_helper_pxor_xmm
}, /* xorps, xorpd */
2746 [0x58] = SSE_FOP(add
),
2747 [0x59] = SSE_FOP(mul
),
2748 [0x5a] = { gen_helper_cvtps2pd
, gen_helper_cvtpd2ps
,
2749 gen_helper_cvtss2sd
, gen_helper_cvtsd2ss
},
2750 [0x5b] = { gen_helper_cvtdq2ps
, gen_helper_cvtps2dq
, gen_helper_cvttps2dq
},
2751 [0x5c] = SSE_FOP(sub
),
2752 [0x5d] = SSE_FOP(min
),
2753 [0x5e] = SSE_FOP(div
),
2754 [0x5f] = SSE_FOP(max
),
2756 [0xc2] = SSE_FOP(cmpeq
),
2757 [0xc6] = { (SSEFunc_0_epp
)gen_helper_shufps
,
2758 (SSEFunc_0_epp
)gen_helper_shufpd
}, /* XXX: casts */
2760 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */
2761 [0x38] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2762 [0x3a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2764 /* MMX ops and their SSE extensions */
2765 [0x60] = MMX_OP2(punpcklbw
),
2766 [0x61] = MMX_OP2(punpcklwd
),
2767 [0x62] = MMX_OP2(punpckldq
),
2768 [0x63] = MMX_OP2(packsswb
),
2769 [0x64] = MMX_OP2(pcmpgtb
),
2770 [0x65] = MMX_OP2(pcmpgtw
),
2771 [0x66] = MMX_OP2(pcmpgtl
),
2772 [0x67] = MMX_OP2(packuswb
),
2773 [0x68] = MMX_OP2(punpckhbw
),
2774 [0x69] = MMX_OP2(punpckhwd
),
2775 [0x6a] = MMX_OP2(punpckhdq
),
2776 [0x6b] = MMX_OP2(packssdw
),
2777 [0x6c] = { NULL
, gen_helper_punpcklqdq_xmm
},
2778 [0x6d] = { NULL
, gen_helper_punpckhqdq_xmm
},
2779 [0x6e] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movd mm, ea */
2780 [0x6f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, , movqdu */
2781 [0x70] = { (SSEFunc_0_epp
)gen_helper_pshufw_mmx
,
2782 (SSEFunc_0_epp
)gen_helper_pshufd_xmm
,
2783 (SSEFunc_0_epp
)gen_helper_pshufhw_xmm
,
2784 (SSEFunc_0_epp
)gen_helper_pshuflw_xmm
}, /* XXX: casts */
2785 [0x71] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftw */
2786 [0x72] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftd */
2787 [0x73] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftq */
2788 [0x74] = MMX_OP2(pcmpeqb
),
2789 [0x75] = MMX_OP2(pcmpeqw
),
2790 [0x76] = MMX_OP2(pcmpeql
),
2791 [0x77] = { SSE_DUMMY
}, /* emms */
2792 [0x78] = { NULL
, SSE_SPECIAL
, NULL
, SSE_SPECIAL
}, /* extrq_i, insertq_i */
2793 [0x79] = { NULL
, gen_helper_extrq_r
, NULL
, gen_helper_insertq_r
},
2794 [0x7c] = { NULL
, gen_helper_haddpd
, NULL
, gen_helper_haddps
},
2795 [0x7d] = { NULL
, gen_helper_hsubpd
, NULL
, gen_helper_hsubps
},
2796 [0x7e] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movd, movd, , movq */
2797 [0x7f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, movdqu */
2798 [0xc4] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pinsrw */
2799 [0xc5] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pextrw */
2800 [0xd0] = { NULL
, gen_helper_addsubpd
, NULL
, gen_helper_addsubps
},
2801 [0xd1] = MMX_OP2(psrlw
),
2802 [0xd2] = MMX_OP2(psrld
),
2803 [0xd3] = MMX_OP2(psrlq
),
2804 [0xd4] = MMX_OP2(paddq
),
2805 [0xd5] = MMX_OP2(pmullw
),
2806 [0xd6] = { NULL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2807 [0xd7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pmovmskb */
2808 [0xd8] = MMX_OP2(psubusb
),
2809 [0xd9] = MMX_OP2(psubusw
),
2810 [0xda] = MMX_OP2(pminub
),
2811 [0xdb] = MMX_OP2(pand
),
2812 [0xdc] = MMX_OP2(paddusb
),
2813 [0xdd] = MMX_OP2(paddusw
),
2814 [0xde] = MMX_OP2(pmaxub
),
2815 [0xdf] = MMX_OP2(pandn
),
2816 [0xe0] = MMX_OP2(pavgb
),
2817 [0xe1] = MMX_OP2(psraw
),
2818 [0xe2] = MMX_OP2(psrad
),
2819 [0xe3] = MMX_OP2(pavgw
),
2820 [0xe4] = MMX_OP2(pmulhuw
),
2821 [0xe5] = MMX_OP2(pmulhw
),
2822 [0xe6] = { NULL
, gen_helper_cvttpd2dq
, gen_helper_cvtdq2pd
, gen_helper_cvtpd2dq
},
2823 [0xe7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movntq, movntq */
2824 [0xe8] = MMX_OP2(psubsb
),
2825 [0xe9] = MMX_OP2(psubsw
),
2826 [0xea] = MMX_OP2(pminsw
),
2827 [0xeb] = MMX_OP2(por
),
2828 [0xec] = MMX_OP2(paddsb
),
2829 [0xed] = MMX_OP2(paddsw
),
2830 [0xee] = MMX_OP2(pmaxsw
),
2831 [0xef] = MMX_OP2(pxor
),
2832 [0xf0] = { NULL
, NULL
, NULL
, SSE_SPECIAL
}, /* lddqu */
2833 [0xf1] = MMX_OP2(psllw
),
2834 [0xf2] = MMX_OP2(pslld
),
2835 [0xf3] = MMX_OP2(psllq
),
2836 [0xf4] = MMX_OP2(pmuludq
),
2837 [0xf5] = MMX_OP2(pmaddwd
),
2838 [0xf6] = MMX_OP2(psadbw
),
2839 [0xf7] = { (SSEFunc_0_epp
)gen_helper_maskmov_mmx
,
2840 (SSEFunc_0_epp
)gen_helper_maskmov_xmm
}, /* XXX: casts */
2841 [0xf8] = MMX_OP2(psubb
),
2842 [0xf9] = MMX_OP2(psubw
),
2843 [0xfa] = MMX_OP2(psubl
),
2844 [0xfb] = MMX_OP2(psubq
),
2845 [0xfc] = MMX_OP2(paddb
),
2846 [0xfd] = MMX_OP2(paddw
),
2847 [0xfe] = MMX_OP2(paddl
),
2850 static const SSEFunc_0_epp sse_op_table2
[3 * 8][2] = {
2851 [0 + 2] = MMX_OP2(psrlw
),
2852 [0 + 4] = MMX_OP2(psraw
),
2853 [0 + 6] = MMX_OP2(psllw
),
2854 [8 + 2] = MMX_OP2(psrld
),
2855 [8 + 4] = MMX_OP2(psrad
),
2856 [8 + 6] = MMX_OP2(pslld
),
2857 [16 + 2] = MMX_OP2(psrlq
),
2858 [16 + 3] = { NULL
, gen_helper_psrldq_xmm
},
2859 [16 + 6] = MMX_OP2(psllq
),
2860 [16 + 7] = { NULL
, gen_helper_pslldq_xmm
},
2863 static const SSEFunc_0_epi sse_op_table3ai
[] = {
2864 gen_helper_cvtsi2ss
,
2868 #ifdef TARGET_X86_64
2869 static const SSEFunc_0_epl sse_op_table3aq
[] = {
2870 gen_helper_cvtsq2ss
,
2875 static const SSEFunc_i_ep sse_op_table3bi
[] = {
2876 gen_helper_cvttss2si
,
2877 gen_helper_cvtss2si
,
2878 gen_helper_cvttsd2si
,
2882 #ifdef TARGET_X86_64
2883 static const SSEFunc_l_ep sse_op_table3bq
[] = {
2884 gen_helper_cvttss2sq
,
2885 gen_helper_cvtss2sq
,
2886 gen_helper_cvttsd2sq
,
2891 static const SSEFunc_0_epp sse_op_table4
[8][4] = {
2902 static const SSEFunc_0_epp sse_op_table5
[256] = {
2903 [0x0c] = gen_helper_pi2fw
,
2904 [0x0d] = gen_helper_pi2fd
,
2905 [0x1c] = gen_helper_pf2iw
,
2906 [0x1d] = gen_helper_pf2id
,
2907 [0x8a] = gen_helper_pfnacc
,
2908 [0x8e] = gen_helper_pfpnacc
,
2909 [0x90] = gen_helper_pfcmpge
,
2910 [0x94] = gen_helper_pfmin
,
2911 [0x96] = gen_helper_pfrcp
,
2912 [0x97] = gen_helper_pfrsqrt
,
2913 [0x9a] = gen_helper_pfsub
,
2914 [0x9e] = gen_helper_pfadd
,
2915 [0xa0] = gen_helper_pfcmpgt
,
2916 [0xa4] = gen_helper_pfmax
,
2917 [0xa6] = gen_helper_movq
, /* pfrcpit1; no need to actually increase precision */
2918 [0xa7] = gen_helper_movq
, /* pfrsqit1 */
2919 [0xaa] = gen_helper_pfsubr
,
2920 [0xae] = gen_helper_pfacc
,
2921 [0xb0] = gen_helper_pfcmpeq
,
2922 [0xb4] = gen_helper_pfmul
,
2923 [0xb6] = gen_helper_movq
, /* pfrcpit2 */
2924 [0xb7] = gen_helper_pmulhrw_mmx
,
2925 [0xbb] = gen_helper_pswapd
,
2926 [0xbf] = gen_helper_pavgb_mmx
/* pavgusb */
2929 struct SSEOpHelper_epp
{
2930 SSEFunc_0_epp op
[2];
2934 struct SSEOpHelper_eppi
{
2935 SSEFunc_0_eppi op
[2];
2939 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
2940 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
2941 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
2942 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
2943 #define PCLMULQDQ_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, \
2944 CPUID_EXT_PCLMULQDQ }
2945 #define AESNI_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_AES }
2947 static const struct SSEOpHelper_epp sse_op_table6
[256] = {
2948 [0x00] = SSSE3_OP(pshufb
),
2949 [0x01] = SSSE3_OP(phaddw
),
2950 [0x02] = SSSE3_OP(phaddd
),
2951 [0x03] = SSSE3_OP(phaddsw
),
2952 [0x04] = SSSE3_OP(pmaddubsw
),
2953 [0x05] = SSSE3_OP(phsubw
),
2954 [0x06] = SSSE3_OP(phsubd
),
2955 [0x07] = SSSE3_OP(phsubsw
),
2956 [0x08] = SSSE3_OP(psignb
),
2957 [0x09] = SSSE3_OP(psignw
),
2958 [0x0a] = SSSE3_OP(psignd
),
2959 [0x0b] = SSSE3_OP(pmulhrsw
),
2960 [0x10] = SSE41_OP(pblendvb
),
2961 [0x14] = SSE41_OP(blendvps
),
2962 [0x15] = SSE41_OP(blendvpd
),
2963 [0x17] = SSE41_OP(ptest
),
2964 [0x1c] = SSSE3_OP(pabsb
),
2965 [0x1d] = SSSE3_OP(pabsw
),
2966 [0x1e] = SSSE3_OP(pabsd
),
2967 [0x20] = SSE41_OP(pmovsxbw
),
2968 [0x21] = SSE41_OP(pmovsxbd
),
2969 [0x22] = SSE41_OP(pmovsxbq
),
2970 [0x23] = SSE41_OP(pmovsxwd
),
2971 [0x24] = SSE41_OP(pmovsxwq
),
2972 [0x25] = SSE41_OP(pmovsxdq
),
2973 [0x28] = SSE41_OP(pmuldq
),
2974 [0x29] = SSE41_OP(pcmpeqq
),
2975 [0x2a] = SSE41_SPECIAL
, /* movntqda */
2976 [0x2b] = SSE41_OP(packusdw
),
2977 [0x30] = SSE41_OP(pmovzxbw
),
2978 [0x31] = SSE41_OP(pmovzxbd
),
2979 [0x32] = SSE41_OP(pmovzxbq
),
2980 [0x33] = SSE41_OP(pmovzxwd
),
2981 [0x34] = SSE41_OP(pmovzxwq
),
2982 [0x35] = SSE41_OP(pmovzxdq
),
2983 [0x37] = SSE42_OP(pcmpgtq
),
2984 [0x38] = SSE41_OP(pminsb
),
2985 [0x39] = SSE41_OP(pminsd
),
2986 [0x3a] = SSE41_OP(pminuw
),
2987 [0x3b] = SSE41_OP(pminud
),
2988 [0x3c] = SSE41_OP(pmaxsb
),
2989 [0x3d] = SSE41_OP(pmaxsd
),
2990 [0x3e] = SSE41_OP(pmaxuw
),
2991 [0x3f] = SSE41_OP(pmaxud
),
2992 [0x40] = SSE41_OP(pmulld
),
2993 [0x41] = SSE41_OP(phminposuw
),
2994 [0xdb] = AESNI_OP(aesimc
),
2995 [0xdc] = AESNI_OP(aesenc
),
2996 [0xdd] = AESNI_OP(aesenclast
),
2997 [0xde] = AESNI_OP(aesdec
),
2998 [0xdf] = AESNI_OP(aesdeclast
),
3001 static const struct SSEOpHelper_eppi sse_op_table7
[256] = {
3002 [0x08] = SSE41_OP(roundps
),
3003 [0x09] = SSE41_OP(roundpd
),
3004 [0x0a] = SSE41_OP(roundss
),
3005 [0x0b] = SSE41_OP(roundsd
),
3006 [0x0c] = SSE41_OP(blendps
),
3007 [0x0d] = SSE41_OP(blendpd
),
3008 [0x0e] = SSE41_OP(pblendw
),
3009 [0x0f] = SSSE3_OP(palignr
),
3010 [0x14] = SSE41_SPECIAL
, /* pextrb */
3011 [0x15] = SSE41_SPECIAL
, /* pextrw */
3012 [0x16] = SSE41_SPECIAL
, /* pextrd/pextrq */
3013 [0x17] = SSE41_SPECIAL
, /* extractps */
3014 [0x20] = SSE41_SPECIAL
, /* pinsrb */
3015 [0x21] = SSE41_SPECIAL
, /* insertps */
3016 [0x22] = SSE41_SPECIAL
, /* pinsrd/pinsrq */
3017 [0x40] = SSE41_OP(dpps
),
3018 [0x41] = SSE41_OP(dppd
),
3019 [0x42] = SSE41_OP(mpsadbw
),
3020 [0x44] = PCLMULQDQ_OP(pclmulqdq
),
3021 [0x60] = SSE42_OP(pcmpestrm
),
3022 [0x61] = SSE42_OP(pcmpestri
),
3023 [0x62] = SSE42_OP(pcmpistrm
),
3024 [0x63] = SSE42_OP(pcmpistri
),
3025 [0xdf] = AESNI_OP(aeskeygenassist
),
3028 static void gen_sse(CPUX86State
*env
, DisasContext
*s
, int b
,
3029 target_ulong pc_start
, int rex_r
)
3031 int b1
, op1_offset
, op2_offset
, is_xmm
, val
;
3032 int modrm
, mod
, rm
, reg
;
3033 SSEFunc_0_epp sse_fn_epp
;
3034 SSEFunc_0_eppi sse_fn_eppi
;
3035 SSEFunc_0_ppi sse_fn_ppi
;
3036 SSEFunc_0_eppt sse_fn_eppt
;
3040 if (s
->prefix
& PREFIX_DATA
)
3042 else if (s
->prefix
& PREFIX_REPZ
)
3044 else if (s
->prefix
& PREFIX_REPNZ
)
3048 sse_fn_epp
= sse_op_table1
[b
][b1
];
3052 if ((b
<= 0x5f && b
>= 0x10) || b
== 0xc6 || b
== 0xc2) {
3062 /* simple MMX/SSE operation */
3063 if (s
->flags
& HF_TS_MASK
) {
3064 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
3067 if (s
->flags
& HF_EM_MASK
) {
3069 gen_illegal_opcode(s
);
3073 && !(s
->flags
& HF_OSFXSR_MASK
)
3074 && ((b
!= 0x38 && b
!= 0x3a) || (s
->prefix
& PREFIX_DATA
))) {
3078 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
)) {
3079 /* If we were fully decoding this we might use illegal_op. */
3083 gen_helper_emms(cpu_env
);
3088 gen_helper_emms(cpu_env
);
3091 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3092 the static cpu state) */
3094 gen_helper_enter_mmx(cpu_env
);
3097 modrm
= x86_ldub_code(env
, s
);
3098 reg
= ((modrm
>> 3) & 7);
3101 mod
= (modrm
>> 6) & 3;
3102 if (sse_fn_epp
== SSE_SPECIAL
) {
3105 case 0x0e7: /* movntq */
3109 gen_lea_modrm(env
, s
, modrm
);
3110 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3112 case 0x1e7: /* movntdq */
3113 case 0x02b: /* movntps */
3114 case 0x12b: /* movntps */
3117 gen_lea_modrm(env
, s
, modrm
);
3118 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3120 case 0x3f0: /* lddqu */
3123 gen_lea_modrm(env
, s
, modrm
);
3124 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3126 case 0x22b: /* movntss */
3127 case 0x32b: /* movntsd */
3130 gen_lea_modrm(env
, s
, modrm
);
3132 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3133 xmm_regs
[reg
].ZMM_Q(0)));
3135 tcg_gen_ld32u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
3136 xmm_regs
[reg
].ZMM_L(0)));
3137 gen_op_st_v(s
, MO_32
, s
->T0
, s
->A0
);
3140 case 0x6e: /* movd mm, ea */
3141 #ifdef TARGET_X86_64
3142 if (s
->dflag
== MO_64
) {
3143 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3144 tcg_gen_st_tl(s
->T0
, cpu_env
,
3145 offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3149 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3150 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3151 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3152 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
3153 gen_helper_movl_mm_T0_mmx(s
->ptr0
, s
->tmp2_i32
);
3156 case 0x16e: /* movd xmm, ea */
3157 #ifdef TARGET_X86_64
3158 if (s
->dflag
== MO_64
) {
3159 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3160 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3161 offsetof(CPUX86State
,xmm_regs
[reg
]));
3162 gen_helper_movq_mm_T0_xmm(s
->ptr0
, s
->T0
);
3166 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3167 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3168 offsetof(CPUX86State
,xmm_regs
[reg
]));
3169 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
3170 gen_helper_movl_mm_T0_xmm(s
->ptr0
, s
->tmp2_i32
);
3173 case 0x6f: /* movq mm, ea */
3175 gen_lea_modrm(env
, s
, modrm
);
3176 gen_ldq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3179 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
,
3180 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3181 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
,
3182 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3185 case 0x010: /* movups */
3186 case 0x110: /* movupd */
3187 case 0x028: /* movaps */
3188 case 0x128: /* movapd */
3189 case 0x16f: /* movdqa xmm, ea */
3190 case 0x26f: /* movdqu xmm, ea */
3192 gen_lea_modrm(env
, s
, modrm
);
3193 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3195 rm
= (modrm
& 7) | REX_B(s
);
3196 gen_op_movo(s
, offsetof(CPUX86State
, xmm_regs
[reg
]),
3197 offsetof(CPUX86State
,xmm_regs
[rm
]));
3200 case 0x210: /* movss xmm, ea */
3202 gen_lea_modrm(env
, s
, modrm
);
3203 gen_op_ld_v(s
, MO_32
, s
->T0
, s
->A0
);
3204 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3205 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(0)));
3206 tcg_gen_movi_tl(s
->T0
, 0);
3207 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3208 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(1)));
3209 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3210 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(2)));
3211 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3212 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(3)));
3214 rm
= (modrm
& 7) | REX_B(s
);
3215 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(0)),
3216 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)));
3219 case 0x310: /* movsd xmm, ea */
3221 gen_lea_modrm(env
, s
, modrm
);
3222 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3223 xmm_regs
[reg
].ZMM_Q(0)));
3224 tcg_gen_movi_tl(s
->T0
, 0);
3225 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3226 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(2)));
3227 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3228 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(3)));
3230 rm
= (modrm
& 7) | REX_B(s
);
3231 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(0)),
3232 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3235 case 0x012: /* movlps */
3236 case 0x112: /* movlpd */
3238 gen_lea_modrm(env
, s
, modrm
);
3239 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3240 xmm_regs
[reg
].ZMM_Q(0)));
3243 rm
= (modrm
& 7) | REX_B(s
);
3244 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(0)),
3245 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(1)));
3248 case 0x212: /* movsldup */
3250 gen_lea_modrm(env
, s
, modrm
);
3251 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3253 rm
= (modrm
& 7) | REX_B(s
);
3254 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(0)),
3255 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)));
3256 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(2)),
3257 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(2)));
3259 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(1)),
3260 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3261 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(3)),
3262 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)));
3264 case 0x312: /* movddup */
3266 gen_lea_modrm(env
, s
, modrm
);
3267 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3268 xmm_regs
[reg
].ZMM_Q(0)));
3270 rm
= (modrm
& 7) | REX_B(s
);
3271 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(0)),
3272 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3274 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(1)),
3275 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3277 case 0x016: /* movhps */
3278 case 0x116: /* movhpd */
3280 gen_lea_modrm(env
, s
, modrm
);
3281 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3282 xmm_regs
[reg
].ZMM_Q(1)));
3285 rm
= (modrm
& 7) | REX_B(s
);
3286 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(1)),
3287 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3290 case 0x216: /* movshdup */
3292 gen_lea_modrm(env
, s
, modrm
);
3293 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3295 rm
= (modrm
& 7) | REX_B(s
);
3296 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(1)),
3297 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(1)));
3298 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(3)),
3299 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(3)));
3301 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(0)),
3302 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)));
3303 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(2)),
3304 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)));
3309 int bit_index
, field_length
;
3311 if (b1
== 1 && reg
!= 0)
3313 field_length
= x86_ldub_code(env
, s
) & 0x3F;
3314 bit_index
= x86_ldub_code(env
, s
) & 0x3F;
3315 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3316 offsetof(CPUX86State
,xmm_regs
[reg
]));
3318 gen_helper_extrq_i(cpu_env
, s
->ptr0
,
3319 tcg_const_i32(bit_index
),
3320 tcg_const_i32(field_length
));
3322 gen_helper_insertq_i(cpu_env
, s
->ptr0
,
3323 tcg_const_i32(bit_index
),
3324 tcg_const_i32(field_length
));
3327 case 0x7e: /* movd ea, mm */
3328 #ifdef TARGET_X86_64
3329 if (s
->dflag
== MO_64
) {
3330 tcg_gen_ld_i64(s
->T0
, cpu_env
,
3331 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3332 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3336 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
3337 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_L(0)));
3338 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3341 case 0x17e: /* movd ea, xmm */
3342 #ifdef TARGET_X86_64
3343 if (s
->dflag
== MO_64
) {
3344 tcg_gen_ld_i64(s
->T0
, cpu_env
,
3345 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3346 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3350 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
3351 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3352 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3355 case 0x27e: /* movq xmm, ea */
3357 gen_lea_modrm(env
, s
, modrm
);
3358 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3359 xmm_regs
[reg
].ZMM_Q(0)));
3361 rm
= (modrm
& 7) | REX_B(s
);
3362 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(0)),
3363 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3365 gen_op_movq_env_0(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(1)));
3367 case 0x7f: /* movq ea, mm */
3369 gen_lea_modrm(env
, s
, modrm
);
3370 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3373 gen_op_movq(s
, offsetof(CPUX86State
, fpregs
[rm
].mmx
),
3374 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3377 case 0x011: /* movups */
3378 case 0x111: /* movupd */
3379 case 0x029: /* movaps */
3380 case 0x129: /* movapd */
3381 case 0x17f: /* movdqa ea, xmm */
3382 case 0x27f: /* movdqu ea, xmm */
3384 gen_lea_modrm(env
, s
, modrm
);
3385 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3387 rm
= (modrm
& 7) | REX_B(s
);
3388 gen_op_movo(s
, offsetof(CPUX86State
, xmm_regs
[rm
]),
3389 offsetof(CPUX86State
,xmm_regs
[reg
]));
3392 case 0x211: /* movss ea, xmm */
3394 gen_lea_modrm(env
, s
, modrm
);
3395 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
3396 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(0)));
3397 gen_op_st_v(s
, MO_32
, s
->T0
, s
->A0
);
3399 rm
= (modrm
& 7) | REX_B(s
);
3400 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[rm
].ZMM_L(0)),
3401 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3404 case 0x311: /* movsd ea, xmm */
3406 gen_lea_modrm(env
, s
, modrm
);
3407 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3408 xmm_regs
[reg
].ZMM_Q(0)));
3410 rm
= (modrm
& 7) | REX_B(s
);
3411 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[rm
].ZMM_Q(0)),
3412 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3415 case 0x013: /* movlps */
3416 case 0x113: /* movlpd */
3418 gen_lea_modrm(env
, s
, modrm
);
3419 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3420 xmm_regs
[reg
].ZMM_Q(0)));
3425 case 0x017: /* movhps */
3426 case 0x117: /* movhpd */
3428 gen_lea_modrm(env
, s
, modrm
);
3429 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3430 xmm_regs
[reg
].ZMM_Q(1)));
3435 case 0x71: /* shift mm, im */
3438 case 0x171: /* shift xmm, im */
3444 val
= x86_ldub_code(env
, s
);
3446 tcg_gen_movi_tl(s
->T0
, val
);
3447 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3448 offsetof(CPUX86State
, xmm_t0
.ZMM_L(0)));
3449 tcg_gen_movi_tl(s
->T0
, 0);
3450 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3451 offsetof(CPUX86State
, xmm_t0
.ZMM_L(1)));
3452 op1_offset
= offsetof(CPUX86State
,xmm_t0
);
3454 tcg_gen_movi_tl(s
->T0
, val
);
3455 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3456 offsetof(CPUX86State
, mmx_t0
.MMX_L(0)));
3457 tcg_gen_movi_tl(s
->T0
, 0);
3458 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3459 offsetof(CPUX86State
, mmx_t0
.MMX_L(1)));
3460 op1_offset
= offsetof(CPUX86State
,mmx_t0
);
3462 sse_fn_epp
= sse_op_table2
[((b
- 1) & 3) * 8 +
3463 (((modrm
>> 3)) & 7)][b1
];
3468 rm
= (modrm
& 7) | REX_B(s
);
3469 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3472 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3474 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op2_offset
);
3475 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op1_offset
);
3476 sse_fn_epp(cpu_env
, s
->ptr0
, s
->ptr1
);
3478 case 0x050: /* movmskps */
3479 rm
= (modrm
& 7) | REX_B(s
);
3480 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3481 offsetof(CPUX86State
,xmm_regs
[rm
]));
3482 gen_helper_movmskps(s
->tmp2_i32
, cpu_env
, s
->ptr0
);
3483 tcg_gen_extu_i32_tl(cpu_regs
[reg
], s
->tmp2_i32
);
3485 case 0x150: /* movmskpd */
3486 rm
= (modrm
& 7) | REX_B(s
);
3487 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3488 offsetof(CPUX86State
,xmm_regs
[rm
]));
3489 gen_helper_movmskpd(s
->tmp2_i32
, cpu_env
, s
->ptr0
);
3490 tcg_gen_extu_i32_tl(cpu_regs
[reg
], s
->tmp2_i32
);
3492 case 0x02a: /* cvtpi2ps */
3493 case 0x12a: /* cvtpi2pd */
3494 gen_helper_enter_mmx(cpu_env
);
3496 gen_lea_modrm(env
, s
, modrm
);
3497 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3498 gen_ldq_env_A0(s
, op2_offset
);
3501 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3503 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3504 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
3505 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
3508 gen_helper_cvtpi2ps(cpu_env
, s
->ptr0
, s
->ptr1
);
3512 gen_helper_cvtpi2pd(cpu_env
, s
->ptr0
, s
->ptr1
);
3516 case 0x22a: /* cvtsi2ss */
3517 case 0x32a: /* cvtsi2sd */
3518 ot
= mo_64_32(s
->dflag
);
3519 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3520 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3521 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
3523 SSEFunc_0_epi sse_fn_epi
= sse_op_table3ai
[(b
>> 8) & 1];
3524 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
3525 sse_fn_epi(cpu_env
, s
->ptr0
, s
->tmp2_i32
);
3527 #ifdef TARGET_X86_64
3528 SSEFunc_0_epl sse_fn_epl
= sse_op_table3aq
[(b
>> 8) & 1];
3529 sse_fn_epl(cpu_env
, s
->ptr0
, s
->T0
);
3535 case 0x02c: /* cvttps2pi */
3536 case 0x12c: /* cvttpd2pi */
3537 case 0x02d: /* cvtps2pi */
3538 case 0x12d: /* cvtpd2pi */
3539 gen_helper_enter_mmx(cpu_env
);
3541 gen_lea_modrm(env
, s
, modrm
);
3542 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3543 gen_ldo_env_A0(s
, op2_offset
);
3545 rm
= (modrm
& 7) | REX_B(s
);
3546 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3548 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
);
3549 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
3550 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
3553 gen_helper_cvttps2pi(cpu_env
, s
->ptr0
, s
->ptr1
);
3556 gen_helper_cvttpd2pi(cpu_env
, s
->ptr0
, s
->ptr1
);
3559 gen_helper_cvtps2pi(cpu_env
, s
->ptr0
, s
->ptr1
);
3562 gen_helper_cvtpd2pi(cpu_env
, s
->ptr0
, s
->ptr1
);
3566 case 0x22c: /* cvttss2si */
3567 case 0x32c: /* cvttsd2si */
3568 case 0x22d: /* cvtss2si */
3569 case 0x32d: /* cvtsd2si */
3570 ot
= mo_64_32(s
->dflag
);
3572 gen_lea_modrm(env
, s
, modrm
);
3574 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.ZMM_Q(0)));
3576 gen_op_ld_v(s
, MO_32
, s
->T0
, s
->A0
);
3577 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3578 offsetof(CPUX86State
, xmm_t0
.ZMM_L(0)));
3580 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3582 rm
= (modrm
& 7) | REX_B(s
);
3583 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3585 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op2_offset
);
3587 SSEFunc_i_ep sse_fn_i_ep
=
3588 sse_op_table3bi
[((b
>> 7) & 2) | (b
& 1)];
3589 sse_fn_i_ep(s
->tmp2_i32
, cpu_env
, s
->ptr0
);
3590 tcg_gen_extu_i32_tl(s
->T0
, s
->tmp2_i32
);
3592 #ifdef TARGET_X86_64
3593 SSEFunc_l_ep sse_fn_l_ep
=
3594 sse_op_table3bq
[((b
>> 7) & 2) | (b
& 1)];
3595 sse_fn_l_ep(s
->T0
, cpu_env
, s
->ptr0
);
3600 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
3602 case 0xc4: /* pinsrw */
3605 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
3606 val
= x86_ldub_code(env
, s
);
3609 tcg_gen_st16_tl(s
->T0
, cpu_env
,
3610 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_W(val
)));
3613 tcg_gen_st16_tl(s
->T0
, cpu_env
,
3614 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_W(val
)));
3617 case 0xc5: /* pextrw */
3621 ot
= mo_64_32(s
->dflag
);
3622 val
= x86_ldub_code(env
, s
);
3625 rm
= (modrm
& 7) | REX_B(s
);
3626 tcg_gen_ld16u_tl(s
->T0
, cpu_env
,
3627 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_W(val
)));
3631 tcg_gen_ld16u_tl(s
->T0
, cpu_env
,
3632 offsetof(CPUX86State
,fpregs
[rm
].mmx
.MMX_W(val
)));
3634 reg
= ((modrm
>> 3) & 7) | rex_r
;
3635 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
3637 case 0x1d6: /* movq ea, xmm */
3639 gen_lea_modrm(env
, s
, modrm
);
3640 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3641 xmm_regs
[reg
].ZMM_Q(0)));
3643 rm
= (modrm
& 7) | REX_B(s
);
3644 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[rm
].ZMM_Q(0)),
3645 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3646 gen_op_movq_env_0(s
,
3647 offsetof(CPUX86State
, xmm_regs
[rm
].ZMM_Q(1)));
3650 case 0x2d6: /* movq2dq */
3651 gen_helper_enter_mmx(cpu_env
);
3653 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(0)),
3654 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3655 gen_op_movq_env_0(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(1)));
3657 case 0x3d6: /* movdq2q */
3658 gen_helper_enter_mmx(cpu_env
);
3659 rm
= (modrm
& 7) | REX_B(s
);
3660 gen_op_movq(s
, offsetof(CPUX86State
, fpregs
[reg
& 7].mmx
),
3661 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3663 case 0xd7: /* pmovmskb */
3668 rm
= (modrm
& 7) | REX_B(s
);
3669 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3670 offsetof(CPUX86State
, xmm_regs
[rm
]));
3671 gen_helper_pmovmskb_xmm(s
->tmp2_i32
, cpu_env
, s
->ptr0
);
3674 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3675 offsetof(CPUX86State
, fpregs
[rm
].mmx
));
3676 gen_helper_pmovmskb_mmx(s
->tmp2_i32
, cpu_env
, s
->ptr0
);
3678 reg
= ((modrm
>> 3) & 7) | rex_r
;
3679 tcg_gen_extu_i32_tl(cpu_regs
[reg
], s
->tmp2_i32
);
3685 if ((b
& 0xf0) == 0xf0) {
3688 modrm
= x86_ldub_code(env
, s
);
3690 reg
= ((modrm
>> 3) & 7) | rex_r
;
3691 mod
= (modrm
>> 6) & 3;
3696 sse_fn_epp
= sse_op_table6
[b
].op
[b1
];
3700 if (!(s
->cpuid_ext_features
& sse_op_table6
[b
].ext_mask
))
3704 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3706 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
3708 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3709 gen_lea_modrm(env
, s
, modrm
);
3711 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3712 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3713 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3714 gen_ldq_env_A0(s
, op2_offset
+
3715 offsetof(ZMMReg
, ZMM_Q(0)));
3717 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3718 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3719 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
3720 s
->mem_index
, MO_LEUL
);
3721 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
, op2_offset
+
3722 offsetof(ZMMReg
, ZMM_L(0)));
3724 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3725 tcg_gen_qemu_ld_tl(s
->tmp0
, s
->A0
,
3726 s
->mem_index
, MO_LEUW
);
3727 tcg_gen_st16_tl(s
->tmp0
, cpu_env
, op2_offset
+
3728 offsetof(ZMMReg
, ZMM_W(0)));
3730 case 0x2a: /* movntqda */
3731 gen_ldo_env_A0(s
, op1_offset
);
3734 gen_ldo_env_A0(s
, op2_offset
);
3738 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
3740 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3742 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3743 gen_lea_modrm(env
, s
, modrm
);
3744 gen_ldq_env_A0(s
, op2_offset
);
3747 if (sse_fn_epp
== SSE_SPECIAL
) {
3751 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
3752 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
3753 sse_fn_epp(cpu_env
, s
->ptr0
, s
->ptr1
);
3756 set_cc_op(s
, CC_OP_EFLAGS
);
3763 /* Various integer extensions at 0f 38 f[0-f]. */
3764 b
= modrm
| (b1
<< 8);
3765 modrm
= x86_ldub_code(env
, s
);
3766 reg
= ((modrm
>> 3) & 7) | rex_r
;
3769 case 0x3f0: /* crc32 Gd,Eb */
3770 case 0x3f1: /* crc32 Gd,Ey */
3772 if (!(s
->cpuid_ext_features
& CPUID_EXT_SSE42
)) {
3775 if ((b
& 0xff) == 0xf0) {
3777 } else if (s
->dflag
!= MO_64
) {
3778 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3783 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[reg
]);
3784 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3785 gen_helper_crc32(s
->T0
, s
->tmp2_i32
,
3786 s
->T0
, tcg_const_i32(8 << ot
));
3788 ot
= mo_64_32(s
->dflag
);
3789 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
3792 case 0x1f0: /* crc32 or movbe */
3794 /* For these insns, the f3 prefix is supposed to have priority
3795 over the 66 prefix, but that's not what we implement above
3797 if (s
->prefix
& PREFIX_REPNZ
) {
3801 case 0x0f0: /* movbe Gy,My */
3802 case 0x0f1: /* movbe My,Gy */
3803 if (!(s
->cpuid_ext_features
& CPUID_EXT_MOVBE
)) {
3806 if (s
->dflag
!= MO_64
) {
3807 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3812 gen_lea_modrm(env
, s
, modrm
);
3814 tcg_gen_qemu_ld_tl(s
->T0
, s
->A0
,
3815 s
->mem_index
, ot
| MO_BE
);
3816 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
3818 tcg_gen_qemu_st_tl(cpu_regs
[reg
], s
->A0
,
3819 s
->mem_index
, ot
| MO_BE
);
3823 case 0x0f2: /* andn Gy, By, Ey */
3824 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3825 || !(s
->prefix
& PREFIX_VEX
)
3829 ot
= mo_64_32(s
->dflag
);
3830 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3831 tcg_gen_andc_tl(s
->T0
, s
->T0
, cpu_regs
[s
->vex_v
]);
3832 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
3833 gen_op_update1_cc(s
);
3834 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3837 case 0x0f7: /* bextr Gy, Ey, By */
3838 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3839 || !(s
->prefix
& PREFIX_VEX
)
3843 ot
= mo_64_32(s
->dflag
);
3847 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3848 /* Extract START, and shift the operand.
3849 Shifts larger than operand size get zeros. */
3850 tcg_gen_ext8u_tl(s
->A0
, cpu_regs
[s
->vex_v
]);
3851 tcg_gen_shr_tl(s
->T0
, s
->T0
, s
->A0
);
3853 bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3854 zero
= tcg_const_tl(0);
3855 tcg_gen_movcond_tl(TCG_COND_LEU
, s
->T0
, s
->A0
, bound
,
3857 tcg_temp_free(zero
);
3859 /* Extract the LEN into a mask. Lengths larger than
3860 operand size get all ones. */
3861 tcg_gen_extract_tl(s
->A0
, cpu_regs
[s
->vex_v
], 8, 8);
3862 tcg_gen_movcond_tl(TCG_COND_LEU
, s
->A0
, s
->A0
, bound
,
3864 tcg_temp_free(bound
);
3865 tcg_gen_movi_tl(s
->T1
, 1);
3866 tcg_gen_shl_tl(s
->T1
, s
->T1
, s
->A0
);
3867 tcg_gen_subi_tl(s
->T1
, s
->T1
, 1);
3868 tcg_gen_and_tl(s
->T0
, s
->T0
, s
->T1
);
3870 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
3871 gen_op_update1_cc(s
);
3872 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3876 case 0x0f5: /* bzhi Gy, Ey, By */
3877 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3878 || !(s
->prefix
& PREFIX_VEX
)
3882 ot
= mo_64_32(s
->dflag
);
3883 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3884 tcg_gen_ext8u_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
3886 TCGv bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3887 /* Note that since we're using BMILG (in order to get O
3888 cleared) we need to store the inverse into C. */
3889 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_cc_src
,
3891 tcg_gen_movcond_tl(TCG_COND_GT
, s
->T1
, s
->T1
,
3892 bound
, bound
, s
->T1
);
3893 tcg_temp_free(bound
);
3895 tcg_gen_movi_tl(s
->A0
, -1);
3896 tcg_gen_shl_tl(s
->A0
, s
->A0
, s
->T1
);
3897 tcg_gen_andc_tl(s
->T0
, s
->T0
, s
->A0
);
3898 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
3899 gen_op_update1_cc(s
);
3900 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
3903 case 0x3f6: /* mulx By, Gy, rdx, Ey */
3904 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3905 || !(s
->prefix
& PREFIX_VEX
)
3909 ot
= mo_64_32(s
->dflag
);
3910 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3913 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
3914 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, cpu_regs
[R_EDX
]);
3915 tcg_gen_mulu2_i32(s
->tmp2_i32
, s
->tmp3_i32
,
3916 s
->tmp2_i32
, s
->tmp3_i32
);
3917 tcg_gen_extu_i32_tl(cpu_regs
[s
->vex_v
], s
->tmp2_i32
);
3918 tcg_gen_extu_i32_tl(cpu_regs
[reg
], s
->tmp3_i32
);
3920 #ifdef TARGET_X86_64
3922 tcg_gen_mulu2_i64(s
->T0
, s
->T1
,
3923 s
->T0
, cpu_regs
[R_EDX
]);
3924 tcg_gen_mov_i64(cpu_regs
[s
->vex_v
], s
->T0
);
3925 tcg_gen_mov_i64(cpu_regs
[reg
], s
->T1
);
3931 case 0x3f5: /* pdep Gy, By, Ey */
3932 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3933 || !(s
->prefix
& PREFIX_VEX
)
3937 ot
= mo_64_32(s
->dflag
);
3938 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3939 /* Note that by zero-extending the mask operand, we
3940 automatically handle zero-extending the result. */
3942 tcg_gen_mov_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
3944 tcg_gen_ext32u_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
3946 gen_helper_pdep(cpu_regs
[reg
], s
->T0
, s
->T1
);
3949 case 0x2f5: /* pext Gy, By, Ey */
3950 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3951 || !(s
->prefix
& PREFIX_VEX
)
3955 ot
= mo_64_32(s
->dflag
);
3956 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3957 /* Note that by zero-extending the mask operand, we
3958 automatically handle zero-extending the result. */
3960 tcg_gen_mov_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
3962 tcg_gen_ext32u_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
3964 gen_helper_pext(cpu_regs
[reg
], s
->T0
, s
->T1
);
3967 case 0x1f6: /* adcx Gy, Ey */
3968 case 0x2f6: /* adox Gy, Ey */
3969 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_ADX
)) {
3972 TCGv carry_in
, carry_out
, zero
;
3975 ot
= mo_64_32(s
->dflag
);
3976 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3978 /* Re-use the carry-out from a previous round. */
3980 carry_out
= (b
== 0x1f6 ? cpu_cc_dst
: cpu_cc_src2
);
3984 carry_in
= cpu_cc_dst
;
3985 end_op
= CC_OP_ADCX
;
3987 end_op
= CC_OP_ADCOX
;
3992 end_op
= CC_OP_ADCOX
;
3994 carry_in
= cpu_cc_src2
;
3995 end_op
= CC_OP_ADOX
;
3999 end_op
= CC_OP_ADCOX
;
4000 carry_in
= carry_out
;
4003 end_op
= (b
== 0x1f6 ? CC_OP_ADCX
: CC_OP_ADOX
);
4006 /* If we can't reuse carry-out, get it out of EFLAGS. */
4008 if (s
->cc_op
!= CC_OP_ADCX
&& s
->cc_op
!= CC_OP_ADOX
) {
4009 gen_compute_eflags(s
);
4012 tcg_gen_extract_tl(carry_in
, cpu_cc_src
,
4013 ctz32(b
== 0x1f6 ? CC_C
: CC_O
), 1);
4017 #ifdef TARGET_X86_64
4019 /* If we know TL is 64-bit, and we want a 32-bit
4020 result, just do everything in 64-bit arithmetic. */
4021 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_regs
[reg
]);
4022 tcg_gen_ext32u_i64(s
->T0
, s
->T0
);
4023 tcg_gen_add_i64(s
->T0
, s
->T0
, cpu_regs
[reg
]);
4024 tcg_gen_add_i64(s
->T0
, s
->T0
, carry_in
);
4025 tcg_gen_ext32u_i64(cpu_regs
[reg
], s
->T0
);
4026 tcg_gen_shri_i64(carry_out
, s
->T0
, 32);
4030 /* Otherwise compute the carry-out in two steps. */
4031 zero
= tcg_const_tl(0);
4032 tcg_gen_add2_tl(s
->T0
, carry_out
,
4035 tcg_gen_add2_tl(cpu_regs
[reg
], carry_out
,
4036 cpu_regs
[reg
], carry_out
,
4038 tcg_temp_free(zero
);
4041 set_cc_op(s
, end_op
);
4045 case 0x1f7: /* shlx Gy, Ey, By */
4046 case 0x2f7: /* sarx Gy, Ey, By */
4047 case 0x3f7: /* shrx Gy, Ey, By */
4048 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4049 || !(s
->prefix
& PREFIX_VEX
)
4053 ot
= mo_64_32(s
->dflag
);
4054 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4056 tcg_gen_andi_tl(s
->T1
, cpu_regs
[s
->vex_v
], 63);
4058 tcg_gen_andi_tl(s
->T1
, cpu_regs
[s
->vex_v
], 31);
4061 tcg_gen_shl_tl(s
->T0
, s
->T0
, s
->T1
);
4062 } else if (b
== 0x2f7) {
4064 tcg_gen_ext32s_tl(s
->T0
, s
->T0
);
4066 tcg_gen_sar_tl(s
->T0
, s
->T0
, s
->T1
);
4069 tcg_gen_ext32u_tl(s
->T0
, s
->T0
);
4071 tcg_gen_shr_tl(s
->T0
, s
->T0
, s
->T1
);
4073 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
4079 case 0x3f3: /* Group 17 */
4080 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
4081 || !(s
->prefix
& PREFIX_VEX
)
4085 ot
= mo_64_32(s
->dflag
);
4086 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4088 tcg_gen_mov_tl(cpu_cc_src
, s
->T0
);
4090 case 1: /* blsr By,Ey */
4091 tcg_gen_subi_tl(s
->T1
, s
->T0
, 1);
4092 tcg_gen_and_tl(s
->T0
, s
->T0
, s
->T1
);
4094 case 2: /* blsmsk By,Ey */
4095 tcg_gen_subi_tl(s
->T1
, s
->T0
, 1);
4096 tcg_gen_xor_tl(s
->T0
, s
->T0
, s
->T1
);
4098 case 3: /* blsi By, Ey */
4099 tcg_gen_neg_tl(s
->T1
, s
->T0
);
4100 tcg_gen_and_tl(s
->T0
, s
->T0
, s
->T1
);
4105 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
4106 gen_op_mov_reg_v(s
, ot
, s
->vex_v
, s
->T0
);
4107 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4118 modrm
= x86_ldub_code(env
, s
);
4120 reg
= ((modrm
>> 3) & 7) | rex_r
;
4121 mod
= (modrm
>> 6) & 3;
4126 sse_fn_eppi
= sse_op_table7
[b
].op
[b1
];
4130 if (!(s
->cpuid_ext_features
& sse_op_table7
[b
].ext_mask
))
4135 if (sse_fn_eppi
== SSE_SPECIAL
) {
4136 ot
= mo_64_32(s
->dflag
);
4137 rm
= (modrm
& 7) | REX_B(s
);
4139 gen_lea_modrm(env
, s
, modrm
);
4140 reg
= ((modrm
>> 3) & 7) | rex_r
;
4141 val
= x86_ldub_code(env
, s
);
4143 case 0x14: /* pextrb */
4144 tcg_gen_ld8u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
4145 xmm_regs
[reg
].ZMM_B(val
& 15)));
4147 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
4149 tcg_gen_qemu_st_tl(s
->T0
, s
->A0
,
4150 s
->mem_index
, MO_UB
);
4153 case 0x15: /* pextrw */
4154 tcg_gen_ld16u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
4155 xmm_regs
[reg
].ZMM_W(val
& 7)));
4157 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
4159 tcg_gen_qemu_st_tl(s
->T0
, s
->A0
,
4160 s
->mem_index
, MO_LEUW
);
4164 if (ot
== MO_32
) { /* pextrd */
4165 tcg_gen_ld_i32(s
->tmp2_i32
, cpu_env
,
4166 offsetof(CPUX86State
,
4167 xmm_regs
[reg
].ZMM_L(val
& 3)));
4169 tcg_gen_extu_i32_tl(cpu_regs
[rm
], s
->tmp2_i32
);
4171 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
4172 s
->mem_index
, MO_LEUL
);
4174 } else { /* pextrq */
4175 #ifdef TARGET_X86_64
4176 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
,
4177 offsetof(CPUX86State
,
4178 xmm_regs
[reg
].ZMM_Q(val
& 1)));
4180 tcg_gen_mov_i64(cpu_regs
[rm
], s
->tmp1_i64
);
4182 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
,
4183 s
->mem_index
, MO_LEQ
);
4190 case 0x17: /* extractps */
4191 tcg_gen_ld32u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
4192 xmm_regs
[reg
].ZMM_L(val
& 3)));
4194 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
4196 tcg_gen_qemu_st_tl(s
->T0
, s
->A0
,
4197 s
->mem_index
, MO_LEUL
);
4200 case 0x20: /* pinsrb */
4202 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, rm
);
4204 tcg_gen_qemu_ld_tl(s
->T0
, s
->A0
,
4205 s
->mem_index
, MO_UB
);
4207 tcg_gen_st8_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
4208 xmm_regs
[reg
].ZMM_B(val
& 15)));
4210 case 0x21: /* insertps */
4212 tcg_gen_ld_i32(s
->tmp2_i32
, cpu_env
,
4213 offsetof(CPUX86State
,xmm_regs
[rm
]
4214 .ZMM_L((val
>> 6) & 3)));
4216 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
4217 s
->mem_index
, MO_LEUL
);
4219 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
,
4220 offsetof(CPUX86State
,xmm_regs
[reg
]
4221 .ZMM_L((val
>> 4) & 3)));
4223 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4224 cpu_env
, offsetof(CPUX86State
,
4225 xmm_regs
[reg
].ZMM_L(0)));
4227 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4228 cpu_env
, offsetof(CPUX86State
,
4229 xmm_regs
[reg
].ZMM_L(1)));
4231 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4232 cpu_env
, offsetof(CPUX86State
,
4233 xmm_regs
[reg
].ZMM_L(2)));
4235 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4236 cpu_env
, offsetof(CPUX86State
,
4237 xmm_regs
[reg
].ZMM_L(3)));
4240 if (ot
== MO_32
) { /* pinsrd */
4242 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[rm
]);
4244 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
4245 s
->mem_index
, MO_LEUL
);
4247 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
,
4248 offsetof(CPUX86State
,
4249 xmm_regs
[reg
].ZMM_L(val
& 3)));
4250 } else { /* pinsrq */
4251 #ifdef TARGET_X86_64
4253 gen_op_mov_v_reg(s
, ot
, s
->tmp1_i64
, rm
);
4255 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
,
4256 s
->mem_index
, MO_LEQ
);
4258 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
,
4259 offsetof(CPUX86State
,
4260 xmm_regs
[reg
].ZMM_Q(val
& 1)));
4271 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4273 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
4275 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4276 gen_lea_modrm(env
, s
, modrm
);
4277 gen_ldo_env_A0(s
, op2_offset
);
4280 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4282 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4284 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4285 gen_lea_modrm(env
, s
, modrm
);
4286 gen_ldq_env_A0(s
, op2_offset
);
4289 val
= x86_ldub_code(env
, s
);
4291 if ((b
& 0xfc) == 0x60) { /* pcmpXstrX */
4292 set_cc_op(s
, CC_OP_EFLAGS
);
4294 if (s
->dflag
== MO_64
) {
4295 /* The helper must use entire 64-bit gp registers */
4300 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
4301 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
4302 sse_fn_eppi(cpu_env
, s
->ptr0
, s
->ptr1
, tcg_const_i32(val
));
4306 /* Various integer extensions at 0f 3a f[0-f]. */
4307 b
= modrm
| (b1
<< 8);
4308 modrm
= x86_ldub_code(env
, s
);
4309 reg
= ((modrm
>> 3) & 7) | rex_r
;
4312 case 0x3f0: /* rorx Gy,Ey, Ib */
4313 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4314 || !(s
->prefix
& PREFIX_VEX
)
4318 ot
= mo_64_32(s
->dflag
);
4319 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4320 b
= x86_ldub_code(env
, s
);
4322 tcg_gen_rotri_tl(s
->T0
, s
->T0
, b
& 63);
4324 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
4325 tcg_gen_rotri_i32(s
->tmp2_i32
, s
->tmp2_i32
, b
& 31);
4326 tcg_gen_extu_i32_tl(s
->T0
, s
->tmp2_i32
);
4328 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
4338 gen_unknown_opcode(env
, s
);
4342 /* generic MMX or SSE operation */
4344 case 0x70: /* pshufx insn */
4345 case 0xc6: /* pshufx insn */
4346 case 0xc2: /* compare insns */
4353 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4357 gen_lea_modrm(env
, s
, modrm
);
4358 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4364 /* Most sse scalar operations. */
4367 } else if (b1
== 3) {
4372 case 0x2e: /* ucomis[sd] */
4373 case 0x2f: /* comis[sd] */
4385 gen_op_ld_v(s
, MO_32
, s
->T0
, s
->A0
);
4386 tcg_gen_st32_tl(s
->T0
, cpu_env
,
4387 offsetof(CPUX86State
,xmm_t0
.ZMM_L(0)));
4391 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.ZMM_D(0)));
4394 /* 128 bit access */
4395 gen_ldo_env_A0(s
, op2_offset
);
4399 rm
= (modrm
& 7) | REX_B(s
);
4400 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
4403 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4405 gen_lea_modrm(env
, s
, modrm
);
4406 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4407 gen_ldq_env_A0(s
, op2_offset
);
4410 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4414 case 0x0f: /* 3DNow! data insns */
4415 val
= x86_ldub_code(env
, s
);
4416 sse_fn_epp
= sse_op_table5
[val
];
4420 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
)) {
4423 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
4424 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
4425 sse_fn_epp(cpu_env
, s
->ptr0
, s
->ptr1
);
4427 case 0x70: /* pshufx insn */
4428 case 0xc6: /* pshufx insn */
4429 val
= x86_ldub_code(env
, s
);
4430 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
4431 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
4432 /* XXX: introduce a new table? */
4433 sse_fn_ppi
= (SSEFunc_0_ppi
)sse_fn_epp
;
4434 sse_fn_ppi(s
->ptr0
, s
->ptr1
, tcg_const_i32(val
));
4438 val
= x86_ldub_code(env
, s
);
4441 sse_fn_epp
= sse_op_table4
[val
][b1
];
4443 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
4444 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
4445 sse_fn_epp(cpu_env
, s
->ptr0
, s
->ptr1
);
4448 /* maskmov : we must prepare A0 */
4451 tcg_gen_mov_tl(s
->A0
, cpu_regs
[R_EDI
]);
4452 gen_extu(s
->aflag
, s
->A0
);
4453 gen_add_A0_ds_seg(s
);
4455 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
4456 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
4457 /* XXX: introduce a new table? */
4458 sse_fn_eppt
= (SSEFunc_0_eppt
)sse_fn_epp
;
4459 sse_fn_eppt(cpu_env
, s
->ptr0
, s
->ptr1
, s
->A0
);
4462 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
4463 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
4464 sse_fn_epp(cpu_env
, s
->ptr0
, s
->ptr1
);
4467 if (b
== 0x2e || b
== 0x2f) {
4468 set_cc_op(s
, CC_OP_EFLAGS
);
4473 /* convert one instruction. s->base.is_jmp is set if the translation must
4474 be stopped. Return the next pc value */
4475 static target_ulong
disas_insn(DisasContext
*s
, CPUState
*cpu
)
4477 CPUX86State
*env
= cpu
->env_ptr
;
4480 MemOp ot
, aflag
, dflag
;
4481 int modrm
, reg
, rm
, mod
, op
, opreg
, val
;
4482 target_ulong next_eip
, tval
;
4484 target_ulong pc_start
= s
->base
.pc_next
;
4486 s
->pc_start
= s
->pc
= pc_start
;
4488 #ifdef TARGET_X86_64
4491 s
->x86_64_hregs
= false;
4493 s
->rip_offset
= 0; /* for relative ip address */
4496 if (sigsetjmp(s
->jmpbuf
, 0) != 0) {
4497 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
4506 b
= x86_ldub_code(env
, s
);
4507 /* Collect prefixes. */
4510 prefixes
|= PREFIX_REPZ
;
4513 prefixes
|= PREFIX_REPNZ
;
4516 prefixes
|= PREFIX_LOCK
;
4537 prefixes
|= PREFIX_DATA
;
4540 prefixes
|= PREFIX_ADR
;
4542 #ifdef TARGET_X86_64
4546 rex_w
= (b
>> 3) & 1;
4547 rex_r
= (b
& 0x4) << 1;
4548 s
->rex_x
= (b
& 0x2) << 2;
4549 REX_B(s
) = (b
& 0x1) << 3;
4550 /* select uniform byte register addressing */
4551 s
->x86_64_hregs
= true;
4556 case 0xc5: /* 2-byte VEX */
4557 case 0xc4: /* 3-byte VEX */
4558 /* VEX prefixes cannot be used except in 32-bit mode.
4559 Otherwise the instruction is LES or LDS. */
4560 if (s
->code32
&& !s
->vm86
) {
4561 static const int pp_prefix
[4] = {
4562 0, PREFIX_DATA
, PREFIX_REPZ
, PREFIX_REPNZ
4564 int vex3
, vex2
= x86_ldub_code(env
, s
);
4566 if (!CODE64(s
) && (vex2
& 0xc0) != 0xc0) {
4567 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4568 otherwise the instruction is LES or LDS. */
4569 s
->pc
--; /* rewind the advance_pc() x86_ldub_code() did */
4573 /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
4574 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
4575 | PREFIX_LOCK
| PREFIX_DATA
)) {
4578 #ifdef TARGET_X86_64
4579 if (s
->x86_64_hregs
) {
4583 rex_r
= (~vex2
>> 4) & 8;
4585 /* 2-byte VEX prefix: RVVVVlpp, implied 0f leading opcode byte */
4587 b
= x86_ldub_code(env
, s
) | 0x100;
4589 /* 3-byte VEX prefix: RXBmmmmm wVVVVlpp */
4590 #ifdef TARGET_X86_64
4591 s
->rex_x
= (~vex2
>> 3) & 8;
4592 s
->rex_b
= (~vex2
>> 2) & 8;
4594 vex3
= x86_ldub_code(env
, s
);
4595 rex_w
= (vex3
>> 7) & 1;
4596 switch (vex2
& 0x1f) {
4597 case 0x01: /* Implied 0f leading opcode bytes. */
4598 b
= x86_ldub_code(env
, s
) | 0x100;
4600 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4603 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4606 default: /* Reserved for future use. */
4610 s
->vex_v
= (~vex3
>> 3) & 0xf;
4611 s
->vex_l
= (vex3
>> 2) & 1;
4612 prefixes
|= pp_prefix
[vex3
& 3] | PREFIX_VEX
;
4617 /* Post-process prefixes. */
4619 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit
4620 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4621 over 0x66 if both are present. */
4622 dflag
= (rex_w
> 0 ? MO_64
: prefixes
& PREFIX_DATA
? MO_16
: MO_32
);
4623 /* In 64-bit mode, 0x67 selects 32-bit addressing. */
4624 aflag
= (prefixes
& PREFIX_ADR
? MO_32
: MO_64
);
4626 /* In 16/32-bit mode, 0x66 selects the opposite data size. */
4627 if (s
->code32
^ ((prefixes
& PREFIX_DATA
) != 0)) {
4632 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */
4633 if (s
->code32
^ ((prefixes
& PREFIX_ADR
) != 0)) {
4640 s
->prefix
= prefixes
;
4644 /* now check op code */
4648 /**************************/
4649 /* extended op code */
4650 b
= x86_ldub_code(env
, s
) | 0x100;
4653 /**************************/
4668 ot
= mo_b_d(b
, dflag
);
4671 case 0: /* OP Ev, Gv */
4672 modrm
= x86_ldub_code(env
, s
);
4673 reg
= ((modrm
>> 3) & 7) | rex_r
;
4674 mod
= (modrm
>> 6) & 3;
4675 rm
= (modrm
& 7) | REX_B(s
);
4677 gen_lea_modrm(env
, s
, modrm
);
4679 } else if (op
== OP_XORL
&& rm
== reg
) {
4681 /* xor reg, reg optimisation */
4682 set_cc_op(s
, CC_OP_CLR
);
4683 tcg_gen_movi_tl(s
->T0
, 0);
4684 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
4689 gen_op_mov_v_reg(s
, ot
, s
->T1
, reg
);
4690 gen_op(s
, op
, ot
, opreg
);
4692 case 1: /* OP Gv, Ev */
4693 modrm
= x86_ldub_code(env
, s
);
4694 mod
= (modrm
>> 6) & 3;
4695 reg
= ((modrm
>> 3) & 7) | rex_r
;
4696 rm
= (modrm
& 7) | REX_B(s
);
4698 gen_lea_modrm(env
, s
, modrm
);
4699 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
4700 } else if (op
== OP_XORL
&& rm
== reg
) {
4703 gen_op_mov_v_reg(s
, ot
, s
->T1
, rm
);
4705 gen_op(s
, op
, ot
, reg
);
4707 case 2: /* OP A, Iv */
4708 val
= insn_get(env
, s
, ot
);
4709 tcg_gen_movi_tl(s
->T1
, val
);
4710 gen_op(s
, op
, ot
, OR_EAX
);
4720 case 0x80: /* GRP1 */
4726 ot
= mo_b_d(b
, dflag
);
4728 modrm
= x86_ldub_code(env
, s
);
4729 mod
= (modrm
>> 6) & 3;
4730 rm
= (modrm
& 7) | REX_B(s
);
4731 op
= (modrm
>> 3) & 7;
4737 s
->rip_offset
= insn_const_size(ot
);
4738 gen_lea_modrm(env
, s
, modrm
);
4749 val
= insn_get(env
, s
, ot
);
4752 val
= (int8_t)insn_get(env
, s
, MO_8
);
4755 tcg_gen_movi_tl(s
->T1
, val
);
4756 gen_op(s
, op
, ot
, opreg
);
4760 /**************************/
4761 /* inc, dec, and other misc arith */
4762 case 0x40 ... 0x47: /* inc Gv */
4764 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), 1);
4766 case 0x48 ... 0x4f: /* dec Gv */
4768 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), -1);
4770 case 0xf6: /* GRP3 */
4772 ot
= mo_b_d(b
, dflag
);
4774 modrm
= x86_ldub_code(env
, s
);
4775 mod
= (modrm
>> 6) & 3;
4776 rm
= (modrm
& 7) | REX_B(s
);
4777 op
= (modrm
>> 3) & 7;
4780 s
->rip_offset
= insn_const_size(ot
);
4782 gen_lea_modrm(env
, s
, modrm
);
4783 /* For those below that handle locked memory, don't load here. */
4784 if (!(s
->prefix
& PREFIX_LOCK
)
4786 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
4789 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
4794 val
= insn_get(env
, s
, ot
);
4795 tcg_gen_movi_tl(s
->T1
, val
);
4796 gen_op_testl_T0_T1_cc(s
);
4797 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4800 if (s
->prefix
& PREFIX_LOCK
) {
4804 tcg_gen_movi_tl(s
->T0
, ~0);
4805 tcg_gen_atomic_xor_fetch_tl(s
->T0
, s
->A0
, s
->T0
,
4806 s
->mem_index
, ot
| MO_LE
);
4808 tcg_gen_not_tl(s
->T0
, s
->T0
);
4810 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
4812 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
4817 if (s
->prefix
& PREFIX_LOCK
) {
4819 TCGv a0
, t0
, t1
, t2
;
4824 a0
= tcg_temp_local_new();
4825 t0
= tcg_temp_local_new();
4826 label1
= gen_new_label();
4828 tcg_gen_mov_tl(a0
, s
->A0
);
4829 tcg_gen_mov_tl(t0
, s
->T0
);
4831 gen_set_label(label1
);
4832 t1
= tcg_temp_new();
4833 t2
= tcg_temp_new();
4834 tcg_gen_mov_tl(t2
, t0
);
4835 tcg_gen_neg_tl(t1
, t0
);
4836 tcg_gen_atomic_cmpxchg_tl(t0
, a0
, t0
, t1
,
4837 s
->mem_index
, ot
| MO_LE
);
4839 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t2
, label1
);
4843 tcg_gen_mov_tl(s
->T0
, t0
);
4846 tcg_gen_neg_tl(s
->T0
, s
->T0
);
4848 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
4850 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
4853 gen_op_update_neg_cc(s
);
4854 set_cc_op(s
, CC_OP_SUBB
+ ot
);
4859 gen_op_mov_v_reg(s
, MO_8
, s
->T1
, R_EAX
);
4860 tcg_gen_ext8u_tl(s
->T0
, s
->T0
);
4861 tcg_gen_ext8u_tl(s
->T1
, s
->T1
);
4862 /* XXX: use 32 bit mul which could be faster */
4863 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
4864 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
4865 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
4866 tcg_gen_andi_tl(cpu_cc_src
, s
->T0
, 0xff00);
4867 set_cc_op(s
, CC_OP_MULB
);
4870 gen_op_mov_v_reg(s
, MO_16
, s
->T1
, R_EAX
);
4871 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
4872 tcg_gen_ext16u_tl(s
->T1
, s
->T1
);
4873 /* XXX: use 32 bit mul which could be faster */
4874 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
4875 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
4876 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
4877 tcg_gen_shri_tl(s
->T0
, s
->T0
, 16);
4878 gen_op_mov_reg_v(s
, MO_16
, R_EDX
, s
->T0
);
4879 tcg_gen_mov_tl(cpu_cc_src
, s
->T0
);
4880 set_cc_op(s
, CC_OP_MULW
);
4884 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
4885 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, cpu_regs
[R_EAX
]);
4886 tcg_gen_mulu2_i32(s
->tmp2_i32
, s
->tmp3_i32
,
4887 s
->tmp2_i32
, s
->tmp3_i32
);
4888 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], s
->tmp2_i32
);
4889 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], s
->tmp3_i32
);
4890 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4891 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4892 set_cc_op(s
, CC_OP_MULL
);
4894 #ifdef TARGET_X86_64
4896 tcg_gen_mulu2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4897 s
->T0
, cpu_regs
[R_EAX
]);
4898 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4899 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4900 set_cc_op(s
, CC_OP_MULQ
);
4908 gen_op_mov_v_reg(s
, MO_8
, s
->T1
, R_EAX
);
4909 tcg_gen_ext8s_tl(s
->T0
, s
->T0
);
4910 tcg_gen_ext8s_tl(s
->T1
, s
->T1
);
4911 /* XXX: use 32 bit mul which could be faster */
4912 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
4913 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
4914 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
4915 tcg_gen_ext8s_tl(s
->tmp0
, s
->T0
);
4916 tcg_gen_sub_tl(cpu_cc_src
, s
->T0
, s
->tmp0
);
4917 set_cc_op(s
, CC_OP_MULB
);
4920 gen_op_mov_v_reg(s
, MO_16
, s
->T1
, R_EAX
);
4921 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
4922 tcg_gen_ext16s_tl(s
->T1
, s
->T1
);
4923 /* XXX: use 32 bit mul which could be faster */
4924 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
4925 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
4926 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
4927 tcg_gen_ext16s_tl(s
->tmp0
, s
->T0
);
4928 tcg_gen_sub_tl(cpu_cc_src
, s
->T0
, s
->tmp0
);
4929 tcg_gen_shri_tl(s
->T0
, s
->T0
, 16);
4930 gen_op_mov_reg_v(s
, MO_16
, R_EDX
, s
->T0
);
4931 set_cc_op(s
, CC_OP_MULW
);
4935 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
4936 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, cpu_regs
[R_EAX
]);
4937 tcg_gen_muls2_i32(s
->tmp2_i32
, s
->tmp3_i32
,
4938 s
->tmp2_i32
, s
->tmp3_i32
);
4939 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], s
->tmp2_i32
);
4940 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], s
->tmp3_i32
);
4941 tcg_gen_sari_i32(s
->tmp2_i32
, s
->tmp2_i32
, 31);
4942 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4943 tcg_gen_sub_i32(s
->tmp2_i32
, s
->tmp2_i32
, s
->tmp3_i32
);
4944 tcg_gen_extu_i32_tl(cpu_cc_src
, s
->tmp2_i32
);
4945 set_cc_op(s
, CC_OP_MULL
);
4947 #ifdef TARGET_X86_64
4949 tcg_gen_muls2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4950 s
->T0
, cpu_regs
[R_EAX
]);
4951 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4952 tcg_gen_sari_tl(cpu_cc_src
, cpu_regs
[R_EAX
], 63);
4953 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_regs
[R_EDX
]);
4954 set_cc_op(s
, CC_OP_MULQ
);
4962 gen_helper_divb_AL(cpu_env
, s
->T0
);
4965 gen_helper_divw_AX(cpu_env
, s
->T0
);
4969 gen_helper_divl_EAX(cpu_env
, s
->T0
);
4971 #ifdef TARGET_X86_64
4973 gen_helper_divq_EAX(cpu_env
, s
->T0
);
4981 gen_helper_idivb_AL(cpu_env
, s
->T0
);
4984 gen_helper_idivw_AX(cpu_env
, s
->T0
);
4988 gen_helper_idivl_EAX(cpu_env
, s
->T0
);
4990 #ifdef TARGET_X86_64
4992 gen_helper_idivq_EAX(cpu_env
, s
->T0
);
5002 case 0xfe: /* GRP4 */
5003 case 0xff: /* GRP5 */
5004 ot
= mo_b_d(b
, dflag
);
5006 modrm
= x86_ldub_code(env
, s
);
5007 mod
= (modrm
>> 6) & 3;
5008 rm
= (modrm
& 7) | REX_B(s
);
5009 op
= (modrm
>> 3) & 7;
5010 if (op
>= 2 && b
== 0xfe) {
5014 if (op
== 2 || op
== 4) {
5015 /* operand size for jumps is 64 bit */
5017 } else if (op
== 3 || op
== 5) {
5018 ot
= dflag
!= MO_16
? MO_32
+ (rex_w
== 1) : MO_16
;
5019 } else if (op
== 6) {
5020 /* default push size is 64 bit */
5021 ot
= mo_pushpop(s
, dflag
);
5025 gen_lea_modrm(env
, s
, modrm
);
5026 if (op
>= 2 && op
!= 3 && op
!= 5)
5027 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
5029 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
5033 case 0: /* inc Ev */
5038 gen_inc(s
, ot
, opreg
, 1);
5040 case 1: /* dec Ev */
5045 gen_inc(s
, ot
, opreg
, -1);
5047 case 2: /* call Ev */
5048 /* XXX: optimize if memory (no 'and' is necessary) */
5049 if (dflag
== MO_16
) {
5050 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
5052 next_eip
= s
->pc
- s
->cs_base
;
5053 tcg_gen_movi_tl(s
->T1
, next_eip
);
5054 gen_push_v(s
, s
->T1
);
5055 gen_op_jmp_v(s
->T0
);
5059 case 3: /* lcall Ev */
5060 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
5061 gen_add_A0_im(s
, 1 << ot
);
5062 gen_op_ld_v(s
, MO_16
, s
->T0
, s
->A0
);
5064 if (s
->pe
&& !s
->vm86
) {
5065 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
5066 gen_helper_lcall_protected(cpu_env
, s
->tmp2_i32
, s
->T1
,
5067 tcg_const_i32(dflag
- 1),
5068 tcg_const_tl(s
->pc
- s
->cs_base
));
5070 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
5071 gen_helper_lcall_real(cpu_env
, s
->tmp2_i32
, s
->T1
,
5072 tcg_const_i32(dflag
- 1),
5073 tcg_const_i32(s
->pc
- s
->cs_base
));
5075 tcg_gen_ld_tl(s
->tmp4
, cpu_env
, offsetof(CPUX86State
, eip
));
5078 case 4: /* jmp Ev */
5079 if (dflag
== MO_16
) {
5080 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
5082 gen_op_jmp_v(s
->T0
);
5086 case 5: /* ljmp Ev */
5087 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
5088 gen_add_A0_im(s
, 1 << ot
);
5089 gen_op_ld_v(s
, MO_16
, s
->T0
, s
->A0
);
5091 if (s
->pe
&& !s
->vm86
) {
5092 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
5093 gen_helper_ljmp_protected(cpu_env
, s
->tmp2_i32
, s
->T1
,
5094 tcg_const_tl(s
->pc
- s
->cs_base
));
5096 gen_op_movl_seg_T0_vm(s
, R_CS
);
5097 gen_op_jmp_v(s
->T1
);
5099 tcg_gen_ld_tl(s
->tmp4
, cpu_env
, offsetof(CPUX86State
, eip
));
5102 case 6: /* push Ev */
5103 gen_push_v(s
, s
->T0
);
5110 case 0x84: /* test Ev, Gv */
5112 ot
= mo_b_d(b
, dflag
);
5114 modrm
= x86_ldub_code(env
, s
);
5115 reg
= ((modrm
>> 3) & 7) | rex_r
;
5117 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5118 gen_op_mov_v_reg(s
, ot
, s
->T1
, reg
);
5119 gen_op_testl_T0_T1_cc(s
);
5120 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5123 case 0xa8: /* test eAX, Iv */
5125 ot
= mo_b_d(b
, dflag
);
5126 val
= insn_get(env
, s
, ot
);
5128 gen_op_mov_v_reg(s
, ot
, s
->T0
, OR_EAX
);
5129 tcg_gen_movi_tl(s
->T1
, val
);
5130 gen_op_testl_T0_T1_cc(s
);
5131 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5134 case 0x98: /* CWDE/CBW */
5136 #ifdef TARGET_X86_64
5138 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, R_EAX
);
5139 tcg_gen_ext32s_tl(s
->T0
, s
->T0
);
5140 gen_op_mov_reg_v(s
, MO_64
, R_EAX
, s
->T0
);
5144 gen_op_mov_v_reg(s
, MO_16
, s
->T0
, R_EAX
);
5145 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5146 gen_op_mov_reg_v(s
, MO_32
, R_EAX
, s
->T0
);
5149 gen_op_mov_v_reg(s
, MO_8
, s
->T0
, R_EAX
);
5150 tcg_gen_ext8s_tl(s
->T0
, s
->T0
);
5151 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
5157 case 0x99: /* CDQ/CWD */
5159 #ifdef TARGET_X86_64
5161 gen_op_mov_v_reg(s
, MO_64
, s
->T0
, R_EAX
);
5162 tcg_gen_sari_tl(s
->T0
, s
->T0
, 63);
5163 gen_op_mov_reg_v(s
, MO_64
, R_EDX
, s
->T0
);
5167 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, R_EAX
);
5168 tcg_gen_ext32s_tl(s
->T0
, s
->T0
);
5169 tcg_gen_sari_tl(s
->T0
, s
->T0
, 31);
5170 gen_op_mov_reg_v(s
, MO_32
, R_EDX
, s
->T0
);
5173 gen_op_mov_v_reg(s
, MO_16
, s
->T0
, R_EAX
);
5174 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5175 tcg_gen_sari_tl(s
->T0
, s
->T0
, 15);
5176 gen_op_mov_reg_v(s
, MO_16
, R_EDX
, s
->T0
);
5182 case 0x1af: /* imul Gv, Ev */
5183 case 0x69: /* imul Gv, Ev, I */
5186 modrm
= x86_ldub_code(env
, s
);
5187 reg
= ((modrm
>> 3) & 7) | rex_r
;
5189 s
->rip_offset
= insn_const_size(ot
);
5192 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5194 val
= insn_get(env
, s
, ot
);
5195 tcg_gen_movi_tl(s
->T1
, val
);
5196 } else if (b
== 0x6b) {
5197 val
= (int8_t)insn_get(env
, s
, MO_8
);
5198 tcg_gen_movi_tl(s
->T1
, val
);
5200 gen_op_mov_v_reg(s
, ot
, s
->T1
, reg
);
5203 #ifdef TARGET_X86_64
5205 tcg_gen_muls2_i64(cpu_regs
[reg
], s
->T1
, s
->T0
, s
->T1
);
5206 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5207 tcg_gen_sari_tl(cpu_cc_src
, cpu_cc_dst
, 63);
5208 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, s
->T1
);
5212 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
5213 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, s
->T1
);
5214 tcg_gen_muls2_i32(s
->tmp2_i32
, s
->tmp3_i32
,
5215 s
->tmp2_i32
, s
->tmp3_i32
);
5216 tcg_gen_extu_i32_tl(cpu_regs
[reg
], s
->tmp2_i32
);
5217 tcg_gen_sari_i32(s
->tmp2_i32
, s
->tmp2_i32
, 31);
5218 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5219 tcg_gen_sub_i32(s
->tmp2_i32
, s
->tmp2_i32
, s
->tmp3_i32
);
5220 tcg_gen_extu_i32_tl(cpu_cc_src
, s
->tmp2_i32
);
5223 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5224 tcg_gen_ext16s_tl(s
->T1
, s
->T1
);
5225 /* XXX: use 32 bit mul which could be faster */
5226 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
5227 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
5228 tcg_gen_ext16s_tl(s
->tmp0
, s
->T0
);
5229 tcg_gen_sub_tl(cpu_cc_src
, s
->T0
, s
->tmp0
);
5230 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
5233 set_cc_op(s
, CC_OP_MULB
+ ot
);
5236 case 0x1c1: /* xadd Ev, Gv */
5237 ot
= mo_b_d(b
, dflag
);
5238 modrm
= x86_ldub_code(env
, s
);
5239 reg
= ((modrm
>> 3) & 7) | rex_r
;
5240 mod
= (modrm
>> 6) & 3;
5241 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
5243 rm
= (modrm
& 7) | REX_B(s
);
5244 gen_op_mov_v_reg(s
, ot
, s
->T1
, rm
);
5245 tcg_gen_add_tl(s
->T0
, s
->T0
, s
->T1
);
5246 gen_op_mov_reg_v(s
, ot
, reg
, s
->T1
);
5247 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
5249 gen_lea_modrm(env
, s
, modrm
);
5250 if (s
->prefix
& PREFIX_LOCK
) {
5251 tcg_gen_atomic_fetch_add_tl(s
->T1
, s
->A0
, s
->T0
,
5252 s
->mem_index
, ot
| MO_LE
);
5253 tcg_gen_add_tl(s
->T0
, s
->T0
, s
->T1
);
5255 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
5256 tcg_gen_add_tl(s
->T0
, s
->T0
, s
->T1
);
5257 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
5259 gen_op_mov_reg_v(s
, ot
, reg
, s
->T1
);
5261 gen_op_update2_cc(s
);
5262 set_cc_op(s
, CC_OP_ADDB
+ ot
);
5265 case 0x1b1: /* cmpxchg Ev, Gv */
5267 TCGv oldv
, newv
, cmpv
;
5269 ot
= mo_b_d(b
, dflag
);
5270 modrm
= x86_ldub_code(env
, s
);
5271 reg
= ((modrm
>> 3) & 7) | rex_r
;
5272 mod
= (modrm
>> 6) & 3;
5273 oldv
= tcg_temp_new();
5274 newv
= tcg_temp_new();
5275 cmpv
= tcg_temp_new();
5276 gen_op_mov_v_reg(s
, ot
, newv
, reg
);
5277 tcg_gen_mov_tl(cmpv
, cpu_regs
[R_EAX
]);
5279 if (s
->prefix
& PREFIX_LOCK
) {
5283 gen_lea_modrm(env
, s
, modrm
);
5284 tcg_gen_atomic_cmpxchg_tl(oldv
, s
->A0
, cmpv
, newv
,
5285 s
->mem_index
, ot
| MO_LE
);
5286 gen_op_mov_reg_v(s
, ot
, R_EAX
, oldv
);
5289 rm
= (modrm
& 7) | REX_B(s
);
5290 gen_op_mov_v_reg(s
, ot
, oldv
, rm
);
5292 gen_lea_modrm(env
, s
, modrm
);
5293 gen_op_ld_v(s
, ot
, oldv
, s
->A0
);
5294 rm
= 0; /* avoid warning */
5298 /* store value = (old == cmp ? new : old); */
5299 tcg_gen_movcond_tl(TCG_COND_EQ
, newv
, oldv
, cmpv
, newv
, oldv
);
5301 gen_op_mov_reg_v(s
, ot
, R_EAX
, oldv
);
5302 gen_op_mov_reg_v(s
, ot
, rm
, newv
);
5304 /* Perform an unconditional store cycle like physical cpu;
5305 must be before changing accumulator to ensure
5306 idempotency if the store faults and the instruction
5308 gen_op_st_v(s
, ot
, newv
, s
->A0
);
5309 gen_op_mov_reg_v(s
, ot
, R_EAX
, oldv
);
5312 tcg_gen_mov_tl(cpu_cc_src
, oldv
);
5313 tcg_gen_mov_tl(s
->cc_srcT
, cmpv
);
5314 tcg_gen_sub_tl(cpu_cc_dst
, cmpv
, oldv
);
5315 set_cc_op(s
, CC_OP_SUBB
+ ot
);
5316 tcg_temp_free(oldv
);
5317 tcg_temp_free(newv
);
5318 tcg_temp_free(cmpv
);
5321 case 0x1c7: /* cmpxchg8b */
5322 modrm
= x86_ldub_code(env
, s
);
5323 mod
= (modrm
>> 6) & 3;
5324 switch ((modrm
>> 3) & 7) {
5325 case 1: /* CMPXCHG8, CMPXCHG16 */
5329 #ifdef TARGET_X86_64
5330 if (dflag
== MO_64
) {
5331 if (!(s
->cpuid_ext_features
& CPUID_EXT_CX16
)) {
5334 gen_lea_modrm(env
, s
, modrm
);
5335 if ((s
->prefix
& PREFIX_LOCK
) &&
5336 (tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
5337 gen_helper_cmpxchg16b(cpu_env
, s
->A0
);
5339 gen_helper_cmpxchg16b_unlocked(cpu_env
, s
->A0
);
5341 set_cc_op(s
, CC_OP_EFLAGS
);
5345 if (!(s
->cpuid_features
& CPUID_CX8
)) {
5348 gen_lea_modrm(env
, s
, modrm
);
5349 if ((s
->prefix
& PREFIX_LOCK
) &&
5350 (tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
5351 gen_helper_cmpxchg8b(cpu_env
, s
->A0
);
5353 gen_helper_cmpxchg8b_unlocked(cpu_env
, s
->A0
);
5355 set_cc_op(s
, CC_OP_EFLAGS
);
5358 case 7: /* RDSEED */
5359 case 6: /* RDRAND */
5361 (s
->prefix
& (PREFIX_LOCK
| PREFIX_REPZ
| PREFIX_REPNZ
)) ||
5362 !(s
->cpuid_ext_features
& CPUID_EXT_RDRAND
)) {
5365 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
5368 gen_helper_rdrand(s
->T0
, cpu_env
);
5369 rm
= (modrm
& 7) | REX_B(s
);
5370 gen_op_mov_reg_v(s
, dflag
, rm
, s
->T0
);
5371 set_cc_op(s
, CC_OP_EFLAGS
);
5372 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
5373 gen_jmp(s
, s
->pc
- s
->cs_base
);
5382 /**************************/
5384 case 0x50 ... 0x57: /* push */
5385 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, (b
& 7) | REX_B(s
));
5386 gen_push_v(s
, s
->T0
);
5388 case 0x58 ... 0x5f: /* pop */
5390 /* NOTE: order is important for pop %sp */
5391 gen_pop_update(s
, ot
);
5392 gen_op_mov_reg_v(s
, ot
, (b
& 7) | REX_B(s
), s
->T0
);
5394 case 0x60: /* pusha */
5399 case 0x61: /* popa */
5404 case 0x68: /* push Iv */
5406 ot
= mo_pushpop(s
, dflag
);
5408 val
= insn_get(env
, s
, ot
);
5410 val
= (int8_t)insn_get(env
, s
, MO_8
);
5411 tcg_gen_movi_tl(s
->T0
, val
);
5412 gen_push_v(s
, s
->T0
);
5414 case 0x8f: /* pop Ev */
5415 modrm
= x86_ldub_code(env
, s
);
5416 mod
= (modrm
>> 6) & 3;
5419 /* NOTE: order is important for pop %sp */
5420 gen_pop_update(s
, ot
);
5421 rm
= (modrm
& 7) | REX_B(s
);
5422 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
5424 /* NOTE: order is important too for MMU exceptions */
5425 s
->popl_esp_hack
= 1 << ot
;
5426 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5427 s
->popl_esp_hack
= 0;
5428 gen_pop_update(s
, ot
);
5431 case 0xc8: /* enter */
5434 val
= x86_lduw_code(env
, s
);
5435 level
= x86_ldub_code(env
, s
);
5436 gen_enter(s
, val
, level
);
5439 case 0xc9: /* leave */
5442 case 0x06: /* push es */
5443 case 0x0e: /* push cs */
5444 case 0x16: /* push ss */
5445 case 0x1e: /* push ds */
5448 gen_op_movl_T0_seg(s
, b
>> 3);
5449 gen_push_v(s
, s
->T0
);
5451 case 0x1a0: /* push fs */
5452 case 0x1a8: /* push gs */
5453 gen_op_movl_T0_seg(s
, (b
>> 3) & 7);
5454 gen_push_v(s
, s
->T0
);
5456 case 0x07: /* pop es */
5457 case 0x17: /* pop ss */
5458 case 0x1f: /* pop ds */
5463 gen_movl_seg_T0(s
, reg
);
5464 gen_pop_update(s
, ot
);
5465 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5466 if (s
->base
.is_jmp
) {
5467 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
5470 gen_eob_inhibit_irq(s
, true);
5476 case 0x1a1: /* pop fs */
5477 case 0x1a9: /* pop gs */
5479 gen_movl_seg_T0(s
, (b
>> 3) & 7);
5480 gen_pop_update(s
, ot
);
5481 if (s
->base
.is_jmp
) {
5482 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
5487 /**************************/
5490 case 0x89: /* mov Gv, Ev */
5491 ot
= mo_b_d(b
, dflag
);
5492 modrm
= x86_ldub_code(env
, s
);
5493 reg
= ((modrm
>> 3) & 7) | rex_r
;
5495 /* generate a generic store */
5496 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
5499 case 0xc7: /* mov Ev, Iv */
5500 ot
= mo_b_d(b
, dflag
);
5501 modrm
= x86_ldub_code(env
, s
);
5502 mod
= (modrm
>> 6) & 3;
5504 s
->rip_offset
= insn_const_size(ot
);
5505 gen_lea_modrm(env
, s
, modrm
);
5507 val
= insn_get(env
, s
, ot
);
5508 tcg_gen_movi_tl(s
->T0
, val
);
5510 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
5512 gen_op_mov_reg_v(s
, ot
, (modrm
& 7) | REX_B(s
), s
->T0
);
5516 case 0x8b: /* mov Ev, Gv */
5517 ot
= mo_b_d(b
, dflag
);
5518 modrm
= x86_ldub_code(env
, s
);
5519 reg
= ((modrm
>> 3) & 7) | rex_r
;
5521 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5522 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
5524 case 0x8e: /* mov seg, Gv */
5525 modrm
= x86_ldub_code(env
, s
);
5526 reg
= (modrm
>> 3) & 7;
5527 if (reg
>= 6 || reg
== R_CS
)
5529 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
5530 gen_movl_seg_T0(s
, reg
);
5531 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5532 if (s
->base
.is_jmp
) {
5533 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
5536 gen_eob_inhibit_irq(s
, true);
5542 case 0x8c: /* mov Gv, seg */
5543 modrm
= x86_ldub_code(env
, s
);
5544 reg
= (modrm
>> 3) & 7;
5545 mod
= (modrm
>> 6) & 3;
5548 gen_op_movl_T0_seg(s
, reg
);
5549 ot
= mod
== 3 ? dflag
: MO_16
;
5550 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5553 case 0x1b6: /* movzbS Gv, Eb */
5554 case 0x1b7: /* movzwS Gv, Eb */
5555 case 0x1be: /* movsbS Gv, Eb */
5556 case 0x1bf: /* movswS Gv, Eb */
5561 /* d_ot is the size of destination */
5563 /* ot is the size of source */
5564 ot
= (b
& 1) + MO_8
;
5565 /* s_ot is the sign+size of source */
5566 s_ot
= b
& 8 ? MO_SIGN
| ot
: ot
;
5568 modrm
= x86_ldub_code(env
, s
);
5569 reg
= ((modrm
>> 3) & 7) | rex_r
;
5570 mod
= (modrm
>> 6) & 3;
5571 rm
= (modrm
& 7) | REX_B(s
);
5574 if (s_ot
== MO_SB
&& byte_reg_is_xH(s
, rm
)) {
5575 tcg_gen_sextract_tl(s
->T0
, cpu_regs
[rm
- 4], 8, 8);
5577 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
5580 tcg_gen_ext8u_tl(s
->T0
, s
->T0
);
5583 tcg_gen_ext8s_tl(s
->T0
, s
->T0
);
5586 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
5590 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5594 gen_op_mov_reg_v(s
, d_ot
, reg
, s
->T0
);
5596 gen_lea_modrm(env
, s
, modrm
);
5597 gen_op_ld_v(s
, s_ot
, s
->T0
, s
->A0
);
5598 gen_op_mov_reg_v(s
, d_ot
, reg
, s
->T0
);
5603 case 0x8d: /* lea */
5604 modrm
= x86_ldub_code(env
, s
);
5605 mod
= (modrm
>> 6) & 3;
5608 reg
= ((modrm
>> 3) & 7) | rex_r
;
5610 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
5611 TCGv ea
= gen_lea_modrm_1(s
, a
);
5612 gen_lea_v_seg(s
, s
->aflag
, ea
, -1, -1);
5613 gen_op_mov_reg_v(s
, dflag
, reg
, s
->A0
);
5617 case 0xa0: /* mov EAX, Ov */
5619 case 0xa2: /* mov Ov, EAX */
5622 target_ulong offset_addr
;
5624 ot
= mo_b_d(b
, dflag
);
5626 #ifdef TARGET_X86_64
5628 offset_addr
= x86_ldq_code(env
, s
);
5632 offset_addr
= insn_get(env
, s
, s
->aflag
);
5635 tcg_gen_movi_tl(s
->A0
, offset_addr
);
5636 gen_add_A0_ds_seg(s
);
5638 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
5639 gen_op_mov_reg_v(s
, ot
, R_EAX
, s
->T0
);
5641 gen_op_mov_v_reg(s
, ot
, s
->T0
, R_EAX
);
5642 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
5646 case 0xd7: /* xlat */
5647 tcg_gen_mov_tl(s
->A0
, cpu_regs
[R_EBX
]);
5648 tcg_gen_ext8u_tl(s
->T0
, cpu_regs
[R_EAX
]);
5649 tcg_gen_add_tl(s
->A0
, s
->A0
, s
->T0
);
5650 gen_extu(s
->aflag
, s
->A0
);
5651 gen_add_A0_ds_seg(s
);
5652 gen_op_ld_v(s
, MO_8
, s
->T0
, s
->A0
);
5653 gen_op_mov_reg_v(s
, MO_8
, R_EAX
, s
->T0
);
5655 case 0xb0 ... 0xb7: /* mov R, Ib */
5656 val
= insn_get(env
, s
, MO_8
);
5657 tcg_gen_movi_tl(s
->T0
, val
);
5658 gen_op_mov_reg_v(s
, MO_8
, (b
& 7) | REX_B(s
), s
->T0
);
5660 case 0xb8 ... 0xbf: /* mov R, Iv */
5661 #ifdef TARGET_X86_64
5662 if (dflag
== MO_64
) {
5665 tmp
= x86_ldq_code(env
, s
);
5666 reg
= (b
& 7) | REX_B(s
);
5667 tcg_gen_movi_tl(s
->T0
, tmp
);
5668 gen_op_mov_reg_v(s
, MO_64
, reg
, s
->T0
);
5673 val
= insn_get(env
, s
, ot
);
5674 reg
= (b
& 7) | REX_B(s
);
5675 tcg_gen_movi_tl(s
->T0
, val
);
5676 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
5680 case 0x91 ... 0x97: /* xchg R, EAX */
5683 reg
= (b
& 7) | REX_B(s
);
5687 case 0x87: /* xchg Ev, Gv */
5688 ot
= mo_b_d(b
, dflag
);
5689 modrm
= x86_ldub_code(env
, s
);
5690 reg
= ((modrm
>> 3) & 7) | rex_r
;
5691 mod
= (modrm
>> 6) & 3;
5693 rm
= (modrm
& 7) | REX_B(s
);
5695 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
5696 gen_op_mov_v_reg(s
, ot
, s
->T1
, rm
);
5697 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
5698 gen_op_mov_reg_v(s
, ot
, reg
, s
->T1
);
5700 gen_lea_modrm(env
, s
, modrm
);
5701 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
5702 /* for xchg, lock is implicit */
5703 tcg_gen_atomic_xchg_tl(s
->T1
, s
->A0
, s
->T0
,
5704 s
->mem_index
, ot
| MO_LE
);
5705 gen_op_mov_reg_v(s
, ot
, reg
, s
->T1
);
5708 case 0xc4: /* les Gv */
5709 /* In CODE64 this is VEX3; see above. */
5712 case 0xc5: /* lds Gv */
5713 /* In CODE64 this is VEX2; see above. */
5716 case 0x1b2: /* lss Gv */
5719 case 0x1b4: /* lfs Gv */
5722 case 0x1b5: /* lgs Gv */
5725 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
5726 modrm
= x86_ldub_code(env
, s
);
5727 reg
= ((modrm
>> 3) & 7) | rex_r
;
5728 mod
= (modrm
>> 6) & 3;
5731 gen_lea_modrm(env
, s
, modrm
);
5732 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
5733 gen_add_A0_im(s
, 1 << ot
);
5734 /* load the segment first to handle exceptions properly */
5735 gen_op_ld_v(s
, MO_16
, s
->T0
, s
->A0
);
5736 gen_movl_seg_T0(s
, op
);
5737 /* then put the data */
5738 gen_op_mov_reg_v(s
, ot
, reg
, s
->T1
);
5739 if (s
->base
.is_jmp
) {
5740 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
5745 /************************/
5753 ot
= mo_b_d(b
, dflag
);
5754 modrm
= x86_ldub_code(env
, s
);
5755 mod
= (modrm
>> 6) & 3;
5756 op
= (modrm
>> 3) & 7;
5762 gen_lea_modrm(env
, s
, modrm
);
5765 opreg
= (modrm
& 7) | REX_B(s
);
5770 gen_shift(s
, op
, ot
, opreg
, OR_ECX
);
5773 shift
= x86_ldub_code(env
, s
);
5775 gen_shifti(s
, op
, ot
, opreg
, shift
);
5790 case 0x1a4: /* shld imm */
5794 case 0x1a5: /* shld cl */
5798 case 0x1ac: /* shrd imm */
5802 case 0x1ad: /* shrd cl */
5807 modrm
= x86_ldub_code(env
, s
);
5808 mod
= (modrm
>> 6) & 3;
5809 rm
= (modrm
& 7) | REX_B(s
);
5810 reg
= ((modrm
>> 3) & 7) | rex_r
;
5812 gen_lea_modrm(env
, s
, modrm
);
5817 gen_op_mov_v_reg(s
, ot
, s
->T1
, reg
);
5820 TCGv imm
= tcg_const_tl(x86_ldub_code(env
, s
));
5821 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, imm
);
5824 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, cpu_regs
[R_ECX
]);
5828 /************************/
5831 if (s
->flags
& (HF_EM_MASK
| HF_TS_MASK
)) {
5832 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5833 /* XXX: what to do if illegal op ? */
5834 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
5837 modrm
= x86_ldub_code(env
, s
);
5838 mod
= (modrm
>> 6) & 3;
5840 op
= ((b
& 7) << 3) | ((modrm
>> 3) & 7);
5843 gen_lea_modrm(env
, s
, modrm
);
5845 case 0x00 ... 0x07: /* fxxxs */
5846 case 0x10 ... 0x17: /* fixxxl */
5847 case 0x20 ... 0x27: /* fxxxl */
5848 case 0x30 ... 0x37: /* fixxx */
5855 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
5856 s
->mem_index
, MO_LEUL
);
5857 gen_helper_flds_FT0(cpu_env
, s
->tmp2_i32
);
5860 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
5861 s
->mem_index
, MO_LEUL
);
5862 gen_helper_fildl_FT0(cpu_env
, s
->tmp2_i32
);
5865 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
,
5866 s
->mem_index
, MO_LEQ
);
5867 gen_helper_fldl_FT0(cpu_env
, s
->tmp1_i64
);
5871 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
5872 s
->mem_index
, MO_LESW
);
5873 gen_helper_fildl_FT0(cpu_env
, s
->tmp2_i32
);
5877 gen_helper_fp_arith_ST0_FT0(op1
);
5879 /* fcomp needs pop */
5880 gen_helper_fpop(cpu_env
);
5884 case 0x08: /* flds */
5885 case 0x0a: /* fsts */
5886 case 0x0b: /* fstps */
5887 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5888 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5889 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5894 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
5895 s
->mem_index
, MO_LEUL
);
5896 gen_helper_flds_ST0(cpu_env
, s
->tmp2_i32
);
5899 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
5900 s
->mem_index
, MO_LEUL
);
5901 gen_helper_fildl_ST0(cpu_env
, s
->tmp2_i32
);
5904 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
,
5905 s
->mem_index
, MO_LEQ
);
5906 gen_helper_fldl_ST0(cpu_env
, s
->tmp1_i64
);
5910 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
5911 s
->mem_index
, MO_LESW
);
5912 gen_helper_fildl_ST0(cpu_env
, s
->tmp2_i32
);
5917 /* XXX: the corresponding CPUID bit must be tested ! */
5920 gen_helper_fisttl_ST0(s
->tmp2_i32
, cpu_env
);
5921 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
5922 s
->mem_index
, MO_LEUL
);
5925 gen_helper_fisttll_ST0(s
->tmp1_i64
, cpu_env
);
5926 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
,
5927 s
->mem_index
, MO_LEQ
);
5931 gen_helper_fistt_ST0(s
->tmp2_i32
, cpu_env
);
5932 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
5933 s
->mem_index
, MO_LEUW
);
5936 gen_helper_fpop(cpu_env
);
5941 gen_helper_fsts_ST0(s
->tmp2_i32
, cpu_env
);
5942 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
5943 s
->mem_index
, MO_LEUL
);
5946 gen_helper_fistl_ST0(s
->tmp2_i32
, cpu_env
);
5947 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
5948 s
->mem_index
, MO_LEUL
);
5951 gen_helper_fstl_ST0(s
->tmp1_i64
, cpu_env
);
5952 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
,
5953 s
->mem_index
, MO_LEQ
);
5957 gen_helper_fist_ST0(s
->tmp2_i32
, cpu_env
);
5958 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
5959 s
->mem_index
, MO_LEUW
);
5963 gen_helper_fpop(cpu_env
);
5967 case 0x0c: /* fldenv mem */
5968 gen_helper_fldenv(cpu_env
, s
->A0
, tcg_const_i32(dflag
- 1));
5970 case 0x0d: /* fldcw mem */
5971 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
5972 s
->mem_index
, MO_LEUW
);
5973 gen_helper_fldcw(cpu_env
, s
->tmp2_i32
);
5975 case 0x0e: /* fnstenv mem */
5976 gen_helper_fstenv(cpu_env
, s
->A0
, tcg_const_i32(dflag
- 1));
5978 case 0x0f: /* fnstcw mem */
5979 gen_helper_fnstcw(s
->tmp2_i32
, cpu_env
);
5980 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
5981 s
->mem_index
, MO_LEUW
);
5983 case 0x1d: /* fldt mem */
5984 gen_helper_fldt_ST0(cpu_env
, s
->A0
);
5986 case 0x1f: /* fstpt mem */
5987 gen_helper_fstt_ST0(cpu_env
, s
->A0
);
5988 gen_helper_fpop(cpu_env
);
5990 case 0x2c: /* frstor mem */
5991 gen_helper_frstor(cpu_env
, s
->A0
, tcg_const_i32(dflag
- 1));
5993 case 0x2e: /* fnsave mem */
5994 gen_helper_fsave(cpu_env
, s
->A0
, tcg_const_i32(dflag
- 1));
5996 case 0x2f: /* fnstsw mem */
5997 gen_helper_fnstsw(s
->tmp2_i32
, cpu_env
);
5998 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
5999 s
->mem_index
, MO_LEUW
);
6001 case 0x3c: /* fbld */
6002 gen_helper_fbld_ST0(cpu_env
, s
->A0
);
6004 case 0x3e: /* fbstp */
6005 gen_helper_fbst_ST0(cpu_env
, s
->A0
);
6006 gen_helper_fpop(cpu_env
);
6008 case 0x3d: /* fildll */
6009 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
, s
->mem_index
, MO_LEQ
);
6010 gen_helper_fildll_ST0(cpu_env
, s
->tmp1_i64
);
6012 case 0x3f: /* fistpll */
6013 gen_helper_fistll_ST0(s
->tmp1_i64
, cpu_env
);
6014 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
, s
->mem_index
, MO_LEQ
);
6015 gen_helper_fpop(cpu_env
);
6021 /* register float ops */
6025 case 0x08: /* fld sti */
6026 gen_helper_fpush(cpu_env
);
6027 gen_helper_fmov_ST0_STN(cpu_env
,
6028 tcg_const_i32((opreg
+ 1) & 7));
6030 case 0x09: /* fxchg sti */
6031 case 0x29: /* fxchg4 sti, undocumented op */
6032 case 0x39: /* fxchg7 sti, undocumented op */
6033 gen_helper_fxchg_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6035 case 0x0a: /* grp d9/2 */
6038 /* check exceptions (FreeBSD FPU probe) */
6039 gen_helper_fwait(cpu_env
);
6045 case 0x0c: /* grp d9/4 */
6048 gen_helper_fchs_ST0(cpu_env
);
6051 gen_helper_fabs_ST0(cpu_env
);
6054 gen_helper_fldz_FT0(cpu_env
);
6055 gen_helper_fcom_ST0_FT0(cpu_env
);
6058 gen_helper_fxam_ST0(cpu_env
);
6064 case 0x0d: /* grp d9/5 */
6068 gen_helper_fpush(cpu_env
);
6069 gen_helper_fld1_ST0(cpu_env
);
6072 gen_helper_fpush(cpu_env
);
6073 gen_helper_fldl2t_ST0(cpu_env
);
6076 gen_helper_fpush(cpu_env
);
6077 gen_helper_fldl2e_ST0(cpu_env
);
6080 gen_helper_fpush(cpu_env
);
6081 gen_helper_fldpi_ST0(cpu_env
);
6084 gen_helper_fpush(cpu_env
);
6085 gen_helper_fldlg2_ST0(cpu_env
);
6088 gen_helper_fpush(cpu_env
);
6089 gen_helper_fldln2_ST0(cpu_env
);
6092 gen_helper_fpush(cpu_env
);
6093 gen_helper_fldz_ST0(cpu_env
);
6100 case 0x0e: /* grp d9/6 */
6103 gen_helper_f2xm1(cpu_env
);
6106 gen_helper_fyl2x(cpu_env
);
6109 gen_helper_fptan(cpu_env
);
6111 case 3: /* fpatan */
6112 gen_helper_fpatan(cpu_env
);
6114 case 4: /* fxtract */
6115 gen_helper_fxtract(cpu_env
);
6117 case 5: /* fprem1 */
6118 gen_helper_fprem1(cpu_env
);
6120 case 6: /* fdecstp */
6121 gen_helper_fdecstp(cpu_env
);
6124 case 7: /* fincstp */
6125 gen_helper_fincstp(cpu_env
);
6129 case 0x0f: /* grp d9/7 */
6132 gen_helper_fprem(cpu_env
);
6134 case 1: /* fyl2xp1 */
6135 gen_helper_fyl2xp1(cpu_env
);
6138 gen_helper_fsqrt(cpu_env
);
6140 case 3: /* fsincos */
6141 gen_helper_fsincos(cpu_env
);
6143 case 5: /* fscale */
6144 gen_helper_fscale(cpu_env
);
6146 case 4: /* frndint */
6147 gen_helper_frndint(cpu_env
);
6150 gen_helper_fsin(cpu_env
);
6154 gen_helper_fcos(cpu_env
);
6158 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6159 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6160 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6166 gen_helper_fp_arith_STN_ST0(op1
, opreg
);
6168 gen_helper_fpop(cpu_env
);
6170 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6171 gen_helper_fp_arith_ST0_FT0(op1
);
6175 case 0x02: /* fcom */
6176 case 0x22: /* fcom2, undocumented op */
6177 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6178 gen_helper_fcom_ST0_FT0(cpu_env
);
6180 case 0x03: /* fcomp */
6181 case 0x23: /* fcomp3, undocumented op */
6182 case 0x32: /* fcomp5, undocumented op */
6183 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6184 gen_helper_fcom_ST0_FT0(cpu_env
);
6185 gen_helper_fpop(cpu_env
);
6187 case 0x15: /* da/5 */
6189 case 1: /* fucompp */
6190 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6191 gen_helper_fucom_ST0_FT0(cpu_env
);
6192 gen_helper_fpop(cpu_env
);
6193 gen_helper_fpop(cpu_env
);
6201 case 0: /* feni (287 only, just do nop here) */
6203 case 1: /* fdisi (287 only, just do nop here) */
6206 gen_helper_fclex(cpu_env
);
6208 case 3: /* fninit */
6209 gen_helper_fninit(cpu_env
);
6211 case 4: /* fsetpm (287 only, just do nop here) */
6217 case 0x1d: /* fucomi */
6218 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6221 gen_update_cc_op(s
);
6222 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6223 gen_helper_fucomi_ST0_FT0(cpu_env
);
6224 set_cc_op(s
, CC_OP_EFLAGS
);
6226 case 0x1e: /* fcomi */
6227 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6230 gen_update_cc_op(s
);
6231 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6232 gen_helper_fcomi_ST0_FT0(cpu_env
);
6233 set_cc_op(s
, CC_OP_EFLAGS
);
6235 case 0x28: /* ffree sti */
6236 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6238 case 0x2a: /* fst sti */
6239 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6241 case 0x2b: /* fstp sti */
6242 case 0x0b: /* fstp1 sti, undocumented op */
6243 case 0x3a: /* fstp8 sti, undocumented op */
6244 case 0x3b: /* fstp9 sti, undocumented op */
6245 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6246 gen_helper_fpop(cpu_env
);
6248 case 0x2c: /* fucom st(i) */
6249 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6250 gen_helper_fucom_ST0_FT0(cpu_env
);
6252 case 0x2d: /* fucomp st(i) */
6253 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6254 gen_helper_fucom_ST0_FT0(cpu_env
);
6255 gen_helper_fpop(cpu_env
);
6257 case 0x33: /* de/3 */
6259 case 1: /* fcompp */
6260 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6261 gen_helper_fcom_ST0_FT0(cpu_env
);
6262 gen_helper_fpop(cpu_env
);
6263 gen_helper_fpop(cpu_env
);
6269 case 0x38: /* ffreep sti, undocumented op */
6270 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6271 gen_helper_fpop(cpu_env
);
6273 case 0x3c: /* df/4 */
6276 gen_helper_fnstsw(s
->tmp2_i32
, cpu_env
);
6277 tcg_gen_extu_i32_tl(s
->T0
, s
->tmp2_i32
);
6278 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
6284 case 0x3d: /* fucomip */
6285 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6288 gen_update_cc_op(s
);
6289 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6290 gen_helper_fucomi_ST0_FT0(cpu_env
);
6291 gen_helper_fpop(cpu_env
);
6292 set_cc_op(s
, CC_OP_EFLAGS
);
6294 case 0x3e: /* fcomip */
6295 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6298 gen_update_cc_op(s
);
6299 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6300 gen_helper_fcomi_ST0_FT0(cpu_env
);
6301 gen_helper_fpop(cpu_env
);
6302 set_cc_op(s
, CC_OP_EFLAGS
);
6304 case 0x10 ... 0x13: /* fcmovxx */
6309 static const uint8_t fcmov_cc
[8] = {
6316 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6319 op1
= fcmov_cc
[op
& 3] | (((op
>> 3) & 1) ^ 1);
6320 l1
= gen_new_label();
6321 gen_jcc1_noeob(s
, op1
, l1
);
6322 gen_helper_fmov_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6331 /************************/
6334 case 0xa4: /* movsS */
6336 ot
= mo_b_d(b
, dflag
);
6337 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6338 gen_repz_movs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6344 case 0xaa: /* stosS */
6346 ot
= mo_b_d(b
, dflag
);
6347 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6348 gen_repz_stos(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6353 case 0xac: /* lodsS */
6355 ot
= mo_b_d(b
, dflag
);
6356 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6357 gen_repz_lods(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6362 case 0xae: /* scasS */
6364 ot
= mo_b_d(b
, dflag
);
6365 if (prefixes
& PREFIX_REPNZ
) {
6366 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6367 } else if (prefixes
& PREFIX_REPZ
) {
6368 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6374 case 0xa6: /* cmpsS */
6376 ot
= mo_b_d(b
, dflag
);
6377 if (prefixes
& PREFIX_REPNZ
) {
6378 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6379 } else if (prefixes
& PREFIX_REPZ
) {
6380 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6385 case 0x6c: /* insS */
6387 ot
= mo_b_d32(b
, dflag
);
6388 tcg_gen_ext16u_tl(s
->T0
, cpu_regs
[R_EDX
]);
6389 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6390 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
) | 4);
6391 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6394 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6395 gen_repz_ins(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6396 /* jump generated by gen_repz_ins */
6399 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6400 gen_jmp(s
, s
->pc
- s
->cs_base
);
6404 case 0x6e: /* outsS */
6406 ot
= mo_b_d32(b
, dflag
);
6407 tcg_gen_ext16u_tl(s
->T0
, cpu_regs
[R_EDX
]);
6408 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6409 svm_is_rep(prefixes
) | 4);
6410 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6413 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6414 gen_repz_outs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6415 /* jump generated by gen_repz_outs */
6418 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6419 gen_jmp(s
, s
->pc
- s
->cs_base
);
6424 /************************/
6429 ot
= mo_b_d32(b
, dflag
);
6430 val
= x86_ldub_code(env
, s
);
6431 tcg_gen_movi_tl(s
->T0
, val
);
6432 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6433 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6434 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6437 tcg_gen_movi_i32(s
->tmp2_i32
, val
);
6438 gen_helper_in_func(ot
, s
->T1
, s
->tmp2_i32
);
6439 gen_op_mov_reg_v(s
, ot
, R_EAX
, s
->T1
);
6440 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
6441 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6442 gen_jmp(s
, s
->pc
- s
->cs_base
);
6447 ot
= mo_b_d32(b
, dflag
);
6448 val
= x86_ldub_code(env
, s
);
6449 tcg_gen_movi_tl(s
->T0
, val
);
6450 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6451 svm_is_rep(prefixes
));
6452 gen_op_mov_v_reg(s
, ot
, s
->T1
, R_EAX
);
6454 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6457 tcg_gen_movi_i32(s
->tmp2_i32
, val
);
6458 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, s
->T1
);
6459 gen_helper_out_func(ot
, s
->tmp2_i32
, s
->tmp3_i32
);
6460 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
6461 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6462 gen_jmp(s
, s
->pc
- s
->cs_base
);
6467 ot
= mo_b_d32(b
, dflag
);
6468 tcg_gen_ext16u_tl(s
->T0
, cpu_regs
[R_EDX
]);
6469 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6470 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6471 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6474 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
6475 gen_helper_in_func(ot
, s
->T1
, s
->tmp2_i32
);
6476 gen_op_mov_reg_v(s
, ot
, R_EAX
, s
->T1
);
6477 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
6478 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6479 gen_jmp(s
, s
->pc
- s
->cs_base
);
6484 ot
= mo_b_d32(b
, dflag
);
6485 tcg_gen_ext16u_tl(s
->T0
, cpu_regs
[R_EDX
]);
6486 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6487 svm_is_rep(prefixes
));
6488 gen_op_mov_v_reg(s
, ot
, s
->T1
, R_EAX
);
6490 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6493 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
6494 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, s
->T1
);
6495 gen_helper_out_func(ot
, s
->tmp2_i32
, s
->tmp3_i32
);
6496 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
6497 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6498 gen_jmp(s
, s
->pc
- s
->cs_base
);
6502 /************************/
6504 case 0xc2: /* ret im */
6505 val
= x86_ldsw_code(env
, s
);
6507 gen_stack_update(s
, val
+ (1 << ot
));
6508 /* Note that gen_pop_T0 uses a zero-extending load. */
6509 gen_op_jmp_v(s
->T0
);
6513 case 0xc3: /* ret */
6515 gen_pop_update(s
, ot
);
6516 /* Note that gen_pop_T0 uses a zero-extending load. */
6517 gen_op_jmp_v(s
->T0
);
6521 case 0xca: /* lret im */
6522 val
= x86_ldsw_code(env
, s
);
6524 if (s
->pe
&& !s
->vm86
) {
6525 gen_update_cc_op(s
);
6526 gen_jmp_im(s
, pc_start
- s
->cs_base
);
6527 gen_helper_lret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6528 tcg_const_i32(val
));
6532 gen_op_ld_v(s
, dflag
, s
->T0
, s
->A0
);
6533 /* NOTE: keeping EIP updated is not a problem in case of
6535 gen_op_jmp_v(s
->T0
);
6537 gen_add_A0_im(s
, 1 << dflag
);
6538 gen_op_ld_v(s
, dflag
, s
->T0
, s
->A0
);
6539 gen_op_movl_seg_T0_vm(s
, R_CS
);
6540 /* add stack offset */
6541 gen_stack_update(s
, val
+ (2 << dflag
));
6545 case 0xcb: /* lret */
6548 case 0xcf: /* iret */
6549 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IRET
);
6552 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6553 set_cc_op(s
, CC_OP_EFLAGS
);
6554 } else if (s
->vm86
) {
6556 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6558 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6559 set_cc_op(s
, CC_OP_EFLAGS
);
6562 gen_helper_iret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6563 tcg_const_i32(s
->pc
- s
->cs_base
));
6564 set_cc_op(s
, CC_OP_EFLAGS
);
6568 case 0xe8: /* call im */
6570 if (dflag
!= MO_16
) {
6571 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6573 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6575 next_eip
= s
->pc
- s
->cs_base
;
6577 if (dflag
== MO_16
) {
6579 } else if (!CODE64(s
)) {
6582 tcg_gen_movi_tl(s
->T0
, next_eip
);
6583 gen_push_v(s
, s
->T0
);
6588 case 0x9a: /* lcall im */
6590 unsigned int selector
, offset
;
6595 offset
= insn_get(env
, s
, ot
);
6596 selector
= insn_get(env
, s
, MO_16
);
6598 tcg_gen_movi_tl(s
->T0
, selector
);
6599 tcg_gen_movi_tl(s
->T1
, offset
);
6602 case 0xe9: /* jmp im */
6603 if (dflag
!= MO_16
) {
6604 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6606 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6608 tval
+= s
->pc
- s
->cs_base
;
6609 if (dflag
== MO_16
) {
6611 } else if (!CODE64(s
)) {
6617 case 0xea: /* ljmp im */
6619 unsigned int selector
, offset
;
6624 offset
= insn_get(env
, s
, ot
);
6625 selector
= insn_get(env
, s
, MO_16
);
6627 tcg_gen_movi_tl(s
->T0
, selector
);
6628 tcg_gen_movi_tl(s
->T1
, offset
);
6631 case 0xeb: /* jmp Jb */
6632 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6633 tval
+= s
->pc
- s
->cs_base
;
6634 if (dflag
== MO_16
) {
6639 case 0x70 ... 0x7f: /* jcc Jb */
6640 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6642 case 0x180 ... 0x18f: /* jcc Jv */
6643 if (dflag
!= MO_16
) {
6644 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6646 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6649 next_eip
= s
->pc
- s
->cs_base
;
6651 if (dflag
== MO_16
) {
6655 gen_jcc(s
, b
, tval
, next_eip
);
6658 case 0x190 ... 0x19f: /* setcc Gv */
6659 modrm
= x86_ldub_code(env
, s
);
6660 gen_setcc1(s
, b
, s
->T0
);
6661 gen_ldst_modrm(env
, s
, modrm
, MO_8
, OR_TMP0
, 1);
6663 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6664 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6668 modrm
= x86_ldub_code(env
, s
);
6669 reg
= ((modrm
>> 3) & 7) | rex_r
;
6670 gen_cmovcc1(env
, s
, ot
, b
, modrm
, reg
);
6673 /************************/
6675 case 0x9c: /* pushf */
6676 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_PUSHF
);
6677 if (s
->vm86
&& s
->iopl
!= 3) {
6678 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6680 gen_update_cc_op(s
);
6681 gen_helper_read_eflags(s
->T0
, cpu_env
);
6682 gen_push_v(s
, s
->T0
);
6685 case 0x9d: /* popf */
6686 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_POPF
);
6687 if (s
->vm86
&& s
->iopl
!= 3) {
6688 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6692 if (dflag
!= MO_16
) {
6693 gen_helper_write_eflags(cpu_env
, s
->T0
,
6694 tcg_const_i32((TF_MASK
| AC_MASK
|
6699 gen_helper_write_eflags(cpu_env
, s
->T0
,
6700 tcg_const_i32((TF_MASK
| AC_MASK
|
6702 IF_MASK
| IOPL_MASK
)
6706 if (s
->cpl
<= s
->iopl
) {
6707 if (dflag
!= MO_16
) {
6708 gen_helper_write_eflags(cpu_env
, s
->T0
,
6709 tcg_const_i32((TF_MASK
|
6715 gen_helper_write_eflags(cpu_env
, s
->T0
,
6716 tcg_const_i32((TF_MASK
|
6724 if (dflag
!= MO_16
) {
6725 gen_helper_write_eflags(cpu_env
, s
->T0
,
6726 tcg_const_i32((TF_MASK
| AC_MASK
|
6727 ID_MASK
| NT_MASK
)));
6729 gen_helper_write_eflags(cpu_env
, s
->T0
,
6730 tcg_const_i32((TF_MASK
| AC_MASK
|
6736 gen_pop_update(s
, ot
);
6737 set_cc_op(s
, CC_OP_EFLAGS
);
6738 /* abort translation because TF/AC flag may change */
6739 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
6743 case 0x9e: /* sahf */
6744 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6746 gen_op_mov_v_reg(s
, MO_8
, s
->T0
, R_AH
);
6747 gen_compute_eflags(s
);
6748 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, CC_O
);
6749 tcg_gen_andi_tl(s
->T0
, s
->T0
, CC_S
| CC_Z
| CC_A
| CC_P
| CC_C
);
6750 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, s
->T0
);
6752 case 0x9f: /* lahf */
6753 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6755 gen_compute_eflags(s
);
6756 /* Note: gen_compute_eflags() only gives the condition codes */
6757 tcg_gen_ori_tl(s
->T0
, cpu_cc_src
, 0x02);
6758 gen_op_mov_reg_v(s
, MO_8
, R_AH
, s
->T0
);
6760 case 0xf5: /* cmc */
6761 gen_compute_eflags(s
);
6762 tcg_gen_xori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6764 case 0xf8: /* clc */
6765 gen_compute_eflags(s
);
6766 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_C
);
6768 case 0xf9: /* stc */
6769 gen_compute_eflags(s
);
6770 tcg_gen_ori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6772 case 0xfc: /* cld */
6773 tcg_gen_movi_i32(s
->tmp2_i32
, 1);
6774 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6776 case 0xfd: /* std */
6777 tcg_gen_movi_i32(s
->tmp2_i32
, -1);
6778 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6781 /************************/
6782 /* bit operations */
6783 case 0x1ba: /* bt/bts/btr/btc Gv, im */
6785 modrm
= x86_ldub_code(env
, s
);
6786 op
= (modrm
>> 3) & 7;
6787 mod
= (modrm
>> 6) & 3;
6788 rm
= (modrm
& 7) | REX_B(s
);
6791 gen_lea_modrm(env
, s
, modrm
);
6792 if (!(s
->prefix
& PREFIX_LOCK
)) {
6793 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
6796 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
6799 val
= x86_ldub_code(env
, s
);
6800 tcg_gen_movi_tl(s
->T1
, val
);
6805 case 0x1a3: /* bt Gv, Ev */
6808 case 0x1ab: /* bts */
6811 case 0x1b3: /* btr */
6814 case 0x1bb: /* btc */
6818 modrm
= x86_ldub_code(env
, s
);
6819 reg
= ((modrm
>> 3) & 7) | rex_r
;
6820 mod
= (modrm
>> 6) & 3;
6821 rm
= (modrm
& 7) | REX_B(s
);
6822 gen_op_mov_v_reg(s
, MO_32
, s
->T1
, reg
);
6824 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
6825 /* specific case: we need to add a displacement */
6826 gen_exts(ot
, s
->T1
);
6827 tcg_gen_sari_tl(s
->tmp0
, s
->T1
, 3 + ot
);
6828 tcg_gen_shli_tl(s
->tmp0
, s
->tmp0
, ot
);
6829 tcg_gen_add_tl(s
->A0
, gen_lea_modrm_1(s
, a
), s
->tmp0
);
6830 gen_lea_v_seg(s
, s
->aflag
, s
->A0
, a
.def_seg
, s
->override
);
6831 if (!(s
->prefix
& PREFIX_LOCK
)) {
6832 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
6835 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
6838 tcg_gen_andi_tl(s
->T1
, s
->T1
, (1 << (3 + ot
)) - 1);
6839 tcg_gen_movi_tl(s
->tmp0
, 1);
6840 tcg_gen_shl_tl(s
->tmp0
, s
->tmp0
, s
->T1
);
6841 if (s
->prefix
& PREFIX_LOCK
) {
6844 /* Needs no atomic ops; we surpressed the normal
6845 memory load for LOCK above so do it now. */
6846 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
6849 tcg_gen_atomic_fetch_or_tl(s
->T0
, s
->A0
, s
->tmp0
,
6850 s
->mem_index
, ot
| MO_LE
);
6853 tcg_gen_not_tl(s
->tmp0
, s
->tmp0
);
6854 tcg_gen_atomic_fetch_and_tl(s
->T0
, s
->A0
, s
->tmp0
,
6855 s
->mem_index
, ot
| MO_LE
);
6859 tcg_gen_atomic_fetch_xor_tl(s
->T0
, s
->A0
, s
->tmp0
,
6860 s
->mem_index
, ot
| MO_LE
);
6863 tcg_gen_shr_tl(s
->tmp4
, s
->T0
, s
->T1
);
6865 tcg_gen_shr_tl(s
->tmp4
, s
->T0
, s
->T1
);
6868 /* Data already loaded; nothing to do. */
6871 tcg_gen_or_tl(s
->T0
, s
->T0
, s
->tmp0
);
6874 tcg_gen_andc_tl(s
->T0
, s
->T0
, s
->tmp0
);
6878 tcg_gen_xor_tl(s
->T0
, s
->T0
, s
->tmp0
);
6883 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
6885 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
6890 /* Delay all CC updates until after the store above. Note that
6891 C is the result of the test, Z is unchanged, and the others
6892 are all undefined. */
6894 case CC_OP_MULB
... CC_OP_MULQ
:
6895 case CC_OP_ADDB
... CC_OP_ADDQ
:
6896 case CC_OP_ADCB
... CC_OP_ADCQ
:
6897 case CC_OP_SUBB
... CC_OP_SUBQ
:
6898 case CC_OP_SBBB
... CC_OP_SBBQ
:
6899 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
6900 case CC_OP_INCB
... CC_OP_INCQ
:
6901 case CC_OP_DECB
... CC_OP_DECQ
:
6902 case CC_OP_SHLB
... CC_OP_SHLQ
:
6903 case CC_OP_SARB
... CC_OP_SARQ
:
6904 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
6905 /* Z was going to be computed from the non-zero status of CC_DST.
6906 We can get that same Z value (and the new C value) by leaving
6907 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
6909 tcg_gen_mov_tl(cpu_cc_src
, s
->tmp4
);
6910 set_cc_op(s
, ((s
->cc_op
- CC_OP_MULB
) & 3) + CC_OP_SARB
);
6913 /* Otherwise, generate EFLAGS and replace the C bit. */
6914 gen_compute_eflags(s
);
6915 tcg_gen_deposit_tl(cpu_cc_src
, cpu_cc_src
, s
->tmp4
,
6920 case 0x1bc: /* bsf / tzcnt */
6921 case 0x1bd: /* bsr / lzcnt */
6923 modrm
= x86_ldub_code(env
, s
);
6924 reg
= ((modrm
>> 3) & 7) | rex_r
;
6925 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
6926 gen_extu(ot
, s
->T0
);
6928 /* Note that lzcnt and tzcnt are in different extensions. */
6929 if ((prefixes
& PREFIX_REPZ
)
6931 ? s
->cpuid_ext3_features
& CPUID_EXT3_ABM
6932 : s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)) {
6934 /* For lzcnt/tzcnt, C bit is defined related to the input. */
6935 tcg_gen_mov_tl(cpu_cc_src
, s
->T0
);
6937 /* For lzcnt, reduce the target_ulong result by the
6938 number of zeros that we expect to find at the top. */
6939 tcg_gen_clzi_tl(s
->T0
, s
->T0
, TARGET_LONG_BITS
);
6940 tcg_gen_subi_tl(s
->T0
, s
->T0
, TARGET_LONG_BITS
- size
);
6942 /* For tzcnt, a zero input must return the operand size. */
6943 tcg_gen_ctzi_tl(s
->T0
, s
->T0
, size
);
6945 /* For lzcnt/tzcnt, Z bit is defined related to the result. */
6946 gen_op_update1_cc(s
);
6947 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
6949 /* For bsr/bsf, only the Z bit is defined and it is related
6950 to the input and not the result. */
6951 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
6952 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
6954 /* ??? The manual says that the output is undefined when the
6955 input is zero, but real hardware leaves it unchanged, and
6956 real programs appear to depend on that. Accomplish this
6957 by passing the output as the value to return upon zero. */
6959 /* For bsr, return the bit index of the first 1 bit,
6960 not the count of leading zeros. */
6961 tcg_gen_xori_tl(s
->T1
, cpu_regs
[reg
], TARGET_LONG_BITS
- 1);
6962 tcg_gen_clz_tl(s
->T0
, s
->T0
, s
->T1
);
6963 tcg_gen_xori_tl(s
->T0
, s
->T0
, TARGET_LONG_BITS
- 1);
6965 tcg_gen_ctz_tl(s
->T0
, s
->T0
, cpu_regs
[reg
]);
6968 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
6970 /************************/
6972 case 0x27: /* daa */
6975 gen_update_cc_op(s
);
6976 gen_helper_daa(cpu_env
);
6977 set_cc_op(s
, CC_OP_EFLAGS
);
6979 case 0x2f: /* das */
6982 gen_update_cc_op(s
);
6983 gen_helper_das(cpu_env
);
6984 set_cc_op(s
, CC_OP_EFLAGS
);
6986 case 0x37: /* aaa */
6989 gen_update_cc_op(s
);
6990 gen_helper_aaa(cpu_env
);
6991 set_cc_op(s
, CC_OP_EFLAGS
);
6993 case 0x3f: /* aas */
6996 gen_update_cc_op(s
);
6997 gen_helper_aas(cpu_env
);
6998 set_cc_op(s
, CC_OP_EFLAGS
);
7000 case 0xd4: /* aam */
7003 val
= x86_ldub_code(env
, s
);
7005 gen_exception(s
, EXCP00_DIVZ
, pc_start
- s
->cs_base
);
7007 gen_helper_aam(cpu_env
, tcg_const_i32(val
));
7008 set_cc_op(s
, CC_OP_LOGICB
);
7011 case 0xd5: /* aad */
7014 val
= x86_ldub_code(env
, s
);
7015 gen_helper_aad(cpu_env
, tcg_const_i32(val
));
7016 set_cc_op(s
, CC_OP_LOGICB
);
7018 /************************/
7020 case 0x90: /* nop */
7021 /* XXX: correct lock test for all insn */
7022 if (prefixes
& PREFIX_LOCK
) {
7025 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
7027 goto do_xchg_reg_eax
;
7029 if (prefixes
& PREFIX_REPZ
) {
7030 gen_update_cc_op(s
);
7031 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7032 gen_helper_pause(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7033 s
->base
.is_jmp
= DISAS_NORETURN
;
7036 case 0x9b: /* fwait */
7037 if ((s
->flags
& (HF_MP_MASK
| HF_TS_MASK
)) ==
7038 (HF_MP_MASK
| HF_TS_MASK
)) {
7039 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7041 gen_helper_fwait(cpu_env
);
7044 case 0xcc: /* int3 */
7045 gen_interrupt(s
, EXCP03_INT3
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
7047 case 0xcd: /* int N */
7048 val
= x86_ldub_code(env
, s
);
7049 if (s
->vm86
&& s
->iopl
!= 3) {
7050 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7052 gen_interrupt(s
, val
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
7055 case 0xce: /* into */
7058 gen_update_cc_op(s
);
7059 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7060 gen_helper_into(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7063 case 0xf1: /* icebp (undocumented, exits to external debugger) */
7064 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_ICEBP
);
7065 gen_debug(s
, pc_start
- s
->cs_base
);
7068 case 0xfa: /* cli */
7070 if (s
->cpl
<= s
->iopl
) {
7071 gen_helper_cli(cpu_env
);
7073 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7077 gen_helper_cli(cpu_env
);
7079 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7083 case 0xfb: /* sti */
7084 if (s
->vm86
? s
->iopl
== 3 : s
->cpl
<= s
->iopl
) {
7085 gen_helper_sti(cpu_env
);
7086 /* interruptions are enabled only the first insn after sti */
7087 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7088 gen_eob_inhibit_irq(s
, true);
7090 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7093 case 0x62: /* bound */
7097 modrm
= x86_ldub_code(env
, s
);
7098 reg
= (modrm
>> 3) & 7;
7099 mod
= (modrm
>> 6) & 3;
7102 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
7103 gen_lea_modrm(env
, s
, modrm
);
7104 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
7106 gen_helper_boundw(cpu_env
, s
->A0
, s
->tmp2_i32
);
7108 gen_helper_boundl(cpu_env
, s
->A0
, s
->tmp2_i32
);
7111 case 0x1c8 ... 0x1cf: /* bswap reg */
7112 reg
= (b
& 7) | REX_B(s
);
7113 #ifdef TARGET_X86_64
7114 if (dflag
== MO_64
) {
7115 gen_op_mov_v_reg(s
, MO_64
, s
->T0
, reg
);
7116 tcg_gen_bswap64_i64(s
->T0
, s
->T0
);
7117 gen_op_mov_reg_v(s
, MO_64
, reg
, s
->T0
);
7121 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, reg
);
7122 tcg_gen_ext32u_tl(s
->T0
, s
->T0
);
7123 tcg_gen_bswap32_tl(s
->T0
, s
->T0
);
7124 gen_op_mov_reg_v(s
, MO_32
, reg
, s
->T0
);
7127 case 0xd6: /* salc */
7130 gen_compute_eflags_c(s
, s
->T0
);
7131 tcg_gen_neg_tl(s
->T0
, s
->T0
);
7132 gen_op_mov_reg_v(s
, MO_8
, R_EAX
, s
->T0
);
7134 case 0xe0: /* loopnz */
7135 case 0xe1: /* loopz */
7136 case 0xe2: /* loop */
7137 case 0xe3: /* jecxz */
7139 TCGLabel
*l1
, *l2
, *l3
;
7141 tval
= (int8_t)insn_get(env
, s
, MO_8
);
7142 next_eip
= s
->pc
- s
->cs_base
;
7144 if (dflag
== MO_16
) {
7148 l1
= gen_new_label();
7149 l2
= gen_new_label();
7150 l3
= gen_new_label();
7151 gen_update_cc_op(s
);
7154 case 0: /* loopnz */
7156 gen_op_add_reg_im(s
, s
->aflag
, R_ECX
, -1);
7157 gen_op_jz_ecx(s
, s
->aflag
, l3
);
7158 gen_jcc1(s
, (JCC_Z
<< 1) | (b
^ 1), l1
);
7161 gen_op_add_reg_im(s
, s
->aflag
, R_ECX
, -1);
7162 gen_op_jnz_ecx(s
, s
->aflag
, l1
);
7166 gen_op_jz_ecx(s
, s
->aflag
, l1
);
7171 gen_jmp_im(s
, next_eip
);
7175 gen_jmp_im(s
, tval
);
7180 case 0x130: /* wrmsr */
7181 case 0x132: /* rdmsr */
7183 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7185 gen_update_cc_op(s
);
7186 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7188 gen_helper_rdmsr(cpu_env
);
7190 gen_helper_wrmsr(cpu_env
);
7194 case 0x131: /* rdtsc */
7195 gen_update_cc_op(s
);
7196 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7197 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7200 gen_helper_rdtsc(cpu_env
);
7201 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7202 gen_jmp(s
, s
->pc
- s
->cs_base
);
7205 case 0x133: /* rdpmc */
7206 gen_update_cc_op(s
);
7207 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7208 gen_helper_rdpmc(cpu_env
);
7210 case 0x134: /* sysenter */
7211 /* For Intel SYSENTER is valid on 64-bit */
7212 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7215 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7217 gen_helper_sysenter(cpu_env
);
7221 case 0x135: /* sysexit */
7222 /* For Intel SYSEXIT is valid on 64-bit */
7223 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7226 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7228 gen_helper_sysexit(cpu_env
, tcg_const_i32(dflag
- 1));
7232 #ifdef TARGET_X86_64
7233 case 0x105: /* syscall */
7234 /* XXX: is it usable in real mode ? */
7235 gen_update_cc_op(s
);
7236 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7237 gen_helper_syscall(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7238 /* TF handling for the syscall insn is different. The TF bit is checked
7239 after the syscall insn completes. This allows #DB to not be
7240 generated after one has entered CPL0 if TF is set in FMASK. */
7241 gen_eob_worker(s
, false, true);
7243 case 0x107: /* sysret */
7245 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7247 gen_helper_sysret(cpu_env
, tcg_const_i32(dflag
- 1));
7248 /* condition codes are modified only in long mode */
7250 set_cc_op(s
, CC_OP_EFLAGS
);
7252 /* TF handling for the sysret insn is different. The TF bit is
7253 checked after the sysret insn completes. This allows #DB to be
7254 generated "as if" the syscall insn in userspace has just
7256 gen_eob_worker(s
, false, true);
7260 case 0x1a2: /* cpuid */
7261 gen_update_cc_op(s
);
7262 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7263 gen_helper_cpuid(cpu_env
);
7265 case 0xf4: /* hlt */
7267 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7269 gen_update_cc_op(s
);
7270 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7271 gen_helper_hlt(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7272 s
->base
.is_jmp
= DISAS_NORETURN
;
7276 modrm
= x86_ldub_code(env
, s
);
7277 mod
= (modrm
>> 6) & 3;
7278 op
= (modrm
>> 3) & 7;
7281 if (!s
->pe
|| s
->vm86
)
7283 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_READ
);
7284 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
7285 offsetof(CPUX86State
, ldt
.selector
));
7286 ot
= mod
== 3 ? dflag
: MO_16
;
7287 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7290 if (!s
->pe
|| s
->vm86
)
7293 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7295 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_WRITE
);
7296 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7297 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
7298 gen_helper_lldt(cpu_env
, s
->tmp2_i32
);
7302 if (!s
->pe
|| s
->vm86
)
7304 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_READ
);
7305 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
7306 offsetof(CPUX86State
, tr
.selector
));
7307 ot
= mod
== 3 ? dflag
: MO_16
;
7308 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7311 if (!s
->pe
|| s
->vm86
)
7314 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7316 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_WRITE
);
7317 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7318 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
7319 gen_helper_ltr(cpu_env
, s
->tmp2_i32
);
7324 if (!s
->pe
|| s
->vm86
)
7326 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7327 gen_update_cc_op(s
);
7329 gen_helper_verr(cpu_env
, s
->T0
);
7331 gen_helper_verw(cpu_env
, s
->T0
);
7333 set_cc_op(s
, CC_OP_EFLAGS
);
7341 modrm
= x86_ldub_code(env
, s
);
7343 CASE_MODRM_MEM_OP(0): /* sgdt */
7344 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_READ
);
7345 gen_lea_modrm(env
, s
, modrm
);
7346 tcg_gen_ld32u_tl(s
->T0
,
7347 cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7348 gen_op_st_v(s
, MO_16
, s
->T0
, s
->A0
);
7349 gen_add_A0_im(s
, 2);
7350 tcg_gen_ld_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7351 if (dflag
== MO_16
) {
7352 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xffffff);
7354 gen_op_st_v(s
, CODE64(s
) + MO_32
, s
->T0
, s
->A0
);
7357 case 0xc8: /* monitor */
7358 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) || s
->cpl
!= 0) {
7361 gen_update_cc_op(s
);
7362 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7363 tcg_gen_mov_tl(s
->A0
, cpu_regs
[R_EAX
]);
7364 gen_extu(s
->aflag
, s
->A0
);
7365 gen_add_A0_ds_seg(s
);
7366 gen_helper_monitor(cpu_env
, s
->A0
);
7369 case 0xc9: /* mwait */
7370 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) || s
->cpl
!= 0) {
7373 gen_update_cc_op(s
);
7374 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7375 gen_helper_mwait(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7379 case 0xca: /* clac */
7380 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
)
7384 gen_helper_clac(cpu_env
);
7385 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7389 case 0xcb: /* stac */
7390 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
)
7394 gen_helper_stac(cpu_env
);
7395 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7399 CASE_MODRM_MEM_OP(1): /* sidt */
7400 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_READ
);
7401 gen_lea_modrm(env
, s
, modrm
);
7402 tcg_gen_ld32u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7403 gen_op_st_v(s
, MO_16
, s
->T0
, s
->A0
);
7404 gen_add_A0_im(s
, 2);
7405 tcg_gen_ld_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, idt
.base
));
7406 if (dflag
== MO_16
) {
7407 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xffffff);
7409 gen_op_st_v(s
, CODE64(s
) + MO_32
, s
->T0
, s
->A0
);
7412 case 0xd0: /* xgetbv */
7413 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
7414 || (s
->prefix
& (PREFIX_LOCK
| PREFIX_DATA
7415 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
7418 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_ECX
]);
7419 gen_helper_xgetbv(s
->tmp1_i64
, cpu_env
, s
->tmp2_i32
);
7420 tcg_gen_extr_i64_tl(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
], s
->tmp1_i64
);
7423 case 0xd1: /* xsetbv */
7424 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
7425 || (s
->prefix
& (PREFIX_LOCK
| PREFIX_DATA
7426 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
7430 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7433 tcg_gen_concat_tl_i64(s
->tmp1_i64
, cpu_regs
[R_EAX
],
7435 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_ECX
]);
7436 gen_helper_xsetbv(cpu_env
, s
->tmp2_i32
, s
->tmp1_i64
);
7437 /* End TB because translation flags may change. */
7438 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7442 case 0xd8: /* VMRUN */
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(s
, pc_start
- s
->cs_base
);
7452 gen_helper_vmrun(cpu_env
, tcg_const_i32(s
->aflag
- 1),
7453 tcg_const_i32(s
->pc
- pc_start
));
7454 tcg_gen_exit_tb(NULL
, 0);
7455 s
->base
.is_jmp
= DISAS_NORETURN
;
7458 case 0xd9: /* VMMCALL */
7459 if (!(s
->flags
& HF_SVME_MASK
)) {
7462 gen_update_cc_op(s
);
7463 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7464 gen_helper_vmmcall(cpu_env
);
7467 case 0xda: /* VMLOAD */
7468 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7472 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7475 gen_update_cc_op(s
);
7476 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7477 gen_helper_vmload(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7480 case 0xdb: /* VMSAVE */
7481 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7485 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7488 gen_update_cc_op(s
);
7489 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7490 gen_helper_vmsave(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7493 case 0xdc: /* STGI */
7494 if ((!(s
->flags
& HF_SVME_MASK
)
7495 && !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
))
7500 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7503 gen_update_cc_op(s
);
7504 gen_helper_stgi(cpu_env
);
7505 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7509 case 0xdd: /* CLGI */
7510 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7514 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7517 gen_update_cc_op(s
);
7518 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7519 gen_helper_clgi(cpu_env
);
7522 case 0xde: /* SKINIT */
7523 if ((!(s
->flags
& HF_SVME_MASK
)
7524 && !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
))
7528 gen_update_cc_op(s
);
7529 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7530 gen_helper_skinit(cpu_env
);
7533 case 0xdf: /* INVLPGA */
7534 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7538 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7541 gen_update_cc_op(s
);
7542 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7543 gen_helper_invlpga(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7546 CASE_MODRM_MEM_OP(2): /* lgdt */
7548 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7551 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_WRITE
);
7552 gen_lea_modrm(env
, s
, modrm
);
7553 gen_op_ld_v(s
, MO_16
, s
->T1
, s
->A0
);
7554 gen_add_A0_im(s
, 2);
7555 gen_op_ld_v(s
, CODE64(s
) + MO_32
, s
->T0
, s
->A0
);
7556 if (dflag
== MO_16
) {
7557 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xffffff);
7559 tcg_gen_st_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7560 tcg_gen_st32_tl(s
->T1
, cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7563 CASE_MODRM_MEM_OP(3): /* lidt */
7565 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7568 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_WRITE
);
7569 gen_lea_modrm(env
, s
, modrm
);
7570 gen_op_ld_v(s
, MO_16
, s
->T1
, s
->A0
);
7571 gen_add_A0_im(s
, 2);
7572 gen_op_ld_v(s
, CODE64(s
) + MO_32
, s
->T0
, s
->A0
);
7573 if (dflag
== MO_16
) {
7574 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xffffff);
7576 tcg_gen_st_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, idt
.base
));
7577 tcg_gen_st32_tl(s
->T1
, cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7580 CASE_MODRM_OP(4): /* smsw */
7581 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_CR0
);
7582 tcg_gen_ld_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, cr
[0]));
7584 * In 32-bit mode, the higher 16 bits of the destination
7585 * register are undefined. In practice CR0[31:0] is stored
7586 * just like in 64-bit mode.
7588 mod
= (modrm
>> 6) & 3;
7589 ot
= (mod
!= 3 ? MO_16
: s
->dflag
);
7590 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7592 case 0xee: /* rdpkru */
7593 if (prefixes
& PREFIX_LOCK
) {
7596 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_ECX
]);
7597 gen_helper_rdpkru(s
->tmp1_i64
, cpu_env
, s
->tmp2_i32
);
7598 tcg_gen_extr_i64_tl(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
], s
->tmp1_i64
);
7600 case 0xef: /* wrpkru */
7601 if (prefixes
& PREFIX_LOCK
) {
7604 tcg_gen_concat_tl_i64(s
->tmp1_i64
, cpu_regs
[R_EAX
],
7606 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_ECX
]);
7607 gen_helper_wrpkru(cpu_env
, s
->tmp2_i32
, s
->tmp1_i64
);
7609 CASE_MODRM_OP(6): /* lmsw */
7611 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7614 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7615 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7616 gen_helper_lmsw(cpu_env
, s
->T0
);
7617 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7621 CASE_MODRM_MEM_OP(7): /* invlpg */
7623 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7626 gen_update_cc_op(s
);
7627 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7628 gen_lea_modrm(env
, s
, modrm
);
7629 gen_helper_invlpg(cpu_env
, s
->A0
);
7630 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7634 case 0xf8: /* swapgs */
7635 #ifdef TARGET_X86_64
7638 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7640 tcg_gen_mov_tl(s
->T0
, cpu_seg_base
[R_GS
]);
7641 tcg_gen_ld_tl(cpu_seg_base
[R_GS
], cpu_env
,
7642 offsetof(CPUX86State
, kernelgsbase
));
7643 tcg_gen_st_tl(s
->T0
, cpu_env
,
7644 offsetof(CPUX86State
, kernelgsbase
));
7651 case 0xf9: /* rdtscp */
7652 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_RDTSCP
)) {
7655 gen_update_cc_op(s
);
7656 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7657 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7660 gen_helper_rdtscp(cpu_env
);
7661 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7662 gen_jmp(s
, s
->pc
- s
->cs_base
);
7671 case 0x108: /* invd */
7672 case 0x109: /* wbinvd */
7674 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7676 gen_svm_check_intercept(s
, pc_start
, (b
& 2) ? SVM_EXIT_INVD
: SVM_EXIT_WBINVD
);
7680 case 0x63: /* arpl or movslS (x86_64) */
7681 #ifdef TARGET_X86_64
7684 /* d_ot is the size of destination */
7687 modrm
= x86_ldub_code(env
, s
);
7688 reg
= ((modrm
>> 3) & 7) | rex_r
;
7689 mod
= (modrm
>> 6) & 3;
7690 rm
= (modrm
& 7) | REX_B(s
);
7693 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, rm
);
7695 if (d_ot
== MO_64
) {
7696 tcg_gen_ext32s_tl(s
->T0
, s
->T0
);
7698 gen_op_mov_reg_v(s
, d_ot
, reg
, s
->T0
);
7700 gen_lea_modrm(env
, s
, modrm
);
7701 gen_op_ld_v(s
, MO_32
| MO_SIGN
, s
->T0
, s
->A0
);
7702 gen_op_mov_reg_v(s
, d_ot
, reg
, s
->T0
);
7708 TCGv t0
, t1
, t2
, a0
;
7710 if (!s
->pe
|| s
->vm86
)
7712 t0
= tcg_temp_local_new();
7713 t1
= tcg_temp_local_new();
7714 t2
= tcg_temp_local_new();
7716 modrm
= x86_ldub_code(env
, s
);
7717 reg
= (modrm
>> 3) & 7;
7718 mod
= (modrm
>> 6) & 3;
7721 gen_lea_modrm(env
, s
, modrm
);
7722 gen_op_ld_v(s
, ot
, t0
, s
->A0
);
7723 a0
= tcg_temp_local_new();
7724 tcg_gen_mov_tl(a0
, s
->A0
);
7726 gen_op_mov_v_reg(s
, ot
, t0
, rm
);
7729 gen_op_mov_v_reg(s
, ot
, t1
, reg
);
7730 tcg_gen_andi_tl(s
->tmp0
, t0
, 3);
7731 tcg_gen_andi_tl(t1
, t1
, 3);
7732 tcg_gen_movi_tl(t2
, 0);
7733 label1
= gen_new_label();
7734 tcg_gen_brcond_tl(TCG_COND_GE
, s
->tmp0
, t1
, label1
);
7735 tcg_gen_andi_tl(t0
, t0
, ~3);
7736 tcg_gen_or_tl(t0
, t0
, t1
);
7737 tcg_gen_movi_tl(t2
, CC_Z
);
7738 gen_set_label(label1
);
7740 gen_op_st_v(s
, ot
, t0
, a0
);
7743 gen_op_mov_reg_v(s
, ot
, rm
, t0
);
7745 gen_compute_eflags(s
);
7746 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_Z
);
7747 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, t2
);
7753 case 0x102: /* lar */
7754 case 0x103: /* lsl */
7758 if (!s
->pe
|| s
->vm86
)
7760 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
7761 modrm
= x86_ldub_code(env
, s
);
7762 reg
= ((modrm
>> 3) & 7) | rex_r
;
7763 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7764 t0
= tcg_temp_local_new();
7765 gen_update_cc_op(s
);
7767 gen_helper_lar(t0
, cpu_env
, s
->T0
);
7769 gen_helper_lsl(t0
, cpu_env
, s
->T0
);
7771 tcg_gen_andi_tl(s
->tmp0
, cpu_cc_src
, CC_Z
);
7772 label1
= gen_new_label();
7773 tcg_gen_brcondi_tl(TCG_COND_EQ
, s
->tmp0
, 0, label1
);
7774 gen_op_mov_reg_v(s
, ot
, reg
, t0
);
7775 gen_set_label(label1
);
7776 set_cc_op(s
, CC_OP_EFLAGS
);
7781 modrm
= x86_ldub_code(env
, s
);
7782 mod
= (modrm
>> 6) & 3;
7783 op
= (modrm
>> 3) & 7;
7785 case 0: /* prefetchnta */
7786 case 1: /* prefetchnt0 */
7787 case 2: /* prefetchnt0 */
7788 case 3: /* prefetchnt0 */
7791 gen_nop_modrm(env
, s
, modrm
);
7792 /* nothing more to do */
7794 default: /* nop (multi byte) */
7795 gen_nop_modrm(env
, s
, modrm
);
7800 modrm
= x86_ldub_code(env
, s
);
7801 if (s
->flags
& HF_MPX_EN_MASK
) {
7802 mod
= (modrm
>> 6) & 3;
7803 reg
= ((modrm
>> 3) & 7) | rex_r
;
7804 if (prefixes
& PREFIX_REPZ
) {
7807 || (prefixes
& PREFIX_LOCK
)
7808 || s
->aflag
== MO_16
) {
7811 gen_bndck(env
, s
, modrm
, TCG_COND_LTU
, cpu_bndl
[reg
]);
7812 } else if (prefixes
& PREFIX_REPNZ
) {
7815 || (prefixes
& PREFIX_LOCK
)
7816 || s
->aflag
== MO_16
) {
7819 TCGv_i64 notu
= tcg_temp_new_i64();
7820 tcg_gen_not_i64(notu
, cpu_bndu
[reg
]);
7821 gen_bndck(env
, s
, modrm
, TCG_COND_GTU
, notu
);
7822 tcg_temp_free_i64(notu
);
7823 } else if (prefixes
& PREFIX_DATA
) {
7824 /* bndmov -- from reg/mem */
7825 if (reg
>= 4 || s
->aflag
== MO_16
) {
7829 int reg2
= (modrm
& 7) | REX_B(s
);
7830 if (reg2
>= 4 || (prefixes
& PREFIX_LOCK
)) {
7833 if (s
->flags
& HF_MPX_IU_MASK
) {
7834 tcg_gen_mov_i64(cpu_bndl
[reg
], cpu_bndl
[reg2
]);
7835 tcg_gen_mov_i64(cpu_bndu
[reg
], cpu_bndu
[reg2
]);
7838 gen_lea_modrm(env
, s
, modrm
);
7840 tcg_gen_qemu_ld_i64(cpu_bndl
[reg
], s
->A0
,
7841 s
->mem_index
, MO_LEQ
);
7842 tcg_gen_addi_tl(s
->A0
, s
->A0
, 8);
7843 tcg_gen_qemu_ld_i64(cpu_bndu
[reg
], s
->A0
,
7844 s
->mem_index
, MO_LEQ
);
7846 tcg_gen_qemu_ld_i64(cpu_bndl
[reg
], s
->A0
,
7847 s
->mem_index
, MO_LEUL
);
7848 tcg_gen_addi_tl(s
->A0
, s
->A0
, 4);
7849 tcg_gen_qemu_ld_i64(cpu_bndu
[reg
], s
->A0
,
7850 s
->mem_index
, MO_LEUL
);
7852 /* bnd registers are now in-use */
7853 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7855 } else if (mod
!= 3) {
7857 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7859 || (prefixes
& PREFIX_LOCK
)
7860 || s
->aflag
== MO_16
7865 tcg_gen_addi_tl(s
->A0
, cpu_regs
[a
.base
], a
.disp
);
7867 tcg_gen_movi_tl(s
->A0
, 0);
7869 gen_lea_v_seg(s
, s
->aflag
, s
->A0
, a
.def_seg
, s
->override
);
7871 tcg_gen_mov_tl(s
->T0
, cpu_regs
[a
.index
]);
7873 tcg_gen_movi_tl(s
->T0
, 0);
7876 gen_helper_bndldx64(cpu_bndl
[reg
], cpu_env
, s
->A0
, s
->T0
);
7877 tcg_gen_ld_i64(cpu_bndu
[reg
], cpu_env
,
7878 offsetof(CPUX86State
, mmx_t0
.MMX_Q(0)));
7880 gen_helper_bndldx32(cpu_bndu
[reg
], cpu_env
, s
->A0
, s
->T0
);
7881 tcg_gen_ext32u_i64(cpu_bndl
[reg
], cpu_bndu
[reg
]);
7882 tcg_gen_shri_i64(cpu_bndu
[reg
], cpu_bndu
[reg
], 32);
7884 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7887 gen_nop_modrm(env
, s
, modrm
);
7890 modrm
= x86_ldub_code(env
, s
);
7891 if (s
->flags
& HF_MPX_EN_MASK
) {
7892 mod
= (modrm
>> 6) & 3;
7893 reg
= ((modrm
>> 3) & 7) | rex_r
;
7894 if (mod
!= 3 && (prefixes
& PREFIX_REPZ
)) {
7897 || (prefixes
& PREFIX_LOCK
)
7898 || s
->aflag
== MO_16
) {
7901 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7903 tcg_gen_extu_tl_i64(cpu_bndl
[reg
], cpu_regs
[a
.base
]);
7905 tcg_gen_ext32u_i64(cpu_bndl
[reg
], cpu_bndl
[reg
]);
7907 } else if (a
.base
== -1) {
7908 /* no base register has lower bound of 0 */
7909 tcg_gen_movi_i64(cpu_bndl
[reg
], 0);
7911 /* rip-relative generates #ud */
7914 tcg_gen_not_tl(s
->A0
, gen_lea_modrm_1(s
, a
));
7916 tcg_gen_ext32u_tl(s
->A0
, s
->A0
);
7918 tcg_gen_extu_tl_i64(cpu_bndu
[reg
], s
->A0
);
7919 /* bnd registers are now in-use */
7920 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7922 } else if (prefixes
& PREFIX_REPNZ
) {
7925 || (prefixes
& PREFIX_LOCK
)
7926 || s
->aflag
== MO_16
) {
7929 gen_bndck(env
, s
, modrm
, TCG_COND_GTU
, cpu_bndu
[reg
]);
7930 } else if (prefixes
& PREFIX_DATA
) {
7931 /* bndmov -- to reg/mem */
7932 if (reg
>= 4 || s
->aflag
== MO_16
) {
7936 int reg2
= (modrm
& 7) | REX_B(s
);
7937 if (reg2
>= 4 || (prefixes
& PREFIX_LOCK
)) {
7940 if (s
->flags
& HF_MPX_IU_MASK
) {
7941 tcg_gen_mov_i64(cpu_bndl
[reg2
], cpu_bndl
[reg
]);
7942 tcg_gen_mov_i64(cpu_bndu
[reg2
], cpu_bndu
[reg
]);
7945 gen_lea_modrm(env
, s
, modrm
);
7947 tcg_gen_qemu_st_i64(cpu_bndl
[reg
], s
->A0
,
7948 s
->mem_index
, MO_LEQ
);
7949 tcg_gen_addi_tl(s
->A0
, s
->A0
, 8);
7950 tcg_gen_qemu_st_i64(cpu_bndu
[reg
], s
->A0
,
7951 s
->mem_index
, MO_LEQ
);
7953 tcg_gen_qemu_st_i64(cpu_bndl
[reg
], s
->A0
,
7954 s
->mem_index
, MO_LEUL
);
7955 tcg_gen_addi_tl(s
->A0
, s
->A0
, 4);
7956 tcg_gen_qemu_st_i64(cpu_bndu
[reg
], s
->A0
,
7957 s
->mem_index
, MO_LEUL
);
7960 } else if (mod
!= 3) {
7962 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7964 || (prefixes
& PREFIX_LOCK
)
7965 || s
->aflag
== MO_16
7970 tcg_gen_addi_tl(s
->A0
, cpu_regs
[a
.base
], a
.disp
);
7972 tcg_gen_movi_tl(s
->A0
, 0);
7974 gen_lea_v_seg(s
, s
->aflag
, s
->A0
, a
.def_seg
, s
->override
);
7976 tcg_gen_mov_tl(s
->T0
, cpu_regs
[a
.index
]);
7978 tcg_gen_movi_tl(s
->T0
, 0);
7981 gen_helper_bndstx64(cpu_env
, s
->A0
, s
->T0
,
7982 cpu_bndl
[reg
], cpu_bndu
[reg
]);
7984 gen_helper_bndstx32(cpu_env
, s
->A0
, s
->T0
,
7985 cpu_bndl
[reg
], cpu_bndu
[reg
]);
7989 gen_nop_modrm(env
, s
, modrm
);
7991 case 0x119: case 0x11c ... 0x11f: /* nop (multi byte) */
7992 modrm
= x86_ldub_code(env
, s
);
7993 gen_nop_modrm(env
, s
, modrm
);
7995 case 0x120: /* mov reg, crN */
7996 case 0x122: /* mov crN, reg */
7998 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
8000 modrm
= x86_ldub_code(env
, s
);
8001 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
8002 * AMD documentation (24594.pdf) and testing of
8003 * intel 386 and 486 processors all show that the mod bits
8004 * are assumed to be 1's, regardless of actual values.
8006 rm
= (modrm
& 7) | REX_B(s
);
8007 reg
= ((modrm
>> 3) & 7) | rex_r
;
8012 if ((prefixes
& PREFIX_LOCK
) && (reg
== 0) &&
8013 (s
->cpuid_ext3_features
& CPUID_EXT3_CR8LEG
)) {
8022 gen_update_cc_op(s
);
8023 gen_jmp_im(s
, pc_start
- s
->cs_base
);
8025 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
8028 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
8029 gen_helper_write_crN(cpu_env
, tcg_const_i32(reg
),
8031 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8034 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
8037 gen_helper_read_crN(s
->T0
, cpu_env
, tcg_const_i32(reg
));
8038 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
8039 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
8040 gen_jmp(s
, s
->pc
- s
->cs_base
);
8049 case 0x121: /* mov reg, drN */
8050 case 0x123: /* mov drN, reg */
8052 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
8054 modrm
= x86_ldub_code(env
, s
);
8055 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
8056 * AMD documentation (24594.pdf) and testing of
8057 * intel 386 and 486 processors all show that the mod bits
8058 * are assumed to be 1's, regardless of actual values.
8060 rm
= (modrm
& 7) | REX_B(s
);
8061 reg
= ((modrm
>> 3) & 7) | rex_r
;
8070 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_DR0
+ reg
);
8071 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
8072 tcg_gen_movi_i32(s
->tmp2_i32
, reg
);
8073 gen_helper_set_dr(cpu_env
, s
->tmp2_i32
, s
->T0
);
8074 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8077 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_DR0
+ reg
);
8078 tcg_gen_movi_i32(s
->tmp2_i32
, reg
);
8079 gen_helper_get_dr(s
->T0
, cpu_env
, s
->tmp2_i32
);
8080 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
8084 case 0x106: /* clts */
8086 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
8088 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
8089 gen_helper_clts(cpu_env
);
8090 /* abort block because static cpu state changed */
8091 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8095 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
8096 case 0x1c3: /* MOVNTI reg, mem */
8097 if (!(s
->cpuid_features
& CPUID_SSE2
))
8099 ot
= mo_64_32(dflag
);
8100 modrm
= x86_ldub_code(env
, s
);
8101 mod
= (modrm
>> 6) & 3;
8104 reg
= ((modrm
>> 3) & 7) | rex_r
;
8105 /* generate a generic store */
8106 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
8109 modrm
= x86_ldub_code(env
, s
);
8111 CASE_MODRM_MEM_OP(0): /* fxsave */
8112 if (!(s
->cpuid_features
& CPUID_FXSR
)
8113 || (prefixes
& PREFIX_LOCK
)) {
8116 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
8117 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8120 gen_lea_modrm(env
, s
, modrm
);
8121 gen_helper_fxsave(cpu_env
, s
->A0
);
8124 CASE_MODRM_MEM_OP(1): /* fxrstor */
8125 if (!(s
->cpuid_features
& CPUID_FXSR
)
8126 || (prefixes
& PREFIX_LOCK
)) {
8129 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
8130 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8133 gen_lea_modrm(env
, s
, modrm
);
8134 gen_helper_fxrstor(cpu_env
, s
->A0
);
8137 CASE_MODRM_MEM_OP(2): /* ldmxcsr */
8138 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
)) {
8141 if (s
->flags
& HF_TS_MASK
) {
8142 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8145 gen_lea_modrm(env
, s
, modrm
);
8146 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
, s
->mem_index
, MO_LEUL
);
8147 gen_helper_ldmxcsr(cpu_env
, s
->tmp2_i32
);
8150 CASE_MODRM_MEM_OP(3): /* stmxcsr */
8151 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
)) {
8154 if (s
->flags
& HF_TS_MASK
) {
8155 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8158 gen_helper_update_mxcsr(cpu_env
);
8159 gen_lea_modrm(env
, s
, modrm
);
8160 tcg_gen_ld32u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, mxcsr
));
8161 gen_op_st_v(s
, MO_32
, s
->T0
, s
->A0
);
8164 CASE_MODRM_MEM_OP(4): /* xsave */
8165 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8166 || (prefixes
& (PREFIX_LOCK
| PREFIX_DATA
8167 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
8170 gen_lea_modrm(env
, s
, modrm
);
8171 tcg_gen_concat_tl_i64(s
->tmp1_i64
, cpu_regs
[R_EAX
],
8173 gen_helper_xsave(cpu_env
, s
->A0
, s
->tmp1_i64
);
8176 CASE_MODRM_MEM_OP(5): /* xrstor */
8177 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8178 || (prefixes
& (PREFIX_LOCK
| PREFIX_DATA
8179 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
8182 gen_lea_modrm(env
, s
, modrm
);
8183 tcg_gen_concat_tl_i64(s
->tmp1_i64
, cpu_regs
[R_EAX
],
8185 gen_helper_xrstor(cpu_env
, s
->A0
, s
->tmp1_i64
);
8186 /* XRSTOR is how MPX is enabled, which changes how
8187 we translate. Thus we need to end the TB. */
8188 gen_update_cc_op(s
);
8189 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8193 CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */
8194 if (prefixes
& PREFIX_LOCK
) {
8197 if (prefixes
& PREFIX_DATA
) {
8199 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLWB
)) {
8202 gen_nop_modrm(env
, s
, modrm
);
8205 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8206 || (s
->cpuid_xsave_features
& CPUID_XSAVE_XSAVEOPT
) == 0
8207 || (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
))) {
8210 gen_lea_modrm(env
, s
, modrm
);
8211 tcg_gen_concat_tl_i64(s
->tmp1_i64
, cpu_regs
[R_EAX
],
8213 gen_helper_xsaveopt(cpu_env
, s
->A0
, s
->tmp1_i64
);
8217 CASE_MODRM_MEM_OP(7): /* clflush / clflushopt */
8218 if (prefixes
& PREFIX_LOCK
) {
8221 if (prefixes
& PREFIX_DATA
) {
8223 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLFLUSHOPT
)) {
8228 if ((s
->prefix
& (PREFIX_REPZ
| PREFIX_REPNZ
))
8229 || !(s
->cpuid_features
& CPUID_CLFLUSH
)) {
8233 gen_nop_modrm(env
, s
, modrm
);
8236 case 0xc0 ... 0xc7: /* rdfsbase (f3 0f ae /0) */
8237 case 0xc8 ... 0xcf: /* rdgsbase (f3 0f ae /1) */
8238 case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */
8239 case 0xd8 ... 0xdf: /* wrgsbase (f3 0f ae /3) */
8241 && (prefixes
& PREFIX_REPZ
)
8242 && !(prefixes
& PREFIX_LOCK
)
8243 && (s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_FSGSBASE
)) {
8244 TCGv base
, treg
, src
, dst
;
8246 /* Preserve hflags bits by testing CR4 at runtime. */
8247 tcg_gen_movi_i32(s
->tmp2_i32
, CR4_FSGSBASE_MASK
);
8248 gen_helper_cr4_testbit(cpu_env
, s
->tmp2_i32
);
8250 base
= cpu_seg_base
[modrm
& 8 ? R_GS
: R_FS
];
8251 treg
= cpu_regs
[(modrm
& 7) | REX_B(s
)];
8255 dst
= base
, src
= treg
;
8258 dst
= treg
, src
= base
;
8261 if (s
->dflag
== MO_32
) {
8262 tcg_gen_ext32u_tl(dst
, src
);
8264 tcg_gen_mov_tl(dst
, src
);
8270 case 0xf8: /* sfence / pcommit */
8271 if (prefixes
& PREFIX_DATA
) {
8273 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_PCOMMIT
)
8274 || (prefixes
& PREFIX_LOCK
)) {
8280 case 0xf9 ... 0xff: /* sfence */
8281 if (!(s
->cpuid_features
& CPUID_SSE
)
8282 || (prefixes
& PREFIX_LOCK
)) {
8285 tcg_gen_mb(TCG_MO_ST_ST
| TCG_BAR_SC
);
8287 case 0xe8 ... 0xef: /* lfence */
8288 if (!(s
->cpuid_features
& CPUID_SSE
)
8289 || (prefixes
& PREFIX_LOCK
)) {
8292 tcg_gen_mb(TCG_MO_LD_LD
| TCG_BAR_SC
);
8294 case 0xf0 ... 0xf7: /* mfence */
8295 if (!(s
->cpuid_features
& CPUID_SSE2
)
8296 || (prefixes
& PREFIX_LOCK
)) {
8299 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8307 case 0x10d: /* 3DNow! prefetch(w) */
8308 modrm
= x86_ldub_code(env
, s
);
8309 mod
= (modrm
>> 6) & 3;
8312 gen_nop_modrm(env
, s
, modrm
);
8314 case 0x1aa: /* rsm */
8315 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_RSM
);
8316 if (!(s
->flags
& HF_SMM_MASK
))
8318 gen_update_cc_op(s
);
8319 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8320 gen_helper_rsm(cpu_env
);
8323 case 0x1b8: /* SSE4.2 popcnt */
8324 if ((prefixes
& (PREFIX_REPZ
| PREFIX_LOCK
| PREFIX_REPNZ
)) !=
8327 if (!(s
->cpuid_ext_features
& CPUID_EXT_POPCNT
))
8330 modrm
= x86_ldub_code(env
, s
);
8331 reg
= ((modrm
>> 3) & 7) | rex_r
;
8333 if (s
->prefix
& PREFIX_DATA
) {
8336 ot
= mo_64_32(dflag
);
8339 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
8340 gen_extu(ot
, s
->T0
);
8341 tcg_gen_mov_tl(cpu_cc_src
, s
->T0
);
8342 tcg_gen_ctpop_tl(s
->T0
, s
->T0
);
8343 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
8345 set_cc_op(s
, CC_OP_POPCNT
);
8347 case 0x10e ... 0x10f:
8348 /* 3DNow! instructions, ignore prefixes */
8349 s
->prefix
&= ~(PREFIX_REPZ
| PREFIX_REPNZ
| PREFIX_DATA
);
8351 case 0x110 ... 0x117:
8352 case 0x128 ... 0x12f:
8353 case 0x138 ... 0x13a:
8354 case 0x150 ... 0x179:
8355 case 0x17c ... 0x17f:
8357 case 0x1c4 ... 0x1c6:
8358 case 0x1d0 ... 0x1fe:
8359 gen_sse(env
, s
, b
, pc_start
, rex_r
);
8366 gen_illegal_opcode(s
);
8369 gen_unknown_opcode(env
, s
);
8373 void tcg_x86_init(void)
8375 static const char reg_names
[CPU_NB_REGS
][4] = {
8376 #ifdef TARGET_X86_64
8404 static const char seg_base_names
[6][8] = {
8412 static const char bnd_regl_names
[4][8] = {
8413 "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb"
8415 static const char bnd_regu_names
[4][8] = {
8416 "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub"
8420 cpu_cc_op
= tcg_global_mem_new_i32(cpu_env
,
8421 offsetof(CPUX86State
, cc_op
), "cc_op");
8422 cpu_cc_dst
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_dst
),
8424 cpu_cc_src
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_src
),
8426 cpu_cc_src2
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_src2
),
8429 for (i
= 0; i
< CPU_NB_REGS
; ++i
) {
8430 cpu_regs
[i
] = tcg_global_mem_new(cpu_env
,
8431 offsetof(CPUX86State
, regs
[i
]),
8435 for (i
= 0; i
< 6; ++i
) {
8437 = tcg_global_mem_new(cpu_env
,
8438 offsetof(CPUX86State
, segs
[i
].base
),
8442 for (i
= 0; i
< 4; ++i
) {
8444 = tcg_global_mem_new_i64(cpu_env
,
8445 offsetof(CPUX86State
, bnd_regs
[i
].lb
),
8448 = tcg_global_mem_new_i64(cpu_env
,
8449 offsetof(CPUX86State
, bnd_regs
[i
].ub
),
8454 static void i386_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cpu
)
8456 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8457 CPUX86State
*env
= cpu
->env_ptr
;
8458 uint32_t flags
= dc
->base
.tb
->flags
;
8459 target_ulong cs_base
= dc
->base
.tb
->cs_base
;
8461 dc
->pe
= (flags
>> HF_PE_SHIFT
) & 1;
8462 dc
->code32
= (flags
>> HF_CS32_SHIFT
) & 1;
8463 dc
->ss32
= (flags
>> HF_SS32_SHIFT
) & 1;
8464 dc
->addseg
= (flags
>> HF_ADDSEG_SHIFT
) & 1;
8466 dc
->vm86
= (flags
>> VM_SHIFT
) & 1;
8467 dc
->cpl
= (flags
>> HF_CPL_SHIFT
) & 3;
8468 dc
->iopl
= (flags
>> IOPL_SHIFT
) & 3;
8469 dc
->tf
= (flags
>> TF_SHIFT
) & 1;
8470 dc
->cc_op
= CC_OP_DYNAMIC
;
8471 dc
->cc_op_dirty
= false;
8472 dc
->cs_base
= cs_base
;
8473 dc
->popl_esp_hack
= 0;
8474 /* select memory access functions */
8476 #ifdef CONFIG_SOFTMMU
8477 dc
->mem_index
= cpu_mmu_index(env
, false);
8479 dc
->cpuid_features
= env
->features
[FEAT_1_EDX
];
8480 dc
->cpuid_ext_features
= env
->features
[FEAT_1_ECX
];
8481 dc
->cpuid_ext2_features
= env
->features
[FEAT_8000_0001_EDX
];
8482 dc
->cpuid_ext3_features
= env
->features
[FEAT_8000_0001_ECX
];
8483 dc
->cpuid_7_0_ebx_features
= env
->features
[FEAT_7_0_EBX
];
8484 dc
->cpuid_xsave_features
= env
->features
[FEAT_XSAVE
];
8485 #ifdef TARGET_X86_64
8486 dc
->lma
= (flags
>> HF_LMA_SHIFT
) & 1;
8487 dc
->code64
= (flags
>> HF_CS64_SHIFT
) & 1;
8490 dc
->jmp_opt
= !(dc
->tf
|| dc
->base
.singlestep_enabled
||
8491 (flags
& HF_INHIBIT_IRQ_MASK
));
8492 /* Do not optimize repz jumps at all in icount mode, because
8493 rep movsS instructions are execured with different paths
8494 in !repz_opt and repz_opt modes. The first one was used
8495 always except single step mode. And this setting
8496 disables jumps optimization and control paths become
8497 equivalent in run and single step modes.
8498 Now there will be no jump optimization for repz in
8499 record/replay modes and there will always be an
8500 additional step for ecx=0 when icount is enabled.
8502 dc
->repz_opt
= !dc
->jmp_opt
&& !(tb_cflags(dc
->base
.tb
) & CF_USE_ICOUNT
);
8504 /* check addseg logic */
8505 if (!dc
->addseg
&& (dc
->vm86
|| !dc
->pe
|| !dc
->code32
))
8506 printf("ERROR addseg\n");
8509 dc
->T0
= tcg_temp_new();
8510 dc
->T1
= tcg_temp_new();
8511 dc
->A0
= tcg_temp_new();
8513 dc
->tmp0
= tcg_temp_new();
8514 dc
->tmp1_i64
= tcg_temp_new_i64();
8515 dc
->tmp2_i32
= tcg_temp_new_i32();
8516 dc
->tmp3_i32
= tcg_temp_new_i32();
8517 dc
->tmp4
= tcg_temp_new();
8518 dc
->ptr0
= tcg_temp_new_ptr();
8519 dc
->ptr1
= tcg_temp_new_ptr();
8520 dc
->cc_srcT
= tcg_temp_local_new();
8523 static void i386_tr_tb_start(DisasContextBase
*db
, CPUState
*cpu
)
8527 static void i386_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
8529 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8531 tcg_gen_insn_start(dc
->base
.pc_next
, dc
->cc_op
);
8534 static bool i386_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cpu
,
8535 const CPUBreakpoint
*bp
)
8537 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8538 /* If RF is set, suppress an internally generated breakpoint. */
8539 int flags
= dc
->base
.tb
->flags
& HF_RF_MASK
? BP_GDB
: BP_ANY
;
8540 if (bp
->flags
& flags
) {
8541 gen_debug(dc
, dc
->base
.pc_next
- dc
->cs_base
);
8542 dc
->base
.is_jmp
= DISAS_NORETURN
;
8543 /* The address covered by the breakpoint must be included in
8544 [tb->pc, tb->pc + tb->size) in order to for it to be
8545 properly cleared -- thus we increment the PC here so that
8546 the generic logic setting tb->size later does the right thing. */
8547 dc
->base
.pc_next
+= 1;
8554 static void i386_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
8556 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8557 target_ulong pc_next
;
8559 #ifdef TARGET_VSYSCALL_PAGE
8561 * Detect entry into the vsyscall page and invoke the syscall.
8563 if ((dc
->base
.pc_next
& TARGET_PAGE_MASK
) == TARGET_VSYSCALL_PAGE
) {
8564 gen_exception(dc
, EXCP_VSYSCALL
, dc
->base
.pc_next
);
8569 pc_next
= disas_insn(dc
, cpu
);
8571 if (dc
->tf
|| (dc
->base
.tb
->flags
& HF_INHIBIT_IRQ_MASK
)) {
8572 /* if single step mode, we generate only one instruction and
8573 generate an exception */
8574 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
8575 the flag and abort the translation to give the irqs a
8577 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
8578 } else if ((tb_cflags(dc
->base
.tb
) & CF_USE_ICOUNT
)
8579 && ((pc_next
& TARGET_PAGE_MASK
)
8580 != ((pc_next
+ TARGET_MAX_INSN_SIZE
- 1)
8582 || (pc_next
& ~TARGET_PAGE_MASK
) == 0)) {
8583 /* Do not cross the boundary of the pages in icount mode,
8584 it can cause an exception. Do it only when boundary is
8585 crossed by the first instruction in the block.
8586 If current instruction already crossed the bound - it's ok,
8587 because an exception hasn't stopped this code.
8589 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
8590 } else if ((pc_next
- dc
->base
.pc_first
) >= (TARGET_PAGE_SIZE
- 32)) {
8591 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
8594 dc
->base
.pc_next
= pc_next
;
8597 static void i386_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cpu
)
8599 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8601 if (dc
->base
.is_jmp
== DISAS_TOO_MANY
) {
8602 gen_jmp_im(dc
, dc
->base
.pc_next
- dc
->cs_base
);
8607 static void i386_tr_disas_log(const DisasContextBase
*dcbase
,
8610 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8612 qemu_log("IN: %s\n", lookup_symbol(dc
->base
.pc_first
));
8613 log_target_disas(cpu
, dc
->base
.pc_first
, dc
->base
.tb
->size
);
8616 static const TranslatorOps i386_tr_ops
= {
8617 .init_disas_context
= i386_tr_init_disas_context
,
8618 .tb_start
= i386_tr_tb_start
,
8619 .insn_start
= i386_tr_insn_start
,
8620 .breakpoint_check
= i386_tr_breakpoint_check
,
8621 .translate_insn
= i386_tr_translate_insn
,
8622 .tb_stop
= i386_tr_tb_stop
,
8623 .disas_log
= i386_tr_disas_log
,
8626 /* generate intermediate code for basic block 'tb'. */
8627 void gen_intermediate_code(CPUState
*cpu
, TranslationBlock
*tb
, int max_insns
)
8631 translator_loop(&i386_tr_ops
, &dc
.base
, cpu
, tb
, max_insns
);
8634 void restore_state_to_opc(CPUX86State
*env
, TranslationBlock
*tb
,
8637 int cc_op
= data
[1];
8638 env
->eip
= data
[0] - tb
->cs_base
;
8639 if (cc_op
!= CC_OP_DYNAMIC
) {