4 * Copyright (c) 2003 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 #include "qemu/osdep.h"
21 #include "qemu/host-utils.h"
23 #include "disas/disas.h"
24 #include "exec/exec-all.h"
26 #include "exec/cpu_ldst.h"
27 #include "exec/translator.h"
29 #include "exec/helper-proto.h"
30 #include "exec/helper-gen.h"
32 #include "trace-tcg.h"
35 #define PREFIX_REPZ 0x01
36 #define PREFIX_REPNZ 0x02
37 #define PREFIX_LOCK 0x04
38 #define PREFIX_DATA 0x08
39 #define PREFIX_ADR 0x10
40 #define PREFIX_VEX 0x20
43 #define CODE64(s) ((s)->code64)
44 #define REX_X(s) ((s)->rex_x)
45 #define REX_B(s) ((s)->rex_b)
60 /* For a switch indexed by MODRM, match all memory operands for a given OP. */
61 #define CASE_MODRM_MEM_OP(OP) \
62 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
63 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
64 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7
66 #define CASE_MODRM_OP(OP) \
67 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
68 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
69 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7: \
70 case (3 << 6) | (OP << 3) | 0 ... (3 << 6) | (OP << 3) | 7
72 //#define MACRO_TEST 1
74 /* global register indexes */
75 static TCGv cpu_cc_dst
, cpu_cc_src
, cpu_cc_src2
;
76 static TCGv_i32 cpu_cc_op
;
77 static TCGv cpu_regs
[CPU_NB_REGS
];
78 static TCGv cpu_seg_base
[6];
79 static TCGv_i64 cpu_bndl
[4];
80 static TCGv_i64 cpu_bndu
[4];
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
, TCGMemOp 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 TCGMemOp
mo_pushpop(DisasContext
*s
, TCGMemOp ot
)
326 return ot
== MO_16
? MO_16
: MO_64
;
332 /* Select the size of the stack pointer. */
333 static inline TCGMemOp
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 TCGMemOp
mo_64_32(TCGMemOp 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 TCGMemOp
mo_b_d(int b
, TCGMemOp 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 TCGMemOp
mo_b_d32(int b
, TCGMemOp ot
)
359 return b
& 1 ? (ot
== MO_16
? MO_16
: MO_32
) : MO_8
;
362 static void gen_op_mov_reg_v(DisasContext
*s
, TCGMemOp 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
, TCGMemOp 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
, TCGMemOp 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
, TCGMemOp 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
, TCGMemOp 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
, TCGMemOp 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
, TCGMemOp 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(TCGMemOp ot
, TCGv reg
)
556 gen_ext_tl(reg
, reg
, ot
, false);
559 static void gen_exts(TCGMemOp ot
, TCGv reg
)
561 gen_ext_tl(reg
, reg
, ot
, true);
565 void gen_op_jnz_ecx(DisasContext
*s
, TCGMemOp 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
, TCGMemOp 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(TCGMemOp 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(TCGMemOp 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
, TCGMemOp 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
, TCGMemOp 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 TCGMemOp 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 TCGMemOp 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
, TCGMemOp 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
, TCGMemOp 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
, TCGMemOp 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
, TCGMemOp 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
, TCGMemOp ot
)
1131 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
1134 gen_string_movl_A0_EDI(s
);
1135 /* Note: we must do this dummy write first to be restartable in
1136 case of page fault. */
1137 tcg_gen_movi_tl(s
->T0
, 0);
1138 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
1139 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_EDX
]);
1140 tcg_gen_andi_i32(s
->tmp2_i32
, s
->tmp2_i32
, 0xffff);
1141 gen_helper_in_func(ot
, s
->T0
, s
->tmp2_i32
);
1142 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
1143 gen_op_movl_T0_Dshift(s
, ot
);
1144 gen_op_add_reg_T0(s
, s
->aflag
, R_EDI
);
1145 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
1146 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
1151 static inline void gen_outs(DisasContext
*s
, TCGMemOp ot
)
1153 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
1156 gen_string_movl_A0_ESI(s
);
1157 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1159 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_EDX
]);
1160 tcg_gen_andi_i32(s
->tmp2_i32
, s
->tmp2_i32
, 0xffff);
1161 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, s
->T0
);
1162 gen_helper_out_func(ot
, s
->tmp2_i32
, s
->tmp3_i32
);
1163 gen_op_movl_T0_Dshift(s
, ot
);
1164 gen_op_add_reg_T0(s
, s
->aflag
, R_ESI
);
1165 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
1166 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
1171 /* same method as Valgrind : we generate jumps to current or next
1173 #define GEN_REPZ(op) \
1174 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1175 target_ulong cur_eip, target_ulong next_eip) \
1178 gen_update_cc_op(s); \
1179 l2 = gen_jz_ecx_string(s, next_eip); \
1180 gen_ ## op(s, ot); \
1181 gen_op_add_reg_im(s, s->aflag, R_ECX, -1); \
1182 /* a loop would cause two single step exceptions if ECX = 1 \
1183 before rep string_insn */ \
1185 gen_op_jz_ecx(s, s->aflag, l2); \
1186 gen_jmp(s, cur_eip); \
1189 #define GEN_REPZ2(op) \
1190 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1191 target_ulong cur_eip, \
1192 target_ulong next_eip, \
1196 gen_update_cc_op(s); \
1197 l2 = gen_jz_ecx_string(s, next_eip); \
1198 gen_ ## op(s, ot); \
1199 gen_op_add_reg_im(s, s->aflag, R_ECX, -1); \
1200 gen_update_cc_op(s); \
1201 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
1203 gen_op_jz_ecx(s, s->aflag, l2); \
1204 gen_jmp(s, cur_eip); \
1215 static void gen_helper_fp_arith_ST0_FT0(int op
)
1219 gen_helper_fadd_ST0_FT0(cpu_env
);
1222 gen_helper_fmul_ST0_FT0(cpu_env
);
1225 gen_helper_fcom_ST0_FT0(cpu_env
);
1228 gen_helper_fcom_ST0_FT0(cpu_env
);
1231 gen_helper_fsub_ST0_FT0(cpu_env
);
1234 gen_helper_fsubr_ST0_FT0(cpu_env
);
1237 gen_helper_fdiv_ST0_FT0(cpu_env
);
1240 gen_helper_fdivr_ST0_FT0(cpu_env
);
1245 /* NOTE the exception in "r" op ordering */
1246 static void gen_helper_fp_arith_STN_ST0(int op
, int opreg
)
1248 TCGv_i32 tmp
= tcg_const_i32(opreg
);
1251 gen_helper_fadd_STN_ST0(cpu_env
, tmp
);
1254 gen_helper_fmul_STN_ST0(cpu_env
, tmp
);
1257 gen_helper_fsubr_STN_ST0(cpu_env
, tmp
);
1260 gen_helper_fsub_STN_ST0(cpu_env
, tmp
);
1263 gen_helper_fdivr_STN_ST0(cpu_env
, tmp
);
1266 gen_helper_fdiv_STN_ST0(cpu_env
, tmp
);
1271 static void gen_exception(DisasContext
*s
, int trapno
, target_ulong cur_eip
)
1273 gen_update_cc_op(s
);
1274 gen_jmp_im(s
, cur_eip
);
1275 gen_helper_raise_exception(cpu_env
, tcg_const_i32(trapno
));
1276 s
->base
.is_jmp
= DISAS_NORETURN
;
1279 /* Generate #UD for the current instruction. The assumption here is that
1280 the instruction is known, but it isn't allowed in the current cpu mode. */
1281 static void gen_illegal_opcode(DisasContext
*s
)
1283 gen_exception(s
, EXCP06_ILLOP
, s
->pc_start
- s
->cs_base
);
1286 /* if d == OR_TMP0, it means memory operand (address in A0) */
1287 static void gen_op(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
)
1290 if (s1
->prefix
& PREFIX_LOCK
) {
1291 /* Lock prefix when destination is not memory. */
1292 gen_illegal_opcode(s1
);
1295 gen_op_mov_v_reg(s1
, ot
, s1
->T0
, d
);
1296 } else if (!(s1
->prefix
& PREFIX_LOCK
)) {
1297 gen_op_ld_v(s1
, ot
, s1
->T0
, s1
->A0
);
1301 gen_compute_eflags_c(s1
, s1
->tmp4
);
1302 if (s1
->prefix
& PREFIX_LOCK
) {
1303 tcg_gen_add_tl(s1
->T0
, s1
->tmp4
, s1
->T1
);
1304 tcg_gen_atomic_add_fetch_tl(s1
->T0
, s1
->A0
, s1
->T0
,
1305 s1
->mem_index
, ot
| MO_LE
);
1307 tcg_gen_add_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1308 tcg_gen_add_tl(s1
->T0
, s1
->T0
, s1
->tmp4
);
1309 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1311 gen_op_update3_cc(s1
, s1
->tmp4
);
1312 set_cc_op(s1
, CC_OP_ADCB
+ ot
);
1315 gen_compute_eflags_c(s1
, s1
->tmp4
);
1316 if (s1
->prefix
& PREFIX_LOCK
) {
1317 tcg_gen_add_tl(s1
->T0
, s1
->T1
, s1
->tmp4
);
1318 tcg_gen_neg_tl(s1
->T0
, s1
->T0
);
1319 tcg_gen_atomic_add_fetch_tl(s1
->T0
, s1
->A0
, s1
->T0
,
1320 s1
->mem_index
, ot
| MO_LE
);
1322 tcg_gen_sub_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1323 tcg_gen_sub_tl(s1
->T0
, s1
->T0
, s1
->tmp4
);
1324 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1326 gen_op_update3_cc(s1
, s1
->tmp4
);
1327 set_cc_op(s1
, CC_OP_SBBB
+ ot
);
1330 if (s1
->prefix
& PREFIX_LOCK
) {
1331 tcg_gen_atomic_add_fetch_tl(s1
->T0
, s1
->A0
, s1
->T1
,
1332 s1
->mem_index
, ot
| MO_LE
);
1334 tcg_gen_add_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1335 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1337 gen_op_update2_cc(s1
);
1338 set_cc_op(s1
, CC_OP_ADDB
+ ot
);
1341 if (s1
->prefix
& PREFIX_LOCK
) {
1342 tcg_gen_neg_tl(s1
->T0
, s1
->T1
);
1343 tcg_gen_atomic_fetch_add_tl(s1
->cc_srcT
, s1
->A0
, s1
->T0
,
1344 s1
->mem_index
, ot
| MO_LE
);
1345 tcg_gen_sub_tl(s1
->T0
, s1
->cc_srcT
, s1
->T1
);
1347 tcg_gen_mov_tl(s1
->cc_srcT
, s1
->T0
);
1348 tcg_gen_sub_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1349 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1351 gen_op_update2_cc(s1
);
1352 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1356 if (s1
->prefix
& PREFIX_LOCK
) {
1357 tcg_gen_atomic_and_fetch_tl(s1
->T0
, s1
->A0
, s1
->T1
,
1358 s1
->mem_index
, ot
| MO_LE
);
1360 tcg_gen_and_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1361 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1363 gen_op_update1_cc(s1
);
1364 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1367 if (s1
->prefix
& PREFIX_LOCK
) {
1368 tcg_gen_atomic_or_fetch_tl(s1
->T0
, s1
->A0
, s1
->T1
,
1369 s1
->mem_index
, ot
| MO_LE
);
1371 tcg_gen_or_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1372 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1374 gen_op_update1_cc(s1
);
1375 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1378 if (s1
->prefix
& PREFIX_LOCK
) {
1379 tcg_gen_atomic_xor_fetch_tl(s1
->T0
, s1
->A0
, s1
->T1
,
1380 s1
->mem_index
, ot
| MO_LE
);
1382 tcg_gen_xor_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1383 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1385 gen_op_update1_cc(s1
);
1386 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1389 tcg_gen_mov_tl(cpu_cc_src
, s1
->T1
);
1390 tcg_gen_mov_tl(s1
->cc_srcT
, s1
->T0
);
1391 tcg_gen_sub_tl(cpu_cc_dst
, s1
->T0
, s1
->T1
);
1392 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1397 /* if d == OR_TMP0, it means memory operand (address in A0) */
1398 static void gen_inc(DisasContext
*s1
, TCGMemOp ot
, int d
, int c
)
1400 if (s1
->prefix
& PREFIX_LOCK
) {
1401 tcg_gen_movi_tl(s1
->T0
, c
> 0 ? 1 : -1);
1402 tcg_gen_atomic_add_fetch_tl(s1
->T0
, s1
->A0
, s1
->T0
,
1403 s1
->mem_index
, ot
| MO_LE
);
1406 gen_op_mov_v_reg(s1
, ot
, s1
->T0
, d
);
1408 gen_op_ld_v(s1
, ot
, s1
->T0
, s1
->A0
);
1410 tcg_gen_addi_tl(s1
->T0
, s1
->T0
, (c
> 0 ? 1 : -1));
1411 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1414 gen_compute_eflags_c(s1
, cpu_cc_src
);
1415 tcg_gen_mov_tl(cpu_cc_dst
, s1
->T0
);
1416 set_cc_op(s1
, (c
> 0 ? CC_OP_INCB
: CC_OP_DECB
) + ot
);
1419 static void gen_shift_flags(DisasContext
*s
, TCGMemOp ot
, TCGv result
,
1420 TCGv shm1
, TCGv count
, bool is_right
)
1422 TCGv_i32 z32
, s32
, oldop
;
1425 /* Store the results into the CC variables. If we know that the
1426 variable must be dead, store unconditionally. Otherwise we'll
1427 need to not disrupt the current contents. */
1428 z_tl
= tcg_const_tl(0);
1429 if (cc_op_live
[s
->cc_op
] & USES_CC_DST
) {
1430 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_dst
, count
, z_tl
,
1431 result
, cpu_cc_dst
);
1433 tcg_gen_mov_tl(cpu_cc_dst
, result
);
1435 if (cc_op_live
[s
->cc_op
] & USES_CC_SRC
) {
1436 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_src
, count
, z_tl
,
1439 tcg_gen_mov_tl(cpu_cc_src
, shm1
);
1441 tcg_temp_free(z_tl
);
1443 /* Get the two potential CC_OP values into temporaries. */
1444 tcg_gen_movi_i32(s
->tmp2_i32
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1445 if (s
->cc_op
== CC_OP_DYNAMIC
) {
1448 tcg_gen_movi_i32(s
->tmp3_i32
, s
->cc_op
);
1449 oldop
= s
->tmp3_i32
;
1452 /* Conditionally store the CC_OP value. */
1453 z32
= tcg_const_i32(0);
1454 s32
= tcg_temp_new_i32();
1455 tcg_gen_trunc_tl_i32(s32
, count
);
1456 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, s32
, z32
, s
->tmp2_i32
, oldop
);
1457 tcg_temp_free_i32(z32
);
1458 tcg_temp_free_i32(s32
);
1460 /* The CC_OP value is no longer predictable. */
1461 set_cc_op(s
, CC_OP_DYNAMIC
);
1464 static void gen_shift_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1465 int is_right
, int is_arith
)
1467 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1470 if (op1
== OR_TMP0
) {
1471 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1473 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1476 tcg_gen_andi_tl(s
->T1
, s
->T1
, mask
);
1477 tcg_gen_subi_tl(s
->tmp0
, s
->T1
, 1);
1481 gen_exts(ot
, s
->T0
);
1482 tcg_gen_sar_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1483 tcg_gen_sar_tl(s
->T0
, s
->T0
, s
->T1
);
1485 gen_extu(ot
, s
->T0
);
1486 tcg_gen_shr_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1487 tcg_gen_shr_tl(s
->T0
, s
->T0
, s
->T1
);
1490 tcg_gen_shl_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1491 tcg_gen_shl_tl(s
->T0
, s
->T0
, s
->T1
);
1495 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1497 gen_shift_flags(s
, ot
, s
->T0
, s
->tmp0
, s
->T1
, is_right
);
1500 static void gen_shift_rm_im(DisasContext
*s
, TCGMemOp ot
, int op1
, int op2
,
1501 int is_right
, int is_arith
)
1503 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1507 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1509 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1515 gen_exts(ot
, s
->T0
);
1516 tcg_gen_sari_tl(s
->tmp4
, s
->T0
, op2
- 1);
1517 tcg_gen_sari_tl(s
->T0
, s
->T0
, op2
);
1519 gen_extu(ot
, s
->T0
);
1520 tcg_gen_shri_tl(s
->tmp4
, s
->T0
, op2
- 1);
1521 tcg_gen_shri_tl(s
->T0
, s
->T0
, op2
);
1524 tcg_gen_shli_tl(s
->tmp4
, s
->T0
, op2
- 1);
1525 tcg_gen_shli_tl(s
->T0
, s
->T0
, op2
);
1530 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1532 /* update eflags if non zero shift */
1534 tcg_gen_mov_tl(cpu_cc_src
, s
->tmp4
);
1535 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
1536 set_cc_op(s
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1540 static void gen_rot_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
, int is_right
)
1542 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1546 if (op1
== OR_TMP0
) {
1547 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1549 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1552 tcg_gen_andi_tl(s
->T1
, s
->T1
, mask
);
1556 /* Replicate the 8-bit input so that a 32-bit rotate works. */
1557 tcg_gen_ext8u_tl(s
->T0
, s
->T0
);
1558 tcg_gen_muli_tl(s
->T0
, s
->T0
, 0x01010101);
1561 /* Replicate the 16-bit input so that a 32-bit rotate works. */
1562 tcg_gen_deposit_tl(s
->T0
, s
->T0
, s
->T0
, 16, 16);
1565 #ifdef TARGET_X86_64
1567 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
1568 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, s
->T1
);
1570 tcg_gen_rotr_i32(s
->tmp2_i32
, s
->tmp2_i32
, s
->tmp3_i32
);
1572 tcg_gen_rotl_i32(s
->tmp2_i32
, s
->tmp2_i32
, s
->tmp3_i32
);
1574 tcg_gen_extu_i32_tl(s
->T0
, s
->tmp2_i32
);
1579 tcg_gen_rotr_tl(s
->T0
, s
->T0
, s
->T1
);
1581 tcg_gen_rotl_tl(s
->T0
, s
->T0
, s
->T1
);
1587 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1589 /* We'll need the flags computed into CC_SRC. */
1590 gen_compute_eflags(s
);
1592 /* The value that was "rotated out" is now present at the other end
1593 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1594 since we've computed the flags into CC_SRC, these variables are
1597 tcg_gen_shri_tl(cpu_cc_src2
, s
->T0
, mask
- 1);
1598 tcg_gen_shri_tl(cpu_cc_dst
, s
->T0
, mask
);
1599 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1601 tcg_gen_shri_tl(cpu_cc_src2
, s
->T0
, mask
);
1602 tcg_gen_andi_tl(cpu_cc_dst
, s
->T0
, 1);
1604 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1605 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1607 /* Now conditionally store the new CC_OP value. If the shift count
1608 is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1609 Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1610 exactly as we computed above. */
1611 t0
= tcg_const_i32(0);
1612 t1
= tcg_temp_new_i32();
1613 tcg_gen_trunc_tl_i32(t1
, s
->T1
);
1614 tcg_gen_movi_i32(s
->tmp2_i32
, CC_OP_ADCOX
);
1615 tcg_gen_movi_i32(s
->tmp3_i32
, CC_OP_EFLAGS
);
1616 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, t1
, t0
,
1617 s
->tmp2_i32
, s
->tmp3_i32
);
1618 tcg_temp_free_i32(t0
);
1619 tcg_temp_free_i32(t1
);
1621 /* The CC_OP value is no longer predictable. */
1622 set_cc_op(s
, CC_OP_DYNAMIC
);
1625 static void gen_rot_rm_im(DisasContext
*s
, TCGMemOp ot
, int op1
, int op2
,
1628 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1632 if (op1
== OR_TMP0
) {
1633 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1635 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1641 #ifdef TARGET_X86_64
1643 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
1645 tcg_gen_rotri_i32(s
->tmp2_i32
, s
->tmp2_i32
, op2
);
1647 tcg_gen_rotli_i32(s
->tmp2_i32
, s
->tmp2_i32
, op2
);
1649 tcg_gen_extu_i32_tl(s
->T0
, s
->tmp2_i32
);
1654 tcg_gen_rotri_tl(s
->T0
, s
->T0
, op2
);
1656 tcg_gen_rotli_tl(s
->T0
, s
->T0
, op2
);
1667 shift
= mask
+ 1 - shift
;
1669 gen_extu(ot
, s
->T0
);
1670 tcg_gen_shli_tl(s
->tmp0
, s
->T0
, shift
);
1671 tcg_gen_shri_tl(s
->T0
, s
->T0
, mask
+ 1 - shift
);
1672 tcg_gen_or_tl(s
->T0
, s
->T0
, s
->tmp0
);
1678 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1681 /* Compute the flags into CC_SRC. */
1682 gen_compute_eflags(s
);
1684 /* The value that was "rotated out" is now present at the other end
1685 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1686 since we've computed the flags into CC_SRC, these variables are
1689 tcg_gen_shri_tl(cpu_cc_src2
, s
->T0
, mask
- 1);
1690 tcg_gen_shri_tl(cpu_cc_dst
, s
->T0
, mask
);
1691 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1693 tcg_gen_shri_tl(cpu_cc_src2
, s
->T0
, mask
);
1694 tcg_gen_andi_tl(cpu_cc_dst
, s
->T0
, 1);
1696 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1697 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1698 set_cc_op(s
, CC_OP_ADCOX
);
1702 /* XXX: add faster immediate = 1 case */
1703 static void gen_rotc_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1706 gen_compute_eflags(s
);
1707 assert(s
->cc_op
== CC_OP_EFLAGS
);
1711 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1713 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1718 gen_helper_rcrb(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1721 gen_helper_rcrw(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1724 gen_helper_rcrl(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1726 #ifdef TARGET_X86_64
1728 gen_helper_rcrq(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1737 gen_helper_rclb(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1740 gen_helper_rclw(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1743 gen_helper_rcll(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1745 #ifdef TARGET_X86_64
1747 gen_helper_rclq(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1755 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1758 /* XXX: add faster immediate case */
1759 static void gen_shiftd_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1760 bool is_right
, TCGv count_in
)
1762 target_ulong mask
= (ot
== MO_64
? 63 : 31);
1766 if (op1
== OR_TMP0
) {
1767 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1769 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1772 count
= tcg_temp_new();
1773 tcg_gen_andi_tl(count
, count_in
, mask
);
1777 /* Note: we implement the Intel behaviour for shift count > 16.
1778 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A
1779 portion by constructing it as a 32-bit value. */
1781 tcg_gen_deposit_tl(s
->tmp0
, s
->T0
, s
->T1
, 16, 16);
1782 tcg_gen_mov_tl(s
->T1
, s
->T0
);
1783 tcg_gen_mov_tl(s
->T0
, s
->tmp0
);
1785 tcg_gen_deposit_tl(s
->T1
, s
->T0
, s
->T1
, 16, 16);
1788 #ifdef TARGET_X86_64
1790 /* Concatenate the two 32-bit values and use a 64-bit shift. */
1791 tcg_gen_subi_tl(s
->tmp0
, count
, 1);
1793 tcg_gen_concat_tl_i64(s
->T0
, s
->T0
, s
->T1
);
1794 tcg_gen_shr_i64(s
->tmp0
, s
->T0
, s
->tmp0
);
1795 tcg_gen_shr_i64(s
->T0
, s
->T0
, count
);
1797 tcg_gen_concat_tl_i64(s
->T0
, s
->T1
, s
->T0
);
1798 tcg_gen_shl_i64(s
->tmp0
, s
->T0
, s
->tmp0
);
1799 tcg_gen_shl_i64(s
->T0
, s
->T0
, count
);
1800 tcg_gen_shri_i64(s
->tmp0
, s
->tmp0
, 32);
1801 tcg_gen_shri_i64(s
->T0
, s
->T0
, 32);
1806 tcg_gen_subi_tl(s
->tmp0
, count
, 1);
1808 tcg_gen_shr_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1810 tcg_gen_subfi_tl(s
->tmp4
, mask
+ 1, count
);
1811 tcg_gen_shr_tl(s
->T0
, s
->T0
, count
);
1812 tcg_gen_shl_tl(s
->T1
, s
->T1
, s
->tmp4
);
1814 tcg_gen_shl_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1816 /* Only needed if count > 16, for Intel behaviour. */
1817 tcg_gen_subfi_tl(s
->tmp4
, 33, count
);
1818 tcg_gen_shr_tl(s
->tmp4
, s
->T1
, s
->tmp4
);
1819 tcg_gen_or_tl(s
->tmp0
, s
->tmp0
, s
->tmp4
);
1822 tcg_gen_subfi_tl(s
->tmp4
, mask
+ 1, count
);
1823 tcg_gen_shl_tl(s
->T0
, s
->T0
, count
);
1824 tcg_gen_shr_tl(s
->T1
, s
->T1
, s
->tmp4
);
1826 tcg_gen_movi_tl(s
->tmp4
, 0);
1827 tcg_gen_movcond_tl(TCG_COND_EQ
, s
->T1
, count
, s
->tmp4
,
1829 tcg_gen_or_tl(s
->T0
, s
->T0
, s
->T1
);
1834 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1836 gen_shift_flags(s
, ot
, s
->T0
, s
->tmp0
, count
, is_right
);
1837 tcg_temp_free(count
);
1840 static void gen_shift(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
, int s
)
1843 gen_op_mov_v_reg(s1
, ot
, s1
->T1
, s
);
1846 gen_rot_rm_T1(s1
, ot
, d
, 0);
1849 gen_rot_rm_T1(s1
, ot
, d
, 1);
1853 gen_shift_rm_T1(s1
, ot
, d
, 0, 0);
1856 gen_shift_rm_T1(s1
, ot
, d
, 1, 0);
1859 gen_shift_rm_T1(s1
, ot
, d
, 1, 1);
1862 gen_rotc_rm_T1(s1
, ot
, d
, 0);
1865 gen_rotc_rm_T1(s1
, ot
, d
, 1);
1870 static void gen_shifti(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
, int c
)
1874 gen_rot_rm_im(s1
, ot
, d
, c
, 0);
1877 gen_rot_rm_im(s1
, ot
, d
, c
, 1);
1881 gen_shift_rm_im(s1
, ot
, d
, c
, 0, 0);
1884 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 0);
1887 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 1);
1890 /* currently not optimized */
1891 tcg_gen_movi_tl(s1
->T1
, c
);
1892 gen_shift(s1
, op
, ot
, d
, OR_TMP1
);
1897 #define X86_MAX_INSN_LENGTH 15
1899 static uint64_t advance_pc(CPUX86State
*env
, DisasContext
*s
, int num_bytes
)
1901 uint64_t pc
= s
->pc
;
1904 if (unlikely(s
->pc
- s
->pc_start
> X86_MAX_INSN_LENGTH
)) {
1905 /* If the instruction's 16th byte is on a different page than the 1st, a
1906 * page fault on the second page wins over the general protection fault
1907 * caused by the instruction being too long.
1908 * This can happen even if the operand is only one byte long!
1910 if (((s
->pc
- 1) ^ (pc
- 1)) & TARGET_PAGE_MASK
) {
1911 volatile uint8_t unused
=
1912 cpu_ldub_code(env
, (s
->pc
- 1) & TARGET_PAGE_MASK
);
1915 siglongjmp(s
->jmpbuf
, 1);
1921 static inline uint8_t x86_ldub_code(CPUX86State
*env
, DisasContext
*s
)
1923 return cpu_ldub_code(env
, advance_pc(env
, s
, 1));
1926 static inline int16_t x86_ldsw_code(CPUX86State
*env
, DisasContext
*s
)
1928 return cpu_ldsw_code(env
, advance_pc(env
, s
, 2));
1931 static inline uint16_t x86_lduw_code(CPUX86State
*env
, DisasContext
*s
)
1933 return cpu_lduw_code(env
, advance_pc(env
, s
, 2));
1936 static inline uint32_t x86_ldl_code(CPUX86State
*env
, DisasContext
*s
)
1938 return cpu_ldl_code(env
, advance_pc(env
, s
, 4));
1941 #ifdef TARGET_X86_64
1942 static inline uint64_t x86_ldq_code(CPUX86State
*env
, DisasContext
*s
)
1944 return cpu_ldq_code(env
, advance_pc(env
, s
, 8));
1948 /* Decompose an address. */
1950 typedef struct AddressParts
{
1958 static AddressParts
gen_lea_modrm_0(CPUX86State
*env
, DisasContext
*s
,
1961 int def_seg
, base
, index
, scale
, mod
, rm
;
1970 mod
= (modrm
>> 6) & 3;
1972 base
= rm
| REX_B(s
);
1975 /* Normally filtered out earlier, but including this path
1976 simplifies multi-byte nop, as well as bndcl, bndcu, bndcn. */
1985 int code
= x86_ldub_code(env
, s
);
1986 scale
= (code
>> 6) & 3;
1987 index
= ((code
>> 3) & 7) | REX_X(s
);
1989 index
= -1; /* no index */
1991 base
= (code
& 7) | REX_B(s
);
1997 if ((base
& 7) == 5) {
1999 disp
= (int32_t)x86_ldl_code(env
, s
);
2000 if (CODE64(s
) && !havesib
) {
2002 disp
+= s
->pc
+ s
->rip_offset
;
2007 disp
= (int8_t)x86_ldub_code(env
, s
);
2011 disp
= (int32_t)x86_ldl_code(env
, s
);
2015 /* For correct popl handling with esp. */
2016 if (base
== R_ESP
&& s
->popl_esp_hack
) {
2017 disp
+= s
->popl_esp_hack
;
2019 if (base
== R_EBP
|| base
== R_ESP
) {
2028 disp
= x86_lduw_code(env
, s
);
2031 } else if (mod
== 1) {
2032 disp
= (int8_t)x86_ldub_code(env
, s
);
2034 disp
= (int16_t)x86_lduw_code(env
, s
);
2078 return (AddressParts
){ def_seg
, base
, index
, scale
, disp
};
2081 /* Compute the address, with a minimum number of TCG ops. */
2082 static TCGv
gen_lea_modrm_1(DisasContext
*s
, AddressParts a
)
2088 ea
= cpu_regs
[a
.index
];
2090 tcg_gen_shli_tl(s
->A0
, cpu_regs
[a
.index
], a
.scale
);
2094 tcg_gen_add_tl(s
->A0
, ea
, cpu_regs
[a
.base
]);
2097 } else if (a
.base
>= 0) {
2098 ea
= cpu_regs
[a
.base
];
2101 tcg_gen_movi_tl(s
->A0
, a
.disp
);
2103 } else if (a
.disp
!= 0) {
2104 tcg_gen_addi_tl(s
->A0
, ea
, a
.disp
);
2111 static void gen_lea_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2113 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
2114 TCGv ea
= gen_lea_modrm_1(s
, a
);
2115 gen_lea_v_seg(s
, s
->aflag
, ea
, a
.def_seg
, s
->override
);
2118 static void gen_nop_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2120 (void)gen_lea_modrm_0(env
, s
, modrm
);
2123 /* Used for BNDCL, BNDCU, BNDCN. */
2124 static void gen_bndck(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2125 TCGCond cond
, TCGv_i64 bndv
)
2127 TCGv ea
= gen_lea_modrm_1(s
, gen_lea_modrm_0(env
, s
, modrm
));
2129 tcg_gen_extu_tl_i64(s
->tmp1_i64
, ea
);
2131 tcg_gen_ext32u_i64(s
->tmp1_i64
, s
->tmp1_i64
);
2133 tcg_gen_setcond_i64(cond
, s
->tmp1_i64
, s
->tmp1_i64
, bndv
);
2134 tcg_gen_extrl_i64_i32(s
->tmp2_i32
, s
->tmp1_i64
);
2135 gen_helper_bndck(cpu_env
, s
->tmp2_i32
);
2138 /* used for LEA and MOV AX, mem */
2139 static void gen_add_A0_ds_seg(DisasContext
*s
)
2141 gen_lea_v_seg(s
, s
->aflag
, s
->A0
, R_DS
, s
->override
);
2144 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2146 static void gen_ldst_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2147 TCGMemOp ot
, int reg
, int is_store
)
2151 mod
= (modrm
>> 6) & 3;
2152 rm
= (modrm
& 7) | REX_B(s
);
2156 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
2157 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
2159 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
2161 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
2164 gen_lea_modrm(env
, s
, modrm
);
2167 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
2168 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
2170 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
2172 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
2177 static inline uint32_t insn_get(CPUX86State
*env
, DisasContext
*s
, TCGMemOp ot
)
2183 ret
= x86_ldub_code(env
, s
);
2186 ret
= x86_lduw_code(env
, s
);
2189 #ifdef TARGET_X86_64
2192 ret
= x86_ldl_code(env
, s
);
2200 static inline int insn_const_size(TCGMemOp ot
)
2209 static inline bool use_goto_tb(DisasContext
*s
, target_ulong pc
)
2211 #ifndef CONFIG_USER_ONLY
2212 return (pc
& TARGET_PAGE_MASK
) == (s
->base
.tb
->pc
& TARGET_PAGE_MASK
) ||
2213 (pc
& TARGET_PAGE_MASK
) == (s
->pc_start
& TARGET_PAGE_MASK
);
2219 static inline void gen_goto_tb(DisasContext
*s
, int tb_num
, target_ulong eip
)
2221 target_ulong pc
= s
->cs_base
+ eip
;
2223 if (use_goto_tb(s
, pc
)) {
2224 /* jump to same page: we can use a direct jump */
2225 tcg_gen_goto_tb(tb_num
);
2227 tcg_gen_exit_tb(s
->base
.tb
, tb_num
);
2228 s
->base
.is_jmp
= DISAS_NORETURN
;
2230 /* jump to another page */
2236 static inline void gen_jcc(DisasContext
*s
, int b
,
2237 target_ulong val
, target_ulong next_eip
)
2242 l1
= gen_new_label();
2245 gen_goto_tb(s
, 0, next_eip
);
2248 gen_goto_tb(s
, 1, val
);
2250 l1
= gen_new_label();
2251 l2
= gen_new_label();
2254 gen_jmp_im(s
, next_eip
);
2264 static void gen_cmovcc1(CPUX86State
*env
, DisasContext
*s
, TCGMemOp ot
, int b
,
2269 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
2271 cc
= gen_prepare_cc(s
, b
, s
->T1
);
2272 if (cc
.mask
!= -1) {
2273 TCGv t0
= tcg_temp_new();
2274 tcg_gen_andi_tl(t0
, cc
.reg
, cc
.mask
);
2278 cc
.reg2
= tcg_const_tl(cc
.imm
);
2281 tcg_gen_movcond_tl(cc
.cond
, s
->T0
, cc
.reg
, cc
.reg2
,
2282 s
->T0
, cpu_regs
[reg
]);
2283 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
2285 if (cc
.mask
!= -1) {
2286 tcg_temp_free(cc
.reg
);
2289 tcg_temp_free(cc
.reg2
);
2293 static inline void gen_op_movl_T0_seg(DisasContext
*s
, int seg_reg
)
2295 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
2296 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2299 static inline void gen_op_movl_seg_T0_vm(DisasContext
*s
, int seg_reg
)
2301 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
2302 tcg_gen_st32_tl(s
->T0
, cpu_env
,
2303 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2304 tcg_gen_shli_tl(cpu_seg_base
[seg_reg
], s
->T0
, 4);
2307 /* move T0 to seg_reg and compute if the CPU state may change. Never
2308 call this function with seg_reg == R_CS */
2309 static void gen_movl_seg_T0(DisasContext
*s
, int seg_reg
)
2311 if (s
->pe
&& !s
->vm86
) {
2312 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
2313 gen_helper_load_seg(cpu_env
, tcg_const_i32(seg_reg
), s
->tmp2_i32
);
2314 /* abort translation because the addseg value may change or
2315 because ss32 may change. For R_SS, translation must always
2316 stop as a special handling must be done to disable hardware
2317 interrupts for the next instruction */
2318 if (seg_reg
== R_SS
|| (s
->code32
&& seg_reg
< R_FS
)) {
2319 s
->base
.is_jmp
= DISAS_TOO_MANY
;
2322 gen_op_movl_seg_T0_vm(s
, seg_reg
);
2323 if (seg_reg
== R_SS
) {
2324 s
->base
.is_jmp
= DISAS_TOO_MANY
;
2329 static inline int svm_is_rep(int prefixes
)
2331 return ((prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) ? 8 : 0);
2335 gen_svm_check_intercept_param(DisasContext
*s
, target_ulong pc_start
,
2336 uint32_t type
, uint64_t param
)
2338 /* no SVM activated; fast case */
2339 if (likely(!(s
->flags
& HF_GUEST_MASK
)))
2341 gen_update_cc_op(s
);
2342 gen_jmp_im(s
, pc_start
- s
->cs_base
);
2343 gen_helper_svm_check_intercept_param(cpu_env
, tcg_const_i32(type
),
2344 tcg_const_i64(param
));
2348 gen_svm_check_intercept(DisasContext
*s
, target_ulong pc_start
, uint64_t type
)
2350 gen_svm_check_intercept_param(s
, pc_start
, type
, 0);
2353 static inline void gen_stack_update(DisasContext
*s
, int addend
)
2355 gen_op_add_reg_im(s
, mo_stacksize(s
), R_ESP
, addend
);
2358 /* Generate a push. It depends on ss32, addseg and dflag. */
2359 static void gen_push_v(DisasContext
*s
, TCGv val
)
2361 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2362 TCGMemOp a_ot
= mo_stacksize(s
);
2363 int size
= 1 << d_ot
;
2364 TCGv new_esp
= s
->A0
;
2366 tcg_gen_subi_tl(s
->A0
, cpu_regs
[R_ESP
], size
);
2371 tcg_gen_mov_tl(new_esp
, s
->A0
);
2373 gen_lea_v_seg(s
, a_ot
, s
->A0
, R_SS
, -1);
2376 gen_op_st_v(s
, d_ot
, val
, s
->A0
);
2377 gen_op_mov_reg_v(s
, a_ot
, R_ESP
, new_esp
);
2380 /* two step pop is necessary for precise exceptions */
2381 static TCGMemOp
gen_pop_T0(DisasContext
*s
)
2383 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2385 gen_lea_v_seg(s
, mo_stacksize(s
), cpu_regs
[R_ESP
], R_SS
, -1);
2386 gen_op_ld_v(s
, d_ot
, s
->T0
, s
->A0
);
2391 static inline void gen_pop_update(DisasContext
*s
, TCGMemOp ot
)
2393 gen_stack_update(s
, 1 << ot
);
2396 static inline void gen_stack_A0(DisasContext
*s
)
2398 gen_lea_v_seg(s
, s
->ss32
? MO_32
: MO_16
, cpu_regs
[R_ESP
], R_SS
, -1);
2401 static void gen_pusha(DisasContext
*s
)
2403 TCGMemOp s_ot
= s
->ss32
? MO_32
: MO_16
;
2404 TCGMemOp d_ot
= s
->dflag
;
2405 int size
= 1 << d_ot
;
2408 for (i
= 0; i
< 8; i
++) {
2409 tcg_gen_addi_tl(s
->A0
, cpu_regs
[R_ESP
], (i
- 8) * size
);
2410 gen_lea_v_seg(s
, s_ot
, s
->A0
, R_SS
, -1);
2411 gen_op_st_v(s
, d_ot
, cpu_regs
[7 - i
], s
->A0
);
2414 gen_stack_update(s
, -8 * size
);
2417 static void gen_popa(DisasContext
*s
)
2419 TCGMemOp s_ot
= s
->ss32
? MO_32
: MO_16
;
2420 TCGMemOp d_ot
= s
->dflag
;
2421 int size
= 1 << d_ot
;
2424 for (i
= 0; i
< 8; i
++) {
2425 /* ESP is not reloaded */
2426 if (7 - i
== R_ESP
) {
2429 tcg_gen_addi_tl(s
->A0
, cpu_regs
[R_ESP
], i
* size
);
2430 gen_lea_v_seg(s
, s_ot
, s
->A0
, R_SS
, -1);
2431 gen_op_ld_v(s
, d_ot
, s
->T0
, s
->A0
);
2432 gen_op_mov_reg_v(s
, d_ot
, 7 - i
, s
->T0
);
2435 gen_stack_update(s
, 8 * size
);
2438 static void gen_enter(DisasContext
*s
, int esp_addend
, int level
)
2440 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2441 TCGMemOp a_ot
= CODE64(s
) ? MO_64
: s
->ss32
? MO_32
: MO_16
;
2442 int size
= 1 << d_ot
;
2444 /* Push BP; compute FrameTemp into T1. */
2445 tcg_gen_subi_tl(s
->T1
, cpu_regs
[R_ESP
], size
);
2446 gen_lea_v_seg(s
, a_ot
, s
->T1
, R_SS
, -1);
2447 gen_op_st_v(s
, d_ot
, cpu_regs
[R_EBP
], s
->A0
);
2453 /* Copy level-1 pointers from the previous frame. */
2454 for (i
= 1; i
< level
; ++i
) {
2455 tcg_gen_subi_tl(s
->A0
, cpu_regs
[R_EBP
], size
* i
);
2456 gen_lea_v_seg(s
, a_ot
, s
->A0
, R_SS
, -1);
2457 gen_op_ld_v(s
, d_ot
, s
->tmp0
, s
->A0
);
2459 tcg_gen_subi_tl(s
->A0
, s
->T1
, size
* i
);
2460 gen_lea_v_seg(s
, a_ot
, s
->A0
, R_SS
, -1);
2461 gen_op_st_v(s
, d_ot
, s
->tmp0
, s
->A0
);
2464 /* Push the current FrameTemp as the last level. */
2465 tcg_gen_subi_tl(s
->A0
, s
->T1
, size
* level
);
2466 gen_lea_v_seg(s
, a_ot
, s
->A0
, R_SS
, -1);
2467 gen_op_st_v(s
, d_ot
, s
->T1
, s
->A0
);
2470 /* Copy the FrameTemp value to EBP. */
2471 gen_op_mov_reg_v(s
, a_ot
, R_EBP
, s
->T1
);
2473 /* Compute the final value of ESP. */
2474 tcg_gen_subi_tl(s
->T1
, s
->T1
, esp_addend
+ size
* level
);
2475 gen_op_mov_reg_v(s
, a_ot
, R_ESP
, s
->T1
);
2478 static void gen_leave(DisasContext
*s
)
2480 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2481 TCGMemOp a_ot
= mo_stacksize(s
);
2483 gen_lea_v_seg(s
, a_ot
, cpu_regs
[R_EBP
], R_SS
, -1);
2484 gen_op_ld_v(s
, d_ot
, s
->T0
, s
->A0
);
2486 tcg_gen_addi_tl(s
->T1
, cpu_regs
[R_EBP
], 1 << d_ot
);
2488 gen_op_mov_reg_v(s
, d_ot
, R_EBP
, s
->T0
);
2489 gen_op_mov_reg_v(s
, a_ot
, R_ESP
, s
->T1
);
2492 /* Similarly, except that the assumption here is that we don't decode
2493 the instruction at all -- either a missing opcode, an unimplemented
2494 feature, or just a bogus instruction stream. */
2495 static void gen_unknown_opcode(CPUX86State
*env
, DisasContext
*s
)
2497 gen_illegal_opcode(s
);
2499 if (qemu_loglevel_mask(LOG_UNIMP
)) {
2500 target_ulong pc
= s
->pc_start
, end
= s
->pc
;
2502 qemu_log("ILLOPC: " TARGET_FMT_lx
":", pc
);
2503 for (; pc
< end
; ++pc
) {
2504 qemu_log(" %02x", cpu_ldub_code(env
, pc
));
2511 /* an interrupt is different from an exception because of the
2513 static void gen_interrupt(DisasContext
*s
, int intno
,
2514 target_ulong cur_eip
, target_ulong next_eip
)
2516 gen_update_cc_op(s
);
2517 gen_jmp_im(s
, cur_eip
);
2518 gen_helper_raise_interrupt(cpu_env
, tcg_const_i32(intno
),
2519 tcg_const_i32(next_eip
- cur_eip
));
2520 s
->base
.is_jmp
= DISAS_NORETURN
;
2523 static void gen_debug(DisasContext
*s
, target_ulong cur_eip
)
2525 gen_update_cc_op(s
);
2526 gen_jmp_im(s
, cur_eip
);
2527 gen_helper_debug(cpu_env
);
2528 s
->base
.is_jmp
= DISAS_NORETURN
;
2531 static void gen_set_hflag(DisasContext
*s
, uint32_t mask
)
2533 if ((s
->flags
& mask
) == 0) {
2534 TCGv_i32 t
= tcg_temp_new_i32();
2535 tcg_gen_ld_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2536 tcg_gen_ori_i32(t
, t
, mask
);
2537 tcg_gen_st_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2538 tcg_temp_free_i32(t
);
2543 static void gen_reset_hflag(DisasContext
*s
, uint32_t mask
)
2545 if (s
->flags
& mask
) {
2546 TCGv_i32 t
= tcg_temp_new_i32();
2547 tcg_gen_ld_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2548 tcg_gen_andi_i32(t
, t
, ~mask
);
2549 tcg_gen_st_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2550 tcg_temp_free_i32(t
);
2555 /* Clear BND registers during legacy branches. */
2556 static void gen_bnd_jmp(DisasContext
*s
)
2558 /* Clear the registers only if BND prefix is missing, MPX is enabled,
2559 and if the BNDREGs are known to be in use (non-zero) already.
2560 The helper itself will check BNDPRESERVE at runtime. */
2561 if ((s
->prefix
& PREFIX_REPNZ
) == 0
2562 && (s
->flags
& HF_MPX_EN_MASK
) != 0
2563 && (s
->flags
& HF_MPX_IU_MASK
) != 0) {
2564 gen_helper_bnd_jmp(cpu_env
);
2568 /* Generate an end of block. Trace exception is also generated if needed.
2569 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set.
2570 If RECHECK_TF, emit a rechecking helper for #DB, ignoring the state of
2571 S->TF. This is used by the syscall/sysret insns. */
2573 do_gen_eob_worker(DisasContext
*s
, bool inhibit
, bool recheck_tf
, bool jr
)
2575 gen_update_cc_op(s
);
2577 /* If several instructions disable interrupts, only the first does it. */
2578 if (inhibit
&& !(s
->flags
& HF_INHIBIT_IRQ_MASK
)) {
2579 gen_set_hflag(s
, HF_INHIBIT_IRQ_MASK
);
2581 gen_reset_hflag(s
, HF_INHIBIT_IRQ_MASK
);
2584 if (s
->base
.tb
->flags
& HF_RF_MASK
) {
2585 gen_helper_reset_rf(cpu_env
);
2587 if (s
->base
.singlestep_enabled
) {
2588 gen_helper_debug(cpu_env
);
2589 } else if (recheck_tf
) {
2590 gen_helper_rechecking_single_step(cpu_env
);
2591 tcg_gen_exit_tb(NULL
, 0);
2593 gen_helper_single_step(cpu_env
);
2595 tcg_gen_lookup_and_goto_ptr();
2597 tcg_gen_exit_tb(NULL
, 0);
2599 s
->base
.is_jmp
= DISAS_NORETURN
;
2603 gen_eob_worker(DisasContext
*s
, bool inhibit
, bool recheck_tf
)
2605 do_gen_eob_worker(s
, inhibit
, recheck_tf
, false);
2609 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set. */
2610 static void gen_eob_inhibit_irq(DisasContext
*s
, bool inhibit
)
2612 gen_eob_worker(s
, inhibit
, false);
2615 /* End of block, resetting the inhibit irq flag. */
2616 static void gen_eob(DisasContext
*s
)
2618 gen_eob_worker(s
, false, false);
2621 /* Jump to register */
2622 static void gen_jr(DisasContext
*s
, TCGv dest
)
2624 do_gen_eob_worker(s
, false, false, true);
2627 /* generate a jump to eip. No segment change must happen before as a
2628 direct call to the next block may occur */
2629 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
)
2631 gen_update_cc_op(s
);
2632 set_cc_op(s
, CC_OP_DYNAMIC
);
2634 gen_goto_tb(s
, tb_num
, eip
);
2641 static void gen_jmp(DisasContext
*s
, target_ulong eip
)
2643 gen_jmp_tb(s
, eip
, 0);
2646 static inline void gen_ldq_env_A0(DisasContext
*s
, int offset
)
2648 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
, s
->mem_index
, MO_LEQ
);
2649 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, offset
);
2652 static inline void gen_stq_env_A0(DisasContext
*s
, int offset
)
2654 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, offset
);
2655 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
, s
->mem_index
, MO_LEQ
);
2658 static inline void gen_ldo_env_A0(DisasContext
*s
, int offset
)
2660 int mem_index
= s
->mem_index
;
2661 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
, mem_index
, MO_LEQ
);
2662 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2663 tcg_gen_addi_tl(s
->tmp0
, s
->A0
, 8);
2664 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->tmp0
, mem_index
, MO_LEQ
);
2665 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2668 static inline void gen_sto_env_A0(DisasContext
*s
, int offset
)
2670 int mem_index
= s
->mem_index
;
2671 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2672 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
, mem_index
, MO_LEQ
);
2673 tcg_gen_addi_tl(s
->tmp0
, s
->A0
, 8);
2674 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2675 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->tmp0
, mem_index
, MO_LEQ
);
2678 static inline void gen_op_movo(DisasContext
*s
, int d_offset
, int s_offset
)
2680 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, s_offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2681 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, d_offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2682 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, s_offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2683 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, d_offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2686 static inline void gen_op_movq(DisasContext
*s
, int d_offset
, int s_offset
)
2688 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, s_offset
);
2689 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, d_offset
);
2692 static inline void gen_op_movl(DisasContext
*s
, int d_offset
, int s_offset
)
2694 tcg_gen_ld_i32(s
->tmp2_i32
, cpu_env
, s_offset
);
2695 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
, d_offset
);
2698 static inline void gen_op_movq_env_0(DisasContext
*s
, int d_offset
)
2700 tcg_gen_movi_i64(s
->tmp1_i64
, 0);
2701 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, d_offset
);
2704 typedef void (*SSEFunc_i_ep
)(TCGv_i32 val
, TCGv_ptr env
, TCGv_ptr reg
);
2705 typedef void (*SSEFunc_l_ep
)(TCGv_i64 val
, TCGv_ptr env
, TCGv_ptr reg
);
2706 typedef void (*SSEFunc_0_epi
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i32 val
);
2707 typedef void (*SSEFunc_0_epl
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i64 val
);
2708 typedef void (*SSEFunc_0_epp
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
);
2709 typedef void (*SSEFunc_0_eppi
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2711 typedef void (*SSEFunc_0_ppi
)(TCGv_ptr reg_a
, TCGv_ptr reg_b
, TCGv_i32 val
);
2712 typedef void (*SSEFunc_0_eppt
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2715 #define SSE_SPECIAL ((void *)1)
2716 #define SSE_DUMMY ((void *)2)
2718 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2719 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2720 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2722 static const SSEFunc_0_epp sse_op_table1
[256][4] = {
2723 /* 3DNow! extensions */
2724 [0x0e] = { SSE_DUMMY
}, /* femms */
2725 [0x0f] = { SSE_DUMMY
}, /* pf... */
2726 /* pure SSE operations */
2727 [0x10] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2728 [0x11] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2729 [0x12] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd, movsldup, movddup */
2730 [0x13] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd */
2731 [0x14] = { gen_helper_punpckldq_xmm
, gen_helper_punpcklqdq_xmm
},
2732 [0x15] = { gen_helper_punpckhdq_xmm
, gen_helper_punpckhqdq_xmm
},
2733 [0x16] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd, movshdup */
2734 [0x17] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd */
2736 [0x28] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2737 [0x29] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2738 [0x2a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2739 [0x2b] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movntps, movntpd, movntss, movntsd */
2740 [0x2c] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2741 [0x2d] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2742 [0x2e] = { gen_helper_ucomiss
, gen_helper_ucomisd
},
2743 [0x2f] = { gen_helper_comiss
, gen_helper_comisd
},
2744 [0x50] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movmskps, movmskpd */
2745 [0x51] = SSE_FOP(sqrt
),
2746 [0x52] = { gen_helper_rsqrtps
, NULL
, gen_helper_rsqrtss
, NULL
},
2747 [0x53] = { gen_helper_rcpps
, NULL
, gen_helper_rcpss
, NULL
},
2748 [0x54] = { gen_helper_pand_xmm
, gen_helper_pand_xmm
}, /* andps, andpd */
2749 [0x55] = { gen_helper_pandn_xmm
, gen_helper_pandn_xmm
}, /* andnps, andnpd */
2750 [0x56] = { gen_helper_por_xmm
, gen_helper_por_xmm
}, /* orps, orpd */
2751 [0x57] = { gen_helper_pxor_xmm
, gen_helper_pxor_xmm
}, /* xorps, xorpd */
2752 [0x58] = SSE_FOP(add
),
2753 [0x59] = SSE_FOP(mul
),
2754 [0x5a] = { gen_helper_cvtps2pd
, gen_helper_cvtpd2ps
,
2755 gen_helper_cvtss2sd
, gen_helper_cvtsd2ss
},
2756 [0x5b] = { gen_helper_cvtdq2ps
, gen_helper_cvtps2dq
, gen_helper_cvttps2dq
},
2757 [0x5c] = SSE_FOP(sub
),
2758 [0x5d] = SSE_FOP(min
),
2759 [0x5e] = SSE_FOP(div
),
2760 [0x5f] = SSE_FOP(max
),
2762 [0xc2] = SSE_FOP(cmpeq
),
2763 [0xc6] = { (SSEFunc_0_epp
)gen_helper_shufps
,
2764 (SSEFunc_0_epp
)gen_helper_shufpd
}, /* XXX: casts */
2766 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */
2767 [0x38] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2768 [0x3a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2770 /* MMX ops and their SSE extensions */
2771 [0x60] = MMX_OP2(punpcklbw
),
2772 [0x61] = MMX_OP2(punpcklwd
),
2773 [0x62] = MMX_OP2(punpckldq
),
2774 [0x63] = MMX_OP2(packsswb
),
2775 [0x64] = MMX_OP2(pcmpgtb
),
2776 [0x65] = MMX_OP2(pcmpgtw
),
2777 [0x66] = MMX_OP2(pcmpgtl
),
2778 [0x67] = MMX_OP2(packuswb
),
2779 [0x68] = MMX_OP2(punpckhbw
),
2780 [0x69] = MMX_OP2(punpckhwd
),
2781 [0x6a] = MMX_OP2(punpckhdq
),
2782 [0x6b] = MMX_OP2(packssdw
),
2783 [0x6c] = { NULL
, gen_helper_punpcklqdq_xmm
},
2784 [0x6d] = { NULL
, gen_helper_punpckhqdq_xmm
},
2785 [0x6e] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movd mm, ea */
2786 [0x6f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, , movqdu */
2787 [0x70] = { (SSEFunc_0_epp
)gen_helper_pshufw_mmx
,
2788 (SSEFunc_0_epp
)gen_helper_pshufd_xmm
,
2789 (SSEFunc_0_epp
)gen_helper_pshufhw_xmm
,
2790 (SSEFunc_0_epp
)gen_helper_pshuflw_xmm
}, /* XXX: casts */
2791 [0x71] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftw */
2792 [0x72] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftd */
2793 [0x73] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftq */
2794 [0x74] = MMX_OP2(pcmpeqb
),
2795 [0x75] = MMX_OP2(pcmpeqw
),
2796 [0x76] = MMX_OP2(pcmpeql
),
2797 [0x77] = { SSE_DUMMY
}, /* emms */
2798 [0x78] = { NULL
, SSE_SPECIAL
, NULL
, SSE_SPECIAL
}, /* extrq_i, insertq_i */
2799 [0x79] = { NULL
, gen_helper_extrq_r
, NULL
, gen_helper_insertq_r
},
2800 [0x7c] = { NULL
, gen_helper_haddpd
, NULL
, gen_helper_haddps
},
2801 [0x7d] = { NULL
, gen_helper_hsubpd
, NULL
, gen_helper_hsubps
},
2802 [0x7e] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movd, movd, , movq */
2803 [0x7f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, movdqu */
2804 [0xc4] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pinsrw */
2805 [0xc5] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pextrw */
2806 [0xd0] = { NULL
, gen_helper_addsubpd
, NULL
, gen_helper_addsubps
},
2807 [0xd1] = MMX_OP2(psrlw
),
2808 [0xd2] = MMX_OP2(psrld
),
2809 [0xd3] = MMX_OP2(psrlq
),
2810 [0xd4] = MMX_OP2(paddq
),
2811 [0xd5] = MMX_OP2(pmullw
),
2812 [0xd6] = { NULL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2813 [0xd7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pmovmskb */
2814 [0xd8] = MMX_OP2(psubusb
),
2815 [0xd9] = MMX_OP2(psubusw
),
2816 [0xda] = MMX_OP2(pminub
),
2817 [0xdb] = MMX_OP2(pand
),
2818 [0xdc] = MMX_OP2(paddusb
),
2819 [0xdd] = MMX_OP2(paddusw
),
2820 [0xde] = MMX_OP2(pmaxub
),
2821 [0xdf] = MMX_OP2(pandn
),
2822 [0xe0] = MMX_OP2(pavgb
),
2823 [0xe1] = MMX_OP2(psraw
),
2824 [0xe2] = MMX_OP2(psrad
),
2825 [0xe3] = MMX_OP2(pavgw
),
2826 [0xe4] = MMX_OP2(pmulhuw
),
2827 [0xe5] = MMX_OP2(pmulhw
),
2828 [0xe6] = { NULL
, gen_helper_cvttpd2dq
, gen_helper_cvtdq2pd
, gen_helper_cvtpd2dq
},
2829 [0xe7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movntq, movntq */
2830 [0xe8] = MMX_OP2(psubsb
),
2831 [0xe9] = MMX_OP2(psubsw
),
2832 [0xea] = MMX_OP2(pminsw
),
2833 [0xeb] = MMX_OP2(por
),
2834 [0xec] = MMX_OP2(paddsb
),
2835 [0xed] = MMX_OP2(paddsw
),
2836 [0xee] = MMX_OP2(pmaxsw
),
2837 [0xef] = MMX_OP2(pxor
),
2838 [0xf0] = { NULL
, NULL
, NULL
, SSE_SPECIAL
}, /* lddqu */
2839 [0xf1] = MMX_OP2(psllw
),
2840 [0xf2] = MMX_OP2(pslld
),
2841 [0xf3] = MMX_OP2(psllq
),
2842 [0xf4] = MMX_OP2(pmuludq
),
2843 [0xf5] = MMX_OP2(pmaddwd
),
2844 [0xf6] = MMX_OP2(psadbw
),
2845 [0xf7] = { (SSEFunc_0_epp
)gen_helper_maskmov_mmx
,
2846 (SSEFunc_0_epp
)gen_helper_maskmov_xmm
}, /* XXX: casts */
2847 [0xf8] = MMX_OP2(psubb
),
2848 [0xf9] = MMX_OP2(psubw
),
2849 [0xfa] = MMX_OP2(psubl
),
2850 [0xfb] = MMX_OP2(psubq
),
2851 [0xfc] = MMX_OP2(paddb
),
2852 [0xfd] = MMX_OP2(paddw
),
2853 [0xfe] = MMX_OP2(paddl
),
2856 static const SSEFunc_0_epp sse_op_table2
[3 * 8][2] = {
2857 [0 + 2] = MMX_OP2(psrlw
),
2858 [0 + 4] = MMX_OP2(psraw
),
2859 [0 + 6] = MMX_OP2(psllw
),
2860 [8 + 2] = MMX_OP2(psrld
),
2861 [8 + 4] = MMX_OP2(psrad
),
2862 [8 + 6] = MMX_OP2(pslld
),
2863 [16 + 2] = MMX_OP2(psrlq
),
2864 [16 + 3] = { NULL
, gen_helper_psrldq_xmm
},
2865 [16 + 6] = MMX_OP2(psllq
),
2866 [16 + 7] = { NULL
, gen_helper_pslldq_xmm
},
2869 static const SSEFunc_0_epi sse_op_table3ai
[] = {
2870 gen_helper_cvtsi2ss
,
2874 #ifdef TARGET_X86_64
2875 static const SSEFunc_0_epl sse_op_table3aq
[] = {
2876 gen_helper_cvtsq2ss
,
2881 static const SSEFunc_i_ep sse_op_table3bi
[] = {
2882 gen_helper_cvttss2si
,
2883 gen_helper_cvtss2si
,
2884 gen_helper_cvttsd2si
,
2888 #ifdef TARGET_X86_64
2889 static const SSEFunc_l_ep sse_op_table3bq
[] = {
2890 gen_helper_cvttss2sq
,
2891 gen_helper_cvtss2sq
,
2892 gen_helper_cvttsd2sq
,
2897 static const SSEFunc_0_epp sse_op_table4
[8][4] = {
2908 static const SSEFunc_0_epp sse_op_table5
[256] = {
2909 [0x0c] = gen_helper_pi2fw
,
2910 [0x0d] = gen_helper_pi2fd
,
2911 [0x1c] = gen_helper_pf2iw
,
2912 [0x1d] = gen_helper_pf2id
,
2913 [0x8a] = gen_helper_pfnacc
,
2914 [0x8e] = gen_helper_pfpnacc
,
2915 [0x90] = gen_helper_pfcmpge
,
2916 [0x94] = gen_helper_pfmin
,
2917 [0x96] = gen_helper_pfrcp
,
2918 [0x97] = gen_helper_pfrsqrt
,
2919 [0x9a] = gen_helper_pfsub
,
2920 [0x9e] = gen_helper_pfadd
,
2921 [0xa0] = gen_helper_pfcmpgt
,
2922 [0xa4] = gen_helper_pfmax
,
2923 [0xa6] = gen_helper_movq
, /* pfrcpit1; no need to actually increase precision */
2924 [0xa7] = gen_helper_movq
, /* pfrsqit1 */
2925 [0xaa] = gen_helper_pfsubr
,
2926 [0xae] = gen_helper_pfacc
,
2927 [0xb0] = gen_helper_pfcmpeq
,
2928 [0xb4] = gen_helper_pfmul
,
2929 [0xb6] = gen_helper_movq
, /* pfrcpit2 */
2930 [0xb7] = gen_helper_pmulhrw_mmx
,
2931 [0xbb] = gen_helper_pswapd
,
2932 [0xbf] = gen_helper_pavgb_mmx
/* pavgusb */
2935 struct SSEOpHelper_epp
{
2936 SSEFunc_0_epp op
[2];
2940 struct SSEOpHelper_eppi
{
2941 SSEFunc_0_eppi op
[2];
2945 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
2946 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
2947 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
2948 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
2949 #define PCLMULQDQ_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, \
2950 CPUID_EXT_PCLMULQDQ }
2951 #define AESNI_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_AES }
2953 static const struct SSEOpHelper_epp sse_op_table6
[256] = {
2954 [0x00] = SSSE3_OP(pshufb
),
2955 [0x01] = SSSE3_OP(phaddw
),
2956 [0x02] = SSSE3_OP(phaddd
),
2957 [0x03] = SSSE3_OP(phaddsw
),
2958 [0x04] = SSSE3_OP(pmaddubsw
),
2959 [0x05] = SSSE3_OP(phsubw
),
2960 [0x06] = SSSE3_OP(phsubd
),
2961 [0x07] = SSSE3_OP(phsubsw
),
2962 [0x08] = SSSE3_OP(psignb
),
2963 [0x09] = SSSE3_OP(psignw
),
2964 [0x0a] = SSSE3_OP(psignd
),
2965 [0x0b] = SSSE3_OP(pmulhrsw
),
2966 [0x10] = SSE41_OP(pblendvb
),
2967 [0x14] = SSE41_OP(blendvps
),
2968 [0x15] = SSE41_OP(blendvpd
),
2969 [0x17] = SSE41_OP(ptest
),
2970 [0x1c] = SSSE3_OP(pabsb
),
2971 [0x1d] = SSSE3_OP(pabsw
),
2972 [0x1e] = SSSE3_OP(pabsd
),
2973 [0x20] = SSE41_OP(pmovsxbw
),
2974 [0x21] = SSE41_OP(pmovsxbd
),
2975 [0x22] = SSE41_OP(pmovsxbq
),
2976 [0x23] = SSE41_OP(pmovsxwd
),
2977 [0x24] = SSE41_OP(pmovsxwq
),
2978 [0x25] = SSE41_OP(pmovsxdq
),
2979 [0x28] = SSE41_OP(pmuldq
),
2980 [0x29] = SSE41_OP(pcmpeqq
),
2981 [0x2a] = SSE41_SPECIAL
, /* movntqda */
2982 [0x2b] = SSE41_OP(packusdw
),
2983 [0x30] = SSE41_OP(pmovzxbw
),
2984 [0x31] = SSE41_OP(pmovzxbd
),
2985 [0x32] = SSE41_OP(pmovzxbq
),
2986 [0x33] = SSE41_OP(pmovzxwd
),
2987 [0x34] = SSE41_OP(pmovzxwq
),
2988 [0x35] = SSE41_OP(pmovzxdq
),
2989 [0x37] = SSE42_OP(pcmpgtq
),
2990 [0x38] = SSE41_OP(pminsb
),
2991 [0x39] = SSE41_OP(pminsd
),
2992 [0x3a] = SSE41_OP(pminuw
),
2993 [0x3b] = SSE41_OP(pminud
),
2994 [0x3c] = SSE41_OP(pmaxsb
),
2995 [0x3d] = SSE41_OP(pmaxsd
),
2996 [0x3e] = SSE41_OP(pmaxuw
),
2997 [0x3f] = SSE41_OP(pmaxud
),
2998 [0x40] = SSE41_OP(pmulld
),
2999 [0x41] = SSE41_OP(phminposuw
),
3000 [0xdb] = AESNI_OP(aesimc
),
3001 [0xdc] = AESNI_OP(aesenc
),
3002 [0xdd] = AESNI_OP(aesenclast
),
3003 [0xde] = AESNI_OP(aesdec
),
3004 [0xdf] = AESNI_OP(aesdeclast
),
3007 static const struct SSEOpHelper_eppi sse_op_table7
[256] = {
3008 [0x08] = SSE41_OP(roundps
),
3009 [0x09] = SSE41_OP(roundpd
),
3010 [0x0a] = SSE41_OP(roundss
),
3011 [0x0b] = SSE41_OP(roundsd
),
3012 [0x0c] = SSE41_OP(blendps
),
3013 [0x0d] = SSE41_OP(blendpd
),
3014 [0x0e] = SSE41_OP(pblendw
),
3015 [0x0f] = SSSE3_OP(palignr
),
3016 [0x14] = SSE41_SPECIAL
, /* pextrb */
3017 [0x15] = SSE41_SPECIAL
, /* pextrw */
3018 [0x16] = SSE41_SPECIAL
, /* pextrd/pextrq */
3019 [0x17] = SSE41_SPECIAL
, /* extractps */
3020 [0x20] = SSE41_SPECIAL
, /* pinsrb */
3021 [0x21] = SSE41_SPECIAL
, /* insertps */
3022 [0x22] = SSE41_SPECIAL
, /* pinsrd/pinsrq */
3023 [0x40] = SSE41_OP(dpps
),
3024 [0x41] = SSE41_OP(dppd
),
3025 [0x42] = SSE41_OP(mpsadbw
),
3026 [0x44] = PCLMULQDQ_OP(pclmulqdq
),
3027 [0x60] = SSE42_OP(pcmpestrm
),
3028 [0x61] = SSE42_OP(pcmpestri
),
3029 [0x62] = SSE42_OP(pcmpistrm
),
3030 [0x63] = SSE42_OP(pcmpistri
),
3031 [0xdf] = AESNI_OP(aeskeygenassist
),
3034 static void gen_sse(CPUX86State
*env
, DisasContext
*s
, int b
,
3035 target_ulong pc_start
, int rex_r
)
3037 int b1
, op1_offset
, op2_offset
, is_xmm
, val
;
3038 int modrm
, mod
, rm
, reg
;
3039 SSEFunc_0_epp sse_fn_epp
;
3040 SSEFunc_0_eppi sse_fn_eppi
;
3041 SSEFunc_0_ppi sse_fn_ppi
;
3042 SSEFunc_0_eppt sse_fn_eppt
;
3046 if (s
->prefix
& PREFIX_DATA
)
3048 else if (s
->prefix
& PREFIX_REPZ
)
3050 else if (s
->prefix
& PREFIX_REPNZ
)
3054 sse_fn_epp
= sse_op_table1
[b
][b1
];
3058 if ((b
<= 0x5f && b
>= 0x10) || b
== 0xc6 || b
== 0xc2) {
3068 /* simple MMX/SSE operation */
3069 if (s
->flags
& HF_TS_MASK
) {
3070 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
3073 if (s
->flags
& HF_EM_MASK
) {
3075 gen_illegal_opcode(s
);
3079 && !(s
->flags
& HF_OSFXSR_MASK
)
3080 && ((b
!= 0x38 && b
!= 0x3a) || (s
->prefix
& PREFIX_DATA
))) {
3084 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
)) {
3085 /* If we were fully decoding this we might use illegal_op. */
3089 gen_helper_emms(cpu_env
);
3094 gen_helper_emms(cpu_env
);
3097 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3098 the static cpu state) */
3100 gen_helper_enter_mmx(cpu_env
);
3103 modrm
= x86_ldub_code(env
, s
);
3104 reg
= ((modrm
>> 3) & 7);
3107 mod
= (modrm
>> 6) & 3;
3108 if (sse_fn_epp
== SSE_SPECIAL
) {
3111 case 0x0e7: /* movntq */
3115 gen_lea_modrm(env
, s
, modrm
);
3116 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3118 case 0x1e7: /* movntdq */
3119 case 0x02b: /* movntps */
3120 case 0x12b: /* movntps */
3123 gen_lea_modrm(env
, s
, modrm
);
3124 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3126 case 0x3f0: /* lddqu */
3129 gen_lea_modrm(env
, s
, modrm
);
3130 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3132 case 0x22b: /* movntss */
3133 case 0x32b: /* movntsd */
3136 gen_lea_modrm(env
, s
, modrm
);
3138 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3139 xmm_regs
[reg
].ZMM_Q(0)));
3141 tcg_gen_ld32u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
3142 xmm_regs
[reg
].ZMM_L(0)));
3143 gen_op_st_v(s
, MO_32
, s
->T0
, s
->A0
);
3146 case 0x6e: /* movd mm, ea */
3147 #ifdef TARGET_X86_64
3148 if (s
->dflag
== MO_64
) {
3149 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3150 tcg_gen_st_tl(s
->T0
, cpu_env
,
3151 offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3155 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3156 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3157 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3158 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
3159 gen_helper_movl_mm_T0_mmx(s
->ptr0
, s
->tmp2_i32
);
3162 case 0x16e: /* movd xmm, ea */
3163 #ifdef TARGET_X86_64
3164 if (s
->dflag
== MO_64
) {
3165 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3166 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3167 offsetof(CPUX86State
,xmm_regs
[reg
]));
3168 gen_helper_movq_mm_T0_xmm(s
->ptr0
, s
->T0
);
3172 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3173 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3174 offsetof(CPUX86State
,xmm_regs
[reg
]));
3175 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
3176 gen_helper_movl_mm_T0_xmm(s
->ptr0
, s
->tmp2_i32
);
3179 case 0x6f: /* movq mm, ea */
3181 gen_lea_modrm(env
, s
, modrm
);
3182 gen_ldq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3185 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
,
3186 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3187 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
,
3188 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3191 case 0x010: /* movups */
3192 case 0x110: /* movupd */
3193 case 0x028: /* movaps */
3194 case 0x128: /* movapd */
3195 case 0x16f: /* movdqa xmm, ea */
3196 case 0x26f: /* movdqu xmm, ea */
3198 gen_lea_modrm(env
, s
, modrm
);
3199 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3201 rm
= (modrm
& 7) | REX_B(s
);
3202 gen_op_movo(s
, offsetof(CPUX86State
, xmm_regs
[reg
]),
3203 offsetof(CPUX86State
,xmm_regs
[rm
]));
3206 case 0x210: /* movss xmm, ea */
3208 gen_lea_modrm(env
, s
, modrm
);
3209 gen_op_ld_v(s
, MO_32
, s
->T0
, s
->A0
);
3210 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3211 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(0)));
3212 tcg_gen_movi_tl(s
->T0
, 0);
3213 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3214 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(1)));
3215 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3216 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(2)));
3217 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3218 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(3)));
3220 rm
= (modrm
& 7) | REX_B(s
);
3221 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(0)),
3222 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)));
3225 case 0x310: /* movsd xmm, ea */
3227 gen_lea_modrm(env
, s
, modrm
);
3228 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3229 xmm_regs
[reg
].ZMM_Q(0)));
3230 tcg_gen_movi_tl(s
->T0
, 0);
3231 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3232 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(2)));
3233 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3234 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(3)));
3236 rm
= (modrm
& 7) | REX_B(s
);
3237 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(0)),
3238 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3241 case 0x012: /* movlps */
3242 case 0x112: /* movlpd */
3244 gen_lea_modrm(env
, s
, modrm
);
3245 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3246 xmm_regs
[reg
].ZMM_Q(0)));
3249 rm
= (modrm
& 7) | REX_B(s
);
3250 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(0)),
3251 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(1)));
3254 case 0x212: /* movsldup */
3256 gen_lea_modrm(env
, s
, modrm
);
3257 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3259 rm
= (modrm
& 7) | REX_B(s
);
3260 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(0)),
3261 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)));
3262 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(2)),
3263 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(2)));
3265 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(1)),
3266 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3267 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(3)),
3268 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)));
3270 case 0x312: /* movddup */
3272 gen_lea_modrm(env
, s
, modrm
);
3273 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3274 xmm_regs
[reg
].ZMM_Q(0)));
3276 rm
= (modrm
& 7) | REX_B(s
);
3277 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(0)),
3278 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3280 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(1)),
3281 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3283 case 0x016: /* movhps */
3284 case 0x116: /* movhpd */
3286 gen_lea_modrm(env
, s
, modrm
);
3287 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3288 xmm_regs
[reg
].ZMM_Q(1)));
3291 rm
= (modrm
& 7) | REX_B(s
);
3292 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(1)),
3293 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3296 case 0x216: /* movshdup */
3298 gen_lea_modrm(env
, s
, modrm
);
3299 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3301 rm
= (modrm
& 7) | REX_B(s
);
3302 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(1)),
3303 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(1)));
3304 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(3)),
3305 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(3)));
3307 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(0)),
3308 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)));
3309 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(2)),
3310 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)));
3315 int bit_index
, field_length
;
3317 if (b1
== 1 && reg
!= 0)
3319 field_length
= x86_ldub_code(env
, s
) & 0x3F;
3320 bit_index
= x86_ldub_code(env
, s
) & 0x3F;
3321 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3322 offsetof(CPUX86State
,xmm_regs
[reg
]));
3324 gen_helper_extrq_i(cpu_env
, s
->ptr0
,
3325 tcg_const_i32(bit_index
),
3326 tcg_const_i32(field_length
));
3328 gen_helper_insertq_i(cpu_env
, s
->ptr0
,
3329 tcg_const_i32(bit_index
),
3330 tcg_const_i32(field_length
));
3333 case 0x7e: /* movd ea, mm */
3334 #ifdef TARGET_X86_64
3335 if (s
->dflag
== MO_64
) {
3336 tcg_gen_ld_i64(s
->T0
, cpu_env
,
3337 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3338 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3342 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
3343 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_L(0)));
3344 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3347 case 0x17e: /* movd ea, xmm */
3348 #ifdef TARGET_X86_64
3349 if (s
->dflag
== MO_64
) {
3350 tcg_gen_ld_i64(s
->T0
, cpu_env
,
3351 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3352 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3356 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
3357 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3358 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3361 case 0x27e: /* movq xmm, ea */
3363 gen_lea_modrm(env
, s
, modrm
);
3364 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3365 xmm_regs
[reg
].ZMM_Q(0)));
3367 rm
= (modrm
& 7) | REX_B(s
);
3368 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(0)),
3369 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3371 gen_op_movq_env_0(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(1)));
3373 case 0x7f: /* movq ea, mm */
3375 gen_lea_modrm(env
, s
, modrm
);
3376 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3379 gen_op_movq(s
, offsetof(CPUX86State
, fpregs
[rm
].mmx
),
3380 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3383 case 0x011: /* movups */
3384 case 0x111: /* movupd */
3385 case 0x029: /* movaps */
3386 case 0x129: /* movapd */
3387 case 0x17f: /* movdqa ea, xmm */
3388 case 0x27f: /* movdqu ea, xmm */
3390 gen_lea_modrm(env
, s
, modrm
);
3391 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3393 rm
= (modrm
& 7) | REX_B(s
);
3394 gen_op_movo(s
, offsetof(CPUX86State
, xmm_regs
[rm
]),
3395 offsetof(CPUX86State
,xmm_regs
[reg
]));
3398 case 0x211: /* movss ea, xmm */
3400 gen_lea_modrm(env
, s
, modrm
);
3401 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
3402 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(0)));
3403 gen_op_st_v(s
, MO_32
, s
->T0
, s
->A0
);
3405 rm
= (modrm
& 7) | REX_B(s
);
3406 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[rm
].ZMM_L(0)),
3407 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3410 case 0x311: /* movsd ea, xmm */
3412 gen_lea_modrm(env
, s
, modrm
);
3413 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3414 xmm_regs
[reg
].ZMM_Q(0)));
3416 rm
= (modrm
& 7) | REX_B(s
);
3417 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[rm
].ZMM_Q(0)),
3418 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3421 case 0x013: /* movlps */
3422 case 0x113: /* movlpd */
3424 gen_lea_modrm(env
, s
, modrm
);
3425 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3426 xmm_regs
[reg
].ZMM_Q(0)));
3431 case 0x017: /* movhps */
3432 case 0x117: /* movhpd */
3434 gen_lea_modrm(env
, s
, modrm
);
3435 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3436 xmm_regs
[reg
].ZMM_Q(1)));
3441 case 0x71: /* shift mm, im */
3444 case 0x171: /* shift xmm, im */
3450 val
= x86_ldub_code(env
, s
);
3452 tcg_gen_movi_tl(s
->T0
, val
);
3453 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3454 offsetof(CPUX86State
, xmm_t0
.ZMM_L(0)));
3455 tcg_gen_movi_tl(s
->T0
, 0);
3456 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3457 offsetof(CPUX86State
, xmm_t0
.ZMM_L(1)));
3458 op1_offset
= offsetof(CPUX86State
,xmm_t0
);
3460 tcg_gen_movi_tl(s
->T0
, val
);
3461 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3462 offsetof(CPUX86State
, mmx_t0
.MMX_L(0)));
3463 tcg_gen_movi_tl(s
->T0
, 0);
3464 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3465 offsetof(CPUX86State
, mmx_t0
.MMX_L(1)));
3466 op1_offset
= offsetof(CPUX86State
,mmx_t0
);
3468 sse_fn_epp
= sse_op_table2
[((b
- 1) & 3) * 8 +
3469 (((modrm
>> 3)) & 7)][b1
];
3474 rm
= (modrm
& 7) | REX_B(s
);
3475 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3478 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3480 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op2_offset
);
3481 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op1_offset
);
3482 sse_fn_epp(cpu_env
, s
->ptr0
, s
->ptr1
);
3484 case 0x050: /* movmskps */
3485 rm
= (modrm
& 7) | REX_B(s
);
3486 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3487 offsetof(CPUX86State
,xmm_regs
[rm
]));
3488 gen_helper_movmskps(s
->tmp2_i32
, cpu_env
, s
->ptr0
);
3489 tcg_gen_extu_i32_tl(cpu_regs
[reg
], s
->tmp2_i32
);
3491 case 0x150: /* movmskpd */
3492 rm
= (modrm
& 7) | REX_B(s
);
3493 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3494 offsetof(CPUX86State
,xmm_regs
[rm
]));
3495 gen_helper_movmskpd(s
->tmp2_i32
, cpu_env
, s
->ptr0
);
3496 tcg_gen_extu_i32_tl(cpu_regs
[reg
], s
->tmp2_i32
);
3498 case 0x02a: /* cvtpi2ps */
3499 case 0x12a: /* cvtpi2pd */
3500 gen_helper_enter_mmx(cpu_env
);
3502 gen_lea_modrm(env
, s
, modrm
);
3503 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3504 gen_ldq_env_A0(s
, op2_offset
);
3507 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3509 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3510 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
3511 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
3514 gen_helper_cvtpi2ps(cpu_env
, s
->ptr0
, s
->ptr1
);
3518 gen_helper_cvtpi2pd(cpu_env
, s
->ptr0
, s
->ptr1
);
3522 case 0x22a: /* cvtsi2ss */
3523 case 0x32a: /* cvtsi2sd */
3524 ot
= mo_64_32(s
->dflag
);
3525 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3526 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3527 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
3529 SSEFunc_0_epi sse_fn_epi
= sse_op_table3ai
[(b
>> 8) & 1];
3530 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
3531 sse_fn_epi(cpu_env
, s
->ptr0
, s
->tmp2_i32
);
3533 #ifdef TARGET_X86_64
3534 SSEFunc_0_epl sse_fn_epl
= sse_op_table3aq
[(b
>> 8) & 1];
3535 sse_fn_epl(cpu_env
, s
->ptr0
, s
->T0
);
3541 case 0x02c: /* cvttps2pi */
3542 case 0x12c: /* cvttpd2pi */
3543 case 0x02d: /* cvtps2pi */
3544 case 0x12d: /* cvtpd2pi */
3545 gen_helper_enter_mmx(cpu_env
);
3547 gen_lea_modrm(env
, s
, modrm
);
3548 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3549 gen_ldo_env_A0(s
, op2_offset
);
3551 rm
= (modrm
& 7) | REX_B(s
);
3552 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3554 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
);
3555 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
3556 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
3559 gen_helper_cvttps2pi(cpu_env
, s
->ptr0
, s
->ptr1
);
3562 gen_helper_cvttpd2pi(cpu_env
, s
->ptr0
, s
->ptr1
);
3565 gen_helper_cvtps2pi(cpu_env
, s
->ptr0
, s
->ptr1
);
3568 gen_helper_cvtpd2pi(cpu_env
, s
->ptr0
, s
->ptr1
);
3572 case 0x22c: /* cvttss2si */
3573 case 0x32c: /* cvttsd2si */
3574 case 0x22d: /* cvtss2si */
3575 case 0x32d: /* cvtsd2si */
3576 ot
= mo_64_32(s
->dflag
);
3578 gen_lea_modrm(env
, s
, modrm
);
3580 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.ZMM_Q(0)));
3582 gen_op_ld_v(s
, MO_32
, s
->T0
, s
->A0
);
3583 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3584 offsetof(CPUX86State
, xmm_t0
.ZMM_L(0)));
3586 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3588 rm
= (modrm
& 7) | REX_B(s
);
3589 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3591 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op2_offset
);
3593 SSEFunc_i_ep sse_fn_i_ep
=
3594 sse_op_table3bi
[((b
>> 7) & 2) | (b
& 1)];
3595 sse_fn_i_ep(s
->tmp2_i32
, cpu_env
, s
->ptr0
);
3596 tcg_gen_extu_i32_tl(s
->T0
, s
->tmp2_i32
);
3598 #ifdef TARGET_X86_64
3599 SSEFunc_l_ep sse_fn_l_ep
=
3600 sse_op_table3bq
[((b
>> 7) & 2) | (b
& 1)];
3601 sse_fn_l_ep(s
->T0
, cpu_env
, s
->ptr0
);
3606 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
3608 case 0xc4: /* pinsrw */
3611 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
3612 val
= x86_ldub_code(env
, s
);
3615 tcg_gen_st16_tl(s
->T0
, cpu_env
,
3616 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_W(val
)));
3619 tcg_gen_st16_tl(s
->T0
, cpu_env
,
3620 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_W(val
)));
3623 case 0xc5: /* pextrw */
3627 ot
= mo_64_32(s
->dflag
);
3628 val
= x86_ldub_code(env
, s
);
3631 rm
= (modrm
& 7) | REX_B(s
);
3632 tcg_gen_ld16u_tl(s
->T0
, cpu_env
,
3633 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_W(val
)));
3637 tcg_gen_ld16u_tl(s
->T0
, cpu_env
,
3638 offsetof(CPUX86State
,fpregs
[rm
].mmx
.MMX_W(val
)));
3640 reg
= ((modrm
>> 3) & 7) | rex_r
;
3641 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
3643 case 0x1d6: /* movq ea, xmm */
3645 gen_lea_modrm(env
, s
, modrm
);
3646 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3647 xmm_regs
[reg
].ZMM_Q(0)));
3649 rm
= (modrm
& 7) | REX_B(s
);
3650 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[rm
].ZMM_Q(0)),
3651 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3652 gen_op_movq_env_0(s
,
3653 offsetof(CPUX86State
, xmm_regs
[rm
].ZMM_Q(1)));
3656 case 0x2d6: /* movq2dq */
3657 gen_helper_enter_mmx(cpu_env
);
3659 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(0)),
3660 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3661 gen_op_movq_env_0(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(1)));
3663 case 0x3d6: /* movdq2q */
3664 gen_helper_enter_mmx(cpu_env
);
3665 rm
= (modrm
& 7) | REX_B(s
);
3666 gen_op_movq(s
, offsetof(CPUX86State
, fpregs
[reg
& 7].mmx
),
3667 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3669 case 0xd7: /* pmovmskb */
3674 rm
= (modrm
& 7) | REX_B(s
);
3675 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3676 offsetof(CPUX86State
, xmm_regs
[rm
]));
3677 gen_helper_pmovmskb_xmm(s
->tmp2_i32
, cpu_env
, s
->ptr0
);
3680 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3681 offsetof(CPUX86State
, fpregs
[rm
].mmx
));
3682 gen_helper_pmovmskb_mmx(s
->tmp2_i32
, cpu_env
, s
->ptr0
);
3684 reg
= ((modrm
>> 3) & 7) | rex_r
;
3685 tcg_gen_extu_i32_tl(cpu_regs
[reg
], s
->tmp2_i32
);
3691 if ((b
& 0xf0) == 0xf0) {
3694 modrm
= x86_ldub_code(env
, s
);
3696 reg
= ((modrm
>> 3) & 7) | rex_r
;
3697 mod
= (modrm
>> 6) & 3;
3702 sse_fn_epp
= sse_op_table6
[b
].op
[b1
];
3706 if (!(s
->cpuid_ext_features
& sse_op_table6
[b
].ext_mask
))
3710 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3712 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
3714 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3715 gen_lea_modrm(env
, s
, modrm
);
3717 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3718 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3719 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3720 gen_ldq_env_A0(s
, op2_offset
+
3721 offsetof(ZMMReg
, ZMM_Q(0)));
3723 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3724 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3725 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
3726 s
->mem_index
, MO_LEUL
);
3727 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
, op2_offset
+
3728 offsetof(ZMMReg
, ZMM_L(0)));
3730 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3731 tcg_gen_qemu_ld_tl(s
->tmp0
, s
->A0
,
3732 s
->mem_index
, MO_LEUW
);
3733 tcg_gen_st16_tl(s
->tmp0
, cpu_env
, op2_offset
+
3734 offsetof(ZMMReg
, ZMM_W(0)));
3736 case 0x2a: /* movntqda */
3737 gen_ldo_env_A0(s
, op1_offset
);
3740 gen_ldo_env_A0(s
, op2_offset
);
3744 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
3746 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3748 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3749 gen_lea_modrm(env
, s
, modrm
);
3750 gen_ldq_env_A0(s
, op2_offset
);
3753 if (sse_fn_epp
== SSE_SPECIAL
) {
3757 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
3758 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
3759 sse_fn_epp(cpu_env
, s
->ptr0
, s
->ptr1
);
3762 set_cc_op(s
, CC_OP_EFLAGS
);
3769 /* Various integer extensions at 0f 38 f[0-f]. */
3770 b
= modrm
| (b1
<< 8);
3771 modrm
= x86_ldub_code(env
, s
);
3772 reg
= ((modrm
>> 3) & 7) | rex_r
;
3775 case 0x3f0: /* crc32 Gd,Eb */
3776 case 0x3f1: /* crc32 Gd,Ey */
3778 if (!(s
->cpuid_ext_features
& CPUID_EXT_SSE42
)) {
3781 if ((b
& 0xff) == 0xf0) {
3783 } else if (s
->dflag
!= MO_64
) {
3784 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3789 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[reg
]);
3790 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3791 gen_helper_crc32(s
->T0
, s
->tmp2_i32
,
3792 s
->T0
, tcg_const_i32(8 << ot
));
3794 ot
= mo_64_32(s
->dflag
);
3795 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
3798 case 0x1f0: /* crc32 or movbe */
3800 /* For these insns, the f3 prefix is supposed to have priority
3801 over the 66 prefix, but that's not what we implement above
3803 if (s
->prefix
& PREFIX_REPNZ
) {
3807 case 0x0f0: /* movbe Gy,My */
3808 case 0x0f1: /* movbe My,Gy */
3809 if (!(s
->cpuid_ext_features
& CPUID_EXT_MOVBE
)) {
3812 if (s
->dflag
!= MO_64
) {
3813 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3818 gen_lea_modrm(env
, s
, modrm
);
3820 tcg_gen_qemu_ld_tl(s
->T0
, s
->A0
,
3821 s
->mem_index
, ot
| MO_BE
);
3822 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
3824 tcg_gen_qemu_st_tl(cpu_regs
[reg
], s
->A0
,
3825 s
->mem_index
, ot
| MO_BE
);
3829 case 0x0f2: /* andn Gy, By, Ey */
3830 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3831 || !(s
->prefix
& PREFIX_VEX
)
3835 ot
= mo_64_32(s
->dflag
);
3836 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3837 tcg_gen_andc_tl(s
->T0
, s
->T0
, cpu_regs
[s
->vex_v
]);
3838 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
3839 gen_op_update1_cc(s
);
3840 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3843 case 0x0f7: /* bextr Gy, Ey, By */
3844 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3845 || !(s
->prefix
& PREFIX_VEX
)
3849 ot
= mo_64_32(s
->dflag
);
3853 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3854 /* Extract START, and shift the operand.
3855 Shifts larger than operand size get zeros. */
3856 tcg_gen_ext8u_tl(s
->A0
, cpu_regs
[s
->vex_v
]);
3857 tcg_gen_shr_tl(s
->T0
, s
->T0
, s
->A0
);
3859 bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3860 zero
= tcg_const_tl(0);
3861 tcg_gen_movcond_tl(TCG_COND_LEU
, s
->T0
, s
->A0
, bound
,
3863 tcg_temp_free(zero
);
3865 /* Extract the LEN into a mask. Lengths larger than
3866 operand size get all ones. */
3867 tcg_gen_extract_tl(s
->A0
, cpu_regs
[s
->vex_v
], 8, 8);
3868 tcg_gen_movcond_tl(TCG_COND_LEU
, s
->A0
, s
->A0
, bound
,
3870 tcg_temp_free(bound
);
3871 tcg_gen_movi_tl(s
->T1
, 1);
3872 tcg_gen_shl_tl(s
->T1
, s
->T1
, s
->A0
);
3873 tcg_gen_subi_tl(s
->T1
, s
->T1
, 1);
3874 tcg_gen_and_tl(s
->T0
, s
->T0
, s
->T1
);
3876 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
3877 gen_op_update1_cc(s
);
3878 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3882 case 0x0f5: /* bzhi Gy, Ey, By */
3883 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3884 || !(s
->prefix
& PREFIX_VEX
)
3888 ot
= mo_64_32(s
->dflag
);
3889 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3890 tcg_gen_ext8u_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
3892 TCGv bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3893 /* Note that since we're using BMILG (in order to get O
3894 cleared) we need to store the inverse into C. */
3895 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_cc_src
,
3897 tcg_gen_movcond_tl(TCG_COND_GT
, s
->T1
, s
->T1
,
3898 bound
, bound
, s
->T1
);
3899 tcg_temp_free(bound
);
3901 tcg_gen_movi_tl(s
->A0
, -1);
3902 tcg_gen_shl_tl(s
->A0
, s
->A0
, s
->T1
);
3903 tcg_gen_andc_tl(s
->T0
, s
->T0
, s
->A0
);
3904 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
3905 gen_op_update1_cc(s
);
3906 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
3909 case 0x3f6: /* mulx By, Gy, rdx, Ey */
3910 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3911 || !(s
->prefix
& PREFIX_VEX
)
3915 ot
= mo_64_32(s
->dflag
);
3916 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3919 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
3920 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, cpu_regs
[R_EDX
]);
3921 tcg_gen_mulu2_i32(s
->tmp2_i32
, s
->tmp3_i32
,
3922 s
->tmp2_i32
, s
->tmp3_i32
);
3923 tcg_gen_extu_i32_tl(cpu_regs
[s
->vex_v
], s
->tmp2_i32
);
3924 tcg_gen_extu_i32_tl(cpu_regs
[reg
], s
->tmp3_i32
);
3926 #ifdef TARGET_X86_64
3928 tcg_gen_mulu2_i64(s
->T0
, s
->T1
,
3929 s
->T0
, cpu_regs
[R_EDX
]);
3930 tcg_gen_mov_i64(cpu_regs
[s
->vex_v
], s
->T0
);
3931 tcg_gen_mov_i64(cpu_regs
[reg
], s
->T1
);
3937 case 0x3f5: /* pdep Gy, By, Ey */
3938 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3939 || !(s
->prefix
& PREFIX_VEX
)
3943 ot
= mo_64_32(s
->dflag
);
3944 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3945 /* Note that by zero-extending the mask operand, we
3946 automatically handle zero-extending the result. */
3948 tcg_gen_mov_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
3950 tcg_gen_ext32u_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
3952 gen_helper_pdep(cpu_regs
[reg
], s
->T0
, s
->T1
);
3955 case 0x2f5: /* pext Gy, By, Ey */
3956 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3957 || !(s
->prefix
& PREFIX_VEX
)
3961 ot
= mo_64_32(s
->dflag
);
3962 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3963 /* Note that by zero-extending the mask operand, we
3964 automatically handle zero-extending the result. */
3966 tcg_gen_mov_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
3968 tcg_gen_ext32u_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
3970 gen_helper_pext(cpu_regs
[reg
], s
->T0
, s
->T1
);
3973 case 0x1f6: /* adcx Gy, Ey */
3974 case 0x2f6: /* adox Gy, Ey */
3975 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_ADX
)) {
3978 TCGv carry_in
, carry_out
, zero
;
3981 ot
= mo_64_32(s
->dflag
);
3982 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3984 /* Re-use the carry-out from a previous round. */
3986 carry_out
= (b
== 0x1f6 ? cpu_cc_dst
: cpu_cc_src2
);
3990 carry_in
= cpu_cc_dst
;
3991 end_op
= CC_OP_ADCX
;
3993 end_op
= CC_OP_ADCOX
;
3998 end_op
= CC_OP_ADCOX
;
4000 carry_in
= cpu_cc_src2
;
4001 end_op
= CC_OP_ADOX
;
4005 end_op
= CC_OP_ADCOX
;
4006 carry_in
= carry_out
;
4009 end_op
= (b
== 0x1f6 ? CC_OP_ADCX
: CC_OP_ADOX
);
4012 /* If we can't reuse carry-out, get it out of EFLAGS. */
4014 if (s
->cc_op
!= CC_OP_ADCX
&& s
->cc_op
!= CC_OP_ADOX
) {
4015 gen_compute_eflags(s
);
4018 tcg_gen_extract_tl(carry_in
, cpu_cc_src
,
4019 ctz32(b
== 0x1f6 ? CC_C
: CC_O
), 1);
4023 #ifdef TARGET_X86_64
4025 /* If we know TL is 64-bit, and we want a 32-bit
4026 result, just do everything in 64-bit arithmetic. */
4027 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_regs
[reg
]);
4028 tcg_gen_ext32u_i64(s
->T0
, s
->T0
);
4029 tcg_gen_add_i64(s
->T0
, s
->T0
, cpu_regs
[reg
]);
4030 tcg_gen_add_i64(s
->T0
, s
->T0
, carry_in
);
4031 tcg_gen_ext32u_i64(cpu_regs
[reg
], s
->T0
);
4032 tcg_gen_shri_i64(carry_out
, s
->T0
, 32);
4036 /* Otherwise compute the carry-out in two steps. */
4037 zero
= tcg_const_tl(0);
4038 tcg_gen_add2_tl(s
->T0
, carry_out
,
4041 tcg_gen_add2_tl(cpu_regs
[reg
], carry_out
,
4042 cpu_regs
[reg
], carry_out
,
4044 tcg_temp_free(zero
);
4047 set_cc_op(s
, end_op
);
4051 case 0x1f7: /* shlx Gy, Ey, By */
4052 case 0x2f7: /* sarx Gy, Ey, By */
4053 case 0x3f7: /* shrx Gy, Ey, By */
4054 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4055 || !(s
->prefix
& PREFIX_VEX
)
4059 ot
= mo_64_32(s
->dflag
);
4060 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4062 tcg_gen_andi_tl(s
->T1
, cpu_regs
[s
->vex_v
], 63);
4064 tcg_gen_andi_tl(s
->T1
, cpu_regs
[s
->vex_v
], 31);
4067 tcg_gen_shl_tl(s
->T0
, s
->T0
, s
->T1
);
4068 } else if (b
== 0x2f7) {
4070 tcg_gen_ext32s_tl(s
->T0
, s
->T0
);
4072 tcg_gen_sar_tl(s
->T0
, s
->T0
, s
->T1
);
4075 tcg_gen_ext32u_tl(s
->T0
, s
->T0
);
4077 tcg_gen_shr_tl(s
->T0
, s
->T0
, s
->T1
);
4079 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
4085 case 0x3f3: /* Group 17 */
4086 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
4087 || !(s
->prefix
& PREFIX_VEX
)
4091 ot
= mo_64_32(s
->dflag
);
4092 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4094 tcg_gen_mov_tl(cpu_cc_src
, s
->T0
);
4096 case 1: /* blsr By,Ey */
4097 tcg_gen_subi_tl(s
->T1
, s
->T0
, 1);
4098 tcg_gen_and_tl(s
->T0
, s
->T0
, s
->T1
);
4100 case 2: /* blsmsk By,Ey */
4101 tcg_gen_subi_tl(s
->T1
, s
->T0
, 1);
4102 tcg_gen_xor_tl(s
->T0
, s
->T0
, s
->T1
);
4104 case 3: /* blsi By, Ey */
4105 tcg_gen_neg_tl(s
->T1
, s
->T0
);
4106 tcg_gen_and_tl(s
->T0
, s
->T0
, s
->T1
);
4111 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
4112 gen_op_mov_reg_v(s
, ot
, s
->vex_v
, s
->T0
);
4113 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4124 modrm
= x86_ldub_code(env
, s
);
4126 reg
= ((modrm
>> 3) & 7) | rex_r
;
4127 mod
= (modrm
>> 6) & 3;
4132 sse_fn_eppi
= sse_op_table7
[b
].op
[b1
];
4136 if (!(s
->cpuid_ext_features
& sse_op_table7
[b
].ext_mask
))
4141 if (sse_fn_eppi
== SSE_SPECIAL
) {
4142 ot
= mo_64_32(s
->dflag
);
4143 rm
= (modrm
& 7) | REX_B(s
);
4145 gen_lea_modrm(env
, s
, modrm
);
4146 reg
= ((modrm
>> 3) & 7) | rex_r
;
4147 val
= x86_ldub_code(env
, s
);
4149 case 0x14: /* pextrb */
4150 tcg_gen_ld8u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
4151 xmm_regs
[reg
].ZMM_B(val
& 15)));
4153 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
4155 tcg_gen_qemu_st_tl(s
->T0
, s
->A0
,
4156 s
->mem_index
, MO_UB
);
4159 case 0x15: /* pextrw */
4160 tcg_gen_ld16u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
4161 xmm_regs
[reg
].ZMM_W(val
& 7)));
4163 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
4165 tcg_gen_qemu_st_tl(s
->T0
, s
->A0
,
4166 s
->mem_index
, MO_LEUW
);
4170 if (ot
== MO_32
) { /* pextrd */
4171 tcg_gen_ld_i32(s
->tmp2_i32
, cpu_env
,
4172 offsetof(CPUX86State
,
4173 xmm_regs
[reg
].ZMM_L(val
& 3)));
4175 tcg_gen_extu_i32_tl(cpu_regs
[rm
], s
->tmp2_i32
);
4177 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
4178 s
->mem_index
, MO_LEUL
);
4180 } else { /* pextrq */
4181 #ifdef TARGET_X86_64
4182 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
,
4183 offsetof(CPUX86State
,
4184 xmm_regs
[reg
].ZMM_Q(val
& 1)));
4186 tcg_gen_mov_i64(cpu_regs
[rm
], s
->tmp1_i64
);
4188 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
,
4189 s
->mem_index
, MO_LEQ
);
4196 case 0x17: /* extractps */
4197 tcg_gen_ld32u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
4198 xmm_regs
[reg
].ZMM_L(val
& 3)));
4200 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
4202 tcg_gen_qemu_st_tl(s
->T0
, s
->A0
,
4203 s
->mem_index
, MO_LEUL
);
4206 case 0x20: /* pinsrb */
4208 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, rm
);
4210 tcg_gen_qemu_ld_tl(s
->T0
, s
->A0
,
4211 s
->mem_index
, MO_UB
);
4213 tcg_gen_st8_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
4214 xmm_regs
[reg
].ZMM_B(val
& 15)));
4216 case 0x21: /* insertps */
4218 tcg_gen_ld_i32(s
->tmp2_i32
, cpu_env
,
4219 offsetof(CPUX86State
,xmm_regs
[rm
]
4220 .ZMM_L((val
>> 6) & 3)));
4222 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
4223 s
->mem_index
, MO_LEUL
);
4225 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
,
4226 offsetof(CPUX86State
,xmm_regs
[reg
]
4227 .ZMM_L((val
>> 4) & 3)));
4229 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4230 cpu_env
, offsetof(CPUX86State
,
4231 xmm_regs
[reg
].ZMM_L(0)));
4233 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4234 cpu_env
, offsetof(CPUX86State
,
4235 xmm_regs
[reg
].ZMM_L(1)));
4237 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4238 cpu_env
, offsetof(CPUX86State
,
4239 xmm_regs
[reg
].ZMM_L(2)));
4241 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4242 cpu_env
, offsetof(CPUX86State
,
4243 xmm_regs
[reg
].ZMM_L(3)));
4246 if (ot
== MO_32
) { /* pinsrd */
4248 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[rm
]);
4250 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
4251 s
->mem_index
, MO_LEUL
);
4253 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
,
4254 offsetof(CPUX86State
,
4255 xmm_regs
[reg
].ZMM_L(val
& 3)));
4256 } else { /* pinsrq */
4257 #ifdef TARGET_X86_64
4259 gen_op_mov_v_reg(s
, ot
, s
->tmp1_i64
, rm
);
4261 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
,
4262 s
->mem_index
, MO_LEQ
);
4264 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
,
4265 offsetof(CPUX86State
,
4266 xmm_regs
[reg
].ZMM_Q(val
& 1)));
4277 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4279 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
4281 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4282 gen_lea_modrm(env
, s
, modrm
);
4283 gen_ldo_env_A0(s
, op2_offset
);
4286 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4288 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4290 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4291 gen_lea_modrm(env
, s
, modrm
);
4292 gen_ldq_env_A0(s
, op2_offset
);
4295 val
= x86_ldub_code(env
, s
);
4297 if ((b
& 0xfc) == 0x60) { /* pcmpXstrX */
4298 set_cc_op(s
, CC_OP_EFLAGS
);
4300 if (s
->dflag
== MO_64
) {
4301 /* The helper must use entire 64-bit gp registers */
4306 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
4307 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
4308 sse_fn_eppi(cpu_env
, s
->ptr0
, s
->ptr1
, tcg_const_i32(val
));
4312 /* Various integer extensions at 0f 3a f[0-f]. */
4313 b
= modrm
| (b1
<< 8);
4314 modrm
= x86_ldub_code(env
, s
);
4315 reg
= ((modrm
>> 3) & 7) | rex_r
;
4318 case 0x3f0: /* rorx Gy,Ey, Ib */
4319 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4320 || !(s
->prefix
& PREFIX_VEX
)
4324 ot
= mo_64_32(s
->dflag
);
4325 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4326 b
= x86_ldub_code(env
, s
);
4328 tcg_gen_rotri_tl(s
->T0
, s
->T0
, b
& 63);
4330 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
4331 tcg_gen_rotri_i32(s
->tmp2_i32
, s
->tmp2_i32
, b
& 31);
4332 tcg_gen_extu_i32_tl(s
->T0
, s
->tmp2_i32
);
4334 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
4344 gen_unknown_opcode(env
, s
);
4348 /* generic MMX or SSE operation */
4350 case 0x70: /* pshufx insn */
4351 case 0xc6: /* pshufx insn */
4352 case 0xc2: /* compare insns */
4359 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4363 gen_lea_modrm(env
, s
, modrm
);
4364 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4370 /* Most sse scalar operations. */
4373 } else if (b1
== 3) {
4378 case 0x2e: /* ucomis[sd] */
4379 case 0x2f: /* comis[sd] */
4391 gen_op_ld_v(s
, MO_32
, s
->T0
, s
->A0
);
4392 tcg_gen_st32_tl(s
->T0
, cpu_env
,
4393 offsetof(CPUX86State
,xmm_t0
.ZMM_L(0)));
4397 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.ZMM_D(0)));
4400 /* 128 bit access */
4401 gen_ldo_env_A0(s
, op2_offset
);
4405 rm
= (modrm
& 7) | REX_B(s
);
4406 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
4409 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4411 gen_lea_modrm(env
, s
, modrm
);
4412 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4413 gen_ldq_env_A0(s
, op2_offset
);
4416 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4420 case 0x0f: /* 3DNow! data insns */
4421 val
= x86_ldub_code(env
, s
);
4422 sse_fn_epp
= sse_op_table5
[val
];
4426 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
)) {
4429 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
4430 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
4431 sse_fn_epp(cpu_env
, s
->ptr0
, s
->ptr1
);
4433 case 0x70: /* pshufx insn */
4434 case 0xc6: /* pshufx insn */
4435 val
= x86_ldub_code(env
, s
);
4436 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
4437 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
4438 /* XXX: introduce a new table? */
4439 sse_fn_ppi
= (SSEFunc_0_ppi
)sse_fn_epp
;
4440 sse_fn_ppi(s
->ptr0
, s
->ptr1
, tcg_const_i32(val
));
4444 val
= x86_ldub_code(env
, s
);
4447 sse_fn_epp
= sse_op_table4
[val
][b1
];
4449 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
4450 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
4451 sse_fn_epp(cpu_env
, s
->ptr0
, s
->ptr1
);
4454 /* maskmov : we must prepare A0 */
4457 tcg_gen_mov_tl(s
->A0
, cpu_regs
[R_EDI
]);
4458 gen_extu(s
->aflag
, s
->A0
);
4459 gen_add_A0_ds_seg(s
);
4461 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
4462 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
4463 /* XXX: introduce a new table? */
4464 sse_fn_eppt
= (SSEFunc_0_eppt
)sse_fn_epp
;
4465 sse_fn_eppt(cpu_env
, s
->ptr0
, s
->ptr1
, s
->A0
);
4468 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
4469 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
4470 sse_fn_epp(cpu_env
, s
->ptr0
, s
->ptr1
);
4473 if (b
== 0x2e || b
== 0x2f) {
4474 set_cc_op(s
, CC_OP_EFLAGS
);
4479 /* convert one instruction. s->base.is_jmp is set if the translation must
4480 be stopped. Return the next pc value */
4481 static target_ulong
disas_insn(DisasContext
*s
, CPUState
*cpu
)
4483 CPUX86State
*env
= cpu
->env_ptr
;
4486 TCGMemOp ot
, aflag
, dflag
;
4487 int modrm
, reg
, rm
, mod
, op
, opreg
, val
;
4488 target_ulong next_eip
, tval
;
4490 target_ulong pc_start
= s
->base
.pc_next
;
4492 s
->pc_start
= s
->pc
= pc_start
;
4494 #ifdef TARGET_X86_64
4497 s
->x86_64_hregs
= false;
4499 s
->rip_offset
= 0; /* for relative ip address */
4502 if (sigsetjmp(s
->jmpbuf
, 0) != 0) {
4503 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
4512 b
= x86_ldub_code(env
, s
);
4513 /* Collect prefixes. */
4516 prefixes
|= PREFIX_REPZ
;
4519 prefixes
|= PREFIX_REPNZ
;
4522 prefixes
|= PREFIX_LOCK
;
4543 prefixes
|= PREFIX_DATA
;
4546 prefixes
|= PREFIX_ADR
;
4548 #ifdef TARGET_X86_64
4552 rex_w
= (b
>> 3) & 1;
4553 rex_r
= (b
& 0x4) << 1;
4554 s
->rex_x
= (b
& 0x2) << 2;
4555 REX_B(s
) = (b
& 0x1) << 3;
4556 /* select uniform byte register addressing */
4557 s
->x86_64_hregs
= true;
4562 case 0xc5: /* 2-byte VEX */
4563 case 0xc4: /* 3-byte VEX */
4564 /* VEX prefixes cannot be used except in 32-bit mode.
4565 Otherwise the instruction is LES or LDS. */
4566 if (s
->code32
&& !s
->vm86
) {
4567 static const int pp_prefix
[4] = {
4568 0, PREFIX_DATA
, PREFIX_REPZ
, PREFIX_REPNZ
4570 int vex3
, vex2
= x86_ldub_code(env
, s
);
4572 if (!CODE64(s
) && (vex2
& 0xc0) != 0xc0) {
4573 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4574 otherwise the instruction is LES or LDS. */
4575 s
->pc
--; /* rewind the advance_pc() x86_ldub_code() did */
4579 /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
4580 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
4581 | PREFIX_LOCK
| PREFIX_DATA
)) {
4584 #ifdef TARGET_X86_64
4585 if (s
->x86_64_hregs
) {
4589 rex_r
= (~vex2
>> 4) & 8;
4591 /* 2-byte VEX prefix: RVVVVlpp, implied 0f leading opcode byte */
4593 b
= x86_ldub_code(env
, s
) | 0x100;
4595 /* 3-byte VEX prefix: RXBmmmmm wVVVVlpp */
4596 #ifdef TARGET_X86_64
4597 s
->rex_x
= (~vex2
>> 3) & 8;
4598 s
->rex_b
= (~vex2
>> 2) & 8;
4600 vex3
= x86_ldub_code(env
, s
);
4601 rex_w
= (vex3
>> 7) & 1;
4602 switch (vex2
& 0x1f) {
4603 case 0x01: /* Implied 0f leading opcode bytes. */
4604 b
= x86_ldub_code(env
, s
) | 0x100;
4606 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4609 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4612 default: /* Reserved for future use. */
4616 s
->vex_v
= (~vex3
>> 3) & 0xf;
4617 s
->vex_l
= (vex3
>> 2) & 1;
4618 prefixes
|= pp_prefix
[vex3
& 3] | PREFIX_VEX
;
4623 /* Post-process prefixes. */
4625 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit
4626 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4627 over 0x66 if both are present. */
4628 dflag
= (rex_w
> 0 ? MO_64
: prefixes
& PREFIX_DATA
? MO_16
: MO_32
);
4629 /* In 64-bit mode, 0x67 selects 32-bit addressing. */
4630 aflag
= (prefixes
& PREFIX_ADR
? MO_32
: MO_64
);
4632 /* In 16/32-bit mode, 0x66 selects the opposite data size. */
4633 if (s
->code32
^ ((prefixes
& PREFIX_DATA
) != 0)) {
4638 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */
4639 if (s
->code32
^ ((prefixes
& PREFIX_ADR
) != 0)) {
4646 s
->prefix
= prefixes
;
4650 /* now check op code */
4654 /**************************/
4655 /* extended op code */
4656 b
= x86_ldub_code(env
, s
) | 0x100;
4659 /**************************/
4674 ot
= mo_b_d(b
, dflag
);
4677 case 0: /* OP Ev, Gv */
4678 modrm
= x86_ldub_code(env
, s
);
4679 reg
= ((modrm
>> 3) & 7) | rex_r
;
4680 mod
= (modrm
>> 6) & 3;
4681 rm
= (modrm
& 7) | REX_B(s
);
4683 gen_lea_modrm(env
, s
, modrm
);
4685 } else if (op
== OP_XORL
&& rm
== reg
) {
4687 /* xor reg, reg optimisation */
4688 set_cc_op(s
, CC_OP_CLR
);
4689 tcg_gen_movi_tl(s
->T0
, 0);
4690 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
4695 gen_op_mov_v_reg(s
, ot
, s
->T1
, reg
);
4696 gen_op(s
, op
, ot
, opreg
);
4698 case 1: /* OP Gv, Ev */
4699 modrm
= x86_ldub_code(env
, s
);
4700 mod
= (modrm
>> 6) & 3;
4701 reg
= ((modrm
>> 3) & 7) | rex_r
;
4702 rm
= (modrm
& 7) | REX_B(s
);
4704 gen_lea_modrm(env
, s
, modrm
);
4705 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
4706 } else if (op
== OP_XORL
&& rm
== reg
) {
4709 gen_op_mov_v_reg(s
, ot
, s
->T1
, rm
);
4711 gen_op(s
, op
, ot
, reg
);
4713 case 2: /* OP A, Iv */
4714 val
= insn_get(env
, s
, ot
);
4715 tcg_gen_movi_tl(s
->T1
, val
);
4716 gen_op(s
, op
, ot
, OR_EAX
);
4726 case 0x80: /* GRP1 */
4732 ot
= mo_b_d(b
, dflag
);
4734 modrm
= x86_ldub_code(env
, s
);
4735 mod
= (modrm
>> 6) & 3;
4736 rm
= (modrm
& 7) | REX_B(s
);
4737 op
= (modrm
>> 3) & 7;
4743 s
->rip_offset
= insn_const_size(ot
);
4744 gen_lea_modrm(env
, s
, modrm
);
4755 val
= insn_get(env
, s
, ot
);
4758 val
= (int8_t)insn_get(env
, s
, MO_8
);
4761 tcg_gen_movi_tl(s
->T1
, val
);
4762 gen_op(s
, op
, ot
, opreg
);
4766 /**************************/
4767 /* inc, dec, and other misc arith */
4768 case 0x40 ... 0x47: /* inc Gv */
4770 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), 1);
4772 case 0x48 ... 0x4f: /* dec Gv */
4774 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), -1);
4776 case 0xf6: /* GRP3 */
4778 ot
= mo_b_d(b
, dflag
);
4780 modrm
= x86_ldub_code(env
, s
);
4781 mod
= (modrm
>> 6) & 3;
4782 rm
= (modrm
& 7) | REX_B(s
);
4783 op
= (modrm
>> 3) & 7;
4786 s
->rip_offset
= insn_const_size(ot
);
4788 gen_lea_modrm(env
, s
, modrm
);
4789 /* For those below that handle locked memory, don't load here. */
4790 if (!(s
->prefix
& PREFIX_LOCK
)
4792 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
4795 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
4800 val
= insn_get(env
, s
, ot
);
4801 tcg_gen_movi_tl(s
->T1
, val
);
4802 gen_op_testl_T0_T1_cc(s
);
4803 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4806 if (s
->prefix
& PREFIX_LOCK
) {
4810 tcg_gen_movi_tl(s
->T0
, ~0);
4811 tcg_gen_atomic_xor_fetch_tl(s
->T0
, s
->A0
, s
->T0
,
4812 s
->mem_index
, ot
| MO_LE
);
4814 tcg_gen_not_tl(s
->T0
, s
->T0
);
4816 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
4818 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
4823 if (s
->prefix
& PREFIX_LOCK
) {
4825 TCGv a0
, t0
, t1
, t2
;
4830 a0
= tcg_temp_local_new();
4831 t0
= tcg_temp_local_new();
4832 label1
= gen_new_label();
4834 tcg_gen_mov_tl(a0
, s
->A0
);
4835 tcg_gen_mov_tl(t0
, s
->T0
);
4837 gen_set_label(label1
);
4838 t1
= tcg_temp_new();
4839 t2
= tcg_temp_new();
4840 tcg_gen_mov_tl(t2
, t0
);
4841 tcg_gen_neg_tl(t1
, t0
);
4842 tcg_gen_atomic_cmpxchg_tl(t0
, a0
, t0
, t1
,
4843 s
->mem_index
, ot
| MO_LE
);
4845 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t2
, label1
);
4849 tcg_gen_mov_tl(s
->T0
, t0
);
4852 tcg_gen_neg_tl(s
->T0
, s
->T0
);
4854 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
4856 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
4859 gen_op_update_neg_cc(s
);
4860 set_cc_op(s
, CC_OP_SUBB
+ ot
);
4865 gen_op_mov_v_reg(s
, MO_8
, s
->T1
, R_EAX
);
4866 tcg_gen_ext8u_tl(s
->T0
, s
->T0
);
4867 tcg_gen_ext8u_tl(s
->T1
, s
->T1
);
4868 /* XXX: use 32 bit mul which could be faster */
4869 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
4870 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
4871 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
4872 tcg_gen_andi_tl(cpu_cc_src
, s
->T0
, 0xff00);
4873 set_cc_op(s
, CC_OP_MULB
);
4876 gen_op_mov_v_reg(s
, MO_16
, s
->T1
, R_EAX
);
4877 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
4878 tcg_gen_ext16u_tl(s
->T1
, s
->T1
);
4879 /* XXX: use 32 bit mul which could be faster */
4880 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
4881 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
4882 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
4883 tcg_gen_shri_tl(s
->T0
, s
->T0
, 16);
4884 gen_op_mov_reg_v(s
, MO_16
, R_EDX
, s
->T0
);
4885 tcg_gen_mov_tl(cpu_cc_src
, s
->T0
);
4886 set_cc_op(s
, CC_OP_MULW
);
4890 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
4891 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, cpu_regs
[R_EAX
]);
4892 tcg_gen_mulu2_i32(s
->tmp2_i32
, s
->tmp3_i32
,
4893 s
->tmp2_i32
, s
->tmp3_i32
);
4894 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], s
->tmp2_i32
);
4895 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], s
->tmp3_i32
);
4896 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4897 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4898 set_cc_op(s
, CC_OP_MULL
);
4900 #ifdef TARGET_X86_64
4902 tcg_gen_mulu2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4903 s
->T0
, cpu_regs
[R_EAX
]);
4904 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4905 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4906 set_cc_op(s
, CC_OP_MULQ
);
4914 gen_op_mov_v_reg(s
, MO_8
, s
->T1
, R_EAX
);
4915 tcg_gen_ext8s_tl(s
->T0
, s
->T0
);
4916 tcg_gen_ext8s_tl(s
->T1
, s
->T1
);
4917 /* XXX: use 32 bit mul which could be faster */
4918 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
4919 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
4920 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
4921 tcg_gen_ext8s_tl(s
->tmp0
, s
->T0
);
4922 tcg_gen_sub_tl(cpu_cc_src
, s
->T0
, s
->tmp0
);
4923 set_cc_op(s
, CC_OP_MULB
);
4926 gen_op_mov_v_reg(s
, MO_16
, s
->T1
, R_EAX
);
4927 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
4928 tcg_gen_ext16s_tl(s
->T1
, s
->T1
);
4929 /* XXX: use 32 bit mul which could be faster */
4930 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
4931 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
4932 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
4933 tcg_gen_ext16s_tl(s
->tmp0
, s
->T0
);
4934 tcg_gen_sub_tl(cpu_cc_src
, s
->T0
, s
->tmp0
);
4935 tcg_gen_shri_tl(s
->T0
, s
->T0
, 16);
4936 gen_op_mov_reg_v(s
, MO_16
, R_EDX
, s
->T0
);
4937 set_cc_op(s
, CC_OP_MULW
);
4941 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
4942 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, cpu_regs
[R_EAX
]);
4943 tcg_gen_muls2_i32(s
->tmp2_i32
, s
->tmp3_i32
,
4944 s
->tmp2_i32
, s
->tmp3_i32
);
4945 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], s
->tmp2_i32
);
4946 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], s
->tmp3_i32
);
4947 tcg_gen_sari_i32(s
->tmp2_i32
, s
->tmp2_i32
, 31);
4948 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4949 tcg_gen_sub_i32(s
->tmp2_i32
, s
->tmp2_i32
, s
->tmp3_i32
);
4950 tcg_gen_extu_i32_tl(cpu_cc_src
, s
->tmp2_i32
);
4951 set_cc_op(s
, CC_OP_MULL
);
4953 #ifdef TARGET_X86_64
4955 tcg_gen_muls2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4956 s
->T0
, cpu_regs
[R_EAX
]);
4957 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4958 tcg_gen_sari_tl(cpu_cc_src
, cpu_regs
[R_EAX
], 63);
4959 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_regs
[R_EDX
]);
4960 set_cc_op(s
, CC_OP_MULQ
);
4968 gen_helper_divb_AL(cpu_env
, s
->T0
);
4971 gen_helper_divw_AX(cpu_env
, s
->T0
);
4975 gen_helper_divl_EAX(cpu_env
, s
->T0
);
4977 #ifdef TARGET_X86_64
4979 gen_helper_divq_EAX(cpu_env
, s
->T0
);
4987 gen_helper_idivb_AL(cpu_env
, s
->T0
);
4990 gen_helper_idivw_AX(cpu_env
, s
->T0
);
4994 gen_helper_idivl_EAX(cpu_env
, s
->T0
);
4996 #ifdef TARGET_X86_64
4998 gen_helper_idivq_EAX(cpu_env
, s
->T0
);
5008 case 0xfe: /* GRP4 */
5009 case 0xff: /* GRP5 */
5010 ot
= mo_b_d(b
, dflag
);
5012 modrm
= x86_ldub_code(env
, s
);
5013 mod
= (modrm
>> 6) & 3;
5014 rm
= (modrm
& 7) | REX_B(s
);
5015 op
= (modrm
>> 3) & 7;
5016 if (op
>= 2 && b
== 0xfe) {
5020 if (op
== 2 || op
== 4) {
5021 /* operand size for jumps is 64 bit */
5023 } else if (op
== 3 || op
== 5) {
5024 ot
= dflag
!= MO_16
? MO_32
+ (rex_w
== 1) : MO_16
;
5025 } else if (op
== 6) {
5026 /* default push size is 64 bit */
5027 ot
= mo_pushpop(s
, dflag
);
5031 gen_lea_modrm(env
, s
, modrm
);
5032 if (op
>= 2 && op
!= 3 && op
!= 5)
5033 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
5035 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
5039 case 0: /* inc Ev */
5044 gen_inc(s
, ot
, opreg
, 1);
5046 case 1: /* dec Ev */
5051 gen_inc(s
, ot
, opreg
, -1);
5053 case 2: /* call Ev */
5054 /* XXX: optimize if memory (no 'and' is necessary) */
5055 if (dflag
== MO_16
) {
5056 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
5058 next_eip
= s
->pc
- s
->cs_base
;
5059 tcg_gen_movi_tl(s
->T1
, next_eip
);
5060 gen_push_v(s
, s
->T1
);
5061 gen_op_jmp_v(s
->T0
);
5065 case 3: /* lcall Ev */
5066 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
5067 gen_add_A0_im(s
, 1 << ot
);
5068 gen_op_ld_v(s
, MO_16
, s
->T0
, s
->A0
);
5070 if (s
->pe
&& !s
->vm86
) {
5071 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
5072 gen_helper_lcall_protected(cpu_env
, s
->tmp2_i32
, s
->T1
,
5073 tcg_const_i32(dflag
- 1),
5074 tcg_const_tl(s
->pc
- s
->cs_base
));
5076 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
5077 gen_helper_lcall_real(cpu_env
, s
->tmp2_i32
, s
->T1
,
5078 tcg_const_i32(dflag
- 1),
5079 tcg_const_i32(s
->pc
- s
->cs_base
));
5081 tcg_gen_ld_tl(s
->tmp4
, cpu_env
, offsetof(CPUX86State
, eip
));
5084 case 4: /* jmp Ev */
5085 if (dflag
== MO_16
) {
5086 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
5088 gen_op_jmp_v(s
->T0
);
5092 case 5: /* ljmp Ev */
5093 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
5094 gen_add_A0_im(s
, 1 << ot
);
5095 gen_op_ld_v(s
, MO_16
, s
->T0
, s
->A0
);
5097 if (s
->pe
&& !s
->vm86
) {
5098 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
5099 gen_helper_ljmp_protected(cpu_env
, s
->tmp2_i32
, s
->T1
,
5100 tcg_const_tl(s
->pc
- s
->cs_base
));
5102 gen_op_movl_seg_T0_vm(s
, R_CS
);
5103 gen_op_jmp_v(s
->T1
);
5105 tcg_gen_ld_tl(s
->tmp4
, cpu_env
, offsetof(CPUX86State
, eip
));
5108 case 6: /* push Ev */
5109 gen_push_v(s
, s
->T0
);
5116 case 0x84: /* test Ev, Gv */
5118 ot
= mo_b_d(b
, dflag
);
5120 modrm
= x86_ldub_code(env
, s
);
5121 reg
= ((modrm
>> 3) & 7) | rex_r
;
5123 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5124 gen_op_mov_v_reg(s
, ot
, s
->T1
, reg
);
5125 gen_op_testl_T0_T1_cc(s
);
5126 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5129 case 0xa8: /* test eAX, Iv */
5131 ot
= mo_b_d(b
, dflag
);
5132 val
= insn_get(env
, s
, ot
);
5134 gen_op_mov_v_reg(s
, ot
, s
->T0
, OR_EAX
);
5135 tcg_gen_movi_tl(s
->T1
, val
);
5136 gen_op_testl_T0_T1_cc(s
);
5137 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5140 case 0x98: /* CWDE/CBW */
5142 #ifdef TARGET_X86_64
5144 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, R_EAX
);
5145 tcg_gen_ext32s_tl(s
->T0
, s
->T0
);
5146 gen_op_mov_reg_v(s
, MO_64
, R_EAX
, s
->T0
);
5150 gen_op_mov_v_reg(s
, MO_16
, s
->T0
, R_EAX
);
5151 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5152 gen_op_mov_reg_v(s
, MO_32
, R_EAX
, s
->T0
);
5155 gen_op_mov_v_reg(s
, MO_8
, s
->T0
, R_EAX
);
5156 tcg_gen_ext8s_tl(s
->T0
, s
->T0
);
5157 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
5163 case 0x99: /* CDQ/CWD */
5165 #ifdef TARGET_X86_64
5167 gen_op_mov_v_reg(s
, MO_64
, s
->T0
, R_EAX
);
5168 tcg_gen_sari_tl(s
->T0
, s
->T0
, 63);
5169 gen_op_mov_reg_v(s
, MO_64
, R_EDX
, s
->T0
);
5173 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, R_EAX
);
5174 tcg_gen_ext32s_tl(s
->T0
, s
->T0
);
5175 tcg_gen_sari_tl(s
->T0
, s
->T0
, 31);
5176 gen_op_mov_reg_v(s
, MO_32
, R_EDX
, s
->T0
);
5179 gen_op_mov_v_reg(s
, MO_16
, s
->T0
, R_EAX
);
5180 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5181 tcg_gen_sari_tl(s
->T0
, s
->T0
, 15);
5182 gen_op_mov_reg_v(s
, MO_16
, R_EDX
, s
->T0
);
5188 case 0x1af: /* imul Gv, Ev */
5189 case 0x69: /* imul Gv, Ev, I */
5192 modrm
= x86_ldub_code(env
, s
);
5193 reg
= ((modrm
>> 3) & 7) | rex_r
;
5195 s
->rip_offset
= insn_const_size(ot
);
5198 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5200 val
= insn_get(env
, s
, ot
);
5201 tcg_gen_movi_tl(s
->T1
, val
);
5202 } else if (b
== 0x6b) {
5203 val
= (int8_t)insn_get(env
, s
, MO_8
);
5204 tcg_gen_movi_tl(s
->T1
, val
);
5206 gen_op_mov_v_reg(s
, ot
, s
->T1
, reg
);
5209 #ifdef TARGET_X86_64
5211 tcg_gen_muls2_i64(cpu_regs
[reg
], s
->T1
, s
->T0
, s
->T1
);
5212 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5213 tcg_gen_sari_tl(cpu_cc_src
, cpu_cc_dst
, 63);
5214 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, s
->T1
);
5218 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
5219 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, s
->T1
);
5220 tcg_gen_muls2_i32(s
->tmp2_i32
, s
->tmp3_i32
,
5221 s
->tmp2_i32
, s
->tmp3_i32
);
5222 tcg_gen_extu_i32_tl(cpu_regs
[reg
], s
->tmp2_i32
);
5223 tcg_gen_sari_i32(s
->tmp2_i32
, s
->tmp2_i32
, 31);
5224 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5225 tcg_gen_sub_i32(s
->tmp2_i32
, s
->tmp2_i32
, s
->tmp3_i32
);
5226 tcg_gen_extu_i32_tl(cpu_cc_src
, s
->tmp2_i32
);
5229 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5230 tcg_gen_ext16s_tl(s
->T1
, s
->T1
);
5231 /* XXX: use 32 bit mul which could be faster */
5232 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
5233 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
5234 tcg_gen_ext16s_tl(s
->tmp0
, s
->T0
);
5235 tcg_gen_sub_tl(cpu_cc_src
, s
->T0
, s
->tmp0
);
5236 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
5239 set_cc_op(s
, CC_OP_MULB
+ ot
);
5242 case 0x1c1: /* xadd Ev, Gv */
5243 ot
= mo_b_d(b
, dflag
);
5244 modrm
= x86_ldub_code(env
, s
);
5245 reg
= ((modrm
>> 3) & 7) | rex_r
;
5246 mod
= (modrm
>> 6) & 3;
5247 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
5249 rm
= (modrm
& 7) | REX_B(s
);
5250 gen_op_mov_v_reg(s
, ot
, s
->T1
, rm
);
5251 tcg_gen_add_tl(s
->T0
, s
->T0
, s
->T1
);
5252 gen_op_mov_reg_v(s
, ot
, reg
, s
->T1
);
5253 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
5255 gen_lea_modrm(env
, s
, modrm
);
5256 if (s
->prefix
& PREFIX_LOCK
) {
5257 tcg_gen_atomic_fetch_add_tl(s
->T1
, s
->A0
, s
->T0
,
5258 s
->mem_index
, ot
| MO_LE
);
5259 tcg_gen_add_tl(s
->T0
, s
->T0
, s
->T1
);
5261 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
5262 tcg_gen_add_tl(s
->T0
, s
->T0
, s
->T1
);
5263 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
5265 gen_op_mov_reg_v(s
, ot
, reg
, s
->T1
);
5267 gen_op_update2_cc(s
);
5268 set_cc_op(s
, CC_OP_ADDB
+ ot
);
5271 case 0x1b1: /* cmpxchg Ev, Gv */
5273 TCGv oldv
, newv
, cmpv
;
5275 ot
= mo_b_d(b
, dflag
);
5276 modrm
= x86_ldub_code(env
, s
);
5277 reg
= ((modrm
>> 3) & 7) | rex_r
;
5278 mod
= (modrm
>> 6) & 3;
5279 oldv
= tcg_temp_new();
5280 newv
= tcg_temp_new();
5281 cmpv
= tcg_temp_new();
5282 gen_op_mov_v_reg(s
, ot
, newv
, reg
);
5283 tcg_gen_mov_tl(cmpv
, cpu_regs
[R_EAX
]);
5285 if (s
->prefix
& PREFIX_LOCK
) {
5289 gen_lea_modrm(env
, s
, modrm
);
5290 tcg_gen_atomic_cmpxchg_tl(oldv
, s
->A0
, cmpv
, newv
,
5291 s
->mem_index
, ot
| MO_LE
);
5292 gen_op_mov_reg_v(s
, ot
, R_EAX
, oldv
);
5295 rm
= (modrm
& 7) | REX_B(s
);
5296 gen_op_mov_v_reg(s
, ot
, oldv
, rm
);
5298 gen_lea_modrm(env
, s
, modrm
);
5299 gen_op_ld_v(s
, ot
, oldv
, s
->A0
);
5300 rm
= 0; /* avoid warning */
5304 /* store value = (old == cmp ? new : old); */
5305 tcg_gen_movcond_tl(TCG_COND_EQ
, newv
, oldv
, cmpv
, newv
, oldv
);
5307 gen_op_mov_reg_v(s
, ot
, R_EAX
, oldv
);
5308 gen_op_mov_reg_v(s
, ot
, rm
, newv
);
5310 /* Perform an unconditional store cycle like physical cpu;
5311 must be before changing accumulator to ensure
5312 idempotency if the store faults and the instruction
5314 gen_op_st_v(s
, ot
, newv
, s
->A0
);
5315 gen_op_mov_reg_v(s
, ot
, R_EAX
, oldv
);
5318 tcg_gen_mov_tl(cpu_cc_src
, oldv
);
5319 tcg_gen_mov_tl(s
->cc_srcT
, cmpv
);
5320 tcg_gen_sub_tl(cpu_cc_dst
, cmpv
, oldv
);
5321 set_cc_op(s
, CC_OP_SUBB
+ ot
);
5322 tcg_temp_free(oldv
);
5323 tcg_temp_free(newv
);
5324 tcg_temp_free(cmpv
);
5327 case 0x1c7: /* cmpxchg8b */
5328 modrm
= x86_ldub_code(env
, s
);
5329 mod
= (modrm
>> 6) & 3;
5330 if ((mod
== 3) || ((modrm
& 0x38) != 0x8))
5332 #ifdef TARGET_X86_64
5333 if (dflag
== MO_64
) {
5334 if (!(s
->cpuid_ext_features
& CPUID_EXT_CX16
))
5336 gen_lea_modrm(env
, s
, modrm
);
5337 if ((s
->prefix
& PREFIX_LOCK
) && (tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
5338 gen_helper_cmpxchg16b(cpu_env
, s
->A0
);
5340 gen_helper_cmpxchg16b_unlocked(cpu_env
, s
->A0
);
5345 if (!(s
->cpuid_features
& CPUID_CX8
))
5347 gen_lea_modrm(env
, s
, modrm
);
5348 if ((s
->prefix
& PREFIX_LOCK
) && (tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
5349 gen_helper_cmpxchg8b(cpu_env
, s
->A0
);
5351 gen_helper_cmpxchg8b_unlocked(cpu_env
, s
->A0
);
5354 set_cc_op(s
, CC_OP_EFLAGS
);
5357 /**************************/
5359 case 0x50 ... 0x57: /* push */
5360 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, (b
& 7) | REX_B(s
));
5361 gen_push_v(s
, s
->T0
);
5363 case 0x58 ... 0x5f: /* pop */
5365 /* NOTE: order is important for pop %sp */
5366 gen_pop_update(s
, ot
);
5367 gen_op_mov_reg_v(s
, ot
, (b
& 7) | REX_B(s
), s
->T0
);
5369 case 0x60: /* pusha */
5374 case 0x61: /* popa */
5379 case 0x68: /* push Iv */
5381 ot
= mo_pushpop(s
, dflag
);
5383 val
= insn_get(env
, s
, ot
);
5385 val
= (int8_t)insn_get(env
, s
, MO_8
);
5386 tcg_gen_movi_tl(s
->T0
, val
);
5387 gen_push_v(s
, s
->T0
);
5389 case 0x8f: /* pop Ev */
5390 modrm
= x86_ldub_code(env
, s
);
5391 mod
= (modrm
>> 6) & 3;
5394 /* NOTE: order is important for pop %sp */
5395 gen_pop_update(s
, ot
);
5396 rm
= (modrm
& 7) | REX_B(s
);
5397 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
5399 /* NOTE: order is important too for MMU exceptions */
5400 s
->popl_esp_hack
= 1 << ot
;
5401 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5402 s
->popl_esp_hack
= 0;
5403 gen_pop_update(s
, ot
);
5406 case 0xc8: /* enter */
5409 val
= x86_lduw_code(env
, s
);
5410 level
= x86_ldub_code(env
, s
);
5411 gen_enter(s
, val
, level
);
5414 case 0xc9: /* leave */
5417 case 0x06: /* push es */
5418 case 0x0e: /* push cs */
5419 case 0x16: /* push ss */
5420 case 0x1e: /* push ds */
5423 gen_op_movl_T0_seg(s
, b
>> 3);
5424 gen_push_v(s
, s
->T0
);
5426 case 0x1a0: /* push fs */
5427 case 0x1a8: /* push gs */
5428 gen_op_movl_T0_seg(s
, (b
>> 3) & 7);
5429 gen_push_v(s
, s
->T0
);
5431 case 0x07: /* pop es */
5432 case 0x17: /* pop ss */
5433 case 0x1f: /* pop ds */
5438 gen_movl_seg_T0(s
, reg
);
5439 gen_pop_update(s
, ot
);
5440 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5441 if (s
->base
.is_jmp
) {
5442 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
5445 gen_eob_inhibit_irq(s
, true);
5451 case 0x1a1: /* pop fs */
5452 case 0x1a9: /* pop gs */
5454 gen_movl_seg_T0(s
, (b
>> 3) & 7);
5455 gen_pop_update(s
, ot
);
5456 if (s
->base
.is_jmp
) {
5457 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
5462 /**************************/
5465 case 0x89: /* mov Gv, Ev */
5466 ot
= mo_b_d(b
, dflag
);
5467 modrm
= x86_ldub_code(env
, s
);
5468 reg
= ((modrm
>> 3) & 7) | rex_r
;
5470 /* generate a generic store */
5471 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
5474 case 0xc7: /* mov Ev, Iv */
5475 ot
= mo_b_d(b
, dflag
);
5476 modrm
= x86_ldub_code(env
, s
);
5477 mod
= (modrm
>> 6) & 3;
5479 s
->rip_offset
= insn_const_size(ot
);
5480 gen_lea_modrm(env
, s
, modrm
);
5482 val
= insn_get(env
, s
, ot
);
5483 tcg_gen_movi_tl(s
->T0
, val
);
5485 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
5487 gen_op_mov_reg_v(s
, ot
, (modrm
& 7) | REX_B(s
), s
->T0
);
5491 case 0x8b: /* mov Ev, Gv */
5492 ot
= mo_b_d(b
, dflag
);
5493 modrm
= x86_ldub_code(env
, s
);
5494 reg
= ((modrm
>> 3) & 7) | rex_r
;
5496 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5497 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
5499 case 0x8e: /* mov seg, Gv */
5500 modrm
= x86_ldub_code(env
, s
);
5501 reg
= (modrm
>> 3) & 7;
5502 if (reg
>= 6 || reg
== R_CS
)
5504 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
5505 gen_movl_seg_T0(s
, reg
);
5506 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5507 if (s
->base
.is_jmp
) {
5508 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
5511 gen_eob_inhibit_irq(s
, true);
5517 case 0x8c: /* mov Gv, seg */
5518 modrm
= x86_ldub_code(env
, s
);
5519 reg
= (modrm
>> 3) & 7;
5520 mod
= (modrm
>> 6) & 3;
5523 gen_op_movl_T0_seg(s
, reg
);
5524 ot
= mod
== 3 ? dflag
: MO_16
;
5525 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5528 case 0x1b6: /* movzbS Gv, Eb */
5529 case 0x1b7: /* movzwS Gv, Eb */
5530 case 0x1be: /* movsbS Gv, Eb */
5531 case 0x1bf: /* movswS Gv, Eb */
5536 /* d_ot is the size of destination */
5538 /* ot is the size of source */
5539 ot
= (b
& 1) + MO_8
;
5540 /* s_ot is the sign+size of source */
5541 s_ot
= b
& 8 ? MO_SIGN
| ot
: ot
;
5543 modrm
= x86_ldub_code(env
, s
);
5544 reg
= ((modrm
>> 3) & 7) | rex_r
;
5545 mod
= (modrm
>> 6) & 3;
5546 rm
= (modrm
& 7) | REX_B(s
);
5549 if (s_ot
== MO_SB
&& byte_reg_is_xH(s
, rm
)) {
5550 tcg_gen_sextract_tl(s
->T0
, cpu_regs
[rm
- 4], 8, 8);
5552 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
5555 tcg_gen_ext8u_tl(s
->T0
, s
->T0
);
5558 tcg_gen_ext8s_tl(s
->T0
, s
->T0
);
5561 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
5565 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5569 gen_op_mov_reg_v(s
, d_ot
, reg
, s
->T0
);
5571 gen_lea_modrm(env
, s
, modrm
);
5572 gen_op_ld_v(s
, s_ot
, s
->T0
, s
->A0
);
5573 gen_op_mov_reg_v(s
, d_ot
, reg
, s
->T0
);
5578 case 0x8d: /* lea */
5579 modrm
= x86_ldub_code(env
, s
);
5580 mod
= (modrm
>> 6) & 3;
5583 reg
= ((modrm
>> 3) & 7) | rex_r
;
5585 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
5586 TCGv ea
= gen_lea_modrm_1(s
, a
);
5587 gen_lea_v_seg(s
, s
->aflag
, ea
, -1, -1);
5588 gen_op_mov_reg_v(s
, dflag
, reg
, s
->A0
);
5592 case 0xa0: /* mov EAX, Ov */
5594 case 0xa2: /* mov Ov, EAX */
5597 target_ulong offset_addr
;
5599 ot
= mo_b_d(b
, dflag
);
5601 #ifdef TARGET_X86_64
5603 offset_addr
= x86_ldq_code(env
, s
);
5607 offset_addr
= insn_get(env
, s
, s
->aflag
);
5610 tcg_gen_movi_tl(s
->A0
, offset_addr
);
5611 gen_add_A0_ds_seg(s
);
5613 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
5614 gen_op_mov_reg_v(s
, ot
, R_EAX
, s
->T0
);
5616 gen_op_mov_v_reg(s
, ot
, s
->T0
, R_EAX
);
5617 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
5621 case 0xd7: /* xlat */
5622 tcg_gen_mov_tl(s
->A0
, cpu_regs
[R_EBX
]);
5623 tcg_gen_ext8u_tl(s
->T0
, cpu_regs
[R_EAX
]);
5624 tcg_gen_add_tl(s
->A0
, s
->A0
, s
->T0
);
5625 gen_extu(s
->aflag
, s
->A0
);
5626 gen_add_A0_ds_seg(s
);
5627 gen_op_ld_v(s
, MO_8
, s
->T0
, s
->A0
);
5628 gen_op_mov_reg_v(s
, MO_8
, R_EAX
, s
->T0
);
5630 case 0xb0 ... 0xb7: /* mov R, Ib */
5631 val
= insn_get(env
, s
, MO_8
);
5632 tcg_gen_movi_tl(s
->T0
, val
);
5633 gen_op_mov_reg_v(s
, MO_8
, (b
& 7) | REX_B(s
), s
->T0
);
5635 case 0xb8 ... 0xbf: /* mov R, Iv */
5636 #ifdef TARGET_X86_64
5637 if (dflag
== MO_64
) {
5640 tmp
= x86_ldq_code(env
, s
);
5641 reg
= (b
& 7) | REX_B(s
);
5642 tcg_gen_movi_tl(s
->T0
, tmp
);
5643 gen_op_mov_reg_v(s
, MO_64
, reg
, s
->T0
);
5648 val
= insn_get(env
, s
, ot
);
5649 reg
= (b
& 7) | REX_B(s
);
5650 tcg_gen_movi_tl(s
->T0
, val
);
5651 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
5655 case 0x91 ... 0x97: /* xchg R, EAX */
5658 reg
= (b
& 7) | REX_B(s
);
5662 case 0x87: /* xchg Ev, Gv */
5663 ot
= mo_b_d(b
, dflag
);
5664 modrm
= x86_ldub_code(env
, s
);
5665 reg
= ((modrm
>> 3) & 7) | rex_r
;
5666 mod
= (modrm
>> 6) & 3;
5668 rm
= (modrm
& 7) | REX_B(s
);
5670 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
5671 gen_op_mov_v_reg(s
, ot
, s
->T1
, rm
);
5672 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
5673 gen_op_mov_reg_v(s
, ot
, reg
, s
->T1
);
5675 gen_lea_modrm(env
, s
, modrm
);
5676 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
5677 /* for xchg, lock is implicit */
5678 tcg_gen_atomic_xchg_tl(s
->T1
, s
->A0
, s
->T0
,
5679 s
->mem_index
, ot
| MO_LE
);
5680 gen_op_mov_reg_v(s
, ot
, reg
, s
->T1
);
5683 case 0xc4: /* les Gv */
5684 /* In CODE64 this is VEX3; see above. */
5687 case 0xc5: /* lds Gv */
5688 /* In CODE64 this is VEX2; see above. */
5691 case 0x1b2: /* lss Gv */
5694 case 0x1b4: /* lfs Gv */
5697 case 0x1b5: /* lgs Gv */
5700 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
5701 modrm
= x86_ldub_code(env
, s
);
5702 reg
= ((modrm
>> 3) & 7) | rex_r
;
5703 mod
= (modrm
>> 6) & 3;
5706 gen_lea_modrm(env
, s
, modrm
);
5707 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
5708 gen_add_A0_im(s
, 1 << ot
);
5709 /* load the segment first to handle exceptions properly */
5710 gen_op_ld_v(s
, MO_16
, s
->T0
, s
->A0
);
5711 gen_movl_seg_T0(s
, op
);
5712 /* then put the data */
5713 gen_op_mov_reg_v(s
, ot
, reg
, s
->T1
);
5714 if (s
->base
.is_jmp
) {
5715 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
5720 /************************/
5728 ot
= mo_b_d(b
, dflag
);
5729 modrm
= x86_ldub_code(env
, s
);
5730 mod
= (modrm
>> 6) & 3;
5731 op
= (modrm
>> 3) & 7;
5737 gen_lea_modrm(env
, s
, modrm
);
5740 opreg
= (modrm
& 7) | REX_B(s
);
5745 gen_shift(s
, op
, ot
, opreg
, OR_ECX
);
5748 shift
= x86_ldub_code(env
, s
);
5750 gen_shifti(s
, op
, ot
, opreg
, shift
);
5765 case 0x1a4: /* shld imm */
5769 case 0x1a5: /* shld cl */
5773 case 0x1ac: /* shrd imm */
5777 case 0x1ad: /* shrd cl */
5782 modrm
= x86_ldub_code(env
, s
);
5783 mod
= (modrm
>> 6) & 3;
5784 rm
= (modrm
& 7) | REX_B(s
);
5785 reg
= ((modrm
>> 3) & 7) | rex_r
;
5787 gen_lea_modrm(env
, s
, modrm
);
5792 gen_op_mov_v_reg(s
, ot
, s
->T1
, reg
);
5795 TCGv imm
= tcg_const_tl(x86_ldub_code(env
, s
));
5796 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, imm
);
5799 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, cpu_regs
[R_ECX
]);
5803 /************************/
5806 if (s
->flags
& (HF_EM_MASK
| HF_TS_MASK
)) {
5807 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5808 /* XXX: what to do if illegal op ? */
5809 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
5812 modrm
= x86_ldub_code(env
, s
);
5813 mod
= (modrm
>> 6) & 3;
5815 op
= ((b
& 7) << 3) | ((modrm
>> 3) & 7);
5818 gen_lea_modrm(env
, s
, modrm
);
5820 case 0x00 ... 0x07: /* fxxxs */
5821 case 0x10 ... 0x17: /* fixxxl */
5822 case 0x20 ... 0x27: /* fxxxl */
5823 case 0x30 ... 0x37: /* fixxx */
5830 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
5831 s
->mem_index
, MO_LEUL
);
5832 gen_helper_flds_FT0(cpu_env
, s
->tmp2_i32
);
5835 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
5836 s
->mem_index
, MO_LEUL
);
5837 gen_helper_fildl_FT0(cpu_env
, s
->tmp2_i32
);
5840 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
,
5841 s
->mem_index
, MO_LEQ
);
5842 gen_helper_fldl_FT0(cpu_env
, s
->tmp1_i64
);
5846 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
5847 s
->mem_index
, MO_LESW
);
5848 gen_helper_fildl_FT0(cpu_env
, s
->tmp2_i32
);
5852 gen_helper_fp_arith_ST0_FT0(op1
);
5854 /* fcomp needs pop */
5855 gen_helper_fpop(cpu_env
);
5859 case 0x08: /* flds */
5860 case 0x0a: /* fsts */
5861 case 0x0b: /* fstps */
5862 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5863 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5864 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5869 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
5870 s
->mem_index
, MO_LEUL
);
5871 gen_helper_flds_ST0(cpu_env
, s
->tmp2_i32
);
5874 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
5875 s
->mem_index
, MO_LEUL
);
5876 gen_helper_fildl_ST0(cpu_env
, s
->tmp2_i32
);
5879 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
,
5880 s
->mem_index
, MO_LEQ
);
5881 gen_helper_fldl_ST0(cpu_env
, s
->tmp1_i64
);
5885 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
5886 s
->mem_index
, MO_LESW
);
5887 gen_helper_fildl_ST0(cpu_env
, s
->tmp2_i32
);
5892 /* XXX: the corresponding CPUID bit must be tested ! */
5895 gen_helper_fisttl_ST0(s
->tmp2_i32
, cpu_env
);
5896 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
5897 s
->mem_index
, MO_LEUL
);
5900 gen_helper_fisttll_ST0(s
->tmp1_i64
, cpu_env
);
5901 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
,
5902 s
->mem_index
, MO_LEQ
);
5906 gen_helper_fistt_ST0(s
->tmp2_i32
, cpu_env
);
5907 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
5908 s
->mem_index
, MO_LEUW
);
5911 gen_helper_fpop(cpu_env
);
5916 gen_helper_fsts_ST0(s
->tmp2_i32
, cpu_env
);
5917 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
5918 s
->mem_index
, MO_LEUL
);
5921 gen_helper_fistl_ST0(s
->tmp2_i32
, cpu_env
);
5922 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
5923 s
->mem_index
, MO_LEUL
);
5926 gen_helper_fstl_ST0(s
->tmp1_i64
, cpu_env
);
5927 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
,
5928 s
->mem_index
, MO_LEQ
);
5932 gen_helper_fist_ST0(s
->tmp2_i32
, cpu_env
);
5933 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
5934 s
->mem_index
, MO_LEUW
);
5938 gen_helper_fpop(cpu_env
);
5942 case 0x0c: /* fldenv mem */
5943 gen_helper_fldenv(cpu_env
, s
->A0
, tcg_const_i32(dflag
- 1));
5945 case 0x0d: /* fldcw mem */
5946 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
5947 s
->mem_index
, MO_LEUW
);
5948 gen_helper_fldcw(cpu_env
, s
->tmp2_i32
);
5950 case 0x0e: /* fnstenv mem */
5951 gen_helper_fstenv(cpu_env
, s
->A0
, tcg_const_i32(dflag
- 1));
5953 case 0x0f: /* fnstcw mem */
5954 gen_helper_fnstcw(s
->tmp2_i32
, cpu_env
);
5955 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
5956 s
->mem_index
, MO_LEUW
);
5958 case 0x1d: /* fldt mem */
5959 gen_helper_fldt_ST0(cpu_env
, s
->A0
);
5961 case 0x1f: /* fstpt mem */
5962 gen_helper_fstt_ST0(cpu_env
, s
->A0
);
5963 gen_helper_fpop(cpu_env
);
5965 case 0x2c: /* frstor mem */
5966 gen_helper_frstor(cpu_env
, s
->A0
, tcg_const_i32(dflag
- 1));
5968 case 0x2e: /* fnsave mem */
5969 gen_helper_fsave(cpu_env
, s
->A0
, tcg_const_i32(dflag
- 1));
5971 case 0x2f: /* fnstsw mem */
5972 gen_helper_fnstsw(s
->tmp2_i32
, cpu_env
);
5973 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
5974 s
->mem_index
, MO_LEUW
);
5976 case 0x3c: /* fbld */
5977 gen_helper_fbld_ST0(cpu_env
, s
->A0
);
5979 case 0x3e: /* fbstp */
5980 gen_helper_fbst_ST0(cpu_env
, s
->A0
);
5981 gen_helper_fpop(cpu_env
);
5983 case 0x3d: /* fildll */
5984 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
, s
->mem_index
, MO_LEQ
);
5985 gen_helper_fildll_ST0(cpu_env
, s
->tmp1_i64
);
5987 case 0x3f: /* fistpll */
5988 gen_helper_fistll_ST0(s
->tmp1_i64
, cpu_env
);
5989 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
, s
->mem_index
, MO_LEQ
);
5990 gen_helper_fpop(cpu_env
);
5996 /* register float ops */
6000 case 0x08: /* fld sti */
6001 gen_helper_fpush(cpu_env
);
6002 gen_helper_fmov_ST0_STN(cpu_env
,
6003 tcg_const_i32((opreg
+ 1) & 7));
6005 case 0x09: /* fxchg sti */
6006 case 0x29: /* fxchg4 sti, undocumented op */
6007 case 0x39: /* fxchg7 sti, undocumented op */
6008 gen_helper_fxchg_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6010 case 0x0a: /* grp d9/2 */
6013 /* check exceptions (FreeBSD FPU probe) */
6014 gen_helper_fwait(cpu_env
);
6020 case 0x0c: /* grp d9/4 */
6023 gen_helper_fchs_ST0(cpu_env
);
6026 gen_helper_fabs_ST0(cpu_env
);
6029 gen_helper_fldz_FT0(cpu_env
);
6030 gen_helper_fcom_ST0_FT0(cpu_env
);
6033 gen_helper_fxam_ST0(cpu_env
);
6039 case 0x0d: /* grp d9/5 */
6043 gen_helper_fpush(cpu_env
);
6044 gen_helper_fld1_ST0(cpu_env
);
6047 gen_helper_fpush(cpu_env
);
6048 gen_helper_fldl2t_ST0(cpu_env
);
6051 gen_helper_fpush(cpu_env
);
6052 gen_helper_fldl2e_ST0(cpu_env
);
6055 gen_helper_fpush(cpu_env
);
6056 gen_helper_fldpi_ST0(cpu_env
);
6059 gen_helper_fpush(cpu_env
);
6060 gen_helper_fldlg2_ST0(cpu_env
);
6063 gen_helper_fpush(cpu_env
);
6064 gen_helper_fldln2_ST0(cpu_env
);
6067 gen_helper_fpush(cpu_env
);
6068 gen_helper_fldz_ST0(cpu_env
);
6075 case 0x0e: /* grp d9/6 */
6078 gen_helper_f2xm1(cpu_env
);
6081 gen_helper_fyl2x(cpu_env
);
6084 gen_helper_fptan(cpu_env
);
6086 case 3: /* fpatan */
6087 gen_helper_fpatan(cpu_env
);
6089 case 4: /* fxtract */
6090 gen_helper_fxtract(cpu_env
);
6092 case 5: /* fprem1 */
6093 gen_helper_fprem1(cpu_env
);
6095 case 6: /* fdecstp */
6096 gen_helper_fdecstp(cpu_env
);
6099 case 7: /* fincstp */
6100 gen_helper_fincstp(cpu_env
);
6104 case 0x0f: /* grp d9/7 */
6107 gen_helper_fprem(cpu_env
);
6109 case 1: /* fyl2xp1 */
6110 gen_helper_fyl2xp1(cpu_env
);
6113 gen_helper_fsqrt(cpu_env
);
6115 case 3: /* fsincos */
6116 gen_helper_fsincos(cpu_env
);
6118 case 5: /* fscale */
6119 gen_helper_fscale(cpu_env
);
6121 case 4: /* frndint */
6122 gen_helper_frndint(cpu_env
);
6125 gen_helper_fsin(cpu_env
);
6129 gen_helper_fcos(cpu_env
);
6133 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6134 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6135 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6141 gen_helper_fp_arith_STN_ST0(op1
, opreg
);
6143 gen_helper_fpop(cpu_env
);
6145 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6146 gen_helper_fp_arith_ST0_FT0(op1
);
6150 case 0x02: /* fcom */
6151 case 0x22: /* fcom2, undocumented op */
6152 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6153 gen_helper_fcom_ST0_FT0(cpu_env
);
6155 case 0x03: /* fcomp */
6156 case 0x23: /* fcomp3, undocumented op */
6157 case 0x32: /* fcomp5, undocumented op */
6158 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6159 gen_helper_fcom_ST0_FT0(cpu_env
);
6160 gen_helper_fpop(cpu_env
);
6162 case 0x15: /* da/5 */
6164 case 1: /* fucompp */
6165 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6166 gen_helper_fucom_ST0_FT0(cpu_env
);
6167 gen_helper_fpop(cpu_env
);
6168 gen_helper_fpop(cpu_env
);
6176 case 0: /* feni (287 only, just do nop here) */
6178 case 1: /* fdisi (287 only, just do nop here) */
6181 gen_helper_fclex(cpu_env
);
6183 case 3: /* fninit */
6184 gen_helper_fninit(cpu_env
);
6186 case 4: /* fsetpm (287 only, just do nop here) */
6192 case 0x1d: /* fucomi */
6193 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6196 gen_update_cc_op(s
);
6197 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6198 gen_helper_fucomi_ST0_FT0(cpu_env
);
6199 set_cc_op(s
, CC_OP_EFLAGS
);
6201 case 0x1e: /* fcomi */
6202 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6205 gen_update_cc_op(s
);
6206 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6207 gen_helper_fcomi_ST0_FT0(cpu_env
);
6208 set_cc_op(s
, CC_OP_EFLAGS
);
6210 case 0x28: /* ffree sti */
6211 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6213 case 0x2a: /* fst sti */
6214 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6216 case 0x2b: /* fstp sti */
6217 case 0x0b: /* fstp1 sti, undocumented op */
6218 case 0x3a: /* fstp8 sti, undocumented op */
6219 case 0x3b: /* fstp9 sti, undocumented op */
6220 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6221 gen_helper_fpop(cpu_env
);
6223 case 0x2c: /* fucom st(i) */
6224 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6225 gen_helper_fucom_ST0_FT0(cpu_env
);
6227 case 0x2d: /* fucomp st(i) */
6228 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6229 gen_helper_fucom_ST0_FT0(cpu_env
);
6230 gen_helper_fpop(cpu_env
);
6232 case 0x33: /* de/3 */
6234 case 1: /* fcompp */
6235 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6236 gen_helper_fcom_ST0_FT0(cpu_env
);
6237 gen_helper_fpop(cpu_env
);
6238 gen_helper_fpop(cpu_env
);
6244 case 0x38: /* ffreep sti, undocumented op */
6245 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6246 gen_helper_fpop(cpu_env
);
6248 case 0x3c: /* df/4 */
6251 gen_helper_fnstsw(s
->tmp2_i32
, cpu_env
);
6252 tcg_gen_extu_i32_tl(s
->T0
, s
->tmp2_i32
);
6253 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
6259 case 0x3d: /* fucomip */
6260 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6263 gen_update_cc_op(s
);
6264 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6265 gen_helper_fucomi_ST0_FT0(cpu_env
);
6266 gen_helper_fpop(cpu_env
);
6267 set_cc_op(s
, CC_OP_EFLAGS
);
6269 case 0x3e: /* fcomip */
6270 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6273 gen_update_cc_op(s
);
6274 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6275 gen_helper_fcomi_ST0_FT0(cpu_env
);
6276 gen_helper_fpop(cpu_env
);
6277 set_cc_op(s
, CC_OP_EFLAGS
);
6279 case 0x10 ... 0x13: /* fcmovxx */
6284 static const uint8_t fcmov_cc
[8] = {
6291 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6294 op1
= fcmov_cc
[op
& 3] | (((op
>> 3) & 1) ^ 1);
6295 l1
= gen_new_label();
6296 gen_jcc1_noeob(s
, op1
, l1
);
6297 gen_helper_fmov_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6306 /************************/
6309 case 0xa4: /* movsS */
6311 ot
= mo_b_d(b
, dflag
);
6312 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6313 gen_repz_movs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6319 case 0xaa: /* stosS */
6321 ot
= mo_b_d(b
, dflag
);
6322 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6323 gen_repz_stos(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6328 case 0xac: /* lodsS */
6330 ot
= mo_b_d(b
, dflag
);
6331 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6332 gen_repz_lods(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6337 case 0xae: /* scasS */
6339 ot
= mo_b_d(b
, dflag
);
6340 if (prefixes
& PREFIX_REPNZ
) {
6341 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6342 } else if (prefixes
& PREFIX_REPZ
) {
6343 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6349 case 0xa6: /* cmpsS */
6351 ot
= mo_b_d(b
, dflag
);
6352 if (prefixes
& PREFIX_REPNZ
) {
6353 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6354 } else if (prefixes
& PREFIX_REPZ
) {
6355 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6360 case 0x6c: /* insS */
6362 ot
= mo_b_d32(b
, dflag
);
6363 tcg_gen_ext16u_tl(s
->T0
, cpu_regs
[R_EDX
]);
6364 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6365 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
) | 4);
6366 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6367 gen_repz_ins(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6370 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6371 gen_jmp(s
, s
->pc
- s
->cs_base
);
6375 case 0x6e: /* outsS */
6377 ot
= mo_b_d32(b
, dflag
);
6378 tcg_gen_ext16u_tl(s
->T0
, cpu_regs
[R_EDX
]);
6379 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6380 svm_is_rep(prefixes
) | 4);
6381 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6382 gen_repz_outs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6385 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6386 gen_jmp(s
, s
->pc
- s
->cs_base
);
6391 /************************/
6396 ot
= mo_b_d32(b
, dflag
);
6397 val
= x86_ldub_code(env
, s
);
6398 tcg_gen_movi_tl(s
->T0
, val
);
6399 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6400 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6401 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6404 tcg_gen_movi_i32(s
->tmp2_i32
, val
);
6405 gen_helper_in_func(ot
, s
->T1
, s
->tmp2_i32
);
6406 gen_op_mov_reg_v(s
, ot
, R_EAX
, s
->T1
);
6407 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
6408 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6410 gen_jmp(s
, s
->pc
- s
->cs_base
);
6415 ot
= mo_b_d32(b
, dflag
);
6416 val
= x86_ldub_code(env
, s
);
6417 tcg_gen_movi_tl(s
->T0
, val
);
6418 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6419 svm_is_rep(prefixes
));
6420 gen_op_mov_v_reg(s
, ot
, s
->T1
, R_EAX
);
6422 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6425 tcg_gen_movi_i32(s
->tmp2_i32
, val
);
6426 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, s
->T1
);
6427 gen_helper_out_func(ot
, s
->tmp2_i32
, s
->tmp3_i32
);
6428 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
6429 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6431 gen_jmp(s
, s
->pc
- s
->cs_base
);
6436 ot
= mo_b_d32(b
, dflag
);
6437 tcg_gen_ext16u_tl(s
->T0
, cpu_regs
[R_EDX
]);
6438 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6439 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6440 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6443 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
6444 gen_helper_in_func(ot
, s
->T1
, s
->tmp2_i32
);
6445 gen_op_mov_reg_v(s
, ot
, R_EAX
, s
->T1
);
6446 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
6447 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6449 gen_jmp(s
, s
->pc
- s
->cs_base
);
6454 ot
= mo_b_d32(b
, dflag
);
6455 tcg_gen_ext16u_tl(s
->T0
, cpu_regs
[R_EDX
]);
6456 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6457 svm_is_rep(prefixes
));
6458 gen_op_mov_v_reg(s
, ot
, s
->T1
, R_EAX
);
6460 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6463 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
6464 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, s
->T1
);
6465 gen_helper_out_func(ot
, s
->tmp2_i32
, s
->tmp3_i32
);
6466 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
6467 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6469 gen_jmp(s
, s
->pc
- s
->cs_base
);
6473 /************************/
6475 case 0xc2: /* ret im */
6476 val
= x86_ldsw_code(env
, s
);
6478 gen_stack_update(s
, val
+ (1 << ot
));
6479 /* Note that gen_pop_T0 uses a zero-extending load. */
6480 gen_op_jmp_v(s
->T0
);
6484 case 0xc3: /* ret */
6486 gen_pop_update(s
, ot
);
6487 /* Note that gen_pop_T0 uses a zero-extending load. */
6488 gen_op_jmp_v(s
->T0
);
6492 case 0xca: /* lret im */
6493 val
= x86_ldsw_code(env
, s
);
6495 if (s
->pe
&& !s
->vm86
) {
6496 gen_update_cc_op(s
);
6497 gen_jmp_im(s
, pc_start
- s
->cs_base
);
6498 gen_helper_lret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6499 tcg_const_i32(val
));
6503 gen_op_ld_v(s
, dflag
, s
->T0
, s
->A0
);
6504 /* NOTE: keeping EIP updated is not a problem in case of
6506 gen_op_jmp_v(s
->T0
);
6508 gen_add_A0_im(s
, 1 << dflag
);
6509 gen_op_ld_v(s
, dflag
, s
->T0
, s
->A0
);
6510 gen_op_movl_seg_T0_vm(s
, R_CS
);
6511 /* add stack offset */
6512 gen_stack_update(s
, val
+ (2 << dflag
));
6516 case 0xcb: /* lret */
6519 case 0xcf: /* iret */
6520 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IRET
);
6523 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6524 set_cc_op(s
, CC_OP_EFLAGS
);
6525 } else if (s
->vm86
) {
6527 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6529 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6530 set_cc_op(s
, CC_OP_EFLAGS
);
6533 gen_helper_iret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6534 tcg_const_i32(s
->pc
- s
->cs_base
));
6535 set_cc_op(s
, CC_OP_EFLAGS
);
6539 case 0xe8: /* call im */
6541 if (dflag
!= MO_16
) {
6542 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6544 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6546 next_eip
= s
->pc
- s
->cs_base
;
6548 if (dflag
== MO_16
) {
6550 } else if (!CODE64(s
)) {
6553 tcg_gen_movi_tl(s
->T0
, next_eip
);
6554 gen_push_v(s
, s
->T0
);
6559 case 0x9a: /* lcall im */
6561 unsigned int selector
, offset
;
6566 offset
= insn_get(env
, s
, ot
);
6567 selector
= insn_get(env
, s
, MO_16
);
6569 tcg_gen_movi_tl(s
->T0
, selector
);
6570 tcg_gen_movi_tl(s
->T1
, offset
);
6573 case 0xe9: /* jmp im */
6574 if (dflag
!= MO_16
) {
6575 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6577 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6579 tval
+= s
->pc
- s
->cs_base
;
6580 if (dflag
== MO_16
) {
6582 } else if (!CODE64(s
)) {
6588 case 0xea: /* ljmp 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 0xeb: /* jmp Jb */
6603 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6604 tval
+= s
->pc
- s
->cs_base
;
6605 if (dflag
== MO_16
) {
6610 case 0x70 ... 0x7f: /* jcc Jb */
6611 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6613 case 0x180 ... 0x18f: /* jcc Jv */
6614 if (dflag
!= MO_16
) {
6615 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6617 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6620 next_eip
= s
->pc
- s
->cs_base
;
6622 if (dflag
== MO_16
) {
6626 gen_jcc(s
, b
, tval
, next_eip
);
6629 case 0x190 ... 0x19f: /* setcc Gv */
6630 modrm
= x86_ldub_code(env
, s
);
6631 gen_setcc1(s
, b
, s
->T0
);
6632 gen_ldst_modrm(env
, s
, modrm
, MO_8
, OR_TMP0
, 1);
6634 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6635 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6639 modrm
= x86_ldub_code(env
, s
);
6640 reg
= ((modrm
>> 3) & 7) | rex_r
;
6641 gen_cmovcc1(env
, s
, ot
, b
, modrm
, reg
);
6644 /************************/
6646 case 0x9c: /* pushf */
6647 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_PUSHF
);
6648 if (s
->vm86
&& s
->iopl
!= 3) {
6649 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6651 gen_update_cc_op(s
);
6652 gen_helper_read_eflags(s
->T0
, cpu_env
);
6653 gen_push_v(s
, s
->T0
);
6656 case 0x9d: /* popf */
6657 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_POPF
);
6658 if (s
->vm86
&& s
->iopl
!= 3) {
6659 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6663 if (dflag
!= MO_16
) {
6664 gen_helper_write_eflags(cpu_env
, s
->T0
,
6665 tcg_const_i32((TF_MASK
| AC_MASK
|
6670 gen_helper_write_eflags(cpu_env
, s
->T0
,
6671 tcg_const_i32((TF_MASK
| AC_MASK
|
6673 IF_MASK
| IOPL_MASK
)
6677 if (s
->cpl
<= s
->iopl
) {
6678 if (dflag
!= MO_16
) {
6679 gen_helper_write_eflags(cpu_env
, s
->T0
,
6680 tcg_const_i32((TF_MASK
|
6686 gen_helper_write_eflags(cpu_env
, s
->T0
,
6687 tcg_const_i32((TF_MASK
|
6695 if (dflag
!= MO_16
) {
6696 gen_helper_write_eflags(cpu_env
, s
->T0
,
6697 tcg_const_i32((TF_MASK
| AC_MASK
|
6698 ID_MASK
| NT_MASK
)));
6700 gen_helper_write_eflags(cpu_env
, s
->T0
,
6701 tcg_const_i32((TF_MASK
| AC_MASK
|
6707 gen_pop_update(s
, ot
);
6708 set_cc_op(s
, CC_OP_EFLAGS
);
6709 /* abort translation because TF/AC flag may change */
6710 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
6714 case 0x9e: /* sahf */
6715 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6717 gen_op_mov_v_reg(s
, MO_8
, s
->T0
, R_AH
);
6718 gen_compute_eflags(s
);
6719 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, CC_O
);
6720 tcg_gen_andi_tl(s
->T0
, s
->T0
, CC_S
| CC_Z
| CC_A
| CC_P
| CC_C
);
6721 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, s
->T0
);
6723 case 0x9f: /* lahf */
6724 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6726 gen_compute_eflags(s
);
6727 /* Note: gen_compute_eflags() only gives the condition codes */
6728 tcg_gen_ori_tl(s
->T0
, cpu_cc_src
, 0x02);
6729 gen_op_mov_reg_v(s
, MO_8
, R_AH
, s
->T0
);
6731 case 0xf5: /* cmc */
6732 gen_compute_eflags(s
);
6733 tcg_gen_xori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6735 case 0xf8: /* clc */
6736 gen_compute_eflags(s
);
6737 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_C
);
6739 case 0xf9: /* stc */
6740 gen_compute_eflags(s
);
6741 tcg_gen_ori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6743 case 0xfc: /* cld */
6744 tcg_gen_movi_i32(s
->tmp2_i32
, 1);
6745 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6747 case 0xfd: /* std */
6748 tcg_gen_movi_i32(s
->tmp2_i32
, -1);
6749 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6752 /************************/
6753 /* bit operations */
6754 case 0x1ba: /* bt/bts/btr/btc Gv, im */
6756 modrm
= x86_ldub_code(env
, s
);
6757 op
= (modrm
>> 3) & 7;
6758 mod
= (modrm
>> 6) & 3;
6759 rm
= (modrm
& 7) | REX_B(s
);
6762 gen_lea_modrm(env
, s
, modrm
);
6763 if (!(s
->prefix
& PREFIX_LOCK
)) {
6764 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
6767 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
6770 val
= x86_ldub_code(env
, s
);
6771 tcg_gen_movi_tl(s
->T1
, val
);
6776 case 0x1a3: /* bt Gv, Ev */
6779 case 0x1ab: /* bts */
6782 case 0x1b3: /* btr */
6785 case 0x1bb: /* btc */
6789 modrm
= x86_ldub_code(env
, s
);
6790 reg
= ((modrm
>> 3) & 7) | rex_r
;
6791 mod
= (modrm
>> 6) & 3;
6792 rm
= (modrm
& 7) | REX_B(s
);
6793 gen_op_mov_v_reg(s
, MO_32
, s
->T1
, reg
);
6795 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
6796 /* specific case: we need to add a displacement */
6797 gen_exts(ot
, s
->T1
);
6798 tcg_gen_sari_tl(s
->tmp0
, s
->T1
, 3 + ot
);
6799 tcg_gen_shli_tl(s
->tmp0
, s
->tmp0
, ot
);
6800 tcg_gen_add_tl(s
->A0
, gen_lea_modrm_1(s
, a
), s
->tmp0
);
6801 gen_lea_v_seg(s
, s
->aflag
, s
->A0
, a
.def_seg
, s
->override
);
6802 if (!(s
->prefix
& PREFIX_LOCK
)) {
6803 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
6806 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
6809 tcg_gen_andi_tl(s
->T1
, s
->T1
, (1 << (3 + ot
)) - 1);
6810 tcg_gen_movi_tl(s
->tmp0
, 1);
6811 tcg_gen_shl_tl(s
->tmp0
, s
->tmp0
, s
->T1
);
6812 if (s
->prefix
& PREFIX_LOCK
) {
6815 /* Needs no atomic ops; we surpressed the normal
6816 memory load for LOCK above so do it now. */
6817 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
6820 tcg_gen_atomic_fetch_or_tl(s
->T0
, s
->A0
, s
->tmp0
,
6821 s
->mem_index
, ot
| MO_LE
);
6824 tcg_gen_not_tl(s
->tmp0
, s
->tmp0
);
6825 tcg_gen_atomic_fetch_and_tl(s
->T0
, s
->A0
, s
->tmp0
,
6826 s
->mem_index
, ot
| MO_LE
);
6830 tcg_gen_atomic_fetch_xor_tl(s
->T0
, s
->A0
, s
->tmp0
,
6831 s
->mem_index
, ot
| MO_LE
);
6834 tcg_gen_shr_tl(s
->tmp4
, s
->T0
, s
->T1
);
6836 tcg_gen_shr_tl(s
->tmp4
, s
->T0
, s
->T1
);
6839 /* Data already loaded; nothing to do. */
6842 tcg_gen_or_tl(s
->T0
, s
->T0
, s
->tmp0
);
6845 tcg_gen_andc_tl(s
->T0
, s
->T0
, s
->tmp0
);
6849 tcg_gen_xor_tl(s
->T0
, s
->T0
, s
->tmp0
);
6854 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
6856 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
6861 /* Delay all CC updates until after the store above. Note that
6862 C is the result of the test, Z is unchanged, and the others
6863 are all undefined. */
6865 case CC_OP_MULB
... CC_OP_MULQ
:
6866 case CC_OP_ADDB
... CC_OP_ADDQ
:
6867 case CC_OP_ADCB
... CC_OP_ADCQ
:
6868 case CC_OP_SUBB
... CC_OP_SUBQ
:
6869 case CC_OP_SBBB
... CC_OP_SBBQ
:
6870 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
6871 case CC_OP_INCB
... CC_OP_INCQ
:
6872 case CC_OP_DECB
... CC_OP_DECQ
:
6873 case CC_OP_SHLB
... CC_OP_SHLQ
:
6874 case CC_OP_SARB
... CC_OP_SARQ
:
6875 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
6876 /* Z was going to be computed from the non-zero status of CC_DST.
6877 We can get that same Z value (and the new C value) by leaving
6878 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
6880 tcg_gen_mov_tl(cpu_cc_src
, s
->tmp4
);
6881 set_cc_op(s
, ((s
->cc_op
- CC_OP_MULB
) & 3) + CC_OP_SARB
);
6884 /* Otherwise, generate EFLAGS and replace the C bit. */
6885 gen_compute_eflags(s
);
6886 tcg_gen_deposit_tl(cpu_cc_src
, cpu_cc_src
, s
->tmp4
,
6891 case 0x1bc: /* bsf / tzcnt */
6892 case 0x1bd: /* bsr / lzcnt */
6894 modrm
= x86_ldub_code(env
, s
);
6895 reg
= ((modrm
>> 3) & 7) | rex_r
;
6896 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
6897 gen_extu(ot
, s
->T0
);
6899 /* Note that lzcnt and tzcnt are in different extensions. */
6900 if ((prefixes
& PREFIX_REPZ
)
6902 ? s
->cpuid_ext3_features
& CPUID_EXT3_ABM
6903 : s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)) {
6905 /* For lzcnt/tzcnt, C bit is defined related to the input. */
6906 tcg_gen_mov_tl(cpu_cc_src
, s
->T0
);
6908 /* For lzcnt, reduce the target_ulong result by the
6909 number of zeros that we expect to find at the top. */
6910 tcg_gen_clzi_tl(s
->T0
, s
->T0
, TARGET_LONG_BITS
);
6911 tcg_gen_subi_tl(s
->T0
, s
->T0
, TARGET_LONG_BITS
- size
);
6913 /* For tzcnt, a zero input must return the operand size. */
6914 tcg_gen_ctzi_tl(s
->T0
, s
->T0
, size
);
6916 /* For lzcnt/tzcnt, Z bit is defined related to the result. */
6917 gen_op_update1_cc(s
);
6918 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
6920 /* For bsr/bsf, only the Z bit is defined and it is related
6921 to the input and not the result. */
6922 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
6923 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
6925 /* ??? The manual says that the output is undefined when the
6926 input is zero, but real hardware leaves it unchanged, and
6927 real programs appear to depend on that. Accomplish this
6928 by passing the output as the value to return upon zero. */
6930 /* For bsr, return the bit index of the first 1 bit,
6931 not the count of leading zeros. */
6932 tcg_gen_xori_tl(s
->T1
, cpu_regs
[reg
], TARGET_LONG_BITS
- 1);
6933 tcg_gen_clz_tl(s
->T0
, s
->T0
, s
->T1
);
6934 tcg_gen_xori_tl(s
->T0
, s
->T0
, TARGET_LONG_BITS
- 1);
6936 tcg_gen_ctz_tl(s
->T0
, s
->T0
, cpu_regs
[reg
]);
6939 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
6941 /************************/
6943 case 0x27: /* daa */
6946 gen_update_cc_op(s
);
6947 gen_helper_daa(cpu_env
);
6948 set_cc_op(s
, CC_OP_EFLAGS
);
6950 case 0x2f: /* das */
6953 gen_update_cc_op(s
);
6954 gen_helper_das(cpu_env
);
6955 set_cc_op(s
, CC_OP_EFLAGS
);
6957 case 0x37: /* aaa */
6960 gen_update_cc_op(s
);
6961 gen_helper_aaa(cpu_env
);
6962 set_cc_op(s
, CC_OP_EFLAGS
);
6964 case 0x3f: /* aas */
6967 gen_update_cc_op(s
);
6968 gen_helper_aas(cpu_env
);
6969 set_cc_op(s
, CC_OP_EFLAGS
);
6971 case 0xd4: /* aam */
6974 val
= x86_ldub_code(env
, s
);
6976 gen_exception(s
, EXCP00_DIVZ
, pc_start
- s
->cs_base
);
6978 gen_helper_aam(cpu_env
, tcg_const_i32(val
));
6979 set_cc_op(s
, CC_OP_LOGICB
);
6982 case 0xd5: /* aad */
6985 val
= x86_ldub_code(env
, s
);
6986 gen_helper_aad(cpu_env
, tcg_const_i32(val
));
6987 set_cc_op(s
, CC_OP_LOGICB
);
6989 /************************/
6991 case 0x90: /* nop */
6992 /* XXX: correct lock test for all insn */
6993 if (prefixes
& PREFIX_LOCK
) {
6996 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
6998 goto do_xchg_reg_eax
;
7000 if (prefixes
& PREFIX_REPZ
) {
7001 gen_update_cc_op(s
);
7002 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7003 gen_helper_pause(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7004 s
->base
.is_jmp
= DISAS_NORETURN
;
7007 case 0x9b: /* fwait */
7008 if ((s
->flags
& (HF_MP_MASK
| HF_TS_MASK
)) ==
7009 (HF_MP_MASK
| HF_TS_MASK
)) {
7010 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7012 gen_helper_fwait(cpu_env
);
7015 case 0xcc: /* int3 */
7016 gen_interrupt(s
, EXCP03_INT3
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
7018 case 0xcd: /* int N */
7019 val
= x86_ldub_code(env
, s
);
7020 if (s
->vm86
&& s
->iopl
!= 3) {
7021 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7023 gen_interrupt(s
, val
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
7026 case 0xce: /* into */
7029 gen_update_cc_op(s
);
7030 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7031 gen_helper_into(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7034 case 0xf1: /* icebp (undocumented, exits to external debugger) */
7035 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_ICEBP
);
7036 gen_debug(s
, pc_start
- s
->cs_base
);
7039 case 0xfa: /* cli */
7041 if (s
->cpl
<= s
->iopl
) {
7042 gen_helper_cli(cpu_env
);
7044 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7048 gen_helper_cli(cpu_env
);
7050 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7054 case 0xfb: /* sti */
7055 if (s
->vm86
? s
->iopl
== 3 : s
->cpl
<= s
->iopl
) {
7056 gen_helper_sti(cpu_env
);
7057 /* interruptions are enabled only the first insn after sti */
7058 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7059 gen_eob_inhibit_irq(s
, true);
7061 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7064 case 0x62: /* bound */
7068 modrm
= x86_ldub_code(env
, s
);
7069 reg
= (modrm
>> 3) & 7;
7070 mod
= (modrm
>> 6) & 3;
7073 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
7074 gen_lea_modrm(env
, s
, modrm
);
7075 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
7077 gen_helper_boundw(cpu_env
, s
->A0
, s
->tmp2_i32
);
7079 gen_helper_boundl(cpu_env
, s
->A0
, s
->tmp2_i32
);
7082 case 0x1c8 ... 0x1cf: /* bswap reg */
7083 reg
= (b
& 7) | REX_B(s
);
7084 #ifdef TARGET_X86_64
7085 if (dflag
== MO_64
) {
7086 gen_op_mov_v_reg(s
, MO_64
, s
->T0
, reg
);
7087 tcg_gen_bswap64_i64(s
->T0
, s
->T0
);
7088 gen_op_mov_reg_v(s
, MO_64
, reg
, s
->T0
);
7092 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, reg
);
7093 tcg_gen_ext32u_tl(s
->T0
, s
->T0
);
7094 tcg_gen_bswap32_tl(s
->T0
, s
->T0
);
7095 gen_op_mov_reg_v(s
, MO_32
, reg
, s
->T0
);
7098 case 0xd6: /* salc */
7101 gen_compute_eflags_c(s
, s
->T0
);
7102 tcg_gen_neg_tl(s
->T0
, s
->T0
);
7103 gen_op_mov_reg_v(s
, MO_8
, R_EAX
, s
->T0
);
7105 case 0xe0: /* loopnz */
7106 case 0xe1: /* loopz */
7107 case 0xe2: /* loop */
7108 case 0xe3: /* jecxz */
7110 TCGLabel
*l1
, *l2
, *l3
;
7112 tval
= (int8_t)insn_get(env
, s
, MO_8
);
7113 next_eip
= s
->pc
- s
->cs_base
;
7115 if (dflag
== MO_16
) {
7119 l1
= gen_new_label();
7120 l2
= gen_new_label();
7121 l3
= gen_new_label();
7124 case 0: /* loopnz */
7126 gen_op_add_reg_im(s
, s
->aflag
, R_ECX
, -1);
7127 gen_op_jz_ecx(s
, s
->aflag
, l3
);
7128 gen_jcc1(s
, (JCC_Z
<< 1) | (b
^ 1), l1
);
7131 gen_op_add_reg_im(s
, s
->aflag
, R_ECX
, -1);
7132 gen_op_jnz_ecx(s
, s
->aflag
, l1
);
7136 gen_op_jz_ecx(s
, s
->aflag
, l1
);
7141 gen_jmp_im(s
, next_eip
);
7145 gen_jmp_im(s
, tval
);
7150 case 0x130: /* wrmsr */
7151 case 0x132: /* rdmsr */
7153 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7155 gen_update_cc_op(s
);
7156 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7158 gen_helper_rdmsr(cpu_env
);
7160 gen_helper_wrmsr(cpu_env
);
7164 case 0x131: /* rdtsc */
7165 gen_update_cc_op(s
);
7166 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7167 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7170 gen_helper_rdtsc(cpu_env
);
7171 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7173 gen_jmp(s
, s
->pc
- s
->cs_base
);
7176 case 0x133: /* rdpmc */
7177 gen_update_cc_op(s
);
7178 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7179 gen_helper_rdpmc(cpu_env
);
7181 case 0x134: /* sysenter */
7182 /* For Intel SYSENTER is valid on 64-bit */
7183 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7186 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7188 gen_helper_sysenter(cpu_env
);
7192 case 0x135: /* sysexit */
7193 /* For Intel SYSEXIT is valid on 64-bit */
7194 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7197 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7199 gen_helper_sysexit(cpu_env
, tcg_const_i32(dflag
- 1));
7203 #ifdef TARGET_X86_64
7204 case 0x105: /* syscall */
7205 /* XXX: is it usable in real mode ? */
7206 gen_update_cc_op(s
);
7207 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7208 gen_helper_syscall(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7209 /* TF handling for the syscall insn is different. The TF bit is checked
7210 after the syscall insn completes. This allows #DB to not be
7211 generated after one has entered CPL0 if TF is set in FMASK. */
7212 gen_eob_worker(s
, false, true);
7214 case 0x107: /* sysret */
7216 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7218 gen_helper_sysret(cpu_env
, tcg_const_i32(dflag
- 1));
7219 /* condition codes are modified only in long mode */
7221 set_cc_op(s
, CC_OP_EFLAGS
);
7223 /* TF handling for the sysret insn is different. The TF bit is
7224 checked after the sysret insn completes. This allows #DB to be
7225 generated "as if" the syscall insn in userspace has just
7227 gen_eob_worker(s
, false, true);
7231 case 0x1a2: /* cpuid */
7232 gen_update_cc_op(s
);
7233 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7234 gen_helper_cpuid(cpu_env
);
7236 case 0xf4: /* hlt */
7238 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7240 gen_update_cc_op(s
);
7241 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7242 gen_helper_hlt(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7243 s
->base
.is_jmp
= DISAS_NORETURN
;
7247 modrm
= x86_ldub_code(env
, s
);
7248 mod
= (modrm
>> 6) & 3;
7249 op
= (modrm
>> 3) & 7;
7252 if (!s
->pe
|| s
->vm86
)
7254 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_READ
);
7255 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
7256 offsetof(CPUX86State
, ldt
.selector
));
7257 ot
= mod
== 3 ? dflag
: MO_16
;
7258 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7261 if (!s
->pe
|| s
->vm86
)
7264 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7266 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_WRITE
);
7267 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7268 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
7269 gen_helper_lldt(cpu_env
, s
->tmp2_i32
);
7273 if (!s
->pe
|| s
->vm86
)
7275 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_READ
);
7276 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
7277 offsetof(CPUX86State
, tr
.selector
));
7278 ot
= mod
== 3 ? dflag
: MO_16
;
7279 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7282 if (!s
->pe
|| s
->vm86
)
7285 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7287 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_WRITE
);
7288 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7289 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
7290 gen_helper_ltr(cpu_env
, s
->tmp2_i32
);
7295 if (!s
->pe
|| s
->vm86
)
7297 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7298 gen_update_cc_op(s
);
7300 gen_helper_verr(cpu_env
, s
->T0
);
7302 gen_helper_verw(cpu_env
, s
->T0
);
7304 set_cc_op(s
, CC_OP_EFLAGS
);
7312 modrm
= x86_ldub_code(env
, s
);
7314 CASE_MODRM_MEM_OP(0): /* sgdt */
7315 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_READ
);
7316 gen_lea_modrm(env
, s
, modrm
);
7317 tcg_gen_ld32u_tl(s
->T0
,
7318 cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7319 gen_op_st_v(s
, MO_16
, s
->T0
, s
->A0
);
7320 gen_add_A0_im(s
, 2);
7321 tcg_gen_ld_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7322 if (dflag
== MO_16
) {
7323 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xffffff);
7325 gen_op_st_v(s
, CODE64(s
) + MO_32
, s
->T0
, s
->A0
);
7328 case 0xc8: /* monitor */
7329 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) || s
->cpl
!= 0) {
7332 gen_update_cc_op(s
);
7333 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7334 tcg_gen_mov_tl(s
->A0
, cpu_regs
[R_EAX
]);
7335 gen_extu(s
->aflag
, s
->A0
);
7336 gen_add_A0_ds_seg(s
);
7337 gen_helper_monitor(cpu_env
, s
->A0
);
7340 case 0xc9: /* mwait */
7341 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) || s
->cpl
!= 0) {
7344 gen_update_cc_op(s
);
7345 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7346 gen_helper_mwait(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7350 case 0xca: /* clac */
7351 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
)
7355 gen_helper_clac(cpu_env
);
7356 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7360 case 0xcb: /* stac */
7361 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
)
7365 gen_helper_stac(cpu_env
);
7366 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7370 CASE_MODRM_MEM_OP(1): /* sidt */
7371 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_READ
);
7372 gen_lea_modrm(env
, s
, modrm
);
7373 tcg_gen_ld32u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7374 gen_op_st_v(s
, MO_16
, s
->T0
, s
->A0
);
7375 gen_add_A0_im(s
, 2);
7376 tcg_gen_ld_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, idt
.base
));
7377 if (dflag
== MO_16
) {
7378 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xffffff);
7380 gen_op_st_v(s
, CODE64(s
) + MO_32
, s
->T0
, s
->A0
);
7383 case 0xd0: /* xgetbv */
7384 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
7385 || (s
->prefix
& (PREFIX_LOCK
| PREFIX_DATA
7386 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
7389 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_ECX
]);
7390 gen_helper_xgetbv(s
->tmp1_i64
, cpu_env
, s
->tmp2_i32
);
7391 tcg_gen_extr_i64_tl(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
], s
->tmp1_i64
);
7394 case 0xd1: /* xsetbv */
7395 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
7396 || (s
->prefix
& (PREFIX_LOCK
| PREFIX_DATA
7397 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
7401 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7404 tcg_gen_concat_tl_i64(s
->tmp1_i64
, cpu_regs
[R_EAX
],
7406 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_ECX
]);
7407 gen_helper_xsetbv(cpu_env
, s
->tmp2_i32
, s
->tmp1_i64
);
7408 /* End TB because translation flags may change. */
7409 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7413 case 0xd8: /* VMRUN */
7414 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7418 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7421 gen_update_cc_op(s
);
7422 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7423 gen_helper_vmrun(cpu_env
, tcg_const_i32(s
->aflag
- 1),
7424 tcg_const_i32(s
->pc
- pc_start
));
7425 tcg_gen_exit_tb(NULL
, 0);
7426 s
->base
.is_jmp
= DISAS_NORETURN
;
7429 case 0xd9: /* VMMCALL */
7430 if (!(s
->flags
& HF_SVME_MASK
)) {
7433 gen_update_cc_op(s
);
7434 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7435 gen_helper_vmmcall(cpu_env
);
7438 case 0xda: /* VMLOAD */
7439 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7443 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7446 gen_update_cc_op(s
);
7447 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7448 gen_helper_vmload(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7451 case 0xdb: /* VMSAVE */
7452 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7456 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7459 gen_update_cc_op(s
);
7460 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7461 gen_helper_vmsave(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7464 case 0xdc: /* STGI */
7465 if ((!(s
->flags
& HF_SVME_MASK
)
7466 && !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
))
7471 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7474 gen_update_cc_op(s
);
7475 gen_helper_stgi(cpu_env
);
7476 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7480 case 0xdd: /* CLGI */
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_clgi(cpu_env
);
7493 case 0xde: /* SKINIT */
7494 if ((!(s
->flags
& HF_SVME_MASK
)
7495 && !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
))
7499 gen_update_cc_op(s
);
7500 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7501 gen_helper_skinit(cpu_env
);
7504 case 0xdf: /* INVLPGA */
7505 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7509 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7512 gen_update_cc_op(s
);
7513 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7514 gen_helper_invlpga(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7517 CASE_MODRM_MEM_OP(2): /* lgdt */
7519 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7522 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_WRITE
);
7523 gen_lea_modrm(env
, s
, modrm
);
7524 gen_op_ld_v(s
, MO_16
, s
->T1
, s
->A0
);
7525 gen_add_A0_im(s
, 2);
7526 gen_op_ld_v(s
, CODE64(s
) + MO_32
, s
->T0
, s
->A0
);
7527 if (dflag
== MO_16
) {
7528 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xffffff);
7530 tcg_gen_st_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7531 tcg_gen_st32_tl(s
->T1
, cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7534 CASE_MODRM_MEM_OP(3): /* lidt */
7536 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7539 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_WRITE
);
7540 gen_lea_modrm(env
, s
, modrm
);
7541 gen_op_ld_v(s
, MO_16
, s
->T1
, s
->A0
);
7542 gen_add_A0_im(s
, 2);
7543 gen_op_ld_v(s
, CODE64(s
) + MO_32
, s
->T0
, s
->A0
);
7544 if (dflag
== MO_16
) {
7545 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xffffff);
7547 tcg_gen_st_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, idt
.base
));
7548 tcg_gen_st32_tl(s
->T1
, cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7551 CASE_MODRM_OP(4): /* smsw */
7552 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_CR0
);
7553 tcg_gen_ld_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, cr
[0]));
7555 mod
= (modrm
>> 6) & 3;
7556 ot
= (mod
!= 3 ? MO_16
: s
->dflag
);
7560 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7562 case 0xee: /* rdpkru */
7563 if (prefixes
& PREFIX_LOCK
) {
7566 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_ECX
]);
7567 gen_helper_rdpkru(s
->tmp1_i64
, cpu_env
, s
->tmp2_i32
);
7568 tcg_gen_extr_i64_tl(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
], s
->tmp1_i64
);
7570 case 0xef: /* wrpkru */
7571 if (prefixes
& PREFIX_LOCK
) {
7574 tcg_gen_concat_tl_i64(s
->tmp1_i64
, cpu_regs
[R_EAX
],
7576 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_ECX
]);
7577 gen_helper_wrpkru(cpu_env
, s
->tmp2_i32
, s
->tmp1_i64
);
7579 CASE_MODRM_OP(6): /* lmsw */
7581 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7584 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7585 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7586 gen_helper_lmsw(cpu_env
, s
->T0
);
7587 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7591 CASE_MODRM_MEM_OP(7): /* invlpg */
7593 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7596 gen_update_cc_op(s
);
7597 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7598 gen_lea_modrm(env
, s
, modrm
);
7599 gen_helper_invlpg(cpu_env
, s
->A0
);
7600 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7604 case 0xf8: /* swapgs */
7605 #ifdef TARGET_X86_64
7608 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7610 tcg_gen_mov_tl(s
->T0
, cpu_seg_base
[R_GS
]);
7611 tcg_gen_ld_tl(cpu_seg_base
[R_GS
], cpu_env
,
7612 offsetof(CPUX86State
, kernelgsbase
));
7613 tcg_gen_st_tl(s
->T0
, cpu_env
,
7614 offsetof(CPUX86State
, kernelgsbase
));
7621 case 0xf9: /* rdtscp */
7622 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_RDTSCP
)) {
7625 gen_update_cc_op(s
);
7626 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7627 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7630 gen_helper_rdtscp(cpu_env
);
7631 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7633 gen_jmp(s
, s
->pc
- s
->cs_base
);
7642 case 0x108: /* invd */
7643 case 0x109: /* wbinvd */
7645 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7647 gen_svm_check_intercept(s
, pc_start
, (b
& 2) ? SVM_EXIT_INVD
: SVM_EXIT_WBINVD
);
7651 case 0x63: /* arpl or movslS (x86_64) */
7652 #ifdef TARGET_X86_64
7655 /* d_ot is the size of destination */
7658 modrm
= x86_ldub_code(env
, s
);
7659 reg
= ((modrm
>> 3) & 7) | rex_r
;
7660 mod
= (modrm
>> 6) & 3;
7661 rm
= (modrm
& 7) | REX_B(s
);
7664 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, rm
);
7666 if (d_ot
== MO_64
) {
7667 tcg_gen_ext32s_tl(s
->T0
, s
->T0
);
7669 gen_op_mov_reg_v(s
, d_ot
, reg
, s
->T0
);
7671 gen_lea_modrm(env
, s
, modrm
);
7672 gen_op_ld_v(s
, MO_32
| MO_SIGN
, s
->T0
, s
->A0
);
7673 gen_op_mov_reg_v(s
, d_ot
, reg
, s
->T0
);
7679 TCGv t0
, t1
, t2
, a0
;
7681 if (!s
->pe
|| s
->vm86
)
7683 t0
= tcg_temp_local_new();
7684 t1
= tcg_temp_local_new();
7685 t2
= tcg_temp_local_new();
7687 modrm
= x86_ldub_code(env
, s
);
7688 reg
= (modrm
>> 3) & 7;
7689 mod
= (modrm
>> 6) & 3;
7692 gen_lea_modrm(env
, s
, modrm
);
7693 gen_op_ld_v(s
, ot
, t0
, s
->A0
);
7694 a0
= tcg_temp_local_new();
7695 tcg_gen_mov_tl(a0
, s
->A0
);
7697 gen_op_mov_v_reg(s
, ot
, t0
, rm
);
7700 gen_op_mov_v_reg(s
, ot
, t1
, reg
);
7701 tcg_gen_andi_tl(s
->tmp0
, t0
, 3);
7702 tcg_gen_andi_tl(t1
, t1
, 3);
7703 tcg_gen_movi_tl(t2
, 0);
7704 label1
= gen_new_label();
7705 tcg_gen_brcond_tl(TCG_COND_GE
, s
->tmp0
, t1
, label1
);
7706 tcg_gen_andi_tl(t0
, t0
, ~3);
7707 tcg_gen_or_tl(t0
, t0
, t1
);
7708 tcg_gen_movi_tl(t2
, CC_Z
);
7709 gen_set_label(label1
);
7711 gen_op_st_v(s
, ot
, t0
, a0
);
7714 gen_op_mov_reg_v(s
, ot
, rm
, t0
);
7716 gen_compute_eflags(s
);
7717 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_Z
);
7718 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, t2
);
7724 case 0x102: /* lar */
7725 case 0x103: /* lsl */
7729 if (!s
->pe
|| s
->vm86
)
7731 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
7732 modrm
= x86_ldub_code(env
, s
);
7733 reg
= ((modrm
>> 3) & 7) | rex_r
;
7734 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7735 t0
= tcg_temp_local_new();
7736 gen_update_cc_op(s
);
7738 gen_helper_lar(t0
, cpu_env
, s
->T0
);
7740 gen_helper_lsl(t0
, cpu_env
, s
->T0
);
7742 tcg_gen_andi_tl(s
->tmp0
, cpu_cc_src
, CC_Z
);
7743 label1
= gen_new_label();
7744 tcg_gen_brcondi_tl(TCG_COND_EQ
, s
->tmp0
, 0, label1
);
7745 gen_op_mov_reg_v(s
, ot
, reg
, t0
);
7746 gen_set_label(label1
);
7747 set_cc_op(s
, CC_OP_EFLAGS
);
7752 modrm
= x86_ldub_code(env
, s
);
7753 mod
= (modrm
>> 6) & 3;
7754 op
= (modrm
>> 3) & 7;
7756 case 0: /* prefetchnta */
7757 case 1: /* prefetchnt0 */
7758 case 2: /* prefetchnt0 */
7759 case 3: /* prefetchnt0 */
7762 gen_nop_modrm(env
, s
, modrm
);
7763 /* nothing more to do */
7765 default: /* nop (multi byte) */
7766 gen_nop_modrm(env
, s
, modrm
);
7771 modrm
= x86_ldub_code(env
, s
);
7772 if (s
->flags
& HF_MPX_EN_MASK
) {
7773 mod
= (modrm
>> 6) & 3;
7774 reg
= ((modrm
>> 3) & 7) | rex_r
;
7775 if (prefixes
& PREFIX_REPZ
) {
7778 || (prefixes
& PREFIX_LOCK
)
7779 || s
->aflag
== MO_16
) {
7782 gen_bndck(env
, s
, modrm
, TCG_COND_LTU
, cpu_bndl
[reg
]);
7783 } else if (prefixes
& PREFIX_REPNZ
) {
7786 || (prefixes
& PREFIX_LOCK
)
7787 || s
->aflag
== MO_16
) {
7790 TCGv_i64 notu
= tcg_temp_new_i64();
7791 tcg_gen_not_i64(notu
, cpu_bndu
[reg
]);
7792 gen_bndck(env
, s
, modrm
, TCG_COND_GTU
, notu
);
7793 tcg_temp_free_i64(notu
);
7794 } else if (prefixes
& PREFIX_DATA
) {
7795 /* bndmov -- from reg/mem */
7796 if (reg
>= 4 || s
->aflag
== MO_16
) {
7800 int reg2
= (modrm
& 7) | REX_B(s
);
7801 if (reg2
>= 4 || (prefixes
& PREFIX_LOCK
)) {
7804 if (s
->flags
& HF_MPX_IU_MASK
) {
7805 tcg_gen_mov_i64(cpu_bndl
[reg
], cpu_bndl
[reg2
]);
7806 tcg_gen_mov_i64(cpu_bndu
[reg
], cpu_bndu
[reg2
]);
7809 gen_lea_modrm(env
, s
, modrm
);
7811 tcg_gen_qemu_ld_i64(cpu_bndl
[reg
], s
->A0
,
7812 s
->mem_index
, MO_LEQ
);
7813 tcg_gen_addi_tl(s
->A0
, s
->A0
, 8);
7814 tcg_gen_qemu_ld_i64(cpu_bndu
[reg
], s
->A0
,
7815 s
->mem_index
, MO_LEQ
);
7817 tcg_gen_qemu_ld_i64(cpu_bndl
[reg
], s
->A0
,
7818 s
->mem_index
, MO_LEUL
);
7819 tcg_gen_addi_tl(s
->A0
, s
->A0
, 4);
7820 tcg_gen_qemu_ld_i64(cpu_bndu
[reg
], s
->A0
,
7821 s
->mem_index
, MO_LEUL
);
7823 /* bnd registers are now in-use */
7824 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7826 } else if (mod
!= 3) {
7828 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7830 || (prefixes
& PREFIX_LOCK
)
7831 || s
->aflag
== MO_16
7836 tcg_gen_addi_tl(s
->A0
, cpu_regs
[a
.base
], a
.disp
);
7838 tcg_gen_movi_tl(s
->A0
, 0);
7840 gen_lea_v_seg(s
, s
->aflag
, s
->A0
, a
.def_seg
, s
->override
);
7842 tcg_gen_mov_tl(s
->T0
, cpu_regs
[a
.index
]);
7844 tcg_gen_movi_tl(s
->T0
, 0);
7847 gen_helper_bndldx64(cpu_bndl
[reg
], cpu_env
, s
->A0
, s
->T0
);
7848 tcg_gen_ld_i64(cpu_bndu
[reg
], cpu_env
,
7849 offsetof(CPUX86State
, mmx_t0
.MMX_Q(0)));
7851 gen_helper_bndldx32(cpu_bndu
[reg
], cpu_env
, s
->A0
, s
->T0
);
7852 tcg_gen_ext32u_i64(cpu_bndl
[reg
], cpu_bndu
[reg
]);
7853 tcg_gen_shri_i64(cpu_bndu
[reg
], cpu_bndu
[reg
], 32);
7855 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7858 gen_nop_modrm(env
, s
, modrm
);
7861 modrm
= x86_ldub_code(env
, s
);
7862 if (s
->flags
& HF_MPX_EN_MASK
) {
7863 mod
= (modrm
>> 6) & 3;
7864 reg
= ((modrm
>> 3) & 7) | rex_r
;
7865 if (mod
!= 3 && (prefixes
& PREFIX_REPZ
)) {
7868 || (prefixes
& PREFIX_LOCK
)
7869 || s
->aflag
== MO_16
) {
7872 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7874 tcg_gen_extu_tl_i64(cpu_bndl
[reg
], cpu_regs
[a
.base
]);
7876 tcg_gen_ext32u_i64(cpu_bndl
[reg
], cpu_bndl
[reg
]);
7878 } else if (a
.base
== -1) {
7879 /* no base register has lower bound of 0 */
7880 tcg_gen_movi_i64(cpu_bndl
[reg
], 0);
7882 /* rip-relative generates #ud */
7885 tcg_gen_not_tl(s
->A0
, gen_lea_modrm_1(s
, a
));
7887 tcg_gen_ext32u_tl(s
->A0
, s
->A0
);
7889 tcg_gen_extu_tl_i64(cpu_bndu
[reg
], s
->A0
);
7890 /* bnd registers are now in-use */
7891 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7893 } else if (prefixes
& PREFIX_REPNZ
) {
7896 || (prefixes
& PREFIX_LOCK
)
7897 || s
->aflag
== MO_16
) {
7900 gen_bndck(env
, s
, modrm
, TCG_COND_GTU
, cpu_bndu
[reg
]);
7901 } else if (prefixes
& PREFIX_DATA
) {
7902 /* bndmov -- to reg/mem */
7903 if (reg
>= 4 || s
->aflag
== MO_16
) {
7907 int reg2
= (modrm
& 7) | REX_B(s
);
7908 if (reg2
>= 4 || (prefixes
& PREFIX_LOCK
)) {
7911 if (s
->flags
& HF_MPX_IU_MASK
) {
7912 tcg_gen_mov_i64(cpu_bndl
[reg2
], cpu_bndl
[reg
]);
7913 tcg_gen_mov_i64(cpu_bndu
[reg2
], cpu_bndu
[reg
]);
7916 gen_lea_modrm(env
, s
, modrm
);
7918 tcg_gen_qemu_st_i64(cpu_bndl
[reg
], s
->A0
,
7919 s
->mem_index
, MO_LEQ
);
7920 tcg_gen_addi_tl(s
->A0
, s
->A0
, 8);
7921 tcg_gen_qemu_st_i64(cpu_bndu
[reg
], s
->A0
,
7922 s
->mem_index
, MO_LEQ
);
7924 tcg_gen_qemu_st_i64(cpu_bndl
[reg
], s
->A0
,
7925 s
->mem_index
, MO_LEUL
);
7926 tcg_gen_addi_tl(s
->A0
, s
->A0
, 4);
7927 tcg_gen_qemu_st_i64(cpu_bndu
[reg
], s
->A0
,
7928 s
->mem_index
, MO_LEUL
);
7931 } else if (mod
!= 3) {
7933 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7935 || (prefixes
& PREFIX_LOCK
)
7936 || s
->aflag
== MO_16
7941 tcg_gen_addi_tl(s
->A0
, cpu_regs
[a
.base
], a
.disp
);
7943 tcg_gen_movi_tl(s
->A0
, 0);
7945 gen_lea_v_seg(s
, s
->aflag
, s
->A0
, a
.def_seg
, s
->override
);
7947 tcg_gen_mov_tl(s
->T0
, cpu_regs
[a
.index
]);
7949 tcg_gen_movi_tl(s
->T0
, 0);
7952 gen_helper_bndstx64(cpu_env
, s
->A0
, s
->T0
,
7953 cpu_bndl
[reg
], cpu_bndu
[reg
]);
7955 gen_helper_bndstx32(cpu_env
, s
->A0
, s
->T0
,
7956 cpu_bndl
[reg
], cpu_bndu
[reg
]);
7960 gen_nop_modrm(env
, s
, modrm
);
7962 case 0x119: case 0x11c ... 0x11f: /* nop (multi byte) */
7963 modrm
= x86_ldub_code(env
, s
);
7964 gen_nop_modrm(env
, s
, modrm
);
7966 case 0x120: /* mov reg, crN */
7967 case 0x122: /* mov crN, reg */
7969 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7971 modrm
= x86_ldub_code(env
, s
);
7972 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7973 * AMD documentation (24594.pdf) and testing of
7974 * intel 386 and 486 processors all show that the mod bits
7975 * are assumed to be 1's, regardless of actual values.
7977 rm
= (modrm
& 7) | REX_B(s
);
7978 reg
= ((modrm
>> 3) & 7) | rex_r
;
7983 if ((prefixes
& PREFIX_LOCK
) && (reg
== 0) &&
7984 (s
->cpuid_ext3_features
& CPUID_EXT3_CR8LEG
)) {
7993 gen_update_cc_op(s
);
7994 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7996 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7999 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
8000 gen_helper_write_crN(cpu_env
, tcg_const_i32(reg
),
8002 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
8005 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8008 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
8011 gen_helper_read_crN(s
->T0
, cpu_env
, tcg_const_i32(reg
));
8012 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
8013 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
8023 case 0x121: /* mov reg, drN */
8024 case 0x123: /* mov drN, reg */
8026 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
8028 modrm
= x86_ldub_code(env
, s
);
8029 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
8030 * AMD documentation (24594.pdf) and testing of
8031 * intel 386 and 486 processors all show that the mod bits
8032 * are assumed to be 1's, regardless of actual values.
8034 rm
= (modrm
& 7) | REX_B(s
);
8035 reg
= ((modrm
>> 3) & 7) | rex_r
;
8044 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_DR0
+ reg
);
8045 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
8046 tcg_gen_movi_i32(s
->tmp2_i32
, reg
);
8047 gen_helper_set_dr(cpu_env
, s
->tmp2_i32
, s
->T0
);
8048 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8051 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_DR0
+ reg
);
8052 tcg_gen_movi_i32(s
->tmp2_i32
, reg
);
8053 gen_helper_get_dr(s
->T0
, cpu_env
, s
->tmp2_i32
);
8054 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
8058 case 0x106: /* clts */
8060 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
8062 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
8063 gen_helper_clts(cpu_env
);
8064 /* abort block because static cpu state changed */
8065 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8069 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
8070 case 0x1c3: /* MOVNTI reg, mem */
8071 if (!(s
->cpuid_features
& CPUID_SSE2
))
8073 ot
= mo_64_32(dflag
);
8074 modrm
= x86_ldub_code(env
, s
);
8075 mod
= (modrm
>> 6) & 3;
8078 reg
= ((modrm
>> 3) & 7) | rex_r
;
8079 /* generate a generic store */
8080 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
8083 modrm
= x86_ldub_code(env
, s
);
8085 CASE_MODRM_MEM_OP(0): /* fxsave */
8086 if (!(s
->cpuid_features
& CPUID_FXSR
)
8087 || (prefixes
& PREFIX_LOCK
)) {
8090 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
8091 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8094 gen_lea_modrm(env
, s
, modrm
);
8095 gen_helper_fxsave(cpu_env
, s
->A0
);
8098 CASE_MODRM_MEM_OP(1): /* fxrstor */
8099 if (!(s
->cpuid_features
& CPUID_FXSR
)
8100 || (prefixes
& PREFIX_LOCK
)) {
8103 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
8104 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8107 gen_lea_modrm(env
, s
, modrm
);
8108 gen_helper_fxrstor(cpu_env
, s
->A0
);
8111 CASE_MODRM_MEM_OP(2): /* ldmxcsr */
8112 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
)) {
8115 if (s
->flags
& HF_TS_MASK
) {
8116 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8119 gen_lea_modrm(env
, s
, modrm
);
8120 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
, s
->mem_index
, MO_LEUL
);
8121 gen_helper_ldmxcsr(cpu_env
, s
->tmp2_i32
);
8124 CASE_MODRM_MEM_OP(3): /* stmxcsr */
8125 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
)) {
8128 if (s
->flags
& HF_TS_MASK
) {
8129 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8132 gen_lea_modrm(env
, s
, modrm
);
8133 tcg_gen_ld32u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, mxcsr
));
8134 gen_op_st_v(s
, MO_32
, s
->T0
, s
->A0
);
8137 CASE_MODRM_MEM_OP(4): /* xsave */
8138 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8139 || (prefixes
& (PREFIX_LOCK
| PREFIX_DATA
8140 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
8143 gen_lea_modrm(env
, s
, modrm
);
8144 tcg_gen_concat_tl_i64(s
->tmp1_i64
, cpu_regs
[R_EAX
],
8146 gen_helper_xsave(cpu_env
, s
->A0
, s
->tmp1_i64
);
8149 CASE_MODRM_MEM_OP(5): /* xrstor */
8150 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8151 || (prefixes
& (PREFIX_LOCK
| PREFIX_DATA
8152 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
8155 gen_lea_modrm(env
, s
, modrm
);
8156 tcg_gen_concat_tl_i64(s
->tmp1_i64
, cpu_regs
[R_EAX
],
8158 gen_helper_xrstor(cpu_env
, s
->A0
, s
->tmp1_i64
);
8159 /* XRSTOR is how MPX is enabled, which changes how
8160 we translate. Thus we need to end the TB. */
8161 gen_update_cc_op(s
);
8162 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8166 CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */
8167 if (prefixes
& PREFIX_LOCK
) {
8170 if (prefixes
& PREFIX_DATA
) {
8172 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLWB
)) {
8175 gen_nop_modrm(env
, s
, modrm
);
8178 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8179 || (s
->cpuid_xsave_features
& CPUID_XSAVE_XSAVEOPT
) == 0
8180 || (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
))) {
8183 gen_lea_modrm(env
, s
, modrm
);
8184 tcg_gen_concat_tl_i64(s
->tmp1_i64
, cpu_regs
[R_EAX
],
8186 gen_helper_xsaveopt(cpu_env
, s
->A0
, s
->tmp1_i64
);
8190 CASE_MODRM_MEM_OP(7): /* clflush / clflushopt */
8191 if (prefixes
& PREFIX_LOCK
) {
8194 if (prefixes
& PREFIX_DATA
) {
8196 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLFLUSHOPT
)) {
8201 if ((s
->prefix
& (PREFIX_REPZ
| PREFIX_REPNZ
))
8202 || !(s
->cpuid_features
& CPUID_CLFLUSH
)) {
8206 gen_nop_modrm(env
, s
, modrm
);
8209 case 0xc0 ... 0xc7: /* rdfsbase (f3 0f ae /0) */
8210 case 0xc8 ... 0xcf: /* rdgsbase (f3 0f ae /1) */
8211 case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */
8212 case 0xd8 ... 0xdf: /* wrgsbase (f3 0f ae /3) */
8214 && (prefixes
& PREFIX_REPZ
)
8215 && !(prefixes
& PREFIX_LOCK
)
8216 && (s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_FSGSBASE
)) {
8217 TCGv base
, treg
, src
, dst
;
8219 /* Preserve hflags bits by testing CR4 at runtime. */
8220 tcg_gen_movi_i32(s
->tmp2_i32
, CR4_FSGSBASE_MASK
);
8221 gen_helper_cr4_testbit(cpu_env
, s
->tmp2_i32
);
8223 base
= cpu_seg_base
[modrm
& 8 ? R_GS
: R_FS
];
8224 treg
= cpu_regs
[(modrm
& 7) | REX_B(s
)];
8228 dst
= base
, src
= treg
;
8231 dst
= treg
, src
= base
;
8234 if (s
->dflag
== MO_32
) {
8235 tcg_gen_ext32u_tl(dst
, src
);
8237 tcg_gen_mov_tl(dst
, src
);
8243 case 0xf8: /* sfence / pcommit */
8244 if (prefixes
& PREFIX_DATA
) {
8246 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_PCOMMIT
)
8247 || (prefixes
& PREFIX_LOCK
)) {
8253 case 0xf9 ... 0xff: /* sfence */
8254 if (!(s
->cpuid_features
& CPUID_SSE
)
8255 || (prefixes
& PREFIX_LOCK
)) {
8258 tcg_gen_mb(TCG_MO_ST_ST
| TCG_BAR_SC
);
8260 case 0xe8 ... 0xef: /* lfence */
8261 if (!(s
->cpuid_features
& CPUID_SSE
)
8262 || (prefixes
& PREFIX_LOCK
)) {
8265 tcg_gen_mb(TCG_MO_LD_LD
| TCG_BAR_SC
);
8267 case 0xf0 ... 0xf7: /* mfence */
8268 if (!(s
->cpuid_features
& CPUID_SSE2
)
8269 || (prefixes
& PREFIX_LOCK
)) {
8272 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8280 case 0x10d: /* 3DNow! prefetch(w) */
8281 modrm
= x86_ldub_code(env
, s
);
8282 mod
= (modrm
>> 6) & 3;
8285 gen_nop_modrm(env
, s
, modrm
);
8287 case 0x1aa: /* rsm */
8288 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_RSM
);
8289 if (!(s
->flags
& HF_SMM_MASK
))
8291 gen_update_cc_op(s
);
8292 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8293 gen_helper_rsm(cpu_env
);
8296 case 0x1b8: /* SSE4.2 popcnt */
8297 if ((prefixes
& (PREFIX_REPZ
| PREFIX_LOCK
| PREFIX_REPNZ
)) !=
8300 if (!(s
->cpuid_ext_features
& CPUID_EXT_POPCNT
))
8303 modrm
= x86_ldub_code(env
, s
);
8304 reg
= ((modrm
>> 3) & 7) | rex_r
;
8306 if (s
->prefix
& PREFIX_DATA
) {
8309 ot
= mo_64_32(dflag
);
8312 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
8313 gen_extu(ot
, s
->T0
);
8314 tcg_gen_mov_tl(cpu_cc_src
, s
->T0
);
8315 tcg_gen_ctpop_tl(s
->T0
, s
->T0
);
8316 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
8318 set_cc_op(s
, CC_OP_POPCNT
);
8320 case 0x10e ... 0x10f:
8321 /* 3DNow! instructions, ignore prefixes */
8322 s
->prefix
&= ~(PREFIX_REPZ
| PREFIX_REPNZ
| PREFIX_DATA
);
8324 case 0x110 ... 0x117:
8325 case 0x128 ... 0x12f:
8326 case 0x138 ... 0x13a:
8327 case 0x150 ... 0x179:
8328 case 0x17c ... 0x17f:
8330 case 0x1c4 ... 0x1c6:
8331 case 0x1d0 ... 0x1fe:
8332 gen_sse(env
, s
, b
, pc_start
, rex_r
);
8339 gen_illegal_opcode(s
);
8342 gen_unknown_opcode(env
, s
);
8346 void tcg_x86_init(void)
8348 static const char reg_names
[CPU_NB_REGS
][4] = {
8349 #ifdef TARGET_X86_64
8377 static const char seg_base_names
[6][8] = {
8385 static const char bnd_regl_names
[4][8] = {
8386 "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb"
8388 static const char bnd_regu_names
[4][8] = {
8389 "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub"
8393 cpu_cc_op
= tcg_global_mem_new_i32(cpu_env
,
8394 offsetof(CPUX86State
, cc_op
), "cc_op");
8395 cpu_cc_dst
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_dst
),
8397 cpu_cc_src
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_src
),
8399 cpu_cc_src2
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_src2
),
8402 for (i
= 0; i
< CPU_NB_REGS
; ++i
) {
8403 cpu_regs
[i
] = tcg_global_mem_new(cpu_env
,
8404 offsetof(CPUX86State
, regs
[i
]),
8408 for (i
= 0; i
< 6; ++i
) {
8410 = tcg_global_mem_new(cpu_env
,
8411 offsetof(CPUX86State
, segs
[i
].base
),
8415 for (i
= 0; i
< 4; ++i
) {
8417 = tcg_global_mem_new_i64(cpu_env
,
8418 offsetof(CPUX86State
, bnd_regs
[i
].lb
),
8421 = tcg_global_mem_new_i64(cpu_env
,
8422 offsetof(CPUX86State
, bnd_regs
[i
].ub
),
8427 static void i386_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cpu
)
8429 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8430 CPUX86State
*env
= cpu
->env_ptr
;
8431 uint32_t flags
= dc
->base
.tb
->flags
;
8432 target_ulong cs_base
= dc
->base
.tb
->cs_base
;
8434 dc
->pe
= (flags
>> HF_PE_SHIFT
) & 1;
8435 dc
->code32
= (flags
>> HF_CS32_SHIFT
) & 1;
8436 dc
->ss32
= (flags
>> HF_SS32_SHIFT
) & 1;
8437 dc
->addseg
= (flags
>> HF_ADDSEG_SHIFT
) & 1;
8439 dc
->vm86
= (flags
>> VM_SHIFT
) & 1;
8440 dc
->cpl
= (flags
>> HF_CPL_SHIFT
) & 3;
8441 dc
->iopl
= (flags
>> IOPL_SHIFT
) & 3;
8442 dc
->tf
= (flags
>> TF_SHIFT
) & 1;
8443 dc
->cc_op
= CC_OP_DYNAMIC
;
8444 dc
->cc_op_dirty
= false;
8445 dc
->cs_base
= cs_base
;
8446 dc
->popl_esp_hack
= 0;
8447 /* select memory access functions */
8449 #ifdef CONFIG_SOFTMMU
8450 dc
->mem_index
= cpu_mmu_index(env
, false);
8452 dc
->cpuid_features
= env
->features
[FEAT_1_EDX
];
8453 dc
->cpuid_ext_features
= env
->features
[FEAT_1_ECX
];
8454 dc
->cpuid_ext2_features
= env
->features
[FEAT_8000_0001_EDX
];
8455 dc
->cpuid_ext3_features
= env
->features
[FEAT_8000_0001_ECX
];
8456 dc
->cpuid_7_0_ebx_features
= env
->features
[FEAT_7_0_EBX
];
8457 dc
->cpuid_xsave_features
= env
->features
[FEAT_XSAVE
];
8458 #ifdef TARGET_X86_64
8459 dc
->lma
= (flags
>> HF_LMA_SHIFT
) & 1;
8460 dc
->code64
= (flags
>> HF_CS64_SHIFT
) & 1;
8463 dc
->jmp_opt
= !(dc
->tf
|| dc
->base
.singlestep_enabled
||
8464 (flags
& HF_INHIBIT_IRQ_MASK
));
8465 /* Do not optimize repz jumps at all in icount mode, because
8466 rep movsS instructions are execured with different paths
8467 in !repz_opt and repz_opt modes. The first one was used
8468 always except single step mode. And this setting
8469 disables jumps optimization and control paths become
8470 equivalent in run and single step modes.
8471 Now there will be no jump optimization for repz in
8472 record/replay modes and there will always be an
8473 additional step for ecx=0 when icount is enabled.
8475 dc
->repz_opt
= !dc
->jmp_opt
&& !(tb_cflags(dc
->base
.tb
) & CF_USE_ICOUNT
);
8477 /* check addseg logic */
8478 if (!dc
->addseg
&& (dc
->vm86
|| !dc
->pe
|| !dc
->code32
))
8479 printf("ERROR addseg\n");
8482 dc
->T0
= tcg_temp_new();
8483 dc
->T1
= tcg_temp_new();
8484 dc
->A0
= tcg_temp_new();
8486 dc
->tmp0
= tcg_temp_new();
8487 dc
->tmp1_i64
= tcg_temp_new_i64();
8488 dc
->tmp2_i32
= tcg_temp_new_i32();
8489 dc
->tmp3_i32
= tcg_temp_new_i32();
8490 dc
->tmp4
= tcg_temp_new();
8491 dc
->ptr0
= tcg_temp_new_ptr();
8492 dc
->ptr1
= tcg_temp_new_ptr();
8493 dc
->cc_srcT
= tcg_temp_local_new();
8496 static void i386_tr_tb_start(DisasContextBase
*db
, CPUState
*cpu
)
8500 static void i386_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
8502 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8504 tcg_gen_insn_start(dc
->base
.pc_next
, dc
->cc_op
);
8507 static bool i386_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cpu
,
8508 const CPUBreakpoint
*bp
)
8510 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8511 /* If RF is set, suppress an internally generated breakpoint. */
8512 int flags
= dc
->base
.tb
->flags
& HF_RF_MASK
? BP_GDB
: BP_ANY
;
8513 if (bp
->flags
& flags
) {
8514 gen_debug(dc
, dc
->base
.pc_next
- dc
->cs_base
);
8515 dc
->base
.is_jmp
= DISAS_NORETURN
;
8516 /* The address covered by the breakpoint must be included in
8517 [tb->pc, tb->pc + tb->size) in order to for it to be
8518 properly cleared -- thus we increment the PC here so that
8519 the generic logic setting tb->size later does the right thing. */
8520 dc
->base
.pc_next
+= 1;
8527 static void i386_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
8529 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8530 target_ulong pc_next
= disas_insn(dc
, cpu
);
8532 if (dc
->tf
|| (dc
->base
.tb
->flags
& HF_INHIBIT_IRQ_MASK
)) {
8533 /* if single step mode, we generate only one instruction and
8534 generate an exception */
8535 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
8536 the flag and abort the translation to give the irqs a
8538 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
8539 } else if ((tb_cflags(dc
->base
.tb
) & CF_USE_ICOUNT
)
8540 && ((pc_next
& TARGET_PAGE_MASK
)
8541 != ((pc_next
+ TARGET_MAX_INSN_SIZE
- 1)
8543 || (pc_next
& ~TARGET_PAGE_MASK
) == 0)) {
8544 /* Do not cross the boundary of the pages in icount mode,
8545 it can cause an exception. Do it only when boundary is
8546 crossed by the first instruction in the block.
8547 If current instruction already crossed the bound - it's ok,
8548 because an exception hasn't stopped this code.
8550 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
8551 } else if ((pc_next
- dc
->base
.pc_first
) >= (TARGET_PAGE_SIZE
- 32)) {
8552 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
8555 dc
->base
.pc_next
= pc_next
;
8558 static void i386_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cpu
)
8560 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8562 if (dc
->base
.is_jmp
== DISAS_TOO_MANY
) {
8563 gen_jmp_im(dc
, dc
->base
.pc_next
- dc
->cs_base
);
8568 static void i386_tr_disas_log(const DisasContextBase
*dcbase
,
8571 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8573 qemu_log("IN: %s\n", lookup_symbol(dc
->base
.pc_first
));
8574 log_target_disas(cpu
, dc
->base
.pc_first
, dc
->base
.tb
->size
);
8577 static const TranslatorOps i386_tr_ops
= {
8578 .init_disas_context
= i386_tr_init_disas_context
,
8579 .tb_start
= i386_tr_tb_start
,
8580 .insn_start
= i386_tr_insn_start
,
8581 .breakpoint_check
= i386_tr_breakpoint_check
,
8582 .translate_insn
= i386_tr_translate_insn
,
8583 .tb_stop
= i386_tr_tb_stop
,
8584 .disas_log
= i386_tr_disas_log
,
8587 /* generate intermediate code for basic block 'tb'. */
8588 void gen_intermediate_code(CPUState
*cpu
, TranslationBlock
*tb
)
8592 translator_loop(&i386_tr_ops
, &dc
.base
, cpu
, tb
);
8595 void restore_state_to_opc(CPUX86State
*env
, TranslationBlock
*tb
,
8598 int cc_op
= data
[1];
8599 env
->eip
= data
[0] - tb
->cs_base
;
8600 if (cc_op
!= CC_OP_DYNAMIC
) {