4 * Copyright (c) 2003 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 #include "qemu/osdep.h"
21 #include "qemu/host-utils.h"
23 #include "disas/disas.h"
24 #include "exec/exec-all.h"
26 #include "exec/cpu_ldst.h"
28 #include "exec/helper-proto.h"
29 #include "exec/helper-gen.h"
31 #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_env cpu_env
;
77 static TCGv cpu_cc_dst
, cpu_cc_src
, cpu_cc_src2
, cpu_cc_srcT
;
78 static TCGv_i32 cpu_cc_op
;
79 static TCGv cpu_regs
[CPU_NB_REGS
];
80 static TCGv cpu_seg_base
[6];
81 static TCGv_i64 cpu_bndl
[4];
82 static TCGv_i64 cpu_bndu
[4];
84 static TCGv cpu_T0
, cpu_T1
;
85 /* local register indexes (only used inside old micro ops) */
86 static TCGv cpu_tmp0
, cpu_tmp4
;
87 static TCGv_ptr cpu_ptr0
, cpu_ptr1
;
88 static TCGv_i32 cpu_tmp2_i32
, cpu_tmp3_i32
;
89 static TCGv_i64 cpu_tmp1_i64
;
91 #include "exec/gen-icount.h"
94 static int x86_64_hregs
;
97 typedef struct DisasContext
{
98 /* current insn context */
99 int override
; /* -1 if no override */
103 target_ulong pc_start
;
104 target_ulong pc
; /* pc = eip + cs_base */
105 int is_jmp
; /* 1 = means jump (stop translation), 2 means CPU
106 static state change (stop translation) */
107 /* current block context */
108 target_ulong cs_base
; /* base of CS segment */
109 int pe
; /* protected mode */
110 int code32
; /* 32 bit code segment */
112 int lma
; /* long mode active */
113 int code64
; /* 64 bit code segment */
116 int vex_l
; /* vex vector length */
117 int vex_v
; /* vex vvvv register, without 1's compliment. */
118 int ss32
; /* 32 bit stack segment */
119 CCOp cc_op
; /* current CC operation */
121 int addseg
; /* non zero if either DS/ES/SS have a non zero base */
122 int f_st
; /* currently unused */
123 int vm86
; /* vm86 mode */
126 int tf
; /* TF cpu flag */
127 int singlestep_enabled
; /* "hardware" single step enabled */
128 int jmp_opt
; /* use direct block chaining for direct jumps */
129 int repz_opt
; /* optimize jumps within repz instructions */
130 int mem_index
; /* select memory access functions */
131 uint64_t flags
; /* all execution flags */
132 struct TranslationBlock
*tb
;
133 int popl_esp_hack
; /* for correct popl with esp base handling */
134 int rip_offset
; /* only used in x86_64, but left for simplicity */
136 int cpuid_ext_features
;
137 int cpuid_ext2_features
;
138 int cpuid_ext3_features
;
139 int cpuid_7_0_ebx_features
;
140 int cpuid_xsave_features
;
143 static void gen_eob(DisasContext
*s
);
144 static void gen_jr(DisasContext
*s
, TCGv dest
);
145 static void gen_jmp(DisasContext
*s
, target_ulong eip
);
146 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
);
147 static void gen_op(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
);
149 /* i386 arith/logic operations */
169 OP_SHL1
, /* undocumented */
185 /* I386 int registers */
186 OR_EAX
, /* MUST be even numbered */
195 OR_TMP0
= 16, /* temporary operand register */
197 OR_A0
, /* temporary register used when doing address evaluation */
207 /* Bit set if the global variable is live after setting CC_OP to X. */
208 static const uint8_t cc_op_live
[CC_OP_NB
] = {
209 [CC_OP_DYNAMIC
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
210 [CC_OP_EFLAGS
] = USES_CC_SRC
,
211 [CC_OP_MULB
... CC_OP_MULQ
] = USES_CC_DST
| USES_CC_SRC
,
212 [CC_OP_ADDB
... CC_OP_ADDQ
] = USES_CC_DST
| USES_CC_SRC
,
213 [CC_OP_ADCB
... CC_OP_ADCQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
214 [CC_OP_SUBB
... CC_OP_SUBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRCT
,
215 [CC_OP_SBBB
... CC_OP_SBBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
216 [CC_OP_LOGICB
... CC_OP_LOGICQ
] = USES_CC_DST
,
217 [CC_OP_INCB
... CC_OP_INCQ
] = USES_CC_DST
| USES_CC_SRC
,
218 [CC_OP_DECB
... CC_OP_DECQ
] = USES_CC_DST
| USES_CC_SRC
,
219 [CC_OP_SHLB
... CC_OP_SHLQ
] = USES_CC_DST
| USES_CC_SRC
,
220 [CC_OP_SARB
... CC_OP_SARQ
] = USES_CC_DST
| USES_CC_SRC
,
221 [CC_OP_BMILGB
... CC_OP_BMILGQ
] = USES_CC_DST
| USES_CC_SRC
,
222 [CC_OP_ADCX
] = USES_CC_DST
| USES_CC_SRC
,
223 [CC_OP_ADOX
] = USES_CC_SRC
| USES_CC_SRC2
,
224 [CC_OP_ADCOX
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
226 [CC_OP_POPCNT
] = USES_CC_SRC
,
229 static void set_cc_op(DisasContext
*s
, CCOp op
)
233 if (s
->cc_op
== op
) {
237 /* Discard CC computation that will no longer be used. */
238 dead
= cc_op_live
[s
->cc_op
] & ~cc_op_live
[op
];
239 if (dead
& USES_CC_DST
) {
240 tcg_gen_discard_tl(cpu_cc_dst
);
242 if (dead
& USES_CC_SRC
) {
243 tcg_gen_discard_tl(cpu_cc_src
);
245 if (dead
& USES_CC_SRC2
) {
246 tcg_gen_discard_tl(cpu_cc_src2
);
248 if (dead
& USES_CC_SRCT
) {
249 tcg_gen_discard_tl(cpu_cc_srcT
);
252 if (op
== CC_OP_DYNAMIC
) {
253 /* The DYNAMIC setting is translator only, and should never be
254 stored. Thus we always consider it clean. */
255 s
->cc_op_dirty
= false;
257 /* Discard any computed CC_OP value (see shifts). */
258 if (s
->cc_op
== CC_OP_DYNAMIC
) {
259 tcg_gen_discard_i32(cpu_cc_op
);
261 s
->cc_op_dirty
= true;
266 static void gen_update_cc_op(DisasContext
*s
)
268 if (s
->cc_op_dirty
) {
269 tcg_gen_movi_i32(cpu_cc_op
, s
->cc_op
);
270 s
->cc_op_dirty
= false;
276 #define NB_OP_SIZES 4
278 #else /* !TARGET_X86_64 */
280 #define NB_OP_SIZES 3
282 #endif /* !TARGET_X86_64 */
284 #if defined(HOST_WORDS_BIGENDIAN)
285 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
286 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
287 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
288 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
289 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
291 #define REG_B_OFFSET 0
292 #define REG_H_OFFSET 1
293 #define REG_W_OFFSET 0
294 #define REG_L_OFFSET 0
295 #define REG_LH_OFFSET 4
298 /* In instruction encodings for byte register accesses the
299 * register number usually indicates "low 8 bits of register N";
300 * however there are some special cases where N 4..7 indicates
301 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
302 * true for this special case, false otherwise.
304 static inline bool byte_reg_is_xH(int reg
)
310 if (reg
>= 8 || x86_64_hregs
) {
317 /* Select the size of a push/pop operation. */
318 static inline TCGMemOp
mo_pushpop(DisasContext
*s
, TCGMemOp ot
)
321 return ot
== MO_16
? MO_16
: MO_64
;
327 /* Select the size of the stack pointer. */
328 static inline TCGMemOp
mo_stacksize(DisasContext
*s
)
330 return CODE64(s
) ? MO_64
: s
->ss32
? MO_32
: MO_16
;
333 /* Select only size 64 else 32. Used for SSE operand sizes. */
334 static inline TCGMemOp
mo_64_32(TCGMemOp ot
)
337 return ot
== MO_64
? MO_64
: MO_32
;
343 /* Select size 8 if lsb of B is clear, else OT. Used for decoding
344 byte vs word opcodes. */
345 static inline TCGMemOp
mo_b_d(int b
, TCGMemOp ot
)
347 return b
& 1 ? ot
: MO_8
;
350 /* Select size 8 if lsb of B is clear, else OT capped at 32.
351 Used for decoding operand size of port opcodes. */
352 static inline TCGMemOp
mo_b_d32(int b
, TCGMemOp ot
)
354 return b
& 1 ? (ot
== MO_16
? MO_16
: MO_32
) : MO_8
;
357 static void gen_op_mov_reg_v(TCGMemOp ot
, int reg
, TCGv t0
)
361 if (!byte_reg_is_xH(reg
)) {
362 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 8);
364 tcg_gen_deposit_tl(cpu_regs
[reg
- 4], cpu_regs
[reg
- 4], t0
, 8, 8);
368 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 16);
371 /* For x86_64, this sets the higher half of register to zero.
372 For i386, this is equivalent to a mov. */
373 tcg_gen_ext32u_tl(cpu_regs
[reg
], t0
);
377 tcg_gen_mov_tl(cpu_regs
[reg
], t0
);
385 static inline void gen_op_mov_v_reg(TCGMemOp ot
, TCGv t0
, int reg
)
387 if (ot
== MO_8
&& byte_reg_is_xH(reg
)) {
388 tcg_gen_extract_tl(t0
, cpu_regs
[reg
- 4], 8, 8);
390 tcg_gen_mov_tl(t0
, cpu_regs
[reg
]);
394 static void gen_add_A0_im(DisasContext
*s
, int val
)
396 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, val
);
398 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
402 static inline void gen_op_jmp_v(TCGv dest
)
404 tcg_gen_st_tl(dest
, cpu_env
, offsetof(CPUX86State
, eip
));
407 static inline void gen_op_add_reg_im(TCGMemOp size
, int reg
, int32_t val
)
409 tcg_gen_addi_tl(cpu_tmp0
, cpu_regs
[reg
], val
);
410 gen_op_mov_reg_v(size
, reg
, cpu_tmp0
);
413 static inline void gen_op_add_reg_T0(TCGMemOp size
, int reg
)
415 tcg_gen_add_tl(cpu_tmp0
, cpu_regs
[reg
], cpu_T0
);
416 gen_op_mov_reg_v(size
, reg
, cpu_tmp0
);
419 static inline void gen_op_ld_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
421 tcg_gen_qemu_ld_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
424 static inline void gen_op_st_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
426 tcg_gen_qemu_st_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
429 static inline void gen_op_st_rm_T0_A0(DisasContext
*s
, int idx
, int d
)
432 gen_op_st_v(s
, idx
, cpu_T0
, cpu_A0
);
434 gen_op_mov_reg_v(idx
, d
, cpu_T0
);
438 static inline void gen_jmp_im(target_ulong pc
)
440 tcg_gen_movi_tl(cpu_tmp0
, pc
);
441 gen_op_jmp_v(cpu_tmp0
);
444 /* Compute SEG:REG into A0. SEG is selected from the override segment
445 (OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to
446 indicate no override. */
447 static void gen_lea_v_seg(DisasContext
*s
, TCGMemOp aflag
, TCGv a0
,
448 int def_seg
, int ovr_seg
)
454 tcg_gen_mov_tl(cpu_A0
, a0
);
461 if (ovr_seg
< 0 && s
->addseg
) {
465 tcg_gen_ext32u_tl(cpu_A0
, a0
);
471 tcg_gen_ext16u_tl(cpu_A0
, a0
);
486 TCGv seg
= cpu_seg_base
[ovr_seg
];
488 if (aflag
== MO_64
) {
489 tcg_gen_add_tl(cpu_A0
, a0
, seg
);
490 } else if (CODE64(s
)) {
491 tcg_gen_ext32u_tl(cpu_A0
, a0
);
492 tcg_gen_add_tl(cpu_A0
, cpu_A0
, seg
);
494 tcg_gen_add_tl(cpu_A0
, a0
, seg
);
495 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
500 static inline void gen_string_movl_A0_ESI(DisasContext
*s
)
502 gen_lea_v_seg(s
, s
->aflag
, cpu_regs
[R_ESI
], R_DS
, s
->override
);
505 static inline void gen_string_movl_A0_EDI(DisasContext
*s
)
507 gen_lea_v_seg(s
, s
->aflag
, cpu_regs
[R_EDI
], R_ES
, -1);
510 static inline void gen_op_movl_T0_Dshift(TCGMemOp ot
)
512 tcg_gen_ld32s_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, df
));
513 tcg_gen_shli_tl(cpu_T0
, cpu_T0
, ot
);
516 static TCGv
gen_ext_tl(TCGv dst
, TCGv src
, TCGMemOp size
, bool sign
)
521 tcg_gen_ext8s_tl(dst
, src
);
523 tcg_gen_ext8u_tl(dst
, src
);
528 tcg_gen_ext16s_tl(dst
, src
);
530 tcg_gen_ext16u_tl(dst
, src
);
536 tcg_gen_ext32s_tl(dst
, src
);
538 tcg_gen_ext32u_tl(dst
, src
);
547 static void gen_extu(TCGMemOp ot
, TCGv reg
)
549 gen_ext_tl(reg
, reg
, ot
, false);
552 static void gen_exts(TCGMemOp ot
, TCGv reg
)
554 gen_ext_tl(reg
, reg
, ot
, true);
557 static inline void gen_op_jnz_ecx(TCGMemOp size
, TCGLabel
*label1
)
559 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[R_ECX
]);
560 gen_extu(size
, cpu_tmp0
);
561 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_tmp0
, 0, label1
);
564 static inline void gen_op_jz_ecx(TCGMemOp size
, TCGLabel
*label1
)
566 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[R_ECX
]);
567 gen_extu(size
, cpu_tmp0
);
568 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
571 static void gen_helper_in_func(TCGMemOp ot
, TCGv v
, TCGv_i32 n
)
575 gen_helper_inb(v
, cpu_env
, n
);
578 gen_helper_inw(v
, cpu_env
, n
);
581 gen_helper_inl(v
, cpu_env
, n
);
588 static void gen_helper_out_func(TCGMemOp ot
, TCGv_i32 v
, TCGv_i32 n
)
592 gen_helper_outb(cpu_env
, v
, n
);
595 gen_helper_outw(cpu_env
, v
, n
);
598 gen_helper_outl(cpu_env
, v
, n
);
605 static void gen_check_io(DisasContext
*s
, TCGMemOp ot
, target_ulong cur_eip
,
608 target_ulong next_eip
;
610 if (s
->pe
&& (s
->cpl
> s
->iopl
|| s
->vm86
)) {
611 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
614 gen_helper_check_iob(cpu_env
, cpu_tmp2_i32
);
617 gen_helper_check_iow(cpu_env
, cpu_tmp2_i32
);
620 gen_helper_check_iol(cpu_env
, cpu_tmp2_i32
);
626 if(s
->flags
& HF_SVMI_MASK
) {
629 svm_flags
|= (1 << (4 + ot
));
630 next_eip
= s
->pc
- s
->cs_base
;
631 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
632 gen_helper_svm_check_io(cpu_env
, cpu_tmp2_i32
,
633 tcg_const_i32(svm_flags
),
634 tcg_const_i32(next_eip
- cur_eip
));
638 static inline void gen_movs(DisasContext
*s
, TCGMemOp ot
)
640 gen_string_movl_A0_ESI(s
);
641 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
642 gen_string_movl_A0_EDI(s
);
643 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
644 gen_op_movl_T0_Dshift(ot
);
645 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
646 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
649 static void gen_op_update1_cc(void)
651 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
654 static void gen_op_update2_cc(void)
656 tcg_gen_mov_tl(cpu_cc_src
, cpu_T1
);
657 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
660 static void gen_op_update3_cc(TCGv reg
)
662 tcg_gen_mov_tl(cpu_cc_src2
, reg
);
663 tcg_gen_mov_tl(cpu_cc_src
, cpu_T1
);
664 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
667 static inline void gen_op_testl_T0_T1_cc(void)
669 tcg_gen_and_tl(cpu_cc_dst
, cpu_T0
, cpu_T1
);
672 static void gen_op_update_neg_cc(void)
674 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
675 tcg_gen_neg_tl(cpu_cc_src
, cpu_T0
);
676 tcg_gen_movi_tl(cpu_cc_srcT
, 0);
679 /* compute all eflags to cc_src */
680 static void gen_compute_eflags(DisasContext
*s
)
682 TCGv zero
, dst
, src1
, src2
;
685 if (s
->cc_op
== CC_OP_EFLAGS
) {
688 if (s
->cc_op
== CC_OP_CLR
) {
689 tcg_gen_movi_tl(cpu_cc_src
, CC_Z
| CC_P
);
690 set_cc_op(s
, CC_OP_EFLAGS
);
699 /* Take care to not read values that are not live. */
700 live
= cc_op_live
[s
->cc_op
] & ~USES_CC_SRCT
;
701 dead
= live
^ (USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
);
703 zero
= tcg_const_tl(0);
704 if (dead
& USES_CC_DST
) {
707 if (dead
& USES_CC_SRC
) {
710 if (dead
& USES_CC_SRC2
) {
716 gen_helper_cc_compute_all(cpu_cc_src
, dst
, src1
, src2
, cpu_cc_op
);
717 set_cc_op(s
, CC_OP_EFLAGS
);
724 typedef struct CCPrepare
{
734 /* compute eflags.C to reg */
735 static CCPrepare
gen_prepare_eflags_c(DisasContext
*s
, TCGv reg
)
741 case CC_OP_SUBB
... CC_OP_SUBQ
:
742 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
743 size
= s
->cc_op
- CC_OP_SUBB
;
744 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
745 /* If no temporary was used, be careful not to alias t1 and t0. */
746 t0
= TCGV_EQUAL(t1
, cpu_cc_src
) ? cpu_tmp0
: reg
;
747 tcg_gen_mov_tl(t0
, cpu_cc_srcT
);
751 case CC_OP_ADDB
... CC_OP_ADDQ
:
752 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
753 size
= s
->cc_op
- CC_OP_ADDB
;
754 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
755 t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
757 return (CCPrepare
) { .cond
= TCG_COND_LTU
, .reg
= t0
,
758 .reg2
= t1
, .mask
= -1, .use_reg2
= true };
760 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
763 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
765 case CC_OP_INCB
... CC_OP_INCQ
:
766 case CC_OP_DECB
... CC_OP_DECQ
:
767 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
768 .mask
= -1, .no_setcond
= true };
770 case CC_OP_SHLB
... CC_OP_SHLQ
:
771 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
772 size
= s
->cc_op
- CC_OP_SHLB
;
773 shift
= (8 << size
) - 1;
774 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
775 .mask
= (target_ulong
)1 << shift
};
777 case CC_OP_MULB
... CC_OP_MULQ
:
778 return (CCPrepare
) { .cond
= TCG_COND_NE
,
779 .reg
= cpu_cc_src
, .mask
= -1 };
781 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
782 size
= s
->cc_op
- CC_OP_BMILGB
;
783 t0
= gen_ext_tl(reg
, cpu_cc_src
, size
, false);
784 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
788 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_dst
,
789 .mask
= -1, .no_setcond
= true };
792 case CC_OP_SARB
... CC_OP_SARQ
:
794 return (CCPrepare
) { .cond
= TCG_COND_NE
,
795 .reg
= cpu_cc_src
, .mask
= CC_C
};
798 /* The need to compute only C from CC_OP_DYNAMIC is important
799 in efficiently implementing e.g. INC at the start of a TB. */
801 gen_helper_cc_compute_c(reg
, cpu_cc_dst
, cpu_cc_src
,
802 cpu_cc_src2
, cpu_cc_op
);
803 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
804 .mask
= -1, .no_setcond
= true };
808 /* compute eflags.P to reg */
809 static CCPrepare
gen_prepare_eflags_p(DisasContext
*s
, TCGv reg
)
811 gen_compute_eflags(s
);
812 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
816 /* compute eflags.S to reg */
817 static CCPrepare
gen_prepare_eflags_s(DisasContext
*s
, TCGv reg
)
821 gen_compute_eflags(s
);
827 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
831 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
834 TCGMemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
835 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, true);
836 return (CCPrepare
) { .cond
= TCG_COND_LT
, .reg
= t0
, .mask
= -1 };
841 /* compute eflags.O to reg */
842 static CCPrepare
gen_prepare_eflags_o(DisasContext
*s
, TCGv reg
)
847 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src2
,
848 .mask
= -1, .no_setcond
= true };
851 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
853 gen_compute_eflags(s
);
854 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
859 /* compute eflags.Z to reg */
860 static CCPrepare
gen_prepare_eflags_z(DisasContext
*s
, TCGv reg
)
864 gen_compute_eflags(s
);
870 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
873 return (CCPrepare
) { .cond
= TCG_COND_ALWAYS
, .mask
= -1 };
875 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= cpu_cc_src
,
879 TCGMemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
880 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
881 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
886 /* perform a conditional store into register 'reg' according to jump opcode
887 value 'b'. In the fast case, T0 is guaranted not to be used. */
888 static CCPrepare
gen_prepare_cc(DisasContext
*s
, int b
, TCGv reg
)
890 int inv
, jcc_op
, cond
;
896 jcc_op
= (b
>> 1) & 7;
899 case CC_OP_SUBB
... CC_OP_SUBQ
:
900 /* We optimize relational operators for the cmp/jcc case. */
901 size
= s
->cc_op
- CC_OP_SUBB
;
904 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
905 gen_extu(size
, cpu_tmp4
);
906 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
907 cc
= (CCPrepare
) { .cond
= TCG_COND_LEU
, .reg
= cpu_tmp4
,
908 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
917 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
918 gen_exts(size
, cpu_tmp4
);
919 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, true);
920 cc
= (CCPrepare
) { .cond
= cond
, .reg
= cpu_tmp4
,
921 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
931 /* This actually generates good code for JC, JZ and JS. */
934 cc
= gen_prepare_eflags_o(s
, reg
);
937 cc
= gen_prepare_eflags_c(s
, reg
);
940 cc
= gen_prepare_eflags_z(s
, reg
);
943 gen_compute_eflags(s
);
944 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
945 .mask
= CC_Z
| CC_C
};
948 cc
= gen_prepare_eflags_s(s
, reg
);
951 cc
= gen_prepare_eflags_p(s
, reg
);
954 gen_compute_eflags(s
);
955 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
958 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
959 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
960 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
965 gen_compute_eflags(s
);
966 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
969 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
970 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
971 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
972 .mask
= CC_S
| CC_Z
};
979 cc
.cond
= tcg_invert_cond(cc
.cond
);
984 static void gen_setcc1(DisasContext
*s
, int b
, TCGv reg
)
986 CCPrepare cc
= gen_prepare_cc(s
, b
, reg
);
989 if (cc
.cond
== TCG_COND_EQ
) {
990 tcg_gen_xori_tl(reg
, cc
.reg
, 1);
992 tcg_gen_mov_tl(reg
, cc
.reg
);
997 if (cc
.cond
== TCG_COND_NE
&& !cc
.use_reg2
&& cc
.imm
== 0 &&
998 cc
.mask
!= 0 && (cc
.mask
& (cc
.mask
- 1)) == 0) {
999 tcg_gen_shri_tl(reg
, cc
.reg
, ctztl(cc
.mask
));
1000 tcg_gen_andi_tl(reg
, reg
, 1);
1003 if (cc
.mask
!= -1) {
1004 tcg_gen_andi_tl(reg
, cc
.reg
, cc
.mask
);
1008 tcg_gen_setcond_tl(cc
.cond
, reg
, cc
.reg
, cc
.reg2
);
1010 tcg_gen_setcondi_tl(cc
.cond
, reg
, cc
.reg
, cc
.imm
);
1014 static inline void gen_compute_eflags_c(DisasContext
*s
, TCGv reg
)
1016 gen_setcc1(s
, JCC_B
<< 1, reg
);
1019 /* generate a conditional jump to label 'l1' according to jump opcode
1020 value 'b'. In the fast case, T0 is guaranted not to be used. */
1021 static inline void gen_jcc1_noeob(DisasContext
*s
, int b
, TCGLabel
*l1
)
1023 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T0
);
1025 if (cc
.mask
!= -1) {
1026 tcg_gen_andi_tl(cpu_T0
, cc
.reg
, cc
.mask
);
1030 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1032 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1036 /* Generate a conditional jump to label 'l1' according to jump opcode
1037 value 'b'. In the fast case, T0 is guaranted not to be used.
1038 A translation block must end soon. */
1039 static inline void gen_jcc1(DisasContext
*s
, int b
, TCGLabel
*l1
)
1041 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T0
);
1043 gen_update_cc_op(s
);
1044 if (cc
.mask
!= -1) {
1045 tcg_gen_andi_tl(cpu_T0
, cc
.reg
, cc
.mask
);
1048 set_cc_op(s
, CC_OP_DYNAMIC
);
1050 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1052 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1056 /* XXX: does not work with gdbstub "ice" single step - not a
1058 static TCGLabel
*gen_jz_ecx_string(DisasContext
*s
, target_ulong next_eip
)
1060 TCGLabel
*l1
= gen_new_label();
1061 TCGLabel
*l2
= gen_new_label();
1062 gen_op_jnz_ecx(s
->aflag
, l1
);
1064 gen_jmp_tb(s
, next_eip
, 1);
1069 static inline void gen_stos(DisasContext
*s
, TCGMemOp ot
)
1071 gen_op_mov_v_reg(MO_32
, cpu_T0
, R_EAX
);
1072 gen_string_movl_A0_EDI(s
);
1073 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
1074 gen_op_movl_T0_Dshift(ot
);
1075 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1078 static inline void gen_lods(DisasContext
*s
, TCGMemOp ot
)
1080 gen_string_movl_A0_ESI(s
);
1081 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1082 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T0
);
1083 gen_op_movl_T0_Dshift(ot
);
1084 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1087 static inline void gen_scas(DisasContext
*s
, TCGMemOp ot
)
1089 gen_string_movl_A0_EDI(s
);
1090 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
1091 gen_op(s
, OP_CMPL
, ot
, R_EAX
);
1092 gen_op_movl_T0_Dshift(ot
);
1093 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1096 static inline void gen_cmps(DisasContext
*s
, TCGMemOp ot
)
1098 gen_string_movl_A0_EDI(s
);
1099 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
1100 gen_string_movl_A0_ESI(s
);
1101 gen_op(s
, OP_CMPL
, ot
, OR_TMP0
);
1102 gen_op_movl_T0_Dshift(ot
);
1103 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1104 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1107 static void gen_bpt_io(DisasContext
*s
, TCGv_i32 t_port
, int ot
)
1109 if (s
->flags
& HF_IOBPT_MASK
) {
1110 TCGv_i32 t_size
= tcg_const_i32(1 << ot
);
1111 TCGv t_next
= tcg_const_tl(s
->pc
- s
->cs_base
);
1113 gen_helper_bpt_io(cpu_env
, t_port
, t_size
, t_next
);
1114 tcg_temp_free_i32(t_size
);
1115 tcg_temp_free(t_next
);
1120 static inline void gen_ins(DisasContext
*s
, TCGMemOp ot
)
1122 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1125 gen_string_movl_A0_EDI(s
);
1126 /* Note: we must do this dummy write first to be restartable in
1127 case of page fault. */
1128 tcg_gen_movi_tl(cpu_T0
, 0);
1129 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
1130 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_EDX
]);
1131 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1132 gen_helper_in_func(ot
, cpu_T0
, cpu_tmp2_i32
);
1133 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
1134 gen_op_movl_T0_Dshift(ot
);
1135 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1136 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
1137 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1142 static inline void gen_outs(DisasContext
*s
, TCGMemOp ot
)
1144 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1147 gen_string_movl_A0_ESI(s
);
1148 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1150 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_EDX
]);
1151 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1152 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T0
);
1153 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1154 gen_op_movl_T0_Dshift(ot
);
1155 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1156 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
1157 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1162 /* same method as Valgrind : we generate jumps to current or next
1164 #define GEN_REPZ(op) \
1165 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1166 target_ulong cur_eip, target_ulong next_eip) \
1169 gen_update_cc_op(s); \
1170 l2 = gen_jz_ecx_string(s, next_eip); \
1171 gen_ ## op(s, ot); \
1172 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1173 /* a loop would cause two single step exceptions if ECX = 1 \
1174 before rep string_insn */ \
1176 gen_op_jz_ecx(s->aflag, l2); \
1177 gen_jmp(s, cur_eip); \
1180 #define GEN_REPZ2(op) \
1181 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1182 target_ulong cur_eip, \
1183 target_ulong next_eip, \
1187 gen_update_cc_op(s); \
1188 l2 = gen_jz_ecx_string(s, next_eip); \
1189 gen_ ## op(s, ot); \
1190 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1191 gen_update_cc_op(s); \
1192 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
1194 gen_op_jz_ecx(s->aflag, l2); \
1195 gen_jmp(s, cur_eip); \
1206 static void gen_helper_fp_arith_ST0_FT0(int op
)
1210 gen_helper_fadd_ST0_FT0(cpu_env
);
1213 gen_helper_fmul_ST0_FT0(cpu_env
);
1216 gen_helper_fcom_ST0_FT0(cpu_env
);
1219 gen_helper_fcom_ST0_FT0(cpu_env
);
1222 gen_helper_fsub_ST0_FT0(cpu_env
);
1225 gen_helper_fsubr_ST0_FT0(cpu_env
);
1228 gen_helper_fdiv_ST0_FT0(cpu_env
);
1231 gen_helper_fdivr_ST0_FT0(cpu_env
);
1236 /* NOTE the exception in "r" op ordering */
1237 static void gen_helper_fp_arith_STN_ST0(int op
, int opreg
)
1239 TCGv_i32 tmp
= tcg_const_i32(opreg
);
1242 gen_helper_fadd_STN_ST0(cpu_env
, tmp
);
1245 gen_helper_fmul_STN_ST0(cpu_env
, tmp
);
1248 gen_helper_fsubr_STN_ST0(cpu_env
, tmp
);
1251 gen_helper_fsub_STN_ST0(cpu_env
, tmp
);
1254 gen_helper_fdivr_STN_ST0(cpu_env
, tmp
);
1257 gen_helper_fdiv_STN_ST0(cpu_env
, tmp
);
1262 /* if d == OR_TMP0, it means memory operand (address in A0) */
1263 static void gen_op(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
)
1266 gen_op_mov_v_reg(ot
, cpu_T0
, d
);
1267 } else if (!(s1
->prefix
& PREFIX_LOCK
)) {
1268 gen_op_ld_v(s1
, ot
, cpu_T0
, cpu_A0
);
1272 gen_compute_eflags_c(s1
, cpu_tmp4
);
1273 if (s1
->prefix
& PREFIX_LOCK
) {
1274 tcg_gen_add_tl(cpu_T0
, cpu_tmp4
, cpu_T1
);
1275 tcg_gen_atomic_add_fetch_tl(cpu_T0
, cpu_A0
, cpu_T0
,
1276 s1
->mem_index
, ot
| MO_LE
);
1278 tcg_gen_add_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1279 tcg_gen_add_tl(cpu_T0
, cpu_T0
, cpu_tmp4
);
1280 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1282 gen_op_update3_cc(cpu_tmp4
);
1283 set_cc_op(s1
, CC_OP_ADCB
+ ot
);
1286 gen_compute_eflags_c(s1
, cpu_tmp4
);
1287 if (s1
->prefix
& PREFIX_LOCK
) {
1288 tcg_gen_add_tl(cpu_T0
, cpu_T1
, cpu_tmp4
);
1289 tcg_gen_neg_tl(cpu_T0
, cpu_T0
);
1290 tcg_gen_atomic_add_fetch_tl(cpu_T0
, cpu_A0
, cpu_T0
,
1291 s1
->mem_index
, ot
| MO_LE
);
1293 tcg_gen_sub_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1294 tcg_gen_sub_tl(cpu_T0
, cpu_T0
, cpu_tmp4
);
1295 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1297 gen_op_update3_cc(cpu_tmp4
);
1298 set_cc_op(s1
, CC_OP_SBBB
+ ot
);
1301 if (s1
->prefix
& PREFIX_LOCK
) {
1302 tcg_gen_atomic_add_fetch_tl(cpu_T0
, cpu_A0
, cpu_T1
,
1303 s1
->mem_index
, ot
| MO_LE
);
1305 tcg_gen_add_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1306 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1308 gen_op_update2_cc();
1309 set_cc_op(s1
, CC_OP_ADDB
+ ot
);
1312 if (s1
->prefix
& PREFIX_LOCK
) {
1313 tcg_gen_neg_tl(cpu_T0
, cpu_T1
);
1314 tcg_gen_atomic_fetch_add_tl(cpu_cc_srcT
, cpu_A0
, cpu_T0
,
1315 s1
->mem_index
, ot
| MO_LE
);
1316 tcg_gen_sub_tl(cpu_T0
, cpu_cc_srcT
, cpu_T1
);
1318 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T0
);
1319 tcg_gen_sub_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1320 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1322 gen_op_update2_cc();
1323 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1327 if (s1
->prefix
& PREFIX_LOCK
) {
1328 tcg_gen_atomic_and_fetch_tl(cpu_T0
, cpu_A0
, cpu_T1
,
1329 s1
->mem_index
, ot
| MO_LE
);
1331 tcg_gen_and_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1332 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1334 gen_op_update1_cc();
1335 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1338 if (s1
->prefix
& PREFIX_LOCK
) {
1339 tcg_gen_atomic_or_fetch_tl(cpu_T0
, cpu_A0
, cpu_T1
,
1340 s1
->mem_index
, ot
| MO_LE
);
1342 tcg_gen_or_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1343 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1345 gen_op_update1_cc();
1346 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1349 if (s1
->prefix
& PREFIX_LOCK
) {
1350 tcg_gen_atomic_xor_fetch_tl(cpu_T0
, cpu_A0
, cpu_T1
,
1351 s1
->mem_index
, ot
| MO_LE
);
1353 tcg_gen_xor_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1354 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1356 gen_op_update1_cc();
1357 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1360 tcg_gen_mov_tl(cpu_cc_src
, cpu_T1
);
1361 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T0
);
1362 tcg_gen_sub_tl(cpu_cc_dst
, cpu_T0
, cpu_T1
);
1363 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1368 /* if d == OR_TMP0, it means memory operand (address in A0) */
1369 static void gen_inc(DisasContext
*s1
, TCGMemOp ot
, int d
, int c
)
1371 if (s1
->prefix
& PREFIX_LOCK
) {
1372 tcg_gen_movi_tl(cpu_T0
, c
> 0 ? 1 : -1);
1373 tcg_gen_atomic_add_fetch_tl(cpu_T0
, cpu_A0
, cpu_T0
,
1374 s1
->mem_index
, ot
| MO_LE
);
1377 gen_op_mov_v_reg(ot
, cpu_T0
, d
);
1379 gen_op_ld_v(s1
, ot
, cpu_T0
, cpu_A0
);
1381 tcg_gen_addi_tl(cpu_T0
, cpu_T0
, (c
> 0 ? 1 : -1));
1382 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1385 gen_compute_eflags_c(s1
, cpu_cc_src
);
1386 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
1387 set_cc_op(s1
, (c
> 0 ? CC_OP_INCB
: CC_OP_DECB
) + ot
);
1390 static void gen_shift_flags(DisasContext
*s
, TCGMemOp ot
, TCGv result
,
1391 TCGv shm1
, TCGv count
, bool is_right
)
1393 TCGv_i32 z32
, s32
, oldop
;
1396 /* Store the results into the CC variables. If we know that the
1397 variable must be dead, store unconditionally. Otherwise we'll
1398 need to not disrupt the current contents. */
1399 z_tl
= tcg_const_tl(0);
1400 if (cc_op_live
[s
->cc_op
] & USES_CC_DST
) {
1401 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_dst
, count
, z_tl
,
1402 result
, cpu_cc_dst
);
1404 tcg_gen_mov_tl(cpu_cc_dst
, result
);
1406 if (cc_op_live
[s
->cc_op
] & USES_CC_SRC
) {
1407 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_src
, count
, z_tl
,
1410 tcg_gen_mov_tl(cpu_cc_src
, shm1
);
1412 tcg_temp_free(z_tl
);
1414 /* Get the two potential CC_OP values into temporaries. */
1415 tcg_gen_movi_i32(cpu_tmp2_i32
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1416 if (s
->cc_op
== CC_OP_DYNAMIC
) {
1419 tcg_gen_movi_i32(cpu_tmp3_i32
, s
->cc_op
);
1420 oldop
= cpu_tmp3_i32
;
1423 /* Conditionally store the CC_OP value. */
1424 z32
= tcg_const_i32(0);
1425 s32
= tcg_temp_new_i32();
1426 tcg_gen_trunc_tl_i32(s32
, count
);
1427 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, s32
, z32
, cpu_tmp2_i32
, oldop
);
1428 tcg_temp_free_i32(z32
);
1429 tcg_temp_free_i32(s32
);
1431 /* The CC_OP value is no longer predictable. */
1432 set_cc_op(s
, CC_OP_DYNAMIC
);
1435 static void gen_shift_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1436 int is_right
, int is_arith
)
1438 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1441 if (op1
== OR_TMP0
) {
1442 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1444 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1447 tcg_gen_andi_tl(cpu_T1
, cpu_T1
, mask
);
1448 tcg_gen_subi_tl(cpu_tmp0
, cpu_T1
, 1);
1452 gen_exts(ot
, cpu_T0
);
1453 tcg_gen_sar_tl(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1454 tcg_gen_sar_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1456 gen_extu(ot
, cpu_T0
);
1457 tcg_gen_shr_tl(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1458 tcg_gen_shr_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1461 tcg_gen_shl_tl(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1462 tcg_gen_shl_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1466 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1468 gen_shift_flags(s
, ot
, cpu_T0
, cpu_tmp0
, cpu_T1
, is_right
);
1471 static void gen_shift_rm_im(DisasContext
*s
, TCGMemOp ot
, int op1
, int op2
,
1472 int is_right
, int is_arith
)
1474 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1478 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1480 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1486 gen_exts(ot
, cpu_T0
);
1487 tcg_gen_sari_tl(cpu_tmp4
, cpu_T0
, op2
- 1);
1488 tcg_gen_sari_tl(cpu_T0
, cpu_T0
, op2
);
1490 gen_extu(ot
, cpu_T0
);
1491 tcg_gen_shri_tl(cpu_tmp4
, cpu_T0
, op2
- 1);
1492 tcg_gen_shri_tl(cpu_T0
, cpu_T0
, op2
);
1495 tcg_gen_shli_tl(cpu_tmp4
, cpu_T0
, op2
- 1);
1496 tcg_gen_shli_tl(cpu_T0
, cpu_T0
, op2
);
1501 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1503 /* update eflags if non zero shift */
1505 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
1506 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
1507 set_cc_op(s
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1511 static void gen_rot_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
, int is_right
)
1513 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1517 if (op1
== OR_TMP0
) {
1518 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1520 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1523 tcg_gen_andi_tl(cpu_T1
, cpu_T1
, mask
);
1527 /* Replicate the 8-bit input so that a 32-bit rotate works. */
1528 tcg_gen_ext8u_tl(cpu_T0
, cpu_T0
);
1529 tcg_gen_muli_tl(cpu_T0
, cpu_T0
, 0x01010101);
1532 /* Replicate the 16-bit input so that a 32-bit rotate works. */
1533 tcg_gen_deposit_tl(cpu_T0
, cpu_T0
, cpu_T0
, 16, 16);
1536 #ifdef TARGET_X86_64
1538 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
1539 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T1
);
1541 tcg_gen_rotr_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1543 tcg_gen_rotl_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1545 tcg_gen_extu_i32_tl(cpu_T0
, cpu_tmp2_i32
);
1550 tcg_gen_rotr_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1552 tcg_gen_rotl_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1558 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1560 /* We'll need the flags computed into CC_SRC. */
1561 gen_compute_eflags(s
);
1563 /* The value that was "rotated out" is now present at the other end
1564 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1565 since we've computed the flags into CC_SRC, these variables are
1568 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T0
, mask
- 1);
1569 tcg_gen_shri_tl(cpu_cc_dst
, cpu_T0
, mask
);
1570 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1572 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T0
, mask
);
1573 tcg_gen_andi_tl(cpu_cc_dst
, cpu_T0
, 1);
1575 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1576 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1578 /* Now conditionally store the new CC_OP value. If the shift count
1579 is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1580 Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1581 exactly as we computed above. */
1582 t0
= tcg_const_i32(0);
1583 t1
= tcg_temp_new_i32();
1584 tcg_gen_trunc_tl_i32(t1
, cpu_T1
);
1585 tcg_gen_movi_i32(cpu_tmp2_i32
, CC_OP_ADCOX
);
1586 tcg_gen_movi_i32(cpu_tmp3_i32
, CC_OP_EFLAGS
);
1587 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, t1
, t0
,
1588 cpu_tmp2_i32
, cpu_tmp3_i32
);
1589 tcg_temp_free_i32(t0
);
1590 tcg_temp_free_i32(t1
);
1592 /* The CC_OP value is no longer predictable. */
1593 set_cc_op(s
, CC_OP_DYNAMIC
);
1596 static void gen_rot_rm_im(DisasContext
*s
, TCGMemOp ot
, int op1
, int op2
,
1599 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1603 if (op1
== OR_TMP0
) {
1604 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1606 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1612 #ifdef TARGET_X86_64
1614 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
1616 tcg_gen_rotri_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, op2
);
1618 tcg_gen_rotli_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, op2
);
1620 tcg_gen_extu_i32_tl(cpu_T0
, cpu_tmp2_i32
);
1625 tcg_gen_rotri_tl(cpu_T0
, cpu_T0
, op2
);
1627 tcg_gen_rotli_tl(cpu_T0
, cpu_T0
, op2
);
1638 shift
= mask
+ 1 - shift
;
1640 gen_extu(ot
, cpu_T0
);
1641 tcg_gen_shli_tl(cpu_tmp0
, cpu_T0
, shift
);
1642 tcg_gen_shri_tl(cpu_T0
, cpu_T0
, mask
+ 1 - shift
);
1643 tcg_gen_or_tl(cpu_T0
, cpu_T0
, cpu_tmp0
);
1649 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1652 /* Compute the flags into CC_SRC. */
1653 gen_compute_eflags(s
);
1655 /* The value that was "rotated out" is now present at the other end
1656 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1657 since we've computed the flags into CC_SRC, these variables are
1660 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T0
, mask
- 1);
1661 tcg_gen_shri_tl(cpu_cc_dst
, cpu_T0
, mask
);
1662 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1664 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T0
, mask
);
1665 tcg_gen_andi_tl(cpu_cc_dst
, cpu_T0
, 1);
1667 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1668 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1669 set_cc_op(s
, CC_OP_ADCOX
);
1673 /* XXX: add faster immediate = 1 case */
1674 static void gen_rotc_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1677 gen_compute_eflags(s
);
1678 assert(s
->cc_op
== CC_OP_EFLAGS
);
1682 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1684 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1689 gen_helper_rcrb(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1692 gen_helper_rcrw(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1695 gen_helper_rcrl(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1697 #ifdef TARGET_X86_64
1699 gen_helper_rcrq(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1708 gen_helper_rclb(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1711 gen_helper_rclw(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1714 gen_helper_rcll(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1716 #ifdef TARGET_X86_64
1718 gen_helper_rclq(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1726 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1729 /* XXX: add faster immediate case */
1730 static void gen_shiftd_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1731 bool is_right
, TCGv count_in
)
1733 target_ulong mask
= (ot
== MO_64
? 63 : 31);
1737 if (op1
== OR_TMP0
) {
1738 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1740 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1743 count
= tcg_temp_new();
1744 tcg_gen_andi_tl(count
, count_in
, mask
);
1748 /* Note: we implement the Intel behaviour for shift count > 16.
1749 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A
1750 portion by constructing it as a 32-bit value. */
1752 tcg_gen_deposit_tl(cpu_tmp0
, cpu_T0
, cpu_T1
, 16, 16);
1753 tcg_gen_mov_tl(cpu_T1
, cpu_T0
);
1754 tcg_gen_mov_tl(cpu_T0
, cpu_tmp0
);
1756 tcg_gen_deposit_tl(cpu_T1
, cpu_T0
, cpu_T1
, 16, 16);
1759 #ifdef TARGET_X86_64
1761 /* Concatenate the two 32-bit values and use a 64-bit shift. */
1762 tcg_gen_subi_tl(cpu_tmp0
, count
, 1);
1764 tcg_gen_concat_tl_i64(cpu_T0
, cpu_T0
, cpu_T1
);
1765 tcg_gen_shr_i64(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1766 tcg_gen_shr_i64(cpu_T0
, cpu_T0
, count
);
1768 tcg_gen_concat_tl_i64(cpu_T0
, cpu_T1
, cpu_T0
);
1769 tcg_gen_shl_i64(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1770 tcg_gen_shl_i64(cpu_T0
, cpu_T0
, count
);
1771 tcg_gen_shri_i64(cpu_tmp0
, cpu_tmp0
, 32);
1772 tcg_gen_shri_i64(cpu_T0
, cpu_T0
, 32);
1777 tcg_gen_subi_tl(cpu_tmp0
, count
, 1);
1779 tcg_gen_shr_tl(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1781 tcg_gen_subfi_tl(cpu_tmp4
, mask
+ 1, count
);
1782 tcg_gen_shr_tl(cpu_T0
, cpu_T0
, count
);
1783 tcg_gen_shl_tl(cpu_T1
, cpu_T1
, cpu_tmp4
);
1785 tcg_gen_shl_tl(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1787 /* Only needed if count > 16, for Intel behaviour. */
1788 tcg_gen_subfi_tl(cpu_tmp4
, 33, count
);
1789 tcg_gen_shr_tl(cpu_tmp4
, cpu_T1
, cpu_tmp4
);
1790 tcg_gen_or_tl(cpu_tmp0
, cpu_tmp0
, cpu_tmp4
);
1793 tcg_gen_subfi_tl(cpu_tmp4
, mask
+ 1, count
);
1794 tcg_gen_shl_tl(cpu_T0
, cpu_T0
, count
);
1795 tcg_gen_shr_tl(cpu_T1
, cpu_T1
, cpu_tmp4
);
1797 tcg_gen_movi_tl(cpu_tmp4
, 0);
1798 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_T1
, count
, cpu_tmp4
,
1800 tcg_gen_or_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1805 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1807 gen_shift_flags(s
, ot
, cpu_T0
, cpu_tmp0
, count
, is_right
);
1808 tcg_temp_free(count
);
1811 static void gen_shift(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
, int s
)
1814 gen_op_mov_v_reg(ot
, cpu_T1
, s
);
1817 gen_rot_rm_T1(s1
, ot
, d
, 0);
1820 gen_rot_rm_T1(s1
, ot
, d
, 1);
1824 gen_shift_rm_T1(s1
, ot
, d
, 0, 0);
1827 gen_shift_rm_T1(s1
, ot
, d
, 1, 0);
1830 gen_shift_rm_T1(s1
, ot
, d
, 1, 1);
1833 gen_rotc_rm_T1(s1
, ot
, d
, 0);
1836 gen_rotc_rm_T1(s1
, ot
, d
, 1);
1841 static void gen_shifti(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
, int c
)
1845 gen_rot_rm_im(s1
, ot
, d
, c
, 0);
1848 gen_rot_rm_im(s1
, ot
, d
, c
, 1);
1852 gen_shift_rm_im(s1
, ot
, d
, c
, 0, 0);
1855 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 0);
1858 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 1);
1861 /* currently not optimized */
1862 tcg_gen_movi_tl(cpu_T1
, c
);
1863 gen_shift(s1
, op
, ot
, d
, OR_TMP1
);
1868 /* Decompose an address. */
1870 typedef struct AddressParts
{
1878 static AddressParts
gen_lea_modrm_0(CPUX86State
*env
, DisasContext
*s
,
1881 int def_seg
, base
, index
, scale
, mod
, rm
;
1890 mod
= (modrm
>> 6) & 3;
1892 base
= rm
| REX_B(s
);
1895 /* Normally filtered out earlier, but including this path
1896 simplifies multi-byte nop, as well as bndcl, bndcu, bndcn. */
1905 int code
= cpu_ldub_code(env
, s
->pc
++);
1906 scale
= (code
>> 6) & 3;
1907 index
= ((code
>> 3) & 7) | REX_X(s
);
1909 index
= -1; /* no index */
1911 base
= (code
& 7) | REX_B(s
);
1917 if ((base
& 7) == 5) {
1919 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
1921 if (CODE64(s
) && !havesib
) {
1923 disp
+= s
->pc
+ s
->rip_offset
;
1928 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
1932 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
1937 /* For correct popl handling with esp. */
1938 if (base
== R_ESP
&& s
->popl_esp_hack
) {
1939 disp
+= s
->popl_esp_hack
;
1941 if (base
== R_EBP
|| base
== R_ESP
) {
1950 disp
= cpu_lduw_code(env
, s
->pc
);
1954 } else if (mod
== 1) {
1955 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
1957 disp
= (int16_t)cpu_lduw_code(env
, s
->pc
);
2002 return (AddressParts
){ def_seg
, base
, index
, scale
, disp
};
2005 /* Compute the address, with a minimum number of TCG ops. */
2006 static TCGv
gen_lea_modrm_1(AddressParts a
)
2013 ea
= cpu_regs
[a
.index
];
2015 tcg_gen_shli_tl(cpu_A0
, cpu_regs
[a
.index
], a
.scale
);
2019 tcg_gen_add_tl(cpu_A0
, ea
, cpu_regs
[a
.base
]);
2022 } else if (a
.base
>= 0) {
2023 ea
= cpu_regs
[a
.base
];
2025 if (TCGV_IS_UNUSED(ea
)) {
2026 tcg_gen_movi_tl(cpu_A0
, a
.disp
);
2028 } else if (a
.disp
!= 0) {
2029 tcg_gen_addi_tl(cpu_A0
, ea
, a
.disp
);
2036 static void gen_lea_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2038 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
2039 TCGv ea
= gen_lea_modrm_1(a
);
2040 gen_lea_v_seg(s
, s
->aflag
, ea
, a
.def_seg
, s
->override
);
2043 static void gen_nop_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2045 (void)gen_lea_modrm_0(env
, s
, modrm
);
2048 /* Used for BNDCL, BNDCU, BNDCN. */
2049 static void gen_bndck(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2050 TCGCond cond
, TCGv_i64 bndv
)
2052 TCGv ea
= gen_lea_modrm_1(gen_lea_modrm_0(env
, s
, modrm
));
2054 tcg_gen_extu_tl_i64(cpu_tmp1_i64
, ea
);
2056 tcg_gen_ext32u_i64(cpu_tmp1_i64
, cpu_tmp1_i64
);
2058 tcg_gen_setcond_i64(cond
, cpu_tmp1_i64
, cpu_tmp1_i64
, bndv
);
2059 tcg_gen_extrl_i64_i32(cpu_tmp2_i32
, cpu_tmp1_i64
);
2060 gen_helper_bndck(cpu_env
, cpu_tmp2_i32
);
2063 /* used for LEA and MOV AX, mem */
2064 static void gen_add_A0_ds_seg(DisasContext
*s
)
2066 gen_lea_v_seg(s
, s
->aflag
, cpu_A0
, R_DS
, s
->override
);
2069 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2071 static void gen_ldst_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2072 TCGMemOp ot
, int reg
, int is_store
)
2076 mod
= (modrm
>> 6) & 3;
2077 rm
= (modrm
& 7) | REX_B(s
);
2081 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
2082 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
2084 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
2086 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
2089 gen_lea_modrm(env
, s
, modrm
);
2092 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
2093 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
2095 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
2097 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
2102 static inline uint32_t insn_get(CPUX86State
*env
, DisasContext
*s
, TCGMemOp ot
)
2108 ret
= cpu_ldub_code(env
, s
->pc
);
2112 ret
= cpu_lduw_code(env
, s
->pc
);
2116 #ifdef TARGET_X86_64
2119 ret
= cpu_ldl_code(env
, s
->pc
);
2128 static inline int insn_const_size(TCGMemOp ot
)
2137 static inline bool use_goto_tb(DisasContext
*s
, target_ulong pc
)
2139 #ifndef CONFIG_USER_ONLY
2140 return (pc
& TARGET_PAGE_MASK
) == (s
->tb
->pc
& TARGET_PAGE_MASK
) ||
2141 (pc
& TARGET_PAGE_MASK
) == (s
->pc_start
& TARGET_PAGE_MASK
);
2147 static inline void gen_goto_tb(DisasContext
*s
, int tb_num
, target_ulong eip
)
2149 target_ulong pc
= s
->cs_base
+ eip
;
2151 if (use_goto_tb(s
, pc
)) {
2152 /* jump to same page: we can use a direct jump */
2153 tcg_gen_goto_tb(tb_num
);
2155 tcg_gen_exit_tb((uintptr_t)s
->tb
+ tb_num
);
2157 /* jump to another page */
2159 gen_jr(s
, cpu_tmp0
);
2163 static inline void gen_jcc(DisasContext
*s
, int b
,
2164 target_ulong val
, target_ulong next_eip
)
2169 l1
= gen_new_label();
2172 gen_goto_tb(s
, 0, next_eip
);
2175 gen_goto_tb(s
, 1, val
);
2176 s
->is_jmp
= DISAS_TB_JUMP
;
2178 l1
= gen_new_label();
2179 l2
= gen_new_label();
2182 gen_jmp_im(next_eip
);
2192 static void gen_cmovcc1(CPUX86State
*env
, DisasContext
*s
, TCGMemOp ot
, int b
,
2197 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
2199 cc
= gen_prepare_cc(s
, b
, cpu_T1
);
2200 if (cc
.mask
!= -1) {
2201 TCGv t0
= tcg_temp_new();
2202 tcg_gen_andi_tl(t0
, cc
.reg
, cc
.mask
);
2206 cc
.reg2
= tcg_const_tl(cc
.imm
);
2209 tcg_gen_movcond_tl(cc
.cond
, cpu_T0
, cc
.reg
, cc
.reg2
,
2210 cpu_T0
, cpu_regs
[reg
]);
2211 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
2213 if (cc
.mask
!= -1) {
2214 tcg_temp_free(cc
.reg
);
2217 tcg_temp_free(cc
.reg2
);
2221 static inline void gen_op_movl_T0_seg(int seg_reg
)
2223 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
,
2224 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2227 static inline void gen_op_movl_seg_T0_vm(int seg_reg
)
2229 tcg_gen_ext16u_tl(cpu_T0
, cpu_T0
);
2230 tcg_gen_st32_tl(cpu_T0
, cpu_env
,
2231 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2232 tcg_gen_shli_tl(cpu_seg_base
[seg_reg
], cpu_T0
, 4);
2235 /* move T0 to seg_reg and compute if the CPU state may change. Never
2236 call this function with seg_reg == R_CS */
2237 static void gen_movl_seg_T0(DisasContext
*s
, int seg_reg
)
2239 if (s
->pe
&& !s
->vm86
) {
2240 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
2241 gen_helper_load_seg(cpu_env
, tcg_const_i32(seg_reg
), cpu_tmp2_i32
);
2242 /* abort translation because the addseg value may change or
2243 because ss32 may change. For R_SS, translation must always
2244 stop as a special handling must be done to disable hardware
2245 interrupts for the next instruction */
2246 if (seg_reg
== R_SS
|| (s
->code32
&& seg_reg
< R_FS
))
2247 s
->is_jmp
= DISAS_TB_JUMP
;
2249 gen_op_movl_seg_T0_vm(seg_reg
);
2250 if (seg_reg
== R_SS
)
2251 s
->is_jmp
= DISAS_TB_JUMP
;
2255 static inline int svm_is_rep(int prefixes
)
2257 return ((prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) ? 8 : 0);
2261 gen_svm_check_intercept_param(DisasContext
*s
, target_ulong pc_start
,
2262 uint32_t type
, uint64_t param
)
2264 /* no SVM activated; fast case */
2265 if (likely(!(s
->flags
& HF_SVMI_MASK
)))
2267 gen_update_cc_op(s
);
2268 gen_jmp_im(pc_start
- s
->cs_base
);
2269 gen_helper_svm_check_intercept_param(cpu_env
, tcg_const_i32(type
),
2270 tcg_const_i64(param
));
2274 gen_svm_check_intercept(DisasContext
*s
, target_ulong pc_start
, uint64_t type
)
2276 gen_svm_check_intercept_param(s
, pc_start
, type
, 0);
2279 static inline void gen_stack_update(DisasContext
*s
, int addend
)
2281 gen_op_add_reg_im(mo_stacksize(s
), R_ESP
, addend
);
2284 /* Generate a push. It depends on ss32, addseg and dflag. */
2285 static void gen_push_v(DisasContext
*s
, TCGv val
)
2287 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2288 TCGMemOp a_ot
= mo_stacksize(s
);
2289 int size
= 1 << d_ot
;
2290 TCGv new_esp
= cpu_A0
;
2292 tcg_gen_subi_tl(cpu_A0
, cpu_regs
[R_ESP
], size
);
2297 tcg_gen_mov_tl(new_esp
, cpu_A0
);
2299 gen_lea_v_seg(s
, a_ot
, cpu_A0
, R_SS
, -1);
2302 gen_op_st_v(s
, d_ot
, val
, cpu_A0
);
2303 gen_op_mov_reg_v(a_ot
, R_ESP
, new_esp
);
2306 /* two step pop is necessary for precise exceptions */
2307 static TCGMemOp
gen_pop_T0(DisasContext
*s
)
2309 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2311 gen_lea_v_seg(s
, mo_stacksize(s
), cpu_regs
[R_ESP
], R_SS
, -1);
2312 gen_op_ld_v(s
, d_ot
, cpu_T0
, cpu_A0
);
2317 static inline void gen_pop_update(DisasContext
*s
, TCGMemOp ot
)
2319 gen_stack_update(s
, 1 << ot
);
2322 static inline void gen_stack_A0(DisasContext
*s
)
2324 gen_lea_v_seg(s
, s
->ss32
? MO_32
: MO_16
, cpu_regs
[R_ESP
], R_SS
, -1);
2327 static void gen_pusha(DisasContext
*s
)
2329 TCGMemOp s_ot
= s
->ss32
? MO_32
: MO_16
;
2330 TCGMemOp d_ot
= s
->dflag
;
2331 int size
= 1 << d_ot
;
2334 for (i
= 0; i
< 8; i
++) {
2335 tcg_gen_addi_tl(cpu_A0
, cpu_regs
[R_ESP
], (i
- 8) * size
);
2336 gen_lea_v_seg(s
, s_ot
, cpu_A0
, R_SS
, -1);
2337 gen_op_st_v(s
, d_ot
, cpu_regs
[7 - i
], cpu_A0
);
2340 gen_stack_update(s
, -8 * size
);
2343 static void gen_popa(DisasContext
*s
)
2345 TCGMemOp s_ot
= s
->ss32
? MO_32
: MO_16
;
2346 TCGMemOp d_ot
= s
->dflag
;
2347 int size
= 1 << d_ot
;
2350 for (i
= 0; i
< 8; i
++) {
2351 /* ESP is not reloaded */
2352 if (7 - i
== R_ESP
) {
2355 tcg_gen_addi_tl(cpu_A0
, cpu_regs
[R_ESP
], i
* size
);
2356 gen_lea_v_seg(s
, s_ot
, cpu_A0
, R_SS
, -1);
2357 gen_op_ld_v(s
, d_ot
, cpu_T0
, cpu_A0
);
2358 gen_op_mov_reg_v(d_ot
, 7 - i
, cpu_T0
);
2361 gen_stack_update(s
, 8 * size
);
2364 static void gen_enter(DisasContext
*s
, int esp_addend
, int level
)
2366 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2367 TCGMemOp a_ot
= CODE64(s
) ? MO_64
: s
->ss32
? MO_32
: MO_16
;
2368 int size
= 1 << d_ot
;
2370 /* Push BP; compute FrameTemp into T1. */
2371 tcg_gen_subi_tl(cpu_T1
, cpu_regs
[R_ESP
], size
);
2372 gen_lea_v_seg(s
, a_ot
, cpu_T1
, R_SS
, -1);
2373 gen_op_st_v(s
, d_ot
, cpu_regs
[R_EBP
], cpu_A0
);
2379 /* Copy level-1 pointers from the previous frame. */
2380 for (i
= 1; i
< level
; ++i
) {
2381 tcg_gen_subi_tl(cpu_A0
, cpu_regs
[R_EBP
], size
* i
);
2382 gen_lea_v_seg(s
, a_ot
, cpu_A0
, R_SS
, -1);
2383 gen_op_ld_v(s
, d_ot
, cpu_tmp0
, cpu_A0
);
2385 tcg_gen_subi_tl(cpu_A0
, cpu_T1
, size
* i
);
2386 gen_lea_v_seg(s
, a_ot
, cpu_A0
, R_SS
, -1);
2387 gen_op_st_v(s
, d_ot
, cpu_tmp0
, cpu_A0
);
2390 /* Push the current FrameTemp as the last level. */
2391 tcg_gen_subi_tl(cpu_A0
, cpu_T1
, size
* level
);
2392 gen_lea_v_seg(s
, a_ot
, cpu_A0
, R_SS
, -1);
2393 gen_op_st_v(s
, d_ot
, cpu_T1
, cpu_A0
);
2396 /* Copy the FrameTemp value to EBP. */
2397 gen_op_mov_reg_v(a_ot
, R_EBP
, cpu_T1
);
2399 /* Compute the final value of ESP. */
2400 tcg_gen_subi_tl(cpu_T1
, cpu_T1
, esp_addend
+ size
* level
);
2401 gen_op_mov_reg_v(a_ot
, R_ESP
, cpu_T1
);
2404 static void gen_leave(DisasContext
*s
)
2406 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2407 TCGMemOp a_ot
= mo_stacksize(s
);
2409 gen_lea_v_seg(s
, a_ot
, cpu_regs
[R_EBP
], R_SS
, -1);
2410 gen_op_ld_v(s
, d_ot
, cpu_T0
, cpu_A0
);
2412 tcg_gen_addi_tl(cpu_T1
, cpu_regs
[R_EBP
], 1 << d_ot
);
2414 gen_op_mov_reg_v(d_ot
, R_EBP
, cpu_T0
);
2415 gen_op_mov_reg_v(a_ot
, R_ESP
, cpu_T1
);
2418 static void gen_exception(DisasContext
*s
, int trapno
, target_ulong cur_eip
)
2420 gen_update_cc_op(s
);
2421 gen_jmp_im(cur_eip
);
2422 gen_helper_raise_exception(cpu_env
, tcg_const_i32(trapno
));
2423 s
->is_jmp
= DISAS_TB_JUMP
;
2426 /* Generate #UD for the current instruction. The assumption here is that
2427 the instruction is known, but it isn't allowed in the current cpu mode. */
2428 static void gen_illegal_opcode(DisasContext
*s
)
2430 gen_exception(s
, EXCP06_ILLOP
, s
->pc_start
- s
->cs_base
);
2433 /* Similarly, except that the assumption here is that we don't decode
2434 the instruction at all -- either a missing opcode, an unimplemented
2435 feature, or just a bogus instruction stream. */
2436 static void gen_unknown_opcode(CPUX86State
*env
, DisasContext
*s
)
2438 gen_illegal_opcode(s
);
2440 if (qemu_loglevel_mask(LOG_UNIMP
)) {
2441 target_ulong pc
= s
->pc_start
, end
= s
->pc
;
2443 qemu_log("ILLOPC: " TARGET_FMT_lx
":", pc
);
2444 for (; pc
< end
; ++pc
) {
2445 qemu_log(" %02x", cpu_ldub_code(env
, pc
));
2452 /* an interrupt is different from an exception because of the
2454 static void gen_interrupt(DisasContext
*s
, int intno
,
2455 target_ulong cur_eip
, target_ulong next_eip
)
2457 gen_update_cc_op(s
);
2458 gen_jmp_im(cur_eip
);
2459 gen_helper_raise_interrupt(cpu_env
, tcg_const_i32(intno
),
2460 tcg_const_i32(next_eip
- cur_eip
));
2461 s
->is_jmp
= DISAS_TB_JUMP
;
2464 static void gen_debug(DisasContext
*s
, target_ulong cur_eip
)
2466 gen_update_cc_op(s
);
2467 gen_jmp_im(cur_eip
);
2468 gen_helper_debug(cpu_env
);
2469 s
->is_jmp
= DISAS_TB_JUMP
;
2472 static void gen_set_hflag(DisasContext
*s
, uint32_t mask
)
2474 if ((s
->flags
& mask
) == 0) {
2475 TCGv_i32 t
= tcg_temp_new_i32();
2476 tcg_gen_ld_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2477 tcg_gen_ori_i32(t
, t
, mask
);
2478 tcg_gen_st_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2479 tcg_temp_free_i32(t
);
2484 static void gen_reset_hflag(DisasContext
*s
, uint32_t mask
)
2486 if (s
->flags
& mask
) {
2487 TCGv_i32 t
= tcg_temp_new_i32();
2488 tcg_gen_ld_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2489 tcg_gen_andi_i32(t
, t
, ~mask
);
2490 tcg_gen_st_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2491 tcg_temp_free_i32(t
);
2496 /* Clear BND registers during legacy branches. */
2497 static void gen_bnd_jmp(DisasContext
*s
)
2499 /* Clear the registers only if BND prefix is missing, MPX is enabled,
2500 and if the BNDREGs are known to be in use (non-zero) already.
2501 The helper itself will check BNDPRESERVE at runtime. */
2502 if ((s
->prefix
& PREFIX_REPNZ
) == 0
2503 && (s
->flags
& HF_MPX_EN_MASK
) != 0
2504 && (s
->flags
& HF_MPX_IU_MASK
) != 0) {
2505 gen_helper_bnd_jmp(cpu_env
);
2509 /* Generate an end of block. Trace exception is also generated if needed.
2510 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set.
2511 If RECHECK_TF, emit a rechecking helper for #DB, ignoring the state of
2512 S->TF. This is used by the syscall/sysret insns. */
2514 do_gen_eob_worker(DisasContext
*s
, bool inhibit
, bool recheck_tf
, TCGv jr
)
2516 gen_update_cc_op(s
);
2518 /* If several instructions disable interrupts, only the first does it. */
2519 if (inhibit
&& !(s
->flags
& HF_INHIBIT_IRQ_MASK
)) {
2520 gen_set_hflag(s
, HF_INHIBIT_IRQ_MASK
);
2522 gen_reset_hflag(s
, HF_INHIBIT_IRQ_MASK
);
2525 if (s
->tb
->flags
& HF_RF_MASK
) {
2526 gen_helper_reset_rf(cpu_env
);
2528 if (s
->singlestep_enabled
) {
2529 gen_helper_debug(cpu_env
);
2530 } else if (recheck_tf
) {
2531 gen_helper_rechecking_single_step(cpu_env
);
2534 gen_helper_single_step(cpu_env
);
2535 } else if (!TCGV_IS_UNUSED(jr
)) {
2536 TCGv vaddr
= tcg_temp_new();
2538 tcg_gen_add_tl(vaddr
, jr
, cpu_seg_base
[R_CS
]);
2539 tcg_gen_lookup_and_goto_ptr(vaddr
);
2540 tcg_temp_free(vaddr
);
2544 s
->is_jmp
= DISAS_TB_JUMP
;
2548 gen_eob_worker(DisasContext
*s
, bool inhibit
, bool recheck_tf
)
2552 TCGV_UNUSED(unused
);
2553 do_gen_eob_worker(s
, inhibit
, recheck_tf
, unused
);
2557 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set. */
2558 static void gen_eob_inhibit_irq(DisasContext
*s
, bool inhibit
)
2560 gen_eob_worker(s
, inhibit
, false);
2563 /* End of block, resetting the inhibit irq flag. */
2564 static void gen_eob(DisasContext
*s
)
2566 gen_eob_worker(s
, false, false);
2569 /* Jump to register */
2570 static void gen_jr(DisasContext
*s
, TCGv dest
)
2572 do_gen_eob_worker(s
, false, false, dest
);
2575 /* generate a jump to eip. No segment change must happen before as a
2576 direct call to the next block may occur */
2577 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
)
2579 gen_update_cc_op(s
);
2580 set_cc_op(s
, CC_OP_DYNAMIC
);
2582 gen_goto_tb(s
, tb_num
, eip
);
2583 s
->is_jmp
= DISAS_TB_JUMP
;
2590 static void gen_jmp(DisasContext
*s
, target_ulong eip
)
2592 gen_jmp_tb(s
, eip
, 0);
2595 static inline void gen_ldq_env_A0(DisasContext
*s
, int offset
)
2597 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
2598 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2601 static inline void gen_stq_env_A0(DisasContext
*s
, int offset
)
2603 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2604 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
2607 static inline void gen_ldo_env_A0(DisasContext
*s
, int offset
)
2609 int mem_index
= s
->mem_index
;
2610 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, mem_index
, MO_LEQ
);
2611 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2612 tcg_gen_addi_tl(cpu_tmp0
, cpu_A0
, 8);
2613 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
, MO_LEQ
);
2614 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2617 static inline void gen_sto_env_A0(DisasContext
*s
, int offset
)
2619 int mem_index
= s
->mem_index
;
2620 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2621 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, mem_index
, MO_LEQ
);
2622 tcg_gen_addi_tl(cpu_tmp0
, cpu_A0
, 8);
2623 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2624 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
, MO_LEQ
);
2627 static inline void gen_op_movo(int d_offset
, int s_offset
)
2629 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2630 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2631 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2632 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2635 static inline void gen_op_movq(int d_offset
, int s_offset
)
2637 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
);
2638 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2641 static inline void gen_op_movl(int d_offset
, int s_offset
)
2643 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
, s_offset
);
2644 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, d_offset
);
2647 static inline void gen_op_movq_env_0(int d_offset
)
2649 tcg_gen_movi_i64(cpu_tmp1_i64
, 0);
2650 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2653 typedef void (*SSEFunc_i_ep
)(TCGv_i32 val
, TCGv_ptr env
, TCGv_ptr reg
);
2654 typedef void (*SSEFunc_l_ep
)(TCGv_i64 val
, TCGv_ptr env
, TCGv_ptr reg
);
2655 typedef void (*SSEFunc_0_epi
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i32 val
);
2656 typedef void (*SSEFunc_0_epl
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i64 val
);
2657 typedef void (*SSEFunc_0_epp
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
);
2658 typedef void (*SSEFunc_0_eppi
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2660 typedef void (*SSEFunc_0_ppi
)(TCGv_ptr reg_a
, TCGv_ptr reg_b
, TCGv_i32 val
);
2661 typedef void (*SSEFunc_0_eppt
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2664 #define SSE_SPECIAL ((void *)1)
2665 #define SSE_DUMMY ((void *)2)
2667 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2668 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2669 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2671 static const SSEFunc_0_epp sse_op_table1
[256][4] = {
2672 /* 3DNow! extensions */
2673 [0x0e] = { SSE_DUMMY
}, /* femms */
2674 [0x0f] = { SSE_DUMMY
}, /* pf... */
2675 /* pure SSE operations */
2676 [0x10] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2677 [0x11] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2678 [0x12] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd, movsldup, movddup */
2679 [0x13] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd */
2680 [0x14] = { gen_helper_punpckldq_xmm
, gen_helper_punpcklqdq_xmm
},
2681 [0x15] = { gen_helper_punpckhdq_xmm
, gen_helper_punpckhqdq_xmm
},
2682 [0x16] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd, movshdup */
2683 [0x17] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd */
2685 [0x28] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2686 [0x29] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2687 [0x2a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2688 [0x2b] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movntps, movntpd, movntss, movntsd */
2689 [0x2c] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2690 [0x2d] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2691 [0x2e] = { gen_helper_ucomiss
, gen_helper_ucomisd
},
2692 [0x2f] = { gen_helper_comiss
, gen_helper_comisd
},
2693 [0x50] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movmskps, movmskpd */
2694 [0x51] = SSE_FOP(sqrt
),
2695 [0x52] = { gen_helper_rsqrtps
, NULL
, gen_helper_rsqrtss
, NULL
},
2696 [0x53] = { gen_helper_rcpps
, NULL
, gen_helper_rcpss
, NULL
},
2697 [0x54] = { gen_helper_pand_xmm
, gen_helper_pand_xmm
}, /* andps, andpd */
2698 [0x55] = { gen_helper_pandn_xmm
, gen_helper_pandn_xmm
}, /* andnps, andnpd */
2699 [0x56] = { gen_helper_por_xmm
, gen_helper_por_xmm
}, /* orps, orpd */
2700 [0x57] = { gen_helper_pxor_xmm
, gen_helper_pxor_xmm
}, /* xorps, xorpd */
2701 [0x58] = SSE_FOP(add
),
2702 [0x59] = SSE_FOP(mul
),
2703 [0x5a] = { gen_helper_cvtps2pd
, gen_helper_cvtpd2ps
,
2704 gen_helper_cvtss2sd
, gen_helper_cvtsd2ss
},
2705 [0x5b] = { gen_helper_cvtdq2ps
, gen_helper_cvtps2dq
, gen_helper_cvttps2dq
},
2706 [0x5c] = SSE_FOP(sub
),
2707 [0x5d] = SSE_FOP(min
),
2708 [0x5e] = SSE_FOP(div
),
2709 [0x5f] = SSE_FOP(max
),
2711 [0xc2] = SSE_FOP(cmpeq
),
2712 [0xc6] = { (SSEFunc_0_epp
)gen_helper_shufps
,
2713 (SSEFunc_0_epp
)gen_helper_shufpd
}, /* XXX: casts */
2715 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */
2716 [0x38] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2717 [0x3a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2719 /* MMX ops and their SSE extensions */
2720 [0x60] = MMX_OP2(punpcklbw
),
2721 [0x61] = MMX_OP2(punpcklwd
),
2722 [0x62] = MMX_OP2(punpckldq
),
2723 [0x63] = MMX_OP2(packsswb
),
2724 [0x64] = MMX_OP2(pcmpgtb
),
2725 [0x65] = MMX_OP2(pcmpgtw
),
2726 [0x66] = MMX_OP2(pcmpgtl
),
2727 [0x67] = MMX_OP2(packuswb
),
2728 [0x68] = MMX_OP2(punpckhbw
),
2729 [0x69] = MMX_OP2(punpckhwd
),
2730 [0x6a] = MMX_OP2(punpckhdq
),
2731 [0x6b] = MMX_OP2(packssdw
),
2732 [0x6c] = { NULL
, gen_helper_punpcklqdq_xmm
},
2733 [0x6d] = { NULL
, gen_helper_punpckhqdq_xmm
},
2734 [0x6e] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movd mm, ea */
2735 [0x6f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, , movqdu */
2736 [0x70] = { (SSEFunc_0_epp
)gen_helper_pshufw_mmx
,
2737 (SSEFunc_0_epp
)gen_helper_pshufd_xmm
,
2738 (SSEFunc_0_epp
)gen_helper_pshufhw_xmm
,
2739 (SSEFunc_0_epp
)gen_helper_pshuflw_xmm
}, /* XXX: casts */
2740 [0x71] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftw */
2741 [0x72] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftd */
2742 [0x73] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftq */
2743 [0x74] = MMX_OP2(pcmpeqb
),
2744 [0x75] = MMX_OP2(pcmpeqw
),
2745 [0x76] = MMX_OP2(pcmpeql
),
2746 [0x77] = { SSE_DUMMY
}, /* emms */
2747 [0x78] = { NULL
, SSE_SPECIAL
, NULL
, SSE_SPECIAL
}, /* extrq_i, insertq_i */
2748 [0x79] = { NULL
, gen_helper_extrq_r
, NULL
, gen_helper_insertq_r
},
2749 [0x7c] = { NULL
, gen_helper_haddpd
, NULL
, gen_helper_haddps
},
2750 [0x7d] = { NULL
, gen_helper_hsubpd
, NULL
, gen_helper_hsubps
},
2751 [0x7e] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movd, movd, , movq */
2752 [0x7f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, movdqu */
2753 [0xc4] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pinsrw */
2754 [0xc5] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pextrw */
2755 [0xd0] = { NULL
, gen_helper_addsubpd
, NULL
, gen_helper_addsubps
},
2756 [0xd1] = MMX_OP2(psrlw
),
2757 [0xd2] = MMX_OP2(psrld
),
2758 [0xd3] = MMX_OP2(psrlq
),
2759 [0xd4] = MMX_OP2(paddq
),
2760 [0xd5] = MMX_OP2(pmullw
),
2761 [0xd6] = { NULL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2762 [0xd7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pmovmskb */
2763 [0xd8] = MMX_OP2(psubusb
),
2764 [0xd9] = MMX_OP2(psubusw
),
2765 [0xda] = MMX_OP2(pminub
),
2766 [0xdb] = MMX_OP2(pand
),
2767 [0xdc] = MMX_OP2(paddusb
),
2768 [0xdd] = MMX_OP2(paddusw
),
2769 [0xde] = MMX_OP2(pmaxub
),
2770 [0xdf] = MMX_OP2(pandn
),
2771 [0xe0] = MMX_OP2(pavgb
),
2772 [0xe1] = MMX_OP2(psraw
),
2773 [0xe2] = MMX_OP2(psrad
),
2774 [0xe3] = MMX_OP2(pavgw
),
2775 [0xe4] = MMX_OP2(pmulhuw
),
2776 [0xe5] = MMX_OP2(pmulhw
),
2777 [0xe6] = { NULL
, gen_helper_cvttpd2dq
, gen_helper_cvtdq2pd
, gen_helper_cvtpd2dq
},
2778 [0xe7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movntq, movntq */
2779 [0xe8] = MMX_OP2(psubsb
),
2780 [0xe9] = MMX_OP2(psubsw
),
2781 [0xea] = MMX_OP2(pminsw
),
2782 [0xeb] = MMX_OP2(por
),
2783 [0xec] = MMX_OP2(paddsb
),
2784 [0xed] = MMX_OP2(paddsw
),
2785 [0xee] = MMX_OP2(pmaxsw
),
2786 [0xef] = MMX_OP2(pxor
),
2787 [0xf0] = { NULL
, NULL
, NULL
, SSE_SPECIAL
}, /* lddqu */
2788 [0xf1] = MMX_OP2(psllw
),
2789 [0xf2] = MMX_OP2(pslld
),
2790 [0xf3] = MMX_OP2(psllq
),
2791 [0xf4] = MMX_OP2(pmuludq
),
2792 [0xf5] = MMX_OP2(pmaddwd
),
2793 [0xf6] = MMX_OP2(psadbw
),
2794 [0xf7] = { (SSEFunc_0_epp
)gen_helper_maskmov_mmx
,
2795 (SSEFunc_0_epp
)gen_helper_maskmov_xmm
}, /* XXX: casts */
2796 [0xf8] = MMX_OP2(psubb
),
2797 [0xf9] = MMX_OP2(psubw
),
2798 [0xfa] = MMX_OP2(psubl
),
2799 [0xfb] = MMX_OP2(psubq
),
2800 [0xfc] = MMX_OP2(paddb
),
2801 [0xfd] = MMX_OP2(paddw
),
2802 [0xfe] = MMX_OP2(paddl
),
2805 static const SSEFunc_0_epp sse_op_table2
[3 * 8][2] = {
2806 [0 + 2] = MMX_OP2(psrlw
),
2807 [0 + 4] = MMX_OP2(psraw
),
2808 [0 + 6] = MMX_OP2(psllw
),
2809 [8 + 2] = MMX_OP2(psrld
),
2810 [8 + 4] = MMX_OP2(psrad
),
2811 [8 + 6] = MMX_OP2(pslld
),
2812 [16 + 2] = MMX_OP2(psrlq
),
2813 [16 + 3] = { NULL
, gen_helper_psrldq_xmm
},
2814 [16 + 6] = MMX_OP2(psllq
),
2815 [16 + 7] = { NULL
, gen_helper_pslldq_xmm
},
2818 static const SSEFunc_0_epi sse_op_table3ai
[] = {
2819 gen_helper_cvtsi2ss
,
2823 #ifdef TARGET_X86_64
2824 static const SSEFunc_0_epl sse_op_table3aq
[] = {
2825 gen_helper_cvtsq2ss
,
2830 static const SSEFunc_i_ep sse_op_table3bi
[] = {
2831 gen_helper_cvttss2si
,
2832 gen_helper_cvtss2si
,
2833 gen_helper_cvttsd2si
,
2837 #ifdef TARGET_X86_64
2838 static const SSEFunc_l_ep sse_op_table3bq
[] = {
2839 gen_helper_cvttss2sq
,
2840 gen_helper_cvtss2sq
,
2841 gen_helper_cvttsd2sq
,
2846 static const SSEFunc_0_epp sse_op_table4
[8][4] = {
2857 static const SSEFunc_0_epp sse_op_table5
[256] = {
2858 [0x0c] = gen_helper_pi2fw
,
2859 [0x0d] = gen_helper_pi2fd
,
2860 [0x1c] = gen_helper_pf2iw
,
2861 [0x1d] = gen_helper_pf2id
,
2862 [0x8a] = gen_helper_pfnacc
,
2863 [0x8e] = gen_helper_pfpnacc
,
2864 [0x90] = gen_helper_pfcmpge
,
2865 [0x94] = gen_helper_pfmin
,
2866 [0x96] = gen_helper_pfrcp
,
2867 [0x97] = gen_helper_pfrsqrt
,
2868 [0x9a] = gen_helper_pfsub
,
2869 [0x9e] = gen_helper_pfadd
,
2870 [0xa0] = gen_helper_pfcmpgt
,
2871 [0xa4] = gen_helper_pfmax
,
2872 [0xa6] = gen_helper_movq
, /* pfrcpit1; no need to actually increase precision */
2873 [0xa7] = gen_helper_movq
, /* pfrsqit1 */
2874 [0xaa] = gen_helper_pfsubr
,
2875 [0xae] = gen_helper_pfacc
,
2876 [0xb0] = gen_helper_pfcmpeq
,
2877 [0xb4] = gen_helper_pfmul
,
2878 [0xb6] = gen_helper_movq
, /* pfrcpit2 */
2879 [0xb7] = gen_helper_pmulhrw_mmx
,
2880 [0xbb] = gen_helper_pswapd
,
2881 [0xbf] = gen_helper_pavgb_mmx
/* pavgusb */
2884 struct SSEOpHelper_epp
{
2885 SSEFunc_0_epp op
[2];
2889 struct SSEOpHelper_eppi
{
2890 SSEFunc_0_eppi op
[2];
2894 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
2895 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
2896 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
2897 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
2898 #define PCLMULQDQ_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, \
2899 CPUID_EXT_PCLMULQDQ }
2900 #define AESNI_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_AES }
2902 static const struct SSEOpHelper_epp sse_op_table6
[256] = {
2903 [0x00] = SSSE3_OP(pshufb
),
2904 [0x01] = SSSE3_OP(phaddw
),
2905 [0x02] = SSSE3_OP(phaddd
),
2906 [0x03] = SSSE3_OP(phaddsw
),
2907 [0x04] = SSSE3_OP(pmaddubsw
),
2908 [0x05] = SSSE3_OP(phsubw
),
2909 [0x06] = SSSE3_OP(phsubd
),
2910 [0x07] = SSSE3_OP(phsubsw
),
2911 [0x08] = SSSE3_OP(psignb
),
2912 [0x09] = SSSE3_OP(psignw
),
2913 [0x0a] = SSSE3_OP(psignd
),
2914 [0x0b] = SSSE3_OP(pmulhrsw
),
2915 [0x10] = SSE41_OP(pblendvb
),
2916 [0x14] = SSE41_OP(blendvps
),
2917 [0x15] = SSE41_OP(blendvpd
),
2918 [0x17] = SSE41_OP(ptest
),
2919 [0x1c] = SSSE3_OP(pabsb
),
2920 [0x1d] = SSSE3_OP(pabsw
),
2921 [0x1e] = SSSE3_OP(pabsd
),
2922 [0x20] = SSE41_OP(pmovsxbw
),
2923 [0x21] = SSE41_OP(pmovsxbd
),
2924 [0x22] = SSE41_OP(pmovsxbq
),
2925 [0x23] = SSE41_OP(pmovsxwd
),
2926 [0x24] = SSE41_OP(pmovsxwq
),
2927 [0x25] = SSE41_OP(pmovsxdq
),
2928 [0x28] = SSE41_OP(pmuldq
),
2929 [0x29] = SSE41_OP(pcmpeqq
),
2930 [0x2a] = SSE41_SPECIAL
, /* movntqda */
2931 [0x2b] = SSE41_OP(packusdw
),
2932 [0x30] = SSE41_OP(pmovzxbw
),
2933 [0x31] = SSE41_OP(pmovzxbd
),
2934 [0x32] = SSE41_OP(pmovzxbq
),
2935 [0x33] = SSE41_OP(pmovzxwd
),
2936 [0x34] = SSE41_OP(pmovzxwq
),
2937 [0x35] = SSE41_OP(pmovzxdq
),
2938 [0x37] = SSE42_OP(pcmpgtq
),
2939 [0x38] = SSE41_OP(pminsb
),
2940 [0x39] = SSE41_OP(pminsd
),
2941 [0x3a] = SSE41_OP(pminuw
),
2942 [0x3b] = SSE41_OP(pminud
),
2943 [0x3c] = SSE41_OP(pmaxsb
),
2944 [0x3d] = SSE41_OP(pmaxsd
),
2945 [0x3e] = SSE41_OP(pmaxuw
),
2946 [0x3f] = SSE41_OP(pmaxud
),
2947 [0x40] = SSE41_OP(pmulld
),
2948 [0x41] = SSE41_OP(phminposuw
),
2949 [0xdb] = AESNI_OP(aesimc
),
2950 [0xdc] = AESNI_OP(aesenc
),
2951 [0xdd] = AESNI_OP(aesenclast
),
2952 [0xde] = AESNI_OP(aesdec
),
2953 [0xdf] = AESNI_OP(aesdeclast
),
2956 static const struct SSEOpHelper_eppi sse_op_table7
[256] = {
2957 [0x08] = SSE41_OP(roundps
),
2958 [0x09] = SSE41_OP(roundpd
),
2959 [0x0a] = SSE41_OP(roundss
),
2960 [0x0b] = SSE41_OP(roundsd
),
2961 [0x0c] = SSE41_OP(blendps
),
2962 [0x0d] = SSE41_OP(blendpd
),
2963 [0x0e] = SSE41_OP(pblendw
),
2964 [0x0f] = SSSE3_OP(palignr
),
2965 [0x14] = SSE41_SPECIAL
, /* pextrb */
2966 [0x15] = SSE41_SPECIAL
, /* pextrw */
2967 [0x16] = SSE41_SPECIAL
, /* pextrd/pextrq */
2968 [0x17] = SSE41_SPECIAL
, /* extractps */
2969 [0x20] = SSE41_SPECIAL
, /* pinsrb */
2970 [0x21] = SSE41_SPECIAL
, /* insertps */
2971 [0x22] = SSE41_SPECIAL
, /* pinsrd/pinsrq */
2972 [0x40] = SSE41_OP(dpps
),
2973 [0x41] = SSE41_OP(dppd
),
2974 [0x42] = SSE41_OP(mpsadbw
),
2975 [0x44] = PCLMULQDQ_OP(pclmulqdq
),
2976 [0x60] = SSE42_OP(pcmpestrm
),
2977 [0x61] = SSE42_OP(pcmpestri
),
2978 [0x62] = SSE42_OP(pcmpistrm
),
2979 [0x63] = SSE42_OP(pcmpistri
),
2980 [0xdf] = AESNI_OP(aeskeygenassist
),
2983 static void gen_sse(CPUX86State
*env
, DisasContext
*s
, int b
,
2984 target_ulong pc_start
, int rex_r
)
2986 int b1
, op1_offset
, op2_offset
, is_xmm
, val
;
2987 int modrm
, mod
, rm
, reg
;
2988 SSEFunc_0_epp sse_fn_epp
;
2989 SSEFunc_0_eppi sse_fn_eppi
;
2990 SSEFunc_0_ppi sse_fn_ppi
;
2991 SSEFunc_0_eppt sse_fn_eppt
;
2995 if (s
->prefix
& PREFIX_DATA
)
2997 else if (s
->prefix
& PREFIX_REPZ
)
2999 else if (s
->prefix
& PREFIX_REPNZ
)
3003 sse_fn_epp
= sse_op_table1
[b
][b1
];
3007 if ((b
<= 0x5f && b
>= 0x10) || b
== 0xc6 || b
== 0xc2) {
3017 /* simple MMX/SSE operation */
3018 if (s
->flags
& HF_TS_MASK
) {
3019 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
3022 if (s
->flags
& HF_EM_MASK
) {
3024 gen_illegal_opcode(s
);
3028 && !(s
->flags
& HF_OSFXSR_MASK
)
3029 && ((b
!= 0x38 && b
!= 0x3a) || (s
->prefix
& PREFIX_DATA
))) {
3033 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
)) {
3034 /* If we were fully decoding this we might use illegal_op. */
3038 gen_helper_emms(cpu_env
);
3043 gen_helper_emms(cpu_env
);
3046 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3047 the static cpu state) */
3049 gen_helper_enter_mmx(cpu_env
);
3052 modrm
= cpu_ldub_code(env
, s
->pc
++);
3053 reg
= ((modrm
>> 3) & 7);
3056 mod
= (modrm
>> 6) & 3;
3057 if (sse_fn_epp
== SSE_SPECIAL
) {
3060 case 0x0e7: /* movntq */
3064 gen_lea_modrm(env
, s
, modrm
);
3065 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3067 case 0x1e7: /* movntdq */
3068 case 0x02b: /* movntps */
3069 case 0x12b: /* movntps */
3072 gen_lea_modrm(env
, s
, modrm
);
3073 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3075 case 0x3f0: /* lddqu */
3078 gen_lea_modrm(env
, s
, modrm
);
3079 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3081 case 0x22b: /* movntss */
3082 case 0x32b: /* movntsd */
3085 gen_lea_modrm(env
, s
, modrm
);
3087 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3088 xmm_regs
[reg
].ZMM_Q(0)));
3090 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,
3091 xmm_regs
[reg
].ZMM_L(0)));
3092 gen_op_st_v(s
, MO_32
, cpu_T0
, cpu_A0
);
3095 case 0x6e: /* movd mm, ea */
3096 #ifdef TARGET_X86_64
3097 if (s
->dflag
== MO_64
) {
3098 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3099 tcg_gen_st_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3103 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3104 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3105 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3106 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
3107 gen_helper_movl_mm_T0_mmx(cpu_ptr0
, cpu_tmp2_i32
);
3110 case 0x16e: /* movd xmm, ea */
3111 #ifdef TARGET_X86_64
3112 if (s
->dflag
== MO_64
) {
3113 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3114 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3115 offsetof(CPUX86State
,xmm_regs
[reg
]));
3116 gen_helper_movq_mm_T0_xmm(cpu_ptr0
, cpu_T0
);
3120 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3121 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3122 offsetof(CPUX86State
,xmm_regs
[reg
]));
3123 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
3124 gen_helper_movl_mm_T0_xmm(cpu_ptr0
, cpu_tmp2_i32
);
3127 case 0x6f: /* movq mm, ea */
3129 gen_lea_modrm(env
, s
, modrm
);
3130 gen_ldq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3133 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
3134 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3135 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
3136 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3139 case 0x010: /* movups */
3140 case 0x110: /* movupd */
3141 case 0x028: /* movaps */
3142 case 0x128: /* movapd */
3143 case 0x16f: /* movdqa xmm, ea */
3144 case 0x26f: /* movdqu xmm, ea */
3146 gen_lea_modrm(env
, s
, modrm
);
3147 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3149 rm
= (modrm
& 7) | REX_B(s
);
3150 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[reg
]),
3151 offsetof(CPUX86State
,xmm_regs
[rm
]));
3154 case 0x210: /* movss xmm, ea */
3156 gen_lea_modrm(env
, s
, modrm
);
3157 gen_op_ld_v(s
, MO_32
, cpu_T0
, cpu_A0
);
3158 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3159 tcg_gen_movi_tl(cpu_T0
, 0);
3160 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)));
3161 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)));
3162 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)));
3164 rm
= (modrm
& 7) | REX_B(s
);
3165 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)),
3166 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)));
3169 case 0x310: /* movsd xmm, ea */
3171 gen_lea_modrm(env
, s
, modrm
);
3172 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3173 xmm_regs
[reg
].ZMM_Q(0)));
3174 tcg_gen_movi_tl(cpu_T0
, 0);
3175 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)));
3176 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)));
3178 rm
= (modrm
& 7) | REX_B(s
);
3179 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3180 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3183 case 0x012: /* movlps */
3184 case 0x112: /* movlpd */
3186 gen_lea_modrm(env
, s
, modrm
);
3187 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3188 xmm_regs
[reg
].ZMM_Q(0)));
3191 rm
= (modrm
& 7) | REX_B(s
);
3192 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3193 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(1)));
3196 case 0x212: /* movsldup */
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_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)),
3203 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)));
3204 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)),
3205 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(2)));
3207 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)),
3208 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3209 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)),
3210 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)));
3212 case 0x312: /* movddup */
3214 gen_lea_modrm(env
, s
, modrm
);
3215 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3216 xmm_regs
[reg
].ZMM_Q(0)));
3218 rm
= (modrm
& 7) | REX_B(s
);
3219 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3220 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3222 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)),
3223 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3225 case 0x016: /* movhps */
3226 case 0x116: /* movhpd */
3228 gen_lea_modrm(env
, s
, modrm
);
3229 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3230 xmm_regs
[reg
].ZMM_Q(1)));
3233 rm
= (modrm
& 7) | REX_B(s
);
3234 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)),
3235 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3238 case 0x216: /* movshdup */
3240 gen_lea_modrm(env
, s
, modrm
);
3241 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3243 rm
= (modrm
& 7) | REX_B(s
);
3244 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)),
3245 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(1)));
3246 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)),
3247 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(3)));
3249 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)),
3250 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)));
3251 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)),
3252 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)));
3257 int bit_index
, field_length
;
3259 if (b1
== 1 && reg
!= 0)
3261 field_length
= cpu_ldub_code(env
, s
->pc
++) & 0x3F;
3262 bit_index
= cpu_ldub_code(env
, s
->pc
++) & 0x3F;
3263 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3264 offsetof(CPUX86State
,xmm_regs
[reg
]));
3266 gen_helper_extrq_i(cpu_env
, cpu_ptr0
,
3267 tcg_const_i32(bit_index
),
3268 tcg_const_i32(field_length
));
3270 gen_helper_insertq_i(cpu_env
, cpu_ptr0
,
3271 tcg_const_i32(bit_index
),
3272 tcg_const_i32(field_length
));
3275 case 0x7e: /* movd ea, mm */
3276 #ifdef TARGET_X86_64
3277 if (s
->dflag
== MO_64
) {
3278 tcg_gen_ld_i64(cpu_T0
, cpu_env
,
3279 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3280 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3284 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
,
3285 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_L(0)));
3286 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3289 case 0x17e: /* movd ea, xmm */
3290 #ifdef TARGET_X86_64
3291 if (s
->dflag
== MO_64
) {
3292 tcg_gen_ld_i64(cpu_T0
, cpu_env
,
3293 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3294 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3298 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
,
3299 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3300 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3303 case 0x27e: /* movq xmm, ea */
3305 gen_lea_modrm(env
, s
, modrm
);
3306 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3307 xmm_regs
[reg
].ZMM_Q(0)));
3309 rm
= (modrm
& 7) | REX_B(s
);
3310 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3311 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3313 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)));
3315 case 0x7f: /* movq ea, mm */
3317 gen_lea_modrm(env
, s
, modrm
);
3318 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3321 gen_op_movq(offsetof(CPUX86State
,fpregs
[rm
].mmx
),
3322 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3325 case 0x011: /* movups */
3326 case 0x111: /* movupd */
3327 case 0x029: /* movaps */
3328 case 0x129: /* movapd */
3329 case 0x17f: /* movdqa ea, xmm */
3330 case 0x27f: /* movdqu ea, xmm */
3332 gen_lea_modrm(env
, s
, modrm
);
3333 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3335 rm
= (modrm
& 7) | REX_B(s
);
3336 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[rm
]),
3337 offsetof(CPUX86State
,xmm_regs
[reg
]));
3340 case 0x211: /* movss ea, xmm */
3342 gen_lea_modrm(env
, s
, modrm
);
3343 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3344 gen_op_st_v(s
, MO_32
, cpu_T0
, cpu_A0
);
3346 rm
= (modrm
& 7) | REX_B(s
);
3347 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)),
3348 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3351 case 0x311: /* movsd ea, xmm */
3353 gen_lea_modrm(env
, s
, modrm
);
3354 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3355 xmm_regs
[reg
].ZMM_Q(0)));
3357 rm
= (modrm
& 7) | REX_B(s
);
3358 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)),
3359 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3362 case 0x013: /* movlps */
3363 case 0x113: /* movlpd */
3365 gen_lea_modrm(env
, s
, modrm
);
3366 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3367 xmm_regs
[reg
].ZMM_Q(0)));
3372 case 0x017: /* movhps */
3373 case 0x117: /* movhpd */
3375 gen_lea_modrm(env
, s
, modrm
);
3376 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3377 xmm_regs
[reg
].ZMM_Q(1)));
3382 case 0x71: /* shift mm, im */
3385 case 0x171: /* shift xmm, im */
3391 val
= cpu_ldub_code(env
, s
->pc
++);
3393 tcg_gen_movi_tl(cpu_T0
, val
);
3394 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_t0
.ZMM_L(0)));
3395 tcg_gen_movi_tl(cpu_T0
, 0);
3396 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_t0
.ZMM_L(1)));
3397 op1_offset
= offsetof(CPUX86State
,xmm_t0
);
3399 tcg_gen_movi_tl(cpu_T0
, val
);
3400 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,mmx_t0
.MMX_L(0)));
3401 tcg_gen_movi_tl(cpu_T0
, 0);
3402 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,mmx_t0
.MMX_L(1)));
3403 op1_offset
= offsetof(CPUX86State
,mmx_t0
);
3405 sse_fn_epp
= sse_op_table2
[((b
- 1) & 3) * 8 +
3406 (((modrm
>> 3)) & 7)][b1
];
3411 rm
= (modrm
& 7) | REX_B(s
);
3412 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3415 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3417 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3418 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op1_offset
);
3419 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3421 case 0x050: /* movmskps */
3422 rm
= (modrm
& 7) | REX_B(s
);
3423 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3424 offsetof(CPUX86State
,xmm_regs
[rm
]));
3425 gen_helper_movmskps(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3426 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3428 case 0x150: /* movmskpd */
3429 rm
= (modrm
& 7) | REX_B(s
);
3430 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3431 offsetof(CPUX86State
,xmm_regs
[rm
]));
3432 gen_helper_movmskpd(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3433 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3435 case 0x02a: /* cvtpi2ps */
3436 case 0x12a: /* cvtpi2pd */
3437 gen_helper_enter_mmx(cpu_env
);
3439 gen_lea_modrm(env
, s
, modrm
);
3440 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3441 gen_ldq_env_A0(s
, op2_offset
);
3444 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3446 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3447 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3448 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3451 gen_helper_cvtpi2ps(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3455 gen_helper_cvtpi2pd(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3459 case 0x22a: /* cvtsi2ss */
3460 case 0x32a: /* cvtsi2sd */
3461 ot
= mo_64_32(s
->dflag
);
3462 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3463 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3464 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3466 SSEFunc_0_epi sse_fn_epi
= sse_op_table3ai
[(b
>> 8) & 1];
3467 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
3468 sse_fn_epi(cpu_env
, cpu_ptr0
, cpu_tmp2_i32
);
3470 #ifdef TARGET_X86_64
3471 SSEFunc_0_epl sse_fn_epl
= sse_op_table3aq
[(b
>> 8) & 1];
3472 sse_fn_epl(cpu_env
, cpu_ptr0
, cpu_T0
);
3478 case 0x02c: /* cvttps2pi */
3479 case 0x12c: /* cvttpd2pi */
3480 case 0x02d: /* cvtps2pi */
3481 case 0x12d: /* cvtpd2pi */
3482 gen_helper_enter_mmx(cpu_env
);
3484 gen_lea_modrm(env
, s
, modrm
);
3485 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3486 gen_ldo_env_A0(s
, op2_offset
);
3488 rm
= (modrm
& 7) | REX_B(s
);
3489 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3491 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
);
3492 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3493 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3496 gen_helper_cvttps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3499 gen_helper_cvttpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3502 gen_helper_cvtps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3505 gen_helper_cvtpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3509 case 0x22c: /* cvttss2si */
3510 case 0x32c: /* cvttsd2si */
3511 case 0x22d: /* cvtss2si */
3512 case 0x32d: /* cvtsd2si */
3513 ot
= mo_64_32(s
->dflag
);
3515 gen_lea_modrm(env
, s
, modrm
);
3517 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.ZMM_Q(0)));
3519 gen_op_ld_v(s
, MO_32
, cpu_T0
, cpu_A0
);
3520 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_t0
.ZMM_L(0)));
3522 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3524 rm
= (modrm
& 7) | REX_B(s
);
3525 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3527 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3529 SSEFunc_i_ep sse_fn_i_ep
=
3530 sse_op_table3bi
[((b
>> 7) & 2) | (b
& 1)];
3531 sse_fn_i_ep(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3532 tcg_gen_extu_i32_tl(cpu_T0
, cpu_tmp2_i32
);
3534 #ifdef TARGET_X86_64
3535 SSEFunc_l_ep sse_fn_l_ep
=
3536 sse_op_table3bq
[((b
>> 7) & 2) | (b
& 1)];
3537 sse_fn_l_ep(cpu_T0
, cpu_env
, cpu_ptr0
);
3542 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3544 case 0xc4: /* pinsrw */
3547 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
3548 val
= cpu_ldub_code(env
, s
->pc
++);
3551 tcg_gen_st16_tl(cpu_T0
, cpu_env
,
3552 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_W(val
)));
3555 tcg_gen_st16_tl(cpu_T0
, cpu_env
,
3556 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_W(val
)));
3559 case 0xc5: /* pextrw */
3563 ot
= mo_64_32(s
->dflag
);
3564 val
= cpu_ldub_code(env
, s
->pc
++);
3567 rm
= (modrm
& 7) | REX_B(s
);
3568 tcg_gen_ld16u_tl(cpu_T0
, cpu_env
,
3569 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_W(val
)));
3573 tcg_gen_ld16u_tl(cpu_T0
, cpu_env
,
3574 offsetof(CPUX86State
,fpregs
[rm
].mmx
.MMX_W(val
)));
3576 reg
= ((modrm
>> 3) & 7) | rex_r
;
3577 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3579 case 0x1d6: /* movq ea, xmm */
3581 gen_lea_modrm(env
, s
, modrm
);
3582 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3583 xmm_regs
[reg
].ZMM_Q(0)));
3585 rm
= (modrm
& 7) | REX_B(s
);
3586 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)),
3587 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3588 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(1)));
3591 case 0x2d6: /* movq2dq */
3592 gen_helper_enter_mmx(cpu_env
);
3594 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3595 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3596 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)));
3598 case 0x3d6: /* movdq2q */
3599 gen_helper_enter_mmx(cpu_env
);
3600 rm
= (modrm
& 7) | REX_B(s
);
3601 gen_op_movq(offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
),
3602 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3604 case 0xd7: /* pmovmskb */
3609 rm
= (modrm
& 7) | REX_B(s
);
3610 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[rm
]));
3611 gen_helper_pmovmskb_xmm(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3614 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3615 gen_helper_pmovmskb_mmx(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3617 reg
= ((modrm
>> 3) & 7) | rex_r
;
3618 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3624 if ((b
& 0xf0) == 0xf0) {
3627 modrm
= cpu_ldub_code(env
, s
->pc
++);
3629 reg
= ((modrm
>> 3) & 7) | rex_r
;
3630 mod
= (modrm
>> 6) & 3;
3635 sse_fn_epp
= sse_op_table6
[b
].op
[b1
];
3639 if (!(s
->cpuid_ext_features
& sse_op_table6
[b
].ext_mask
))
3643 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3645 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
3647 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3648 gen_lea_modrm(env
, s
, modrm
);
3650 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3651 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3652 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3653 gen_ldq_env_A0(s
, op2_offset
+
3654 offsetof(ZMMReg
, ZMM_Q(0)));
3656 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3657 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3658 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
3659 s
->mem_index
, MO_LEUL
);
3660 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, op2_offset
+
3661 offsetof(ZMMReg
, ZMM_L(0)));
3663 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3664 tcg_gen_qemu_ld_tl(cpu_tmp0
, cpu_A0
,
3665 s
->mem_index
, MO_LEUW
);
3666 tcg_gen_st16_tl(cpu_tmp0
, cpu_env
, op2_offset
+
3667 offsetof(ZMMReg
, ZMM_W(0)));
3669 case 0x2a: /* movntqda */
3670 gen_ldo_env_A0(s
, op1_offset
);
3673 gen_ldo_env_A0(s
, op2_offset
);
3677 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
3679 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3681 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3682 gen_lea_modrm(env
, s
, modrm
);
3683 gen_ldq_env_A0(s
, op2_offset
);
3686 if (sse_fn_epp
== SSE_SPECIAL
) {
3690 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3691 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3692 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3695 set_cc_op(s
, CC_OP_EFLAGS
);
3702 /* Various integer extensions at 0f 38 f[0-f]. */
3703 b
= modrm
| (b1
<< 8);
3704 modrm
= cpu_ldub_code(env
, s
->pc
++);
3705 reg
= ((modrm
>> 3) & 7) | rex_r
;
3708 case 0x3f0: /* crc32 Gd,Eb */
3709 case 0x3f1: /* crc32 Gd,Ey */
3711 if (!(s
->cpuid_ext_features
& CPUID_EXT_SSE42
)) {
3714 if ((b
& 0xff) == 0xf0) {
3716 } else if (s
->dflag
!= MO_64
) {
3717 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3722 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[reg
]);
3723 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3724 gen_helper_crc32(cpu_T0
, cpu_tmp2_i32
,
3725 cpu_T0
, tcg_const_i32(8 << ot
));
3727 ot
= mo_64_32(s
->dflag
);
3728 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3731 case 0x1f0: /* crc32 or movbe */
3733 /* For these insns, the f3 prefix is supposed to have priority
3734 over the 66 prefix, but that's not what we implement above
3736 if (s
->prefix
& PREFIX_REPNZ
) {
3740 case 0x0f0: /* movbe Gy,My */
3741 case 0x0f1: /* movbe My,Gy */
3742 if (!(s
->cpuid_ext_features
& CPUID_EXT_MOVBE
)) {
3745 if (s
->dflag
!= MO_64
) {
3746 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3751 gen_lea_modrm(env
, s
, modrm
);
3753 tcg_gen_qemu_ld_tl(cpu_T0
, cpu_A0
,
3754 s
->mem_index
, ot
| MO_BE
);
3755 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3757 tcg_gen_qemu_st_tl(cpu_regs
[reg
], cpu_A0
,
3758 s
->mem_index
, ot
| MO_BE
);
3762 case 0x0f2: /* andn Gy, By, Ey */
3763 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3764 || !(s
->prefix
& PREFIX_VEX
)
3768 ot
= mo_64_32(s
->dflag
);
3769 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3770 tcg_gen_andc_tl(cpu_T0
, cpu_regs
[s
->vex_v
], cpu_T0
);
3771 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3772 gen_op_update1_cc();
3773 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3776 case 0x0f7: /* bextr Gy, Ey, By */
3777 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3778 || !(s
->prefix
& PREFIX_VEX
)
3782 ot
= mo_64_32(s
->dflag
);
3786 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3787 /* Extract START, and shift the operand.
3788 Shifts larger than operand size get zeros. */
3789 tcg_gen_ext8u_tl(cpu_A0
, cpu_regs
[s
->vex_v
]);
3790 tcg_gen_shr_tl(cpu_T0
, cpu_T0
, cpu_A0
);
3792 bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3793 zero
= tcg_const_tl(0);
3794 tcg_gen_movcond_tl(TCG_COND_LEU
, cpu_T0
, cpu_A0
, bound
,
3796 tcg_temp_free(zero
);
3798 /* Extract the LEN into a mask. Lengths larger than
3799 operand size get all ones. */
3800 tcg_gen_extract_tl(cpu_A0
, cpu_regs
[s
->vex_v
], 8, 8);
3801 tcg_gen_movcond_tl(TCG_COND_LEU
, cpu_A0
, cpu_A0
, bound
,
3803 tcg_temp_free(bound
);
3804 tcg_gen_movi_tl(cpu_T1
, 1);
3805 tcg_gen_shl_tl(cpu_T1
, cpu_T1
, cpu_A0
);
3806 tcg_gen_subi_tl(cpu_T1
, cpu_T1
, 1);
3807 tcg_gen_and_tl(cpu_T0
, cpu_T0
, cpu_T1
);
3809 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3810 gen_op_update1_cc();
3811 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3815 case 0x0f5: /* bzhi Gy, Ey, By */
3816 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3817 || !(s
->prefix
& PREFIX_VEX
)
3821 ot
= mo_64_32(s
->dflag
);
3822 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3823 tcg_gen_ext8u_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3825 TCGv bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3826 /* Note that since we're using BMILG (in order to get O
3827 cleared) we need to store the inverse into C. */
3828 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_cc_src
,
3830 tcg_gen_movcond_tl(TCG_COND_GT
, cpu_T1
, cpu_T1
,
3831 bound
, bound
, cpu_T1
);
3832 tcg_temp_free(bound
);
3834 tcg_gen_movi_tl(cpu_A0
, -1);
3835 tcg_gen_shl_tl(cpu_A0
, cpu_A0
, cpu_T1
);
3836 tcg_gen_andc_tl(cpu_T0
, cpu_T0
, cpu_A0
);
3837 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3838 gen_op_update1_cc();
3839 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
3842 case 0x3f6: /* mulx By, Gy, rdx, Ey */
3843 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3844 || !(s
->prefix
& PREFIX_VEX
)
3848 ot
= mo_64_32(s
->dflag
);
3849 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3852 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
3853 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EDX
]);
3854 tcg_gen_mulu2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
3855 cpu_tmp2_i32
, cpu_tmp3_i32
);
3856 tcg_gen_extu_i32_tl(cpu_regs
[s
->vex_v
], cpu_tmp2_i32
);
3857 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp3_i32
);
3859 #ifdef TARGET_X86_64
3861 tcg_gen_mulu2_i64(cpu_T0
, cpu_T1
,
3862 cpu_T0
, cpu_regs
[R_EDX
]);
3863 tcg_gen_mov_i64(cpu_regs
[s
->vex_v
], cpu_T0
);
3864 tcg_gen_mov_i64(cpu_regs
[reg
], cpu_T1
);
3870 case 0x3f5: /* pdep Gy, By, Ey */
3871 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3872 || !(s
->prefix
& PREFIX_VEX
)
3876 ot
= mo_64_32(s
->dflag
);
3877 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3878 /* Note that by zero-extending the mask operand, we
3879 automatically handle zero-extending the result. */
3881 tcg_gen_mov_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3883 tcg_gen_ext32u_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3885 gen_helper_pdep(cpu_regs
[reg
], cpu_T0
, cpu_T1
);
3888 case 0x2f5: /* pext Gy, By, Ey */
3889 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3890 || !(s
->prefix
& PREFIX_VEX
)
3894 ot
= mo_64_32(s
->dflag
);
3895 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3896 /* Note that by zero-extending the mask operand, we
3897 automatically handle zero-extending the result. */
3899 tcg_gen_mov_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3901 tcg_gen_ext32u_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3903 gen_helper_pext(cpu_regs
[reg
], cpu_T0
, cpu_T1
);
3906 case 0x1f6: /* adcx Gy, Ey */
3907 case 0x2f6: /* adox Gy, Ey */
3908 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_ADX
)) {
3911 TCGv carry_in
, carry_out
, zero
;
3914 ot
= mo_64_32(s
->dflag
);
3915 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3917 /* Re-use the carry-out from a previous round. */
3918 TCGV_UNUSED(carry_in
);
3919 carry_out
= (b
== 0x1f6 ? cpu_cc_dst
: cpu_cc_src2
);
3923 carry_in
= cpu_cc_dst
;
3924 end_op
= CC_OP_ADCX
;
3926 end_op
= CC_OP_ADCOX
;
3931 end_op
= CC_OP_ADCOX
;
3933 carry_in
= cpu_cc_src2
;
3934 end_op
= CC_OP_ADOX
;
3938 end_op
= CC_OP_ADCOX
;
3939 carry_in
= carry_out
;
3942 end_op
= (b
== 0x1f6 ? CC_OP_ADCX
: CC_OP_ADOX
);
3945 /* If we can't reuse carry-out, get it out of EFLAGS. */
3946 if (TCGV_IS_UNUSED(carry_in
)) {
3947 if (s
->cc_op
!= CC_OP_ADCX
&& s
->cc_op
!= CC_OP_ADOX
) {
3948 gen_compute_eflags(s
);
3950 carry_in
= cpu_tmp0
;
3951 tcg_gen_extract_tl(carry_in
, cpu_cc_src
,
3952 ctz32(b
== 0x1f6 ? CC_C
: CC_O
), 1);
3956 #ifdef TARGET_X86_64
3958 /* If we know TL is 64-bit, and we want a 32-bit
3959 result, just do everything in 64-bit arithmetic. */
3960 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_regs
[reg
]);
3961 tcg_gen_ext32u_i64(cpu_T0
, cpu_T0
);
3962 tcg_gen_add_i64(cpu_T0
, cpu_T0
, cpu_regs
[reg
]);
3963 tcg_gen_add_i64(cpu_T0
, cpu_T0
, carry_in
);
3964 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_T0
);
3965 tcg_gen_shri_i64(carry_out
, cpu_T0
, 32);
3969 /* Otherwise compute the carry-out in two steps. */
3970 zero
= tcg_const_tl(0);
3971 tcg_gen_add2_tl(cpu_T0
, carry_out
,
3974 tcg_gen_add2_tl(cpu_regs
[reg
], carry_out
,
3975 cpu_regs
[reg
], carry_out
,
3977 tcg_temp_free(zero
);
3980 set_cc_op(s
, end_op
);
3984 case 0x1f7: /* shlx Gy, Ey, By */
3985 case 0x2f7: /* sarx Gy, Ey, By */
3986 case 0x3f7: /* shrx Gy, Ey, By */
3987 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3988 || !(s
->prefix
& PREFIX_VEX
)
3992 ot
= mo_64_32(s
->dflag
);
3993 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3995 tcg_gen_andi_tl(cpu_T1
, cpu_regs
[s
->vex_v
], 63);
3997 tcg_gen_andi_tl(cpu_T1
, cpu_regs
[s
->vex_v
], 31);
4000 tcg_gen_shl_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4001 } else if (b
== 0x2f7) {
4003 tcg_gen_ext32s_tl(cpu_T0
, cpu_T0
);
4005 tcg_gen_sar_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4008 tcg_gen_ext32u_tl(cpu_T0
, cpu_T0
);
4010 tcg_gen_shr_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4012 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
4018 case 0x3f3: /* Group 17 */
4019 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
4020 || !(s
->prefix
& PREFIX_VEX
)
4024 ot
= mo_64_32(s
->dflag
);
4025 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4028 case 1: /* blsr By,Ey */
4029 tcg_gen_neg_tl(cpu_T1
, cpu_T0
);
4030 tcg_gen_and_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4031 gen_op_mov_reg_v(ot
, s
->vex_v
, cpu_T0
);
4032 gen_op_update2_cc();
4033 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4036 case 2: /* blsmsk By,Ey */
4037 tcg_gen_mov_tl(cpu_cc_src
, cpu_T0
);
4038 tcg_gen_subi_tl(cpu_T0
, cpu_T0
, 1);
4039 tcg_gen_xor_tl(cpu_T0
, cpu_T0
, cpu_cc_src
);
4040 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
4041 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4044 case 3: /* blsi By, Ey */
4045 tcg_gen_mov_tl(cpu_cc_src
, cpu_T0
);
4046 tcg_gen_subi_tl(cpu_T0
, cpu_T0
, 1);
4047 tcg_gen_and_tl(cpu_T0
, cpu_T0
, cpu_cc_src
);
4048 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
4049 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4065 modrm
= cpu_ldub_code(env
, s
->pc
++);
4067 reg
= ((modrm
>> 3) & 7) | rex_r
;
4068 mod
= (modrm
>> 6) & 3;
4073 sse_fn_eppi
= sse_op_table7
[b
].op
[b1
];
4077 if (!(s
->cpuid_ext_features
& sse_op_table7
[b
].ext_mask
))
4080 if (sse_fn_eppi
== SSE_SPECIAL
) {
4081 ot
= mo_64_32(s
->dflag
);
4082 rm
= (modrm
& 7) | REX_B(s
);
4084 gen_lea_modrm(env
, s
, modrm
);
4085 reg
= ((modrm
>> 3) & 7) | rex_r
;
4086 val
= cpu_ldub_code(env
, s
->pc
++);
4088 case 0x14: /* pextrb */
4089 tcg_gen_ld8u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,
4090 xmm_regs
[reg
].ZMM_B(val
& 15)));
4092 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
4094 tcg_gen_qemu_st_tl(cpu_T0
, cpu_A0
,
4095 s
->mem_index
, MO_UB
);
4098 case 0x15: /* pextrw */
4099 tcg_gen_ld16u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,
4100 xmm_regs
[reg
].ZMM_W(val
& 7)));
4102 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
4104 tcg_gen_qemu_st_tl(cpu_T0
, cpu_A0
,
4105 s
->mem_index
, MO_LEUW
);
4109 if (ot
== MO_32
) { /* pextrd */
4110 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4111 offsetof(CPUX86State
,
4112 xmm_regs
[reg
].ZMM_L(val
& 3)));
4114 tcg_gen_extu_i32_tl(cpu_regs
[rm
], cpu_tmp2_i32
);
4116 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
4117 s
->mem_index
, MO_LEUL
);
4119 } else { /* pextrq */
4120 #ifdef TARGET_X86_64
4121 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
4122 offsetof(CPUX86State
,
4123 xmm_regs
[reg
].ZMM_Q(val
& 1)));
4125 tcg_gen_mov_i64(cpu_regs
[rm
], cpu_tmp1_i64
);
4127 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
4128 s
->mem_index
, MO_LEQ
);
4135 case 0x17: /* extractps */
4136 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,
4137 xmm_regs
[reg
].ZMM_L(val
& 3)));
4139 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
4141 tcg_gen_qemu_st_tl(cpu_T0
, cpu_A0
,
4142 s
->mem_index
, MO_LEUL
);
4145 case 0x20: /* pinsrb */
4147 gen_op_mov_v_reg(MO_32
, cpu_T0
, rm
);
4149 tcg_gen_qemu_ld_tl(cpu_T0
, cpu_A0
,
4150 s
->mem_index
, MO_UB
);
4152 tcg_gen_st8_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,
4153 xmm_regs
[reg
].ZMM_B(val
& 15)));
4155 case 0x21: /* insertps */
4157 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4158 offsetof(CPUX86State
,xmm_regs
[rm
]
4159 .ZMM_L((val
>> 6) & 3)));
4161 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
4162 s
->mem_index
, MO_LEUL
);
4164 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4165 offsetof(CPUX86State
,xmm_regs
[reg
]
4166 .ZMM_L((val
>> 4) & 3)));
4168 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4169 cpu_env
, offsetof(CPUX86State
,
4170 xmm_regs
[reg
].ZMM_L(0)));
4172 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4173 cpu_env
, offsetof(CPUX86State
,
4174 xmm_regs
[reg
].ZMM_L(1)));
4176 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4177 cpu_env
, offsetof(CPUX86State
,
4178 xmm_regs
[reg
].ZMM_L(2)));
4180 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4181 cpu_env
, offsetof(CPUX86State
,
4182 xmm_regs
[reg
].ZMM_L(3)));
4185 if (ot
== MO_32
) { /* pinsrd */
4187 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[rm
]);
4189 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
4190 s
->mem_index
, MO_LEUL
);
4192 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4193 offsetof(CPUX86State
,
4194 xmm_regs
[reg
].ZMM_L(val
& 3)));
4195 } else { /* pinsrq */
4196 #ifdef TARGET_X86_64
4198 gen_op_mov_v_reg(ot
, cpu_tmp1_i64
, rm
);
4200 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
4201 s
->mem_index
, MO_LEQ
);
4203 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
4204 offsetof(CPUX86State
,
4205 xmm_regs
[reg
].ZMM_Q(val
& 1)));
4216 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4218 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
4220 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4221 gen_lea_modrm(env
, s
, modrm
);
4222 gen_ldo_env_A0(s
, op2_offset
);
4225 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4227 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4229 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4230 gen_lea_modrm(env
, s
, modrm
);
4231 gen_ldq_env_A0(s
, op2_offset
);
4234 val
= cpu_ldub_code(env
, s
->pc
++);
4236 if ((b
& 0xfc) == 0x60) { /* pcmpXstrX */
4237 set_cc_op(s
, CC_OP_EFLAGS
);
4239 if (s
->dflag
== MO_64
) {
4240 /* The helper must use entire 64-bit gp registers */
4245 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4246 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4247 sse_fn_eppi(cpu_env
, cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4251 /* Various integer extensions at 0f 3a f[0-f]. */
4252 b
= modrm
| (b1
<< 8);
4253 modrm
= cpu_ldub_code(env
, s
->pc
++);
4254 reg
= ((modrm
>> 3) & 7) | rex_r
;
4257 case 0x3f0: /* rorx Gy,Ey, Ib */
4258 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4259 || !(s
->prefix
& PREFIX_VEX
)
4263 ot
= mo_64_32(s
->dflag
);
4264 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4265 b
= cpu_ldub_code(env
, s
->pc
++);
4267 tcg_gen_rotri_tl(cpu_T0
, cpu_T0
, b
& 63);
4269 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
4270 tcg_gen_rotri_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, b
& 31);
4271 tcg_gen_extu_i32_tl(cpu_T0
, cpu_tmp2_i32
);
4273 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
4283 gen_unknown_opcode(env
, s
);
4287 /* generic MMX or SSE operation */
4289 case 0x70: /* pshufx insn */
4290 case 0xc6: /* pshufx insn */
4291 case 0xc2: /* compare insns */
4298 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4302 gen_lea_modrm(env
, s
, modrm
);
4303 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4309 /* Most sse scalar operations. */
4312 } else if (b1
== 3) {
4317 case 0x2e: /* ucomis[sd] */
4318 case 0x2f: /* comis[sd] */
4330 gen_op_ld_v(s
, MO_32
, cpu_T0
, cpu_A0
);
4331 tcg_gen_st32_tl(cpu_T0
, cpu_env
,
4332 offsetof(CPUX86State
,xmm_t0
.ZMM_L(0)));
4336 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.ZMM_D(0)));
4339 /* 128 bit access */
4340 gen_ldo_env_A0(s
, op2_offset
);
4344 rm
= (modrm
& 7) | REX_B(s
);
4345 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
4348 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4350 gen_lea_modrm(env
, s
, modrm
);
4351 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4352 gen_ldq_env_A0(s
, op2_offset
);
4355 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4359 case 0x0f: /* 3DNow! data insns */
4360 val
= cpu_ldub_code(env
, s
->pc
++);
4361 sse_fn_epp
= sse_op_table5
[val
];
4365 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
)) {
4368 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4369 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4370 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4372 case 0x70: /* pshufx insn */
4373 case 0xc6: /* pshufx insn */
4374 val
= cpu_ldub_code(env
, s
->pc
++);
4375 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4376 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4377 /* XXX: introduce a new table? */
4378 sse_fn_ppi
= (SSEFunc_0_ppi
)sse_fn_epp
;
4379 sse_fn_ppi(cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4383 val
= cpu_ldub_code(env
, s
->pc
++);
4386 sse_fn_epp
= sse_op_table4
[val
][b1
];
4388 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4389 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4390 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4393 /* maskmov : we must prepare A0 */
4396 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EDI
]);
4397 gen_extu(s
->aflag
, cpu_A0
);
4398 gen_add_A0_ds_seg(s
);
4400 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4401 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4402 /* XXX: introduce a new table? */
4403 sse_fn_eppt
= (SSEFunc_0_eppt
)sse_fn_epp
;
4404 sse_fn_eppt(cpu_env
, cpu_ptr0
, cpu_ptr1
, cpu_A0
);
4407 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4408 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4409 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4412 if (b
== 0x2e || b
== 0x2f) {
4413 set_cc_op(s
, CC_OP_EFLAGS
);
4418 /* convert one instruction. s->is_jmp is set if the translation must
4419 be stopped. Return the next pc value */
4420 static target_ulong
disas_insn(CPUX86State
*env
, DisasContext
*s
,
4421 target_ulong pc_start
)
4425 TCGMemOp ot
, aflag
, dflag
;
4426 int modrm
, reg
, rm
, mod
, op
, opreg
, val
;
4427 target_ulong next_eip
, tval
;
4430 s
->pc_start
= s
->pc
= pc_start
;
4435 #ifdef TARGET_X86_64
4440 s
->rip_offset
= 0; /* for relative ip address */
4444 /* x86 has an upper limit of 15 bytes for an instruction. Since we
4445 * do not want to decode and generate IR for an illegal
4446 * instruction, the following check limits the instruction size to
4447 * 25 bytes: 14 prefix + 1 opc + 6 (modrm+sib+ofs) + 4 imm */
4448 if (s
->pc
- pc_start
> 14) {
4451 b
= cpu_ldub_code(env
, s
->pc
);
4453 /* Collect prefixes. */
4456 prefixes
|= PREFIX_REPZ
;
4459 prefixes
|= PREFIX_REPNZ
;
4462 prefixes
|= PREFIX_LOCK
;
4483 prefixes
|= PREFIX_DATA
;
4486 prefixes
|= PREFIX_ADR
;
4488 #ifdef TARGET_X86_64
4492 rex_w
= (b
>> 3) & 1;
4493 rex_r
= (b
& 0x4) << 1;
4494 s
->rex_x
= (b
& 0x2) << 2;
4495 REX_B(s
) = (b
& 0x1) << 3;
4496 x86_64_hregs
= 1; /* select uniform byte register addressing */
4501 case 0xc5: /* 2-byte VEX */
4502 case 0xc4: /* 3-byte VEX */
4503 /* VEX prefixes cannot be used except in 32-bit mode.
4504 Otherwise the instruction is LES or LDS. */
4505 if (s
->code32
&& !s
->vm86
) {
4506 static const int pp_prefix
[4] = {
4507 0, PREFIX_DATA
, PREFIX_REPZ
, PREFIX_REPNZ
4509 int vex3
, vex2
= cpu_ldub_code(env
, s
->pc
);
4511 if (!CODE64(s
) && (vex2
& 0xc0) != 0xc0) {
4512 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4513 otherwise the instruction is LES or LDS. */
4518 /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
4519 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
4520 | PREFIX_LOCK
| PREFIX_DATA
)) {
4523 #ifdef TARGET_X86_64
4528 rex_r
= (~vex2
>> 4) & 8;
4531 b
= cpu_ldub_code(env
, s
->pc
++);
4533 #ifdef TARGET_X86_64
4534 s
->rex_x
= (~vex2
>> 3) & 8;
4535 s
->rex_b
= (~vex2
>> 2) & 8;
4537 vex3
= cpu_ldub_code(env
, s
->pc
++);
4538 rex_w
= (vex3
>> 7) & 1;
4539 switch (vex2
& 0x1f) {
4540 case 0x01: /* Implied 0f leading opcode bytes. */
4541 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4543 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4546 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4549 default: /* Reserved for future use. */
4553 s
->vex_v
= (~vex3
>> 3) & 0xf;
4554 s
->vex_l
= (vex3
>> 2) & 1;
4555 prefixes
|= pp_prefix
[vex3
& 3] | PREFIX_VEX
;
4560 /* Post-process prefixes. */
4562 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit
4563 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4564 over 0x66 if both are present. */
4565 dflag
= (rex_w
> 0 ? MO_64
: prefixes
& PREFIX_DATA
? MO_16
: MO_32
);
4566 /* In 64-bit mode, 0x67 selects 32-bit addressing. */
4567 aflag
= (prefixes
& PREFIX_ADR
? MO_32
: MO_64
);
4569 /* In 16/32-bit mode, 0x66 selects the opposite data size. */
4570 if (s
->code32
^ ((prefixes
& PREFIX_DATA
) != 0)) {
4575 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */
4576 if (s
->code32
^ ((prefixes
& PREFIX_ADR
) != 0)) {
4583 s
->prefix
= prefixes
;
4587 /* now check op code */
4591 /**************************/
4592 /* extended op code */
4593 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4596 /**************************/
4611 ot
= mo_b_d(b
, dflag
);
4614 case 0: /* OP Ev, Gv */
4615 modrm
= cpu_ldub_code(env
, s
->pc
++);
4616 reg
= ((modrm
>> 3) & 7) | rex_r
;
4617 mod
= (modrm
>> 6) & 3;
4618 rm
= (modrm
& 7) | REX_B(s
);
4620 gen_lea_modrm(env
, s
, modrm
);
4622 } else if (op
== OP_XORL
&& rm
== reg
) {
4624 /* xor reg, reg optimisation */
4625 set_cc_op(s
, CC_OP_CLR
);
4626 tcg_gen_movi_tl(cpu_T0
, 0);
4627 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
4632 gen_op_mov_v_reg(ot
, cpu_T1
, reg
);
4633 gen_op(s
, op
, ot
, opreg
);
4635 case 1: /* OP Gv, Ev */
4636 modrm
= cpu_ldub_code(env
, s
->pc
++);
4637 mod
= (modrm
>> 6) & 3;
4638 reg
= ((modrm
>> 3) & 7) | rex_r
;
4639 rm
= (modrm
& 7) | REX_B(s
);
4641 gen_lea_modrm(env
, s
, modrm
);
4642 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
4643 } else if (op
== OP_XORL
&& rm
== reg
) {
4646 gen_op_mov_v_reg(ot
, cpu_T1
, rm
);
4648 gen_op(s
, op
, ot
, reg
);
4650 case 2: /* OP A, Iv */
4651 val
= insn_get(env
, s
, ot
);
4652 tcg_gen_movi_tl(cpu_T1
, val
);
4653 gen_op(s
, op
, ot
, OR_EAX
);
4662 case 0x80: /* GRP1 */
4668 ot
= mo_b_d(b
, dflag
);
4670 modrm
= cpu_ldub_code(env
, s
->pc
++);
4671 mod
= (modrm
>> 6) & 3;
4672 rm
= (modrm
& 7) | REX_B(s
);
4673 op
= (modrm
>> 3) & 7;
4679 s
->rip_offset
= insn_const_size(ot
);
4680 gen_lea_modrm(env
, s
, modrm
);
4691 val
= insn_get(env
, s
, ot
);
4694 val
= (int8_t)insn_get(env
, s
, MO_8
);
4697 tcg_gen_movi_tl(cpu_T1
, val
);
4698 gen_op(s
, op
, ot
, opreg
);
4702 /**************************/
4703 /* inc, dec, and other misc arith */
4704 case 0x40 ... 0x47: /* inc Gv */
4706 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), 1);
4708 case 0x48 ... 0x4f: /* dec Gv */
4710 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), -1);
4712 case 0xf6: /* GRP3 */
4714 ot
= mo_b_d(b
, dflag
);
4716 modrm
= cpu_ldub_code(env
, s
->pc
++);
4717 mod
= (modrm
>> 6) & 3;
4718 rm
= (modrm
& 7) | REX_B(s
);
4719 op
= (modrm
>> 3) & 7;
4722 s
->rip_offset
= insn_const_size(ot
);
4724 gen_lea_modrm(env
, s
, modrm
);
4725 /* For those below that handle locked memory, don't load here. */
4726 if (!(s
->prefix
& PREFIX_LOCK
)
4728 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
4731 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
4736 val
= insn_get(env
, s
, ot
);
4737 tcg_gen_movi_tl(cpu_T1
, val
);
4738 gen_op_testl_T0_T1_cc();
4739 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4742 if (s
->prefix
& PREFIX_LOCK
) {
4746 tcg_gen_movi_tl(cpu_T0
, ~0);
4747 tcg_gen_atomic_xor_fetch_tl(cpu_T0
, cpu_A0
, cpu_T0
,
4748 s
->mem_index
, ot
| MO_LE
);
4750 tcg_gen_not_tl(cpu_T0
, cpu_T0
);
4752 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
4754 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
4759 if (s
->prefix
& PREFIX_LOCK
) {
4761 TCGv a0
, t0
, t1
, t2
;
4766 a0
= tcg_temp_local_new();
4767 t0
= tcg_temp_local_new();
4768 label1
= gen_new_label();
4770 tcg_gen_mov_tl(a0
, cpu_A0
);
4771 tcg_gen_mov_tl(t0
, cpu_T0
);
4773 gen_set_label(label1
);
4774 t1
= tcg_temp_new();
4775 t2
= tcg_temp_new();
4776 tcg_gen_mov_tl(t2
, t0
);
4777 tcg_gen_neg_tl(t1
, t0
);
4778 tcg_gen_atomic_cmpxchg_tl(t0
, a0
, t0
, t1
,
4779 s
->mem_index
, ot
| MO_LE
);
4781 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t2
, label1
);
4785 tcg_gen_mov_tl(cpu_T0
, t0
);
4788 tcg_gen_neg_tl(cpu_T0
, cpu_T0
);
4790 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
4792 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
4795 gen_op_update_neg_cc();
4796 set_cc_op(s
, CC_OP_SUBB
+ ot
);
4801 gen_op_mov_v_reg(MO_8
, cpu_T1
, R_EAX
);
4802 tcg_gen_ext8u_tl(cpu_T0
, cpu_T0
);
4803 tcg_gen_ext8u_tl(cpu_T1
, cpu_T1
);
4804 /* XXX: use 32 bit mul which could be faster */
4805 tcg_gen_mul_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4806 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
4807 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
4808 tcg_gen_andi_tl(cpu_cc_src
, cpu_T0
, 0xff00);
4809 set_cc_op(s
, CC_OP_MULB
);
4812 gen_op_mov_v_reg(MO_16
, cpu_T1
, R_EAX
);
4813 tcg_gen_ext16u_tl(cpu_T0
, cpu_T0
);
4814 tcg_gen_ext16u_tl(cpu_T1
, cpu_T1
);
4815 /* XXX: use 32 bit mul which could be faster */
4816 tcg_gen_mul_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4817 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
4818 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
4819 tcg_gen_shri_tl(cpu_T0
, cpu_T0
, 16);
4820 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T0
);
4821 tcg_gen_mov_tl(cpu_cc_src
, cpu_T0
);
4822 set_cc_op(s
, CC_OP_MULW
);
4826 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
4827 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
4828 tcg_gen_mulu2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4829 cpu_tmp2_i32
, cpu_tmp3_i32
);
4830 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
4831 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
4832 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4833 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4834 set_cc_op(s
, CC_OP_MULL
);
4836 #ifdef TARGET_X86_64
4838 tcg_gen_mulu2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4839 cpu_T0
, cpu_regs
[R_EAX
]);
4840 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4841 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4842 set_cc_op(s
, CC_OP_MULQ
);
4850 gen_op_mov_v_reg(MO_8
, cpu_T1
, R_EAX
);
4851 tcg_gen_ext8s_tl(cpu_T0
, cpu_T0
);
4852 tcg_gen_ext8s_tl(cpu_T1
, cpu_T1
);
4853 /* XXX: use 32 bit mul which could be faster */
4854 tcg_gen_mul_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4855 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
4856 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
4857 tcg_gen_ext8s_tl(cpu_tmp0
, cpu_T0
);
4858 tcg_gen_sub_tl(cpu_cc_src
, cpu_T0
, cpu_tmp0
);
4859 set_cc_op(s
, CC_OP_MULB
);
4862 gen_op_mov_v_reg(MO_16
, cpu_T1
, R_EAX
);
4863 tcg_gen_ext16s_tl(cpu_T0
, cpu_T0
);
4864 tcg_gen_ext16s_tl(cpu_T1
, cpu_T1
);
4865 /* XXX: use 32 bit mul which could be faster */
4866 tcg_gen_mul_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4867 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
4868 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
4869 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T0
);
4870 tcg_gen_sub_tl(cpu_cc_src
, cpu_T0
, cpu_tmp0
);
4871 tcg_gen_shri_tl(cpu_T0
, cpu_T0
, 16);
4872 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T0
);
4873 set_cc_op(s
, CC_OP_MULW
);
4877 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
4878 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
4879 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4880 cpu_tmp2_i32
, cpu_tmp3_i32
);
4881 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
4882 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
4883 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
4884 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4885 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
4886 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
4887 set_cc_op(s
, CC_OP_MULL
);
4889 #ifdef TARGET_X86_64
4891 tcg_gen_muls2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4892 cpu_T0
, cpu_regs
[R_EAX
]);
4893 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4894 tcg_gen_sari_tl(cpu_cc_src
, cpu_regs
[R_EAX
], 63);
4895 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_regs
[R_EDX
]);
4896 set_cc_op(s
, CC_OP_MULQ
);
4904 gen_helper_divb_AL(cpu_env
, cpu_T0
);
4907 gen_helper_divw_AX(cpu_env
, cpu_T0
);
4911 gen_helper_divl_EAX(cpu_env
, cpu_T0
);
4913 #ifdef TARGET_X86_64
4915 gen_helper_divq_EAX(cpu_env
, cpu_T0
);
4923 gen_helper_idivb_AL(cpu_env
, cpu_T0
);
4926 gen_helper_idivw_AX(cpu_env
, cpu_T0
);
4930 gen_helper_idivl_EAX(cpu_env
, cpu_T0
);
4932 #ifdef TARGET_X86_64
4934 gen_helper_idivq_EAX(cpu_env
, cpu_T0
);
4944 case 0xfe: /* GRP4 */
4945 case 0xff: /* GRP5 */
4946 ot
= mo_b_d(b
, dflag
);
4948 modrm
= cpu_ldub_code(env
, s
->pc
++);
4949 mod
= (modrm
>> 6) & 3;
4950 rm
= (modrm
& 7) | REX_B(s
);
4951 op
= (modrm
>> 3) & 7;
4952 if (op
>= 2 && b
== 0xfe) {
4956 if (op
== 2 || op
== 4) {
4957 /* operand size for jumps is 64 bit */
4959 } else if (op
== 3 || op
== 5) {
4960 ot
= dflag
!= MO_16
? MO_32
+ (rex_w
== 1) : MO_16
;
4961 } else if (op
== 6) {
4962 /* default push size is 64 bit */
4963 ot
= mo_pushpop(s
, dflag
);
4967 gen_lea_modrm(env
, s
, modrm
);
4968 if (op
>= 2 && op
!= 3 && op
!= 5)
4969 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
4971 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
4975 case 0: /* inc Ev */
4980 gen_inc(s
, ot
, opreg
, 1);
4982 case 1: /* dec Ev */
4987 gen_inc(s
, ot
, opreg
, -1);
4989 case 2: /* call Ev */
4990 /* XXX: optimize if memory (no 'and' is necessary) */
4991 if (dflag
== MO_16
) {
4992 tcg_gen_ext16u_tl(cpu_T0
, cpu_T0
);
4994 next_eip
= s
->pc
- s
->cs_base
;
4995 tcg_gen_movi_tl(cpu_T1
, next_eip
);
4996 gen_push_v(s
, cpu_T1
);
4997 gen_op_jmp_v(cpu_T0
);
5001 case 3: /* lcall Ev */
5002 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
5003 gen_add_A0_im(s
, 1 << ot
);
5004 gen_op_ld_v(s
, MO_16
, cpu_T0
, cpu_A0
);
5006 if (s
->pe
&& !s
->vm86
) {
5007 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
5008 gen_helper_lcall_protected(cpu_env
, cpu_tmp2_i32
, cpu_T1
,
5009 tcg_const_i32(dflag
- 1),
5010 tcg_const_tl(s
->pc
- s
->cs_base
));
5012 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
5013 gen_helper_lcall_real(cpu_env
, cpu_tmp2_i32
, cpu_T1
,
5014 tcg_const_i32(dflag
- 1),
5015 tcg_const_i32(s
->pc
- s
->cs_base
));
5019 case 4: /* jmp Ev */
5020 if (dflag
== MO_16
) {
5021 tcg_gen_ext16u_tl(cpu_T0
, cpu_T0
);
5023 gen_op_jmp_v(cpu_T0
);
5027 case 5: /* ljmp Ev */
5028 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
5029 gen_add_A0_im(s
, 1 << ot
);
5030 gen_op_ld_v(s
, MO_16
, cpu_T0
, cpu_A0
);
5032 if (s
->pe
&& !s
->vm86
) {
5033 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
5034 gen_helper_ljmp_protected(cpu_env
, cpu_tmp2_i32
, cpu_T1
,
5035 tcg_const_tl(s
->pc
- s
->cs_base
));
5037 gen_op_movl_seg_T0_vm(R_CS
);
5038 gen_op_jmp_v(cpu_T1
);
5042 case 6: /* push Ev */
5043 gen_push_v(s
, cpu_T0
);
5050 case 0x84: /* test Ev, Gv */
5052 ot
= mo_b_d(b
, dflag
);
5054 modrm
= cpu_ldub_code(env
, s
->pc
++);
5055 reg
= ((modrm
>> 3) & 7) | rex_r
;
5057 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5058 gen_op_mov_v_reg(ot
, cpu_T1
, reg
);
5059 gen_op_testl_T0_T1_cc();
5060 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5063 case 0xa8: /* test eAX, Iv */
5065 ot
= mo_b_d(b
, dflag
);
5066 val
= insn_get(env
, s
, ot
);
5068 gen_op_mov_v_reg(ot
, cpu_T0
, OR_EAX
);
5069 tcg_gen_movi_tl(cpu_T1
, val
);
5070 gen_op_testl_T0_T1_cc();
5071 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5074 case 0x98: /* CWDE/CBW */
5076 #ifdef TARGET_X86_64
5078 gen_op_mov_v_reg(MO_32
, cpu_T0
, R_EAX
);
5079 tcg_gen_ext32s_tl(cpu_T0
, cpu_T0
);
5080 gen_op_mov_reg_v(MO_64
, R_EAX
, cpu_T0
);
5084 gen_op_mov_v_reg(MO_16
, cpu_T0
, R_EAX
);
5085 tcg_gen_ext16s_tl(cpu_T0
, cpu_T0
);
5086 gen_op_mov_reg_v(MO_32
, R_EAX
, cpu_T0
);
5089 gen_op_mov_v_reg(MO_8
, cpu_T0
, R_EAX
);
5090 tcg_gen_ext8s_tl(cpu_T0
, cpu_T0
);
5091 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
5097 case 0x99: /* CDQ/CWD */
5099 #ifdef TARGET_X86_64
5101 gen_op_mov_v_reg(MO_64
, cpu_T0
, R_EAX
);
5102 tcg_gen_sari_tl(cpu_T0
, cpu_T0
, 63);
5103 gen_op_mov_reg_v(MO_64
, R_EDX
, cpu_T0
);
5107 gen_op_mov_v_reg(MO_32
, cpu_T0
, R_EAX
);
5108 tcg_gen_ext32s_tl(cpu_T0
, cpu_T0
);
5109 tcg_gen_sari_tl(cpu_T0
, cpu_T0
, 31);
5110 gen_op_mov_reg_v(MO_32
, R_EDX
, cpu_T0
);
5113 gen_op_mov_v_reg(MO_16
, cpu_T0
, R_EAX
);
5114 tcg_gen_ext16s_tl(cpu_T0
, cpu_T0
);
5115 tcg_gen_sari_tl(cpu_T0
, cpu_T0
, 15);
5116 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T0
);
5122 case 0x1af: /* imul Gv, Ev */
5123 case 0x69: /* imul Gv, Ev, I */
5126 modrm
= cpu_ldub_code(env
, s
->pc
++);
5127 reg
= ((modrm
>> 3) & 7) | rex_r
;
5129 s
->rip_offset
= insn_const_size(ot
);
5132 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5134 val
= insn_get(env
, s
, ot
);
5135 tcg_gen_movi_tl(cpu_T1
, val
);
5136 } else if (b
== 0x6b) {
5137 val
= (int8_t)insn_get(env
, s
, MO_8
);
5138 tcg_gen_movi_tl(cpu_T1
, val
);
5140 gen_op_mov_v_reg(ot
, cpu_T1
, reg
);
5143 #ifdef TARGET_X86_64
5145 tcg_gen_muls2_i64(cpu_regs
[reg
], cpu_T1
, cpu_T0
, cpu_T1
);
5146 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5147 tcg_gen_sari_tl(cpu_cc_src
, cpu_cc_dst
, 63);
5148 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_T1
);
5152 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
5153 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T1
);
5154 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
5155 cpu_tmp2_i32
, cpu_tmp3_i32
);
5156 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
5157 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
5158 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5159 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
5160 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
5163 tcg_gen_ext16s_tl(cpu_T0
, cpu_T0
);
5164 tcg_gen_ext16s_tl(cpu_T1
, cpu_T1
);
5165 /* XXX: use 32 bit mul which could be faster */
5166 tcg_gen_mul_tl(cpu_T0
, cpu_T0
, cpu_T1
);
5167 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
5168 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T0
);
5169 tcg_gen_sub_tl(cpu_cc_src
, cpu_T0
, cpu_tmp0
);
5170 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
5173 set_cc_op(s
, CC_OP_MULB
+ ot
);
5176 case 0x1c1: /* xadd Ev, Gv */
5177 ot
= mo_b_d(b
, dflag
);
5178 modrm
= cpu_ldub_code(env
, s
->pc
++);
5179 reg
= ((modrm
>> 3) & 7) | rex_r
;
5180 mod
= (modrm
>> 6) & 3;
5181 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
5183 rm
= (modrm
& 7) | REX_B(s
);
5184 gen_op_mov_v_reg(ot
, cpu_T1
, rm
);
5185 tcg_gen_add_tl(cpu_T0
, cpu_T0
, cpu_T1
);
5186 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
5187 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
5189 gen_lea_modrm(env
, s
, modrm
);
5190 if (s
->prefix
& PREFIX_LOCK
) {
5191 tcg_gen_atomic_fetch_add_tl(cpu_T1
, cpu_A0
, cpu_T0
,
5192 s
->mem_index
, ot
| MO_LE
);
5193 tcg_gen_add_tl(cpu_T0
, cpu_T0
, cpu_T1
);
5195 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
5196 tcg_gen_add_tl(cpu_T0
, cpu_T0
, cpu_T1
);
5197 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
5199 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
5201 gen_op_update2_cc();
5202 set_cc_op(s
, CC_OP_ADDB
+ ot
);
5205 case 0x1b1: /* cmpxchg Ev, Gv */
5207 TCGv oldv
, newv
, cmpv
;
5209 ot
= mo_b_d(b
, dflag
);
5210 modrm
= cpu_ldub_code(env
, s
->pc
++);
5211 reg
= ((modrm
>> 3) & 7) | rex_r
;
5212 mod
= (modrm
>> 6) & 3;
5213 oldv
= tcg_temp_new();
5214 newv
= tcg_temp_new();
5215 cmpv
= tcg_temp_new();
5216 gen_op_mov_v_reg(ot
, newv
, reg
);
5217 tcg_gen_mov_tl(cmpv
, cpu_regs
[R_EAX
]);
5219 if (s
->prefix
& PREFIX_LOCK
) {
5223 gen_lea_modrm(env
, s
, modrm
);
5224 tcg_gen_atomic_cmpxchg_tl(oldv
, cpu_A0
, cmpv
, newv
,
5225 s
->mem_index
, ot
| MO_LE
);
5226 gen_op_mov_reg_v(ot
, R_EAX
, oldv
);
5229 rm
= (modrm
& 7) | REX_B(s
);
5230 gen_op_mov_v_reg(ot
, oldv
, rm
);
5232 gen_lea_modrm(env
, s
, modrm
);
5233 gen_op_ld_v(s
, ot
, oldv
, cpu_A0
);
5234 rm
= 0; /* avoid warning */
5238 /* store value = (old == cmp ? new : old); */
5239 tcg_gen_movcond_tl(TCG_COND_EQ
, newv
, oldv
, cmpv
, newv
, oldv
);
5241 gen_op_mov_reg_v(ot
, R_EAX
, oldv
);
5242 gen_op_mov_reg_v(ot
, rm
, newv
);
5244 /* Perform an unconditional store cycle like physical cpu;
5245 must be before changing accumulator to ensure
5246 idempotency if the store faults and the instruction
5248 gen_op_st_v(s
, ot
, newv
, cpu_A0
);
5249 gen_op_mov_reg_v(ot
, R_EAX
, oldv
);
5252 tcg_gen_mov_tl(cpu_cc_src
, oldv
);
5253 tcg_gen_mov_tl(cpu_cc_srcT
, cmpv
);
5254 tcg_gen_sub_tl(cpu_cc_dst
, cmpv
, oldv
);
5255 set_cc_op(s
, CC_OP_SUBB
+ ot
);
5256 tcg_temp_free(oldv
);
5257 tcg_temp_free(newv
);
5258 tcg_temp_free(cmpv
);
5261 case 0x1c7: /* cmpxchg8b */
5262 modrm
= cpu_ldub_code(env
, s
->pc
++);
5263 mod
= (modrm
>> 6) & 3;
5264 if ((mod
== 3) || ((modrm
& 0x38) != 0x8))
5266 #ifdef TARGET_X86_64
5267 if (dflag
== MO_64
) {
5268 if (!(s
->cpuid_ext_features
& CPUID_EXT_CX16
))
5270 gen_lea_modrm(env
, s
, modrm
);
5271 if ((s
->prefix
& PREFIX_LOCK
) && parallel_cpus
) {
5272 gen_helper_cmpxchg16b(cpu_env
, cpu_A0
);
5274 gen_helper_cmpxchg16b_unlocked(cpu_env
, cpu_A0
);
5279 if (!(s
->cpuid_features
& CPUID_CX8
))
5281 gen_lea_modrm(env
, s
, modrm
);
5282 if ((s
->prefix
& PREFIX_LOCK
) && parallel_cpus
) {
5283 gen_helper_cmpxchg8b(cpu_env
, cpu_A0
);
5285 gen_helper_cmpxchg8b_unlocked(cpu_env
, cpu_A0
);
5288 set_cc_op(s
, CC_OP_EFLAGS
);
5291 /**************************/
5293 case 0x50 ... 0x57: /* push */
5294 gen_op_mov_v_reg(MO_32
, cpu_T0
, (b
& 7) | REX_B(s
));
5295 gen_push_v(s
, cpu_T0
);
5297 case 0x58 ... 0x5f: /* pop */
5299 /* NOTE: order is important for pop %sp */
5300 gen_pop_update(s
, ot
);
5301 gen_op_mov_reg_v(ot
, (b
& 7) | REX_B(s
), cpu_T0
);
5303 case 0x60: /* pusha */
5308 case 0x61: /* popa */
5313 case 0x68: /* push Iv */
5315 ot
= mo_pushpop(s
, dflag
);
5317 val
= insn_get(env
, s
, ot
);
5319 val
= (int8_t)insn_get(env
, s
, MO_8
);
5320 tcg_gen_movi_tl(cpu_T0
, val
);
5321 gen_push_v(s
, cpu_T0
);
5323 case 0x8f: /* pop Ev */
5324 modrm
= cpu_ldub_code(env
, s
->pc
++);
5325 mod
= (modrm
>> 6) & 3;
5328 /* NOTE: order is important for pop %sp */
5329 gen_pop_update(s
, ot
);
5330 rm
= (modrm
& 7) | REX_B(s
);
5331 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
5333 /* NOTE: order is important too for MMU exceptions */
5334 s
->popl_esp_hack
= 1 << ot
;
5335 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5336 s
->popl_esp_hack
= 0;
5337 gen_pop_update(s
, ot
);
5340 case 0xc8: /* enter */
5343 val
= cpu_lduw_code(env
, s
->pc
);
5345 level
= cpu_ldub_code(env
, s
->pc
++);
5346 gen_enter(s
, val
, level
);
5349 case 0xc9: /* leave */
5352 case 0x06: /* push es */
5353 case 0x0e: /* push cs */
5354 case 0x16: /* push ss */
5355 case 0x1e: /* push ds */
5358 gen_op_movl_T0_seg(b
>> 3);
5359 gen_push_v(s
, cpu_T0
);
5361 case 0x1a0: /* push fs */
5362 case 0x1a8: /* push gs */
5363 gen_op_movl_T0_seg((b
>> 3) & 7);
5364 gen_push_v(s
, cpu_T0
);
5366 case 0x07: /* pop es */
5367 case 0x17: /* pop ss */
5368 case 0x1f: /* pop ds */
5373 gen_movl_seg_T0(s
, reg
);
5374 gen_pop_update(s
, ot
);
5375 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5377 gen_jmp_im(s
->pc
- s
->cs_base
);
5380 gen_eob_inhibit_irq(s
, true);
5386 case 0x1a1: /* pop fs */
5387 case 0x1a9: /* pop gs */
5389 gen_movl_seg_T0(s
, (b
>> 3) & 7);
5390 gen_pop_update(s
, ot
);
5392 gen_jmp_im(s
->pc
- s
->cs_base
);
5397 /**************************/
5400 case 0x89: /* mov Gv, Ev */
5401 ot
= mo_b_d(b
, dflag
);
5402 modrm
= cpu_ldub_code(env
, s
->pc
++);
5403 reg
= ((modrm
>> 3) & 7) | rex_r
;
5405 /* generate a generic store */
5406 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
5409 case 0xc7: /* mov Ev, Iv */
5410 ot
= mo_b_d(b
, dflag
);
5411 modrm
= cpu_ldub_code(env
, s
->pc
++);
5412 mod
= (modrm
>> 6) & 3;
5414 s
->rip_offset
= insn_const_size(ot
);
5415 gen_lea_modrm(env
, s
, modrm
);
5417 val
= insn_get(env
, s
, ot
);
5418 tcg_gen_movi_tl(cpu_T0
, val
);
5420 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
5422 gen_op_mov_reg_v(ot
, (modrm
& 7) | REX_B(s
), cpu_T0
);
5426 case 0x8b: /* mov Ev, Gv */
5427 ot
= mo_b_d(b
, dflag
);
5428 modrm
= cpu_ldub_code(env
, s
->pc
++);
5429 reg
= ((modrm
>> 3) & 7) | rex_r
;
5431 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5432 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
5434 case 0x8e: /* mov seg, Gv */
5435 modrm
= cpu_ldub_code(env
, s
->pc
++);
5436 reg
= (modrm
>> 3) & 7;
5437 if (reg
>= 6 || reg
== R_CS
)
5439 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
5440 gen_movl_seg_T0(s
, reg
);
5441 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5443 gen_jmp_im(s
->pc
- s
->cs_base
);
5446 gen_eob_inhibit_irq(s
, true);
5452 case 0x8c: /* mov Gv, seg */
5453 modrm
= cpu_ldub_code(env
, s
->pc
++);
5454 reg
= (modrm
>> 3) & 7;
5455 mod
= (modrm
>> 6) & 3;
5458 gen_op_movl_T0_seg(reg
);
5459 ot
= mod
== 3 ? dflag
: MO_16
;
5460 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5463 case 0x1b6: /* movzbS Gv, Eb */
5464 case 0x1b7: /* movzwS Gv, Eb */
5465 case 0x1be: /* movsbS Gv, Eb */
5466 case 0x1bf: /* movswS Gv, Eb */
5471 /* d_ot is the size of destination */
5473 /* ot is the size of source */
5474 ot
= (b
& 1) + MO_8
;
5475 /* s_ot is the sign+size of source */
5476 s_ot
= b
& 8 ? MO_SIGN
| ot
: ot
;
5478 modrm
= cpu_ldub_code(env
, s
->pc
++);
5479 reg
= ((modrm
>> 3) & 7) | rex_r
;
5480 mod
= (modrm
>> 6) & 3;
5481 rm
= (modrm
& 7) | REX_B(s
);
5484 if (s_ot
== MO_SB
&& byte_reg_is_xH(rm
)) {
5485 tcg_gen_sextract_tl(cpu_T0
, cpu_regs
[rm
- 4], 8, 8);
5487 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
5490 tcg_gen_ext8u_tl(cpu_T0
, cpu_T0
);
5493 tcg_gen_ext8s_tl(cpu_T0
, cpu_T0
);
5496 tcg_gen_ext16u_tl(cpu_T0
, cpu_T0
);
5500 tcg_gen_ext16s_tl(cpu_T0
, cpu_T0
);
5504 gen_op_mov_reg_v(d_ot
, reg
, cpu_T0
);
5506 gen_lea_modrm(env
, s
, modrm
);
5507 gen_op_ld_v(s
, s_ot
, cpu_T0
, cpu_A0
);
5508 gen_op_mov_reg_v(d_ot
, reg
, cpu_T0
);
5513 case 0x8d: /* lea */
5514 modrm
= cpu_ldub_code(env
, s
->pc
++);
5515 mod
= (modrm
>> 6) & 3;
5518 reg
= ((modrm
>> 3) & 7) | rex_r
;
5520 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
5521 TCGv ea
= gen_lea_modrm_1(a
);
5522 gen_lea_v_seg(s
, s
->aflag
, ea
, -1, -1);
5523 gen_op_mov_reg_v(dflag
, reg
, cpu_A0
);
5527 case 0xa0: /* mov EAX, Ov */
5529 case 0xa2: /* mov Ov, EAX */
5532 target_ulong offset_addr
;
5534 ot
= mo_b_d(b
, dflag
);
5536 #ifdef TARGET_X86_64
5538 offset_addr
= cpu_ldq_code(env
, s
->pc
);
5543 offset_addr
= insn_get(env
, s
, s
->aflag
);
5546 tcg_gen_movi_tl(cpu_A0
, offset_addr
);
5547 gen_add_A0_ds_seg(s
);
5549 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
5550 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T0
);
5552 gen_op_mov_v_reg(ot
, cpu_T0
, R_EAX
);
5553 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
5557 case 0xd7: /* xlat */
5558 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EBX
]);
5559 tcg_gen_ext8u_tl(cpu_T0
, cpu_regs
[R_EAX
]);
5560 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_T0
);
5561 gen_extu(s
->aflag
, cpu_A0
);
5562 gen_add_A0_ds_seg(s
);
5563 gen_op_ld_v(s
, MO_8
, cpu_T0
, cpu_A0
);
5564 gen_op_mov_reg_v(MO_8
, R_EAX
, cpu_T0
);
5566 case 0xb0 ... 0xb7: /* mov R, Ib */
5567 val
= insn_get(env
, s
, MO_8
);
5568 tcg_gen_movi_tl(cpu_T0
, val
);
5569 gen_op_mov_reg_v(MO_8
, (b
& 7) | REX_B(s
), cpu_T0
);
5571 case 0xb8 ... 0xbf: /* mov R, Iv */
5572 #ifdef TARGET_X86_64
5573 if (dflag
== MO_64
) {
5576 tmp
= cpu_ldq_code(env
, s
->pc
);
5578 reg
= (b
& 7) | REX_B(s
);
5579 tcg_gen_movi_tl(cpu_T0
, tmp
);
5580 gen_op_mov_reg_v(MO_64
, reg
, cpu_T0
);
5585 val
= insn_get(env
, s
, ot
);
5586 reg
= (b
& 7) | REX_B(s
);
5587 tcg_gen_movi_tl(cpu_T0
, val
);
5588 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
5592 case 0x91 ... 0x97: /* xchg R, EAX */
5595 reg
= (b
& 7) | REX_B(s
);
5599 case 0x87: /* xchg Ev, Gv */
5600 ot
= mo_b_d(b
, dflag
);
5601 modrm
= cpu_ldub_code(env
, s
->pc
++);
5602 reg
= ((modrm
>> 3) & 7) | rex_r
;
5603 mod
= (modrm
>> 6) & 3;
5605 rm
= (modrm
& 7) | REX_B(s
);
5607 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
5608 gen_op_mov_v_reg(ot
, cpu_T1
, rm
);
5609 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
5610 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
5612 gen_lea_modrm(env
, s
, modrm
);
5613 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
5614 /* for xchg, lock is implicit */
5615 tcg_gen_atomic_xchg_tl(cpu_T1
, cpu_A0
, cpu_T0
,
5616 s
->mem_index
, ot
| MO_LE
);
5617 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
5620 case 0xc4: /* les Gv */
5621 /* In CODE64 this is VEX3; see above. */
5624 case 0xc5: /* lds Gv */
5625 /* In CODE64 this is VEX2; see above. */
5628 case 0x1b2: /* lss Gv */
5631 case 0x1b4: /* lfs Gv */
5634 case 0x1b5: /* lgs Gv */
5637 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
5638 modrm
= cpu_ldub_code(env
, s
->pc
++);
5639 reg
= ((modrm
>> 3) & 7) | rex_r
;
5640 mod
= (modrm
>> 6) & 3;
5643 gen_lea_modrm(env
, s
, modrm
);
5644 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
5645 gen_add_A0_im(s
, 1 << ot
);
5646 /* load the segment first to handle exceptions properly */
5647 gen_op_ld_v(s
, MO_16
, cpu_T0
, cpu_A0
);
5648 gen_movl_seg_T0(s
, op
);
5649 /* then put the data */
5650 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
5652 gen_jmp_im(s
->pc
- s
->cs_base
);
5657 /************************/
5665 ot
= mo_b_d(b
, dflag
);
5666 modrm
= cpu_ldub_code(env
, s
->pc
++);
5667 mod
= (modrm
>> 6) & 3;
5668 op
= (modrm
>> 3) & 7;
5674 gen_lea_modrm(env
, s
, modrm
);
5677 opreg
= (modrm
& 7) | REX_B(s
);
5682 gen_shift(s
, op
, ot
, opreg
, OR_ECX
);
5685 shift
= cpu_ldub_code(env
, s
->pc
++);
5687 gen_shifti(s
, op
, ot
, opreg
, shift
);
5702 case 0x1a4: /* shld imm */
5706 case 0x1a5: /* shld cl */
5710 case 0x1ac: /* shrd imm */
5714 case 0x1ad: /* shrd cl */
5719 modrm
= cpu_ldub_code(env
, s
->pc
++);
5720 mod
= (modrm
>> 6) & 3;
5721 rm
= (modrm
& 7) | REX_B(s
);
5722 reg
= ((modrm
>> 3) & 7) | rex_r
;
5724 gen_lea_modrm(env
, s
, modrm
);
5729 gen_op_mov_v_reg(ot
, cpu_T1
, reg
);
5732 TCGv imm
= tcg_const_tl(cpu_ldub_code(env
, s
->pc
++));
5733 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, imm
);
5736 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, cpu_regs
[R_ECX
]);
5740 /************************/
5743 if (s
->flags
& (HF_EM_MASK
| HF_TS_MASK
)) {
5744 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5745 /* XXX: what to do if illegal op ? */
5746 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
5749 modrm
= cpu_ldub_code(env
, s
->pc
++);
5750 mod
= (modrm
>> 6) & 3;
5752 op
= ((b
& 7) << 3) | ((modrm
>> 3) & 7);
5755 gen_lea_modrm(env
, s
, modrm
);
5757 case 0x00 ... 0x07: /* fxxxs */
5758 case 0x10 ... 0x17: /* fixxxl */
5759 case 0x20 ... 0x27: /* fxxxl */
5760 case 0x30 ... 0x37: /* fixxx */
5767 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5768 s
->mem_index
, MO_LEUL
);
5769 gen_helper_flds_FT0(cpu_env
, cpu_tmp2_i32
);
5772 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5773 s
->mem_index
, MO_LEUL
);
5774 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
5777 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
5778 s
->mem_index
, MO_LEQ
);
5779 gen_helper_fldl_FT0(cpu_env
, cpu_tmp1_i64
);
5783 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5784 s
->mem_index
, MO_LESW
);
5785 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
5789 gen_helper_fp_arith_ST0_FT0(op1
);
5791 /* fcomp needs pop */
5792 gen_helper_fpop(cpu_env
);
5796 case 0x08: /* flds */
5797 case 0x0a: /* fsts */
5798 case 0x0b: /* fstps */
5799 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5800 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5801 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5806 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5807 s
->mem_index
, MO_LEUL
);
5808 gen_helper_flds_ST0(cpu_env
, cpu_tmp2_i32
);
5811 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5812 s
->mem_index
, MO_LEUL
);
5813 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
5816 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
5817 s
->mem_index
, MO_LEQ
);
5818 gen_helper_fldl_ST0(cpu_env
, cpu_tmp1_i64
);
5822 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5823 s
->mem_index
, MO_LESW
);
5824 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
5829 /* XXX: the corresponding CPUID bit must be tested ! */
5832 gen_helper_fisttl_ST0(cpu_tmp2_i32
, cpu_env
);
5833 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5834 s
->mem_index
, MO_LEUL
);
5837 gen_helper_fisttll_ST0(cpu_tmp1_i64
, cpu_env
);
5838 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
5839 s
->mem_index
, MO_LEQ
);
5843 gen_helper_fistt_ST0(cpu_tmp2_i32
, cpu_env
);
5844 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5845 s
->mem_index
, MO_LEUW
);
5848 gen_helper_fpop(cpu_env
);
5853 gen_helper_fsts_ST0(cpu_tmp2_i32
, cpu_env
);
5854 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5855 s
->mem_index
, MO_LEUL
);
5858 gen_helper_fistl_ST0(cpu_tmp2_i32
, cpu_env
);
5859 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5860 s
->mem_index
, MO_LEUL
);
5863 gen_helper_fstl_ST0(cpu_tmp1_i64
, cpu_env
);
5864 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
5865 s
->mem_index
, MO_LEQ
);
5869 gen_helper_fist_ST0(cpu_tmp2_i32
, cpu_env
);
5870 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5871 s
->mem_index
, MO_LEUW
);
5875 gen_helper_fpop(cpu_env
);
5879 case 0x0c: /* fldenv mem */
5880 gen_helper_fldenv(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5882 case 0x0d: /* fldcw mem */
5883 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5884 s
->mem_index
, MO_LEUW
);
5885 gen_helper_fldcw(cpu_env
, cpu_tmp2_i32
);
5887 case 0x0e: /* fnstenv mem */
5888 gen_helper_fstenv(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5890 case 0x0f: /* fnstcw mem */
5891 gen_helper_fnstcw(cpu_tmp2_i32
, cpu_env
);
5892 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5893 s
->mem_index
, MO_LEUW
);
5895 case 0x1d: /* fldt mem */
5896 gen_helper_fldt_ST0(cpu_env
, cpu_A0
);
5898 case 0x1f: /* fstpt mem */
5899 gen_helper_fstt_ST0(cpu_env
, cpu_A0
);
5900 gen_helper_fpop(cpu_env
);
5902 case 0x2c: /* frstor mem */
5903 gen_helper_frstor(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5905 case 0x2e: /* fnsave mem */
5906 gen_helper_fsave(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5908 case 0x2f: /* fnstsw mem */
5909 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
5910 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5911 s
->mem_index
, MO_LEUW
);
5913 case 0x3c: /* fbld */
5914 gen_helper_fbld_ST0(cpu_env
, cpu_A0
);
5916 case 0x3e: /* fbstp */
5917 gen_helper_fbst_ST0(cpu_env
, cpu_A0
);
5918 gen_helper_fpop(cpu_env
);
5920 case 0x3d: /* fildll */
5921 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
5922 gen_helper_fildll_ST0(cpu_env
, cpu_tmp1_i64
);
5924 case 0x3f: /* fistpll */
5925 gen_helper_fistll_ST0(cpu_tmp1_i64
, cpu_env
);
5926 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
5927 gen_helper_fpop(cpu_env
);
5933 /* register float ops */
5937 case 0x08: /* fld sti */
5938 gen_helper_fpush(cpu_env
);
5939 gen_helper_fmov_ST0_STN(cpu_env
,
5940 tcg_const_i32((opreg
+ 1) & 7));
5942 case 0x09: /* fxchg sti */
5943 case 0x29: /* fxchg4 sti, undocumented op */
5944 case 0x39: /* fxchg7 sti, undocumented op */
5945 gen_helper_fxchg_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
5947 case 0x0a: /* grp d9/2 */
5950 /* check exceptions (FreeBSD FPU probe) */
5951 gen_helper_fwait(cpu_env
);
5957 case 0x0c: /* grp d9/4 */
5960 gen_helper_fchs_ST0(cpu_env
);
5963 gen_helper_fabs_ST0(cpu_env
);
5966 gen_helper_fldz_FT0(cpu_env
);
5967 gen_helper_fcom_ST0_FT0(cpu_env
);
5970 gen_helper_fxam_ST0(cpu_env
);
5976 case 0x0d: /* grp d9/5 */
5980 gen_helper_fpush(cpu_env
);
5981 gen_helper_fld1_ST0(cpu_env
);
5984 gen_helper_fpush(cpu_env
);
5985 gen_helper_fldl2t_ST0(cpu_env
);
5988 gen_helper_fpush(cpu_env
);
5989 gen_helper_fldl2e_ST0(cpu_env
);
5992 gen_helper_fpush(cpu_env
);
5993 gen_helper_fldpi_ST0(cpu_env
);
5996 gen_helper_fpush(cpu_env
);
5997 gen_helper_fldlg2_ST0(cpu_env
);
6000 gen_helper_fpush(cpu_env
);
6001 gen_helper_fldln2_ST0(cpu_env
);
6004 gen_helper_fpush(cpu_env
);
6005 gen_helper_fldz_ST0(cpu_env
);
6012 case 0x0e: /* grp d9/6 */
6015 gen_helper_f2xm1(cpu_env
);
6018 gen_helper_fyl2x(cpu_env
);
6021 gen_helper_fptan(cpu_env
);
6023 case 3: /* fpatan */
6024 gen_helper_fpatan(cpu_env
);
6026 case 4: /* fxtract */
6027 gen_helper_fxtract(cpu_env
);
6029 case 5: /* fprem1 */
6030 gen_helper_fprem1(cpu_env
);
6032 case 6: /* fdecstp */
6033 gen_helper_fdecstp(cpu_env
);
6036 case 7: /* fincstp */
6037 gen_helper_fincstp(cpu_env
);
6041 case 0x0f: /* grp d9/7 */
6044 gen_helper_fprem(cpu_env
);
6046 case 1: /* fyl2xp1 */
6047 gen_helper_fyl2xp1(cpu_env
);
6050 gen_helper_fsqrt(cpu_env
);
6052 case 3: /* fsincos */
6053 gen_helper_fsincos(cpu_env
);
6055 case 5: /* fscale */
6056 gen_helper_fscale(cpu_env
);
6058 case 4: /* frndint */
6059 gen_helper_frndint(cpu_env
);
6062 gen_helper_fsin(cpu_env
);
6066 gen_helper_fcos(cpu_env
);
6070 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6071 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6072 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6078 gen_helper_fp_arith_STN_ST0(op1
, opreg
);
6080 gen_helper_fpop(cpu_env
);
6082 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6083 gen_helper_fp_arith_ST0_FT0(op1
);
6087 case 0x02: /* fcom */
6088 case 0x22: /* fcom2, undocumented op */
6089 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6090 gen_helper_fcom_ST0_FT0(cpu_env
);
6092 case 0x03: /* fcomp */
6093 case 0x23: /* fcomp3, undocumented op */
6094 case 0x32: /* fcomp5, undocumented op */
6095 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6096 gen_helper_fcom_ST0_FT0(cpu_env
);
6097 gen_helper_fpop(cpu_env
);
6099 case 0x15: /* da/5 */
6101 case 1: /* fucompp */
6102 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6103 gen_helper_fucom_ST0_FT0(cpu_env
);
6104 gen_helper_fpop(cpu_env
);
6105 gen_helper_fpop(cpu_env
);
6113 case 0: /* feni (287 only, just do nop here) */
6115 case 1: /* fdisi (287 only, just do nop here) */
6118 gen_helper_fclex(cpu_env
);
6120 case 3: /* fninit */
6121 gen_helper_fninit(cpu_env
);
6123 case 4: /* fsetpm (287 only, just do nop here) */
6129 case 0x1d: /* fucomi */
6130 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6133 gen_update_cc_op(s
);
6134 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6135 gen_helper_fucomi_ST0_FT0(cpu_env
);
6136 set_cc_op(s
, CC_OP_EFLAGS
);
6138 case 0x1e: /* fcomi */
6139 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6142 gen_update_cc_op(s
);
6143 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6144 gen_helper_fcomi_ST0_FT0(cpu_env
);
6145 set_cc_op(s
, CC_OP_EFLAGS
);
6147 case 0x28: /* ffree sti */
6148 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6150 case 0x2a: /* fst sti */
6151 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6153 case 0x2b: /* fstp sti */
6154 case 0x0b: /* fstp1 sti, undocumented op */
6155 case 0x3a: /* fstp8 sti, undocumented op */
6156 case 0x3b: /* fstp9 sti, undocumented op */
6157 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6158 gen_helper_fpop(cpu_env
);
6160 case 0x2c: /* fucom st(i) */
6161 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6162 gen_helper_fucom_ST0_FT0(cpu_env
);
6164 case 0x2d: /* fucomp st(i) */
6165 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6166 gen_helper_fucom_ST0_FT0(cpu_env
);
6167 gen_helper_fpop(cpu_env
);
6169 case 0x33: /* de/3 */
6171 case 1: /* fcompp */
6172 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6173 gen_helper_fcom_ST0_FT0(cpu_env
);
6174 gen_helper_fpop(cpu_env
);
6175 gen_helper_fpop(cpu_env
);
6181 case 0x38: /* ffreep sti, undocumented op */
6182 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6183 gen_helper_fpop(cpu_env
);
6185 case 0x3c: /* df/4 */
6188 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
6189 tcg_gen_extu_i32_tl(cpu_T0
, cpu_tmp2_i32
);
6190 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
6196 case 0x3d: /* fucomip */
6197 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6200 gen_update_cc_op(s
);
6201 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6202 gen_helper_fucomi_ST0_FT0(cpu_env
);
6203 gen_helper_fpop(cpu_env
);
6204 set_cc_op(s
, CC_OP_EFLAGS
);
6206 case 0x3e: /* fcomip */
6207 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6210 gen_update_cc_op(s
);
6211 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6212 gen_helper_fcomi_ST0_FT0(cpu_env
);
6213 gen_helper_fpop(cpu_env
);
6214 set_cc_op(s
, CC_OP_EFLAGS
);
6216 case 0x10 ... 0x13: /* fcmovxx */
6221 static const uint8_t fcmov_cc
[8] = {
6228 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6231 op1
= fcmov_cc
[op
& 3] | (((op
>> 3) & 1) ^ 1);
6232 l1
= gen_new_label();
6233 gen_jcc1_noeob(s
, op1
, l1
);
6234 gen_helper_fmov_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6243 /************************/
6246 case 0xa4: /* movsS */
6248 ot
= mo_b_d(b
, dflag
);
6249 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6250 gen_repz_movs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6256 case 0xaa: /* stosS */
6258 ot
= mo_b_d(b
, dflag
);
6259 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6260 gen_repz_stos(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6265 case 0xac: /* lodsS */
6267 ot
= mo_b_d(b
, dflag
);
6268 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6269 gen_repz_lods(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6274 case 0xae: /* scasS */
6276 ot
= mo_b_d(b
, dflag
);
6277 if (prefixes
& PREFIX_REPNZ
) {
6278 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6279 } else if (prefixes
& PREFIX_REPZ
) {
6280 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6286 case 0xa6: /* cmpsS */
6288 ot
= mo_b_d(b
, dflag
);
6289 if (prefixes
& PREFIX_REPNZ
) {
6290 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6291 } else if (prefixes
& PREFIX_REPZ
) {
6292 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6297 case 0x6c: /* insS */
6299 ot
= mo_b_d32(b
, dflag
);
6300 tcg_gen_ext16u_tl(cpu_T0
, cpu_regs
[R_EDX
]);
6301 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6302 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
) | 4);
6303 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6304 gen_repz_ins(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6307 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6308 gen_jmp(s
, s
->pc
- s
->cs_base
);
6312 case 0x6e: /* outsS */
6314 ot
= mo_b_d32(b
, dflag
);
6315 tcg_gen_ext16u_tl(cpu_T0
, cpu_regs
[R_EDX
]);
6316 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6317 svm_is_rep(prefixes
) | 4);
6318 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6319 gen_repz_outs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6322 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6323 gen_jmp(s
, s
->pc
- s
->cs_base
);
6328 /************************/
6333 ot
= mo_b_d32(b
, dflag
);
6334 val
= cpu_ldub_code(env
, s
->pc
++);
6335 tcg_gen_movi_tl(cpu_T0
, val
);
6336 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6337 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6338 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6341 tcg_gen_movi_i32(cpu_tmp2_i32
, val
);
6342 gen_helper_in_func(ot
, cpu_T1
, cpu_tmp2_i32
);
6343 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T1
);
6344 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6345 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6347 gen_jmp(s
, s
->pc
- s
->cs_base
);
6352 ot
= mo_b_d32(b
, dflag
);
6353 val
= cpu_ldub_code(env
, s
->pc
++);
6354 tcg_gen_movi_tl(cpu_T0
, val
);
6355 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6356 svm_is_rep(prefixes
));
6357 gen_op_mov_v_reg(ot
, cpu_T1
, R_EAX
);
6359 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6362 tcg_gen_movi_i32(cpu_tmp2_i32
, val
);
6363 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T1
);
6364 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6365 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6366 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6368 gen_jmp(s
, s
->pc
- s
->cs_base
);
6373 ot
= mo_b_d32(b
, dflag
);
6374 tcg_gen_ext16u_tl(cpu_T0
, cpu_regs
[R_EDX
]);
6375 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6376 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6377 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6380 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
6381 gen_helper_in_func(ot
, cpu_T1
, cpu_tmp2_i32
);
6382 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T1
);
6383 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6384 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6386 gen_jmp(s
, s
->pc
- s
->cs_base
);
6391 ot
= mo_b_d32(b
, dflag
);
6392 tcg_gen_ext16u_tl(cpu_T0
, cpu_regs
[R_EDX
]);
6393 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6394 svm_is_rep(prefixes
));
6395 gen_op_mov_v_reg(ot
, cpu_T1
, R_EAX
);
6397 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6400 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
6401 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T1
);
6402 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6403 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6404 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6406 gen_jmp(s
, s
->pc
- s
->cs_base
);
6410 /************************/
6412 case 0xc2: /* ret im */
6413 val
= cpu_ldsw_code(env
, s
->pc
);
6416 gen_stack_update(s
, val
+ (1 << ot
));
6417 /* Note that gen_pop_T0 uses a zero-extending load. */
6418 gen_op_jmp_v(cpu_T0
);
6422 case 0xc3: /* ret */
6424 gen_pop_update(s
, ot
);
6425 /* Note that gen_pop_T0 uses a zero-extending load. */
6426 gen_op_jmp_v(cpu_T0
);
6430 case 0xca: /* lret im */
6431 val
= cpu_ldsw_code(env
, s
->pc
);
6434 if (s
->pe
&& !s
->vm86
) {
6435 gen_update_cc_op(s
);
6436 gen_jmp_im(pc_start
- s
->cs_base
);
6437 gen_helper_lret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6438 tcg_const_i32(val
));
6442 gen_op_ld_v(s
, dflag
, cpu_T0
, cpu_A0
);
6443 /* NOTE: keeping EIP updated is not a problem in case of
6445 gen_op_jmp_v(cpu_T0
);
6447 gen_add_A0_im(s
, 1 << dflag
);
6448 gen_op_ld_v(s
, dflag
, cpu_T0
, cpu_A0
);
6449 gen_op_movl_seg_T0_vm(R_CS
);
6450 /* add stack offset */
6451 gen_stack_update(s
, val
+ (2 << dflag
));
6455 case 0xcb: /* lret */
6458 case 0xcf: /* iret */
6459 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IRET
);
6462 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6463 set_cc_op(s
, CC_OP_EFLAGS
);
6464 } else if (s
->vm86
) {
6466 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6468 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6469 set_cc_op(s
, CC_OP_EFLAGS
);
6472 gen_helper_iret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6473 tcg_const_i32(s
->pc
- s
->cs_base
));
6474 set_cc_op(s
, CC_OP_EFLAGS
);
6478 case 0xe8: /* call im */
6480 if (dflag
!= MO_16
) {
6481 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6483 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6485 next_eip
= s
->pc
- s
->cs_base
;
6487 if (dflag
== MO_16
) {
6489 } else if (!CODE64(s
)) {
6492 tcg_gen_movi_tl(cpu_T0
, next_eip
);
6493 gen_push_v(s
, cpu_T0
);
6498 case 0x9a: /* lcall im */
6500 unsigned int selector
, offset
;
6505 offset
= insn_get(env
, s
, ot
);
6506 selector
= insn_get(env
, s
, MO_16
);
6508 tcg_gen_movi_tl(cpu_T0
, selector
);
6509 tcg_gen_movi_tl(cpu_T1
, offset
);
6512 case 0xe9: /* jmp im */
6513 if (dflag
!= MO_16
) {
6514 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6516 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6518 tval
+= s
->pc
- s
->cs_base
;
6519 if (dflag
== MO_16
) {
6521 } else if (!CODE64(s
)) {
6527 case 0xea: /* ljmp im */
6529 unsigned int selector
, offset
;
6534 offset
= insn_get(env
, s
, ot
);
6535 selector
= insn_get(env
, s
, MO_16
);
6537 tcg_gen_movi_tl(cpu_T0
, selector
);
6538 tcg_gen_movi_tl(cpu_T1
, offset
);
6541 case 0xeb: /* jmp Jb */
6542 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6543 tval
+= s
->pc
- s
->cs_base
;
6544 if (dflag
== MO_16
) {
6549 case 0x70 ... 0x7f: /* jcc Jb */
6550 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6552 case 0x180 ... 0x18f: /* jcc Jv */
6553 if (dflag
!= MO_16
) {
6554 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6556 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6559 next_eip
= s
->pc
- s
->cs_base
;
6561 if (dflag
== MO_16
) {
6565 gen_jcc(s
, b
, tval
, next_eip
);
6568 case 0x190 ... 0x19f: /* setcc Gv */
6569 modrm
= cpu_ldub_code(env
, s
->pc
++);
6570 gen_setcc1(s
, b
, cpu_T0
);
6571 gen_ldst_modrm(env
, s
, modrm
, MO_8
, OR_TMP0
, 1);
6573 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6574 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6578 modrm
= cpu_ldub_code(env
, s
->pc
++);
6579 reg
= ((modrm
>> 3) & 7) | rex_r
;
6580 gen_cmovcc1(env
, s
, ot
, b
, modrm
, reg
);
6583 /************************/
6585 case 0x9c: /* pushf */
6586 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_PUSHF
);
6587 if (s
->vm86
&& s
->iopl
!= 3) {
6588 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6590 gen_update_cc_op(s
);
6591 gen_helper_read_eflags(cpu_T0
, cpu_env
);
6592 gen_push_v(s
, cpu_T0
);
6595 case 0x9d: /* popf */
6596 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_POPF
);
6597 if (s
->vm86
&& s
->iopl
!= 3) {
6598 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6602 if (dflag
!= MO_16
) {
6603 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6604 tcg_const_i32((TF_MASK
| AC_MASK
|
6609 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6610 tcg_const_i32((TF_MASK
| AC_MASK
|
6612 IF_MASK
| IOPL_MASK
)
6616 if (s
->cpl
<= s
->iopl
) {
6617 if (dflag
!= MO_16
) {
6618 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6619 tcg_const_i32((TF_MASK
|
6625 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6626 tcg_const_i32((TF_MASK
|
6634 if (dflag
!= MO_16
) {
6635 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6636 tcg_const_i32((TF_MASK
| AC_MASK
|
6637 ID_MASK
| NT_MASK
)));
6639 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6640 tcg_const_i32((TF_MASK
| AC_MASK
|
6646 gen_pop_update(s
, ot
);
6647 set_cc_op(s
, CC_OP_EFLAGS
);
6648 /* abort translation because TF/AC flag may change */
6649 gen_jmp_im(s
->pc
- s
->cs_base
);
6653 case 0x9e: /* sahf */
6654 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6656 gen_op_mov_v_reg(MO_8
, cpu_T0
, R_AH
);
6657 gen_compute_eflags(s
);
6658 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, CC_O
);
6659 tcg_gen_andi_tl(cpu_T0
, cpu_T0
, CC_S
| CC_Z
| CC_A
| CC_P
| CC_C
);
6660 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, cpu_T0
);
6662 case 0x9f: /* lahf */
6663 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6665 gen_compute_eflags(s
);
6666 /* Note: gen_compute_eflags() only gives the condition codes */
6667 tcg_gen_ori_tl(cpu_T0
, cpu_cc_src
, 0x02);
6668 gen_op_mov_reg_v(MO_8
, R_AH
, cpu_T0
);
6670 case 0xf5: /* cmc */
6671 gen_compute_eflags(s
);
6672 tcg_gen_xori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6674 case 0xf8: /* clc */
6675 gen_compute_eflags(s
);
6676 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_C
);
6678 case 0xf9: /* stc */
6679 gen_compute_eflags(s
);
6680 tcg_gen_ori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6682 case 0xfc: /* cld */
6683 tcg_gen_movi_i32(cpu_tmp2_i32
, 1);
6684 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6686 case 0xfd: /* std */
6687 tcg_gen_movi_i32(cpu_tmp2_i32
, -1);
6688 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6691 /************************/
6692 /* bit operations */
6693 case 0x1ba: /* bt/bts/btr/btc Gv, im */
6695 modrm
= cpu_ldub_code(env
, s
->pc
++);
6696 op
= (modrm
>> 3) & 7;
6697 mod
= (modrm
>> 6) & 3;
6698 rm
= (modrm
& 7) | REX_B(s
);
6701 gen_lea_modrm(env
, s
, modrm
);
6702 if (!(s
->prefix
& PREFIX_LOCK
)) {
6703 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
6706 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
6709 val
= cpu_ldub_code(env
, s
->pc
++);
6710 tcg_gen_movi_tl(cpu_T1
, val
);
6715 case 0x1a3: /* bt Gv, Ev */
6718 case 0x1ab: /* bts */
6721 case 0x1b3: /* btr */
6724 case 0x1bb: /* btc */
6728 modrm
= cpu_ldub_code(env
, s
->pc
++);
6729 reg
= ((modrm
>> 3) & 7) | rex_r
;
6730 mod
= (modrm
>> 6) & 3;
6731 rm
= (modrm
& 7) | REX_B(s
);
6732 gen_op_mov_v_reg(MO_32
, cpu_T1
, reg
);
6734 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
6735 /* specific case: we need to add a displacement */
6736 gen_exts(ot
, cpu_T1
);
6737 tcg_gen_sari_tl(cpu_tmp0
, cpu_T1
, 3 + ot
);
6738 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, ot
);
6739 tcg_gen_add_tl(cpu_A0
, gen_lea_modrm_1(a
), cpu_tmp0
);
6740 gen_lea_v_seg(s
, s
->aflag
, cpu_A0
, a
.def_seg
, s
->override
);
6741 if (!(s
->prefix
& PREFIX_LOCK
)) {
6742 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
6745 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
6748 tcg_gen_andi_tl(cpu_T1
, cpu_T1
, (1 << (3 + ot
)) - 1);
6749 tcg_gen_movi_tl(cpu_tmp0
, 1);
6750 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T1
);
6751 if (s
->prefix
& PREFIX_LOCK
) {
6754 /* Needs no atomic ops; we surpressed the normal
6755 memory load for LOCK above so do it now. */
6756 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
6759 tcg_gen_atomic_fetch_or_tl(cpu_T0
, cpu_A0
, cpu_tmp0
,
6760 s
->mem_index
, ot
| MO_LE
);
6763 tcg_gen_not_tl(cpu_tmp0
, cpu_tmp0
);
6764 tcg_gen_atomic_fetch_and_tl(cpu_T0
, cpu_A0
, cpu_tmp0
,
6765 s
->mem_index
, ot
| MO_LE
);
6769 tcg_gen_atomic_fetch_xor_tl(cpu_T0
, cpu_A0
, cpu_tmp0
,
6770 s
->mem_index
, ot
| MO_LE
);
6773 tcg_gen_shr_tl(cpu_tmp4
, cpu_T0
, cpu_T1
);
6775 tcg_gen_shr_tl(cpu_tmp4
, cpu_T0
, cpu_T1
);
6778 /* Data already loaded; nothing to do. */
6781 tcg_gen_or_tl(cpu_T0
, cpu_T0
, cpu_tmp0
);
6784 tcg_gen_andc_tl(cpu_T0
, cpu_T0
, cpu_tmp0
);
6788 tcg_gen_xor_tl(cpu_T0
, cpu_T0
, cpu_tmp0
);
6793 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
6795 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
6800 /* Delay all CC updates until after the store above. Note that
6801 C is the result of the test, Z is unchanged, and the others
6802 are all undefined. */
6804 case CC_OP_MULB
... CC_OP_MULQ
:
6805 case CC_OP_ADDB
... CC_OP_ADDQ
:
6806 case CC_OP_ADCB
... CC_OP_ADCQ
:
6807 case CC_OP_SUBB
... CC_OP_SUBQ
:
6808 case CC_OP_SBBB
... CC_OP_SBBQ
:
6809 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
6810 case CC_OP_INCB
... CC_OP_INCQ
:
6811 case CC_OP_DECB
... CC_OP_DECQ
:
6812 case CC_OP_SHLB
... CC_OP_SHLQ
:
6813 case CC_OP_SARB
... CC_OP_SARQ
:
6814 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
6815 /* Z was going to be computed from the non-zero status of CC_DST.
6816 We can get that same Z value (and the new C value) by leaving
6817 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
6819 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
6820 set_cc_op(s
, ((s
->cc_op
- CC_OP_MULB
) & 3) + CC_OP_SARB
);
6823 /* Otherwise, generate EFLAGS and replace the C bit. */
6824 gen_compute_eflags(s
);
6825 tcg_gen_deposit_tl(cpu_cc_src
, cpu_cc_src
, cpu_tmp4
,
6830 case 0x1bc: /* bsf / tzcnt */
6831 case 0x1bd: /* bsr / lzcnt */
6833 modrm
= cpu_ldub_code(env
, s
->pc
++);
6834 reg
= ((modrm
>> 3) & 7) | rex_r
;
6835 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
6836 gen_extu(ot
, cpu_T0
);
6838 /* Note that lzcnt and tzcnt are in different extensions. */
6839 if ((prefixes
& PREFIX_REPZ
)
6841 ? s
->cpuid_ext3_features
& CPUID_EXT3_ABM
6842 : s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)) {
6844 /* For lzcnt/tzcnt, C bit is defined related to the input. */
6845 tcg_gen_mov_tl(cpu_cc_src
, cpu_T0
);
6847 /* For lzcnt, reduce the target_ulong result by the
6848 number of zeros that we expect to find at the top. */
6849 tcg_gen_clzi_tl(cpu_T0
, cpu_T0
, TARGET_LONG_BITS
);
6850 tcg_gen_subi_tl(cpu_T0
, cpu_T0
, TARGET_LONG_BITS
- size
);
6852 /* For tzcnt, a zero input must return the operand size. */
6853 tcg_gen_ctzi_tl(cpu_T0
, cpu_T0
, size
);
6855 /* For lzcnt/tzcnt, Z bit is defined related to the result. */
6856 gen_op_update1_cc();
6857 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
6859 /* For bsr/bsf, only the Z bit is defined and it is related
6860 to the input and not the result. */
6861 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
6862 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
6864 /* ??? The manual says that the output is undefined when the
6865 input is zero, but real hardware leaves it unchanged, and
6866 real programs appear to depend on that. Accomplish this
6867 by passing the output as the value to return upon zero. */
6869 /* For bsr, return the bit index of the first 1 bit,
6870 not the count of leading zeros. */
6871 tcg_gen_xori_tl(cpu_T1
, cpu_regs
[reg
], TARGET_LONG_BITS
- 1);
6872 tcg_gen_clz_tl(cpu_T0
, cpu_T0
, cpu_T1
);
6873 tcg_gen_xori_tl(cpu_T0
, cpu_T0
, TARGET_LONG_BITS
- 1);
6875 tcg_gen_ctz_tl(cpu_T0
, cpu_T0
, cpu_regs
[reg
]);
6878 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
6880 /************************/
6882 case 0x27: /* daa */
6885 gen_update_cc_op(s
);
6886 gen_helper_daa(cpu_env
);
6887 set_cc_op(s
, CC_OP_EFLAGS
);
6889 case 0x2f: /* das */
6892 gen_update_cc_op(s
);
6893 gen_helper_das(cpu_env
);
6894 set_cc_op(s
, CC_OP_EFLAGS
);
6896 case 0x37: /* aaa */
6899 gen_update_cc_op(s
);
6900 gen_helper_aaa(cpu_env
);
6901 set_cc_op(s
, CC_OP_EFLAGS
);
6903 case 0x3f: /* aas */
6906 gen_update_cc_op(s
);
6907 gen_helper_aas(cpu_env
);
6908 set_cc_op(s
, CC_OP_EFLAGS
);
6910 case 0xd4: /* aam */
6913 val
= cpu_ldub_code(env
, s
->pc
++);
6915 gen_exception(s
, EXCP00_DIVZ
, pc_start
- s
->cs_base
);
6917 gen_helper_aam(cpu_env
, tcg_const_i32(val
));
6918 set_cc_op(s
, CC_OP_LOGICB
);
6921 case 0xd5: /* aad */
6924 val
= cpu_ldub_code(env
, s
->pc
++);
6925 gen_helper_aad(cpu_env
, tcg_const_i32(val
));
6926 set_cc_op(s
, CC_OP_LOGICB
);
6928 /************************/
6930 case 0x90: /* nop */
6931 /* XXX: correct lock test for all insn */
6932 if (prefixes
& PREFIX_LOCK
) {
6935 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
6937 goto do_xchg_reg_eax
;
6939 if (prefixes
& PREFIX_REPZ
) {
6940 gen_update_cc_op(s
);
6941 gen_jmp_im(pc_start
- s
->cs_base
);
6942 gen_helper_pause(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
6943 s
->is_jmp
= DISAS_TB_JUMP
;
6946 case 0x9b: /* fwait */
6947 if ((s
->flags
& (HF_MP_MASK
| HF_TS_MASK
)) ==
6948 (HF_MP_MASK
| HF_TS_MASK
)) {
6949 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
6951 gen_helper_fwait(cpu_env
);
6954 case 0xcc: /* int3 */
6955 gen_interrupt(s
, EXCP03_INT3
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6957 case 0xcd: /* int N */
6958 val
= cpu_ldub_code(env
, s
->pc
++);
6959 if (s
->vm86
&& s
->iopl
!= 3) {
6960 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6962 gen_interrupt(s
, val
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6965 case 0xce: /* into */
6968 gen_update_cc_op(s
);
6969 gen_jmp_im(pc_start
- s
->cs_base
);
6970 gen_helper_into(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
6973 case 0xf1: /* icebp (undocumented, exits to external debugger) */
6974 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_ICEBP
);
6976 gen_debug(s
, pc_start
- s
->cs_base
);
6979 tb_flush(CPU(x86_env_get_cpu(env
)));
6980 qemu_set_log(CPU_LOG_INT
| CPU_LOG_TB_IN_ASM
);
6984 case 0xfa: /* cli */
6986 if (s
->cpl
<= s
->iopl
) {
6987 gen_helper_cli(cpu_env
);
6989 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6993 gen_helper_cli(cpu_env
);
6995 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6999 case 0xfb: /* sti */
7000 if (s
->vm86
? s
->iopl
== 3 : s
->cpl
<= s
->iopl
) {
7001 gen_helper_sti(cpu_env
);
7002 /* interruptions are enabled only the first insn after sti */
7003 gen_jmp_im(s
->pc
- s
->cs_base
);
7004 gen_eob_inhibit_irq(s
, true);
7006 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7009 case 0x62: /* bound */
7013 modrm
= cpu_ldub_code(env
, s
->pc
++);
7014 reg
= (modrm
>> 3) & 7;
7015 mod
= (modrm
>> 6) & 3;
7018 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
7019 gen_lea_modrm(env
, s
, modrm
);
7020 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
7022 gen_helper_boundw(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
7024 gen_helper_boundl(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
7027 case 0x1c8 ... 0x1cf: /* bswap reg */
7028 reg
= (b
& 7) | REX_B(s
);
7029 #ifdef TARGET_X86_64
7030 if (dflag
== MO_64
) {
7031 gen_op_mov_v_reg(MO_64
, cpu_T0
, reg
);
7032 tcg_gen_bswap64_i64(cpu_T0
, cpu_T0
);
7033 gen_op_mov_reg_v(MO_64
, reg
, cpu_T0
);
7037 gen_op_mov_v_reg(MO_32
, cpu_T0
, reg
);
7038 tcg_gen_ext32u_tl(cpu_T0
, cpu_T0
);
7039 tcg_gen_bswap32_tl(cpu_T0
, cpu_T0
);
7040 gen_op_mov_reg_v(MO_32
, reg
, cpu_T0
);
7043 case 0xd6: /* salc */
7046 gen_compute_eflags_c(s
, cpu_T0
);
7047 tcg_gen_neg_tl(cpu_T0
, cpu_T0
);
7048 gen_op_mov_reg_v(MO_8
, R_EAX
, cpu_T0
);
7050 case 0xe0: /* loopnz */
7051 case 0xe1: /* loopz */
7052 case 0xe2: /* loop */
7053 case 0xe3: /* jecxz */
7055 TCGLabel
*l1
, *l2
, *l3
;
7057 tval
= (int8_t)insn_get(env
, s
, MO_8
);
7058 next_eip
= s
->pc
- s
->cs_base
;
7060 if (dflag
== MO_16
) {
7064 l1
= gen_new_label();
7065 l2
= gen_new_label();
7066 l3
= gen_new_label();
7069 case 0: /* loopnz */
7071 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
7072 gen_op_jz_ecx(s
->aflag
, l3
);
7073 gen_jcc1(s
, (JCC_Z
<< 1) | (b
^ 1), l1
);
7076 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
7077 gen_op_jnz_ecx(s
->aflag
, l1
);
7081 gen_op_jz_ecx(s
->aflag
, l1
);
7086 gen_jmp_im(next_eip
);
7095 case 0x130: /* wrmsr */
7096 case 0x132: /* rdmsr */
7098 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7100 gen_update_cc_op(s
);
7101 gen_jmp_im(pc_start
- s
->cs_base
);
7103 gen_helper_rdmsr(cpu_env
);
7105 gen_helper_wrmsr(cpu_env
);
7109 case 0x131: /* rdtsc */
7110 gen_update_cc_op(s
);
7111 gen_jmp_im(pc_start
- s
->cs_base
);
7112 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7115 gen_helper_rdtsc(cpu_env
);
7116 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7118 gen_jmp(s
, s
->pc
- s
->cs_base
);
7121 case 0x133: /* rdpmc */
7122 gen_update_cc_op(s
);
7123 gen_jmp_im(pc_start
- s
->cs_base
);
7124 gen_helper_rdpmc(cpu_env
);
7126 case 0x134: /* sysenter */
7127 /* For Intel SYSENTER is valid on 64-bit */
7128 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7131 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7133 gen_helper_sysenter(cpu_env
);
7137 case 0x135: /* sysexit */
7138 /* For Intel SYSEXIT is valid on 64-bit */
7139 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7142 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7144 gen_helper_sysexit(cpu_env
, tcg_const_i32(dflag
- 1));
7148 #ifdef TARGET_X86_64
7149 case 0x105: /* syscall */
7150 /* XXX: is it usable in real mode ? */
7151 gen_update_cc_op(s
);
7152 gen_jmp_im(pc_start
- s
->cs_base
);
7153 gen_helper_syscall(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7154 /* TF handling for the syscall insn is different. The TF bit is checked
7155 after the syscall insn completes. This allows #DB to not be
7156 generated after one has entered CPL0 if TF is set in FMASK. */
7157 gen_eob_worker(s
, false, true);
7159 case 0x107: /* sysret */
7161 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7163 gen_helper_sysret(cpu_env
, tcg_const_i32(dflag
- 1));
7164 /* condition codes are modified only in long mode */
7166 set_cc_op(s
, CC_OP_EFLAGS
);
7168 /* TF handling for the sysret insn is different. The TF bit is
7169 checked after the sysret insn completes. This allows #DB to be
7170 generated "as if" the syscall insn in userspace has just
7172 gen_eob_worker(s
, false, true);
7176 case 0x1a2: /* cpuid */
7177 gen_update_cc_op(s
);
7178 gen_jmp_im(pc_start
- s
->cs_base
);
7179 gen_helper_cpuid(cpu_env
);
7181 case 0xf4: /* hlt */
7183 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7185 gen_update_cc_op(s
);
7186 gen_jmp_im(pc_start
- s
->cs_base
);
7187 gen_helper_hlt(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7188 s
->is_jmp
= DISAS_TB_JUMP
;
7192 modrm
= cpu_ldub_code(env
, s
->pc
++);
7193 mod
= (modrm
>> 6) & 3;
7194 op
= (modrm
>> 3) & 7;
7197 if (!s
->pe
|| s
->vm86
)
7199 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_READ
);
7200 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
,
7201 offsetof(CPUX86State
, ldt
.selector
));
7202 ot
= mod
== 3 ? dflag
: MO_16
;
7203 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7206 if (!s
->pe
|| s
->vm86
)
7209 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7211 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_WRITE
);
7212 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7213 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
7214 gen_helper_lldt(cpu_env
, cpu_tmp2_i32
);
7218 if (!s
->pe
|| s
->vm86
)
7220 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_READ
);
7221 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
,
7222 offsetof(CPUX86State
, tr
.selector
));
7223 ot
= mod
== 3 ? dflag
: MO_16
;
7224 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7227 if (!s
->pe
|| s
->vm86
)
7230 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7232 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_WRITE
);
7233 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7234 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
7235 gen_helper_ltr(cpu_env
, cpu_tmp2_i32
);
7240 if (!s
->pe
|| s
->vm86
)
7242 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7243 gen_update_cc_op(s
);
7245 gen_helper_verr(cpu_env
, cpu_T0
);
7247 gen_helper_verw(cpu_env
, cpu_T0
);
7249 set_cc_op(s
, CC_OP_EFLAGS
);
7257 modrm
= cpu_ldub_code(env
, s
->pc
++);
7259 CASE_MODRM_MEM_OP(0): /* sgdt */
7260 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_READ
);
7261 gen_lea_modrm(env
, s
, modrm
);
7262 tcg_gen_ld32u_tl(cpu_T0
,
7263 cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7264 gen_op_st_v(s
, MO_16
, cpu_T0
, cpu_A0
);
7265 gen_add_A0_im(s
, 2);
7266 tcg_gen_ld_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7267 if (dflag
== MO_16
) {
7268 tcg_gen_andi_tl(cpu_T0
, cpu_T0
, 0xffffff);
7270 gen_op_st_v(s
, CODE64(s
) + MO_32
, cpu_T0
, cpu_A0
);
7273 case 0xc8: /* monitor */
7274 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) || s
->cpl
!= 0) {
7277 gen_update_cc_op(s
);
7278 gen_jmp_im(pc_start
- s
->cs_base
);
7279 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EAX
]);
7280 gen_extu(s
->aflag
, cpu_A0
);
7281 gen_add_A0_ds_seg(s
);
7282 gen_helper_monitor(cpu_env
, cpu_A0
);
7285 case 0xc9: /* mwait */
7286 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) || s
->cpl
!= 0) {
7289 gen_update_cc_op(s
);
7290 gen_jmp_im(pc_start
- s
->cs_base
);
7291 gen_helper_mwait(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7295 case 0xca: /* clac */
7296 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
)
7300 gen_helper_clac(cpu_env
);
7301 gen_jmp_im(s
->pc
- s
->cs_base
);
7305 case 0xcb: /* stac */
7306 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
)
7310 gen_helper_stac(cpu_env
);
7311 gen_jmp_im(s
->pc
- s
->cs_base
);
7315 CASE_MODRM_MEM_OP(1): /* sidt */
7316 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_READ
);
7317 gen_lea_modrm(env
, s
, modrm
);
7318 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7319 gen_op_st_v(s
, MO_16
, cpu_T0
, cpu_A0
);
7320 gen_add_A0_im(s
, 2);
7321 tcg_gen_ld_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, idt
.base
));
7322 if (dflag
== MO_16
) {
7323 tcg_gen_andi_tl(cpu_T0
, cpu_T0
, 0xffffff);
7325 gen_op_st_v(s
, CODE64(s
) + MO_32
, cpu_T0
, cpu_A0
);
7328 case 0xd0: /* xgetbv */
7329 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
7330 || (s
->prefix
& (PREFIX_LOCK
| PREFIX_DATA
7331 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
7334 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_ECX
]);
7335 gen_helper_xgetbv(cpu_tmp1_i64
, cpu_env
, cpu_tmp2_i32
);
7336 tcg_gen_extr_i64_tl(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
], cpu_tmp1_i64
);
7339 case 0xd1: /* xsetbv */
7340 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
7341 || (s
->prefix
& (PREFIX_LOCK
| PREFIX_DATA
7342 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
7346 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7349 tcg_gen_concat_tl_i64(cpu_tmp1_i64
, cpu_regs
[R_EAX
],
7351 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_ECX
]);
7352 gen_helper_xsetbv(cpu_env
, cpu_tmp2_i32
, cpu_tmp1_i64
);
7353 /* End TB because translation flags may change. */
7354 gen_jmp_im(s
->pc
- s
->cs_base
);
7358 case 0xd8: /* VMRUN */
7359 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7363 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7366 gen_update_cc_op(s
);
7367 gen_jmp_im(pc_start
- s
->cs_base
);
7368 gen_helper_vmrun(cpu_env
, tcg_const_i32(s
->aflag
- 1),
7369 tcg_const_i32(s
->pc
- pc_start
));
7371 s
->is_jmp
= DISAS_TB_JUMP
;
7374 case 0xd9: /* VMMCALL */
7375 if (!(s
->flags
& HF_SVME_MASK
)) {
7378 gen_update_cc_op(s
);
7379 gen_jmp_im(pc_start
- s
->cs_base
);
7380 gen_helper_vmmcall(cpu_env
);
7383 case 0xda: /* VMLOAD */
7384 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7388 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7391 gen_update_cc_op(s
);
7392 gen_jmp_im(pc_start
- s
->cs_base
);
7393 gen_helper_vmload(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7396 case 0xdb: /* VMSAVE */
7397 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7401 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7404 gen_update_cc_op(s
);
7405 gen_jmp_im(pc_start
- s
->cs_base
);
7406 gen_helper_vmsave(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7409 case 0xdc: /* STGI */
7410 if ((!(s
->flags
& HF_SVME_MASK
)
7411 && !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
))
7416 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7419 gen_update_cc_op(s
);
7420 gen_jmp_im(pc_start
- s
->cs_base
);
7421 gen_helper_stgi(cpu_env
);
7424 case 0xdd: /* CLGI */
7425 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7429 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7432 gen_update_cc_op(s
);
7433 gen_jmp_im(pc_start
- s
->cs_base
);
7434 gen_helper_clgi(cpu_env
);
7437 case 0xde: /* SKINIT */
7438 if ((!(s
->flags
& HF_SVME_MASK
)
7439 && !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
))
7443 gen_update_cc_op(s
);
7444 gen_jmp_im(pc_start
- s
->cs_base
);
7445 gen_helper_skinit(cpu_env
);
7448 case 0xdf: /* INVLPGA */
7449 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7453 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7456 gen_update_cc_op(s
);
7457 gen_jmp_im(pc_start
- s
->cs_base
);
7458 gen_helper_invlpga(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7461 CASE_MODRM_MEM_OP(2): /* lgdt */
7463 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7466 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_WRITE
);
7467 gen_lea_modrm(env
, s
, modrm
);
7468 gen_op_ld_v(s
, MO_16
, cpu_T1
, cpu_A0
);
7469 gen_add_A0_im(s
, 2);
7470 gen_op_ld_v(s
, CODE64(s
) + MO_32
, cpu_T0
, cpu_A0
);
7471 if (dflag
== MO_16
) {
7472 tcg_gen_andi_tl(cpu_T0
, cpu_T0
, 0xffffff);
7474 tcg_gen_st_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7475 tcg_gen_st32_tl(cpu_T1
, cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7478 CASE_MODRM_MEM_OP(3): /* lidt */
7480 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7483 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_WRITE
);
7484 gen_lea_modrm(env
, s
, modrm
);
7485 gen_op_ld_v(s
, MO_16
, cpu_T1
, cpu_A0
);
7486 gen_add_A0_im(s
, 2);
7487 gen_op_ld_v(s
, CODE64(s
) + MO_32
, cpu_T0
, cpu_A0
);
7488 if (dflag
== MO_16
) {
7489 tcg_gen_andi_tl(cpu_T0
, cpu_T0
, 0xffffff);
7491 tcg_gen_st_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, idt
.base
));
7492 tcg_gen_st32_tl(cpu_T1
, cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7495 CASE_MODRM_OP(4): /* smsw */
7496 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_CR0
);
7497 tcg_gen_ld_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, cr
[0]));
7499 mod
= (modrm
>> 6) & 3;
7500 ot
= (mod
!= 3 ? MO_16
: s
->dflag
);
7504 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7506 case 0xee: /* rdpkru */
7507 if (prefixes
& PREFIX_LOCK
) {
7510 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_ECX
]);
7511 gen_helper_rdpkru(cpu_tmp1_i64
, cpu_env
, cpu_tmp2_i32
);
7512 tcg_gen_extr_i64_tl(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
], cpu_tmp1_i64
);
7514 case 0xef: /* wrpkru */
7515 if (prefixes
& PREFIX_LOCK
) {
7518 tcg_gen_concat_tl_i64(cpu_tmp1_i64
, cpu_regs
[R_EAX
],
7520 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_ECX
]);
7521 gen_helper_wrpkru(cpu_env
, cpu_tmp2_i32
, cpu_tmp1_i64
);
7523 CASE_MODRM_OP(6): /* lmsw */
7525 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7528 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7529 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7530 gen_helper_lmsw(cpu_env
, cpu_T0
);
7531 gen_jmp_im(s
->pc
- s
->cs_base
);
7535 CASE_MODRM_MEM_OP(7): /* invlpg */
7537 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7540 gen_update_cc_op(s
);
7541 gen_jmp_im(pc_start
- s
->cs_base
);
7542 gen_lea_modrm(env
, s
, modrm
);
7543 gen_helper_invlpg(cpu_env
, cpu_A0
);
7544 gen_jmp_im(s
->pc
- s
->cs_base
);
7548 case 0xf8: /* swapgs */
7549 #ifdef TARGET_X86_64
7552 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7554 tcg_gen_mov_tl(cpu_T0
, cpu_seg_base
[R_GS
]);
7555 tcg_gen_ld_tl(cpu_seg_base
[R_GS
], cpu_env
,
7556 offsetof(CPUX86State
, kernelgsbase
));
7557 tcg_gen_st_tl(cpu_T0
, cpu_env
,
7558 offsetof(CPUX86State
, kernelgsbase
));
7565 case 0xf9: /* rdtscp */
7566 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_RDTSCP
)) {
7569 gen_update_cc_op(s
);
7570 gen_jmp_im(pc_start
- s
->cs_base
);
7571 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7574 gen_helper_rdtscp(cpu_env
);
7575 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7577 gen_jmp(s
, s
->pc
- s
->cs_base
);
7586 case 0x108: /* invd */
7587 case 0x109: /* wbinvd */
7589 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7591 gen_svm_check_intercept(s
, pc_start
, (b
& 2) ? SVM_EXIT_INVD
: SVM_EXIT_WBINVD
);
7595 case 0x63: /* arpl or movslS (x86_64) */
7596 #ifdef TARGET_X86_64
7599 /* d_ot is the size of destination */
7602 modrm
= cpu_ldub_code(env
, s
->pc
++);
7603 reg
= ((modrm
>> 3) & 7) | rex_r
;
7604 mod
= (modrm
>> 6) & 3;
7605 rm
= (modrm
& 7) | REX_B(s
);
7608 gen_op_mov_v_reg(MO_32
, cpu_T0
, rm
);
7610 if (d_ot
== MO_64
) {
7611 tcg_gen_ext32s_tl(cpu_T0
, cpu_T0
);
7613 gen_op_mov_reg_v(d_ot
, reg
, cpu_T0
);
7615 gen_lea_modrm(env
, s
, modrm
);
7616 gen_op_ld_v(s
, MO_32
| MO_SIGN
, cpu_T0
, cpu_A0
);
7617 gen_op_mov_reg_v(d_ot
, reg
, cpu_T0
);
7623 TCGv t0
, t1
, t2
, a0
;
7625 if (!s
->pe
|| s
->vm86
)
7627 t0
= tcg_temp_local_new();
7628 t1
= tcg_temp_local_new();
7629 t2
= tcg_temp_local_new();
7631 modrm
= cpu_ldub_code(env
, s
->pc
++);
7632 reg
= (modrm
>> 3) & 7;
7633 mod
= (modrm
>> 6) & 3;
7636 gen_lea_modrm(env
, s
, modrm
);
7637 gen_op_ld_v(s
, ot
, t0
, cpu_A0
);
7638 a0
= tcg_temp_local_new();
7639 tcg_gen_mov_tl(a0
, cpu_A0
);
7641 gen_op_mov_v_reg(ot
, t0
, rm
);
7644 gen_op_mov_v_reg(ot
, t1
, reg
);
7645 tcg_gen_andi_tl(cpu_tmp0
, t0
, 3);
7646 tcg_gen_andi_tl(t1
, t1
, 3);
7647 tcg_gen_movi_tl(t2
, 0);
7648 label1
= gen_new_label();
7649 tcg_gen_brcond_tl(TCG_COND_GE
, cpu_tmp0
, t1
, label1
);
7650 tcg_gen_andi_tl(t0
, t0
, ~3);
7651 tcg_gen_or_tl(t0
, t0
, t1
);
7652 tcg_gen_movi_tl(t2
, CC_Z
);
7653 gen_set_label(label1
);
7655 gen_op_st_v(s
, ot
, t0
, a0
);
7658 gen_op_mov_reg_v(ot
, rm
, t0
);
7660 gen_compute_eflags(s
);
7661 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_Z
);
7662 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, t2
);
7668 case 0x102: /* lar */
7669 case 0x103: /* lsl */
7673 if (!s
->pe
|| s
->vm86
)
7675 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
7676 modrm
= cpu_ldub_code(env
, s
->pc
++);
7677 reg
= ((modrm
>> 3) & 7) | rex_r
;
7678 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7679 t0
= tcg_temp_local_new();
7680 gen_update_cc_op(s
);
7682 gen_helper_lar(t0
, cpu_env
, cpu_T0
);
7684 gen_helper_lsl(t0
, cpu_env
, cpu_T0
);
7686 tcg_gen_andi_tl(cpu_tmp0
, cpu_cc_src
, CC_Z
);
7687 label1
= gen_new_label();
7688 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
7689 gen_op_mov_reg_v(ot
, reg
, t0
);
7690 gen_set_label(label1
);
7691 set_cc_op(s
, CC_OP_EFLAGS
);
7696 modrm
= cpu_ldub_code(env
, s
->pc
++);
7697 mod
= (modrm
>> 6) & 3;
7698 op
= (modrm
>> 3) & 7;
7700 case 0: /* prefetchnta */
7701 case 1: /* prefetchnt0 */
7702 case 2: /* prefetchnt0 */
7703 case 3: /* prefetchnt0 */
7706 gen_nop_modrm(env
, s
, modrm
);
7707 /* nothing more to do */
7709 default: /* nop (multi byte) */
7710 gen_nop_modrm(env
, s
, modrm
);
7715 modrm
= cpu_ldub_code(env
, s
->pc
++);
7716 if (s
->flags
& HF_MPX_EN_MASK
) {
7717 mod
= (modrm
>> 6) & 3;
7718 reg
= ((modrm
>> 3) & 7) | rex_r
;
7719 if (prefixes
& PREFIX_REPZ
) {
7722 || (prefixes
& PREFIX_LOCK
)
7723 || s
->aflag
== MO_16
) {
7726 gen_bndck(env
, s
, modrm
, TCG_COND_LTU
, cpu_bndl
[reg
]);
7727 } else if (prefixes
& PREFIX_REPNZ
) {
7730 || (prefixes
& PREFIX_LOCK
)
7731 || s
->aflag
== MO_16
) {
7734 TCGv_i64 notu
= tcg_temp_new_i64();
7735 tcg_gen_not_i64(notu
, cpu_bndu
[reg
]);
7736 gen_bndck(env
, s
, modrm
, TCG_COND_GTU
, notu
);
7737 tcg_temp_free_i64(notu
);
7738 } else if (prefixes
& PREFIX_DATA
) {
7739 /* bndmov -- from reg/mem */
7740 if (reg
>= 4 || s
->aflag
== MO_16
) {
7744 int reg2
= (modrm
& 7) | REX_B(s
);
7745 if (reg2
>= 4 || (prefixes
& PREFIX_LOCK
)) {
7748 if (s
->flags
& HF_MPX_IU_MASK
) {
7749 tcg_gen_mov_i64(cpu_bndl
[reg
], cpu_bndl
[reg2
]);
7750 tcg_gen_mov_i64(cpu_bndu
[reg
], cpu_bndu
[reg2
]);
7753 gen_lea_modrm(env
, s
, modrm
);
7755 tcg_gen_qemu_ld_i64(cpu_bndl
[reg
], cpu_A0
,
7756 s
->mem_index
, MO_LEQ
);
7757 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, 8);
7758 tcg_gen_qemu_ld_i64(cpu_bndu
[reg
], cpu_A0
,
7759 s
->mem_index
, MO_LEQ
);
7761 tcg_gen_qemu_ld_i64(cpu_bndl
[reg
], cpu_A0
,
7762 s
->mem_index
, MO_LEUL
);
7763 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, 4);
7764 tcg_gen_qemu_ld_i64(cpu_bndu
[reg
], cpu_A0
,
7765 s
->mem_index
, MO_LEUL
);
7767 /* bnd registers are now in-use */
7768 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7770 } else if (mod
!= 3) {
7772 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7774 || (prefixes
& PREFIX_LOCK
)
7775 || s
->aflag
== MO_16
7780 tcg_gen_addi_tl(cpu_A0
, cpu_regs
[a
.base
], a
.disp
);
7782 tcg_gen_movi_tl(cpu_A0
, 0);
7784 gen_lea_v_seg(s
, s
->aflag
, cpu_A0
, a
.def_seg
, s
->override
);
7786 tcg_gen_mov_tl(cpu_T0
, cpu_regs
[a
.index
]);
7788 tcg_gen_movi_tl(cpu_T0
, 0);
7791 gen_helper_bndldx64(cpu_bndl
[reg
], cpu_env
, cpu_A0
, cpu_T0
);
7792 tcg_gen_ld_i64(cpu_bndu
[reg
], cpu_env
,
7793 offsetof(CPUX86State
, mmx_t0
.MMX_Q(0)));
7795 gen_helper_bndldx32(cpu_bndu
[reg
], cpu_env
, cpu_A0
, cpu_T0
);
7796 tcg_gen_ext32u_i64(cpu_bndl
[reg
], cpu_bndu
[reg
]);
7797 tcg_gen_shri_i64(cpu_bndu
[reg
], cpu_bndu
[reg
], 32);
7799 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7802 gen_nop_modrm(env
, s
, modrm
);
7805 modrm
= cpu_ldub_code(env
, s
->pc
++);
7806 if (s
->flags
& HF_MPX_EN_MASK
) {
7807 mod
= (modrm
>> 6) & 3;
7808 reg
= ((modrm
>> 3) & 7) | rex_r
;
7809 if (mod
!= 3 && (prefixes
& PREFIX_REPZ
)) {
7812 || (prefixes
& PREFIX_LOCK
)
7813 || s
->aflag
== MO_16
) {
7816 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7818 tcg_gen_extu_tl_i64(cpu_bndl
[reg
], cpu_regs
[a
.base
]);
7820 tcg_gen_ext32u_i64(cpu_bndl
[reg
], cpu_bndl
[reg
]);
7822 } else if (a
.base
== -1) {
7823 /* no base register has lower bound of 0 */
7824 tcg_gen_movi_i64(cpu_bndl
[reg
], 0);
7826 /* rip-relative generates #ud */
7829 tcg_gen_not_tl(cpu_A0
, gen_lea_modrm_1(a
));
7831 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
7833 tcg_gen_extu_tl_i64(cpu_bndu
[reg
], cpu_A0
);
7834 /* bnd registers are now in-use */
7835 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7837 } else if (prefixes
& PREFIX_REPNZ
) {
7840 || (prefixes
& PREFIX_LOCK
)
7841 || s
->aflag
== MO_16
) {
7844 gen_bndck(env
, s
, modrm
, TCG_COND_GTU
, cpu_bndu
[reg
]);
7845 } else if (prefixes
& PREFIX_DATA
) {
7846 /* bndmov -- to reg/mem */
7847 if (reg
>= 4 || s
->aflag
== MO_16
) {
7851 int reg2
= (modrm
& 7) | REX_B(s
);
7852 if (reg2
>= 4 || (prefixes
& PREFIX_LOCK
)) {
7855 if (s
->flags
& HF_MPX_IU_MASK
) {
7856 tcg_gen_mov_i64(cpu_bndl
[reg2
], cpu_bndl
[reg
]);
7857 tcg_gen_mov_i64(cpu_bndu
[reg2
], cpu_bndu
[reg
]);
7860 gen_lea_modrm(env
, s
, modrm
);
7862 tcg_gen_qemu_st_i64(cpu_bndl
[reg
], cpu_A0
,
7863 s
->mem_index
, MO_LEQ
);
7864 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, 8);
7865 tcg_gen_qemu_st_i64(cpu_bndu
[reg
], cpu_A0
,
7866 s
->mem_index
, MO_LEQ
);
7868 tcg_gen_qemu_st_i64(cpu_bndl
[reg
], cpu_A0
,
7869 s
->mem_index
, MO_LEUL
);
7870 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, 4);
7871 tcg_gen_qemu_st_i64(cpu_bndu
[reg
], cpu_A0
,
7872 s
->mem_index
, MO_LEUL
);
7875 } else if (mod
!= 3) {
7877 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7879 || (prefixes
& PREFIX_LOCK
)
7880 || s
->aflag
== MO_16
7885 tcg_gen_addi_tl(cpu_A0
, cpu_regs
[a
.base
], a
.disp
);
7887 tcg_gen_movi_tl(cpu_A0
, 0);
7889 gen_lea_v_seg(s
, s
->aflag
, cpu_A0
, a
.def_seg
, s
->override
);
7891 tcg_gen_mov_tl(cpu_T0
, cpu_regs
[a
.index
]);
7893 tcg_gen_movi_tl(cpu_T0
, 0);
7896 gen_helper_bndstx64(cpu_env
, cpu_A0
, cpu_T0
,
7897 cpu_bndl
[reg
], cpu_bndu
[reg
]);
7899 gen_helper_bndstx32(cpu_env
, cpu_A0
, cpu_T0
,
7900 cpu_bndl
[reg
], cpu_bndu
[reg
]);
7904 gen_nop_modrm(env
, s
, modrm
);
7906 case 0x119: case 0x11c ... 0x11f: /* nop (multi byte) */
7907 modrm
= cpu_ldub_code(env
, s
->pc
++);
7908 gen_nop_modrm(env
, s
, modrm
);
7910 case 0x120: /* mov reg, crN */
7911 case 0x122: /* mov crN, reg */
7913 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7915 modrm
= cpu_ldub_code(env
, s
->pc
++);
7916 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7917 * AMD documentation (24594.pdf) and testing of
7918 * intel 386 and 486 processors all show that the mod bits
7919 * are assumed to be 1's, regardless of actual values.
7921 rm
= (modrm
& 7) | REX_B(s
);
7922 reg
= ((modrm
>> 3) & 7) | rex_r
;
7927 if ((prefixes
& PREFIX_LOCK
) && (reg
== 0) &&
7928 (s
->cpuid_ext3_features
& CPUID_EXT3_CR8LEG
)) {
7937 gen_update_cc_op(s
);
7938 gen_jmp_im(pc_start
- s
->cs_base
);
7940 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
7941 gen_helper_write_crN(cpu_env
, tcg_const_i32(reg
),
7943 gen_jmp_im(s
->pc
- s
->cs_base
);
7946 gen_helper_read_crN(cpu_T0
, cpu_env
, tcg_const_i32(reg
));
7947 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
7955 case 0x121: /* mov reg, drN */
7956 case 0x123: /* mov drN, reg */
7958 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7960 modrm
= cpu_ldub_code(env
, s
->pc
++);
7961 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7962 * AMD documentation (24594.pdf) and testing of
7963 * intel 386 and 486 processors all show that the mod bits
7964 * are assumed to be 1's, regardless of actual values.
7966 rm
= (modrm
& 7) | REX_B(s
);
7967 reg
= ((modrm
>> 3) & 7) | rex_r
;
7976 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_DR0
+ reg
);
7977 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
7978 tcg_gen_movi_i32(cpu_tmp2_i32
, reg
);
7979 gen_helper_set_dr(cpu_env
, cpu_tmp2_i32
, cpu_T0
);
7980 gen_jmp_im(s
->pc
- s
->cs_base
);
7983 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_DR0
+ reg
);
7984 tcg_gen_movi_i32(cpu_tmp2_i32
, reg
);
7985 gen_helper_get_dr(cpu_T0
, cpu_env
, cpu_tmp2_i32
);
7986 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
7990 case 0x106: /* clts */
7992 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7994 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7995 gen_helper_clts(cpu_env
);
7996 /* abort block because static cpu state changed */
7997 gen_jmp_im(s
->pc
- s
->cs_base
);
8001 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
8002 case 0x1c3: /* MOVNTI reg, mem */
8003 if (!(s
->cpuid_features
& CPUID_SSE2
))
8005 ot
= mo_64_32(dflag
);
8006 modrm
= cpu_ldub_code(env
, s
->pc
++);
8007 mod
= (modrm
>> 6) & 3;
8010 reg
= ((modrm
>> 3) & 7) | rex_r
;
8011 /* generate a generic store */
8012 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
8015 modrm
= cpu_ldub_code(env
, s
->pc
++);
8017 CASE_MODRM_MEM_OP(0): /* fxsave */
8018 if (!(s
->cpuid_features
& CPUID_FXSR
)
8019 || (prefixes
& PREFIX_LOCK
)) {
8022 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
8023 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8026 gen_lea_modrm(env
, s
, modrm
);
8027 gen_helper_fxsave(cpu_env
, cpu_A0
);
8030 CASE_MODRM_MEM_OP(1): /* fxrstor */
8031 if (!(s
->cpuid_features
& CPUID_FXSR
)
8032 || (prefixes
& PREFIX_LOCK
)) {
8035 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
8036 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8039 gen_lea_modrm(env
, s
, modrm
);
8040 gen_helper_fxrstor(cpu_env
, cpu_A0
);
8043 CASE_MODRM_MEM_OP(2): /* ldmxcsr */
8044 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
)) {
8047 if (s
->flags
& HF_TS_MASK
) {
8048 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8051 gen_lea_modrm(env
, s
, modrm
);
8052 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
, s
->mem_index
, MO_LEUL
);
8053 gen_helper_ldmxcsr(cpu_env
, cpu_tmp2_i32
);
8056 CASE_MODRM_MEM_OP(3): /* stmxcsr */
8057 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
)) {
8060 if (s
->flags
& HF_TS_MASK
) {
8061 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8064 gen_lea_modrm(env
, s
, modrm
);
8065 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, mxcsr
));
8066 gen_op_st_v(s
, MO_32
, cpu_T0
, cpu_A0
);
8069 CASE_MODRM_MEM_OP(4): /* xsave */
8070 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8071 || (prefixes
& (PREFIX_LOCK
| PREFIX_DATA
8072 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
8075 gen_lea_modrm(env
, s
, modrm
);
8076 tcg_gen_concat_tl_i64(cpu_tmp1_i64
, cpu_regs
[R_EAX
],
8078 gen_helper_xsave(cpu_env
, cpu_A0
, cpu_tmp1_i64
);
8081 CASE_MODRM_MEM_OP(5): /* xrstor */
8082 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8083 || (prefixes
& (PREFIX_LOCK
| PREFIX_DATA
8084 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
8087 gen_lea_modrm(env
, s
, modrm
);
8088 tcg_gen_concat_tl_i64(cpu_tmp1_i64
, cpu_regs
[R_EAX
],
8090 gen_helper_xrstor(cpu_env
, cpu_A0
, cpu_tmp1_i64
);
8091 /* XRSTOR is how MPX is enabled, which changes how
8092 we translate. Thus we need to end the TB. */
8093 gen_update_cc_op(s
);
8094 gen_jmp_im(s
->pc
- s
->cs_base
);
8098 CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */
8099 if (prefixes
& PREFIX_LOCK
) {
8102 if (prefixes
& PREFIX_DATA
) {
8104 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLWB
)) {
8107 gen_nop_modrm(env
, s
, modrm
);
8110 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8111 || (s
->cpuid_xsave_features
& CPUID_XSAVE_XSAVEOPT
) == 0
8112 || (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
))) {
8115 gen_lea_modrm(env
, s
, modrm
);
8116 tcg_gen_concat_tl_i64(cpu_tmp1_i64
, cpu_regs
[R_EAX
],
8118 gen_helper_xsaveopt(cpu_env
, cpu_A0
, cpu_tmp1_i64
);
8122 CASE_MODRM_MEM_OP(7): /* clflush / clflushopt */
8123 if (prefixes
& PREFIX_LOCK
) {
8126 if (prefixes
& PREFIX_DATA
) {
8128 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLFLUSHOPT
)) {
8133 if ((s
->prefix
& (PREFIX_REPZ
| PREFIX_REPNZ
))
8134 || !(s
->cpuid_features
& CPUID_CLFLUSH
)) {
8138 gen_nop_modrm(env
, s
, modrm
);
8141 case 0xc0 ... 0xc7: /* rdfsbase (f3 0f ae /0) */
8142 case 0xc8 ... 0xc8: /* rdgsbase (f3 0f ae /1) */
8143 case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */
8144 case 0xd8 ... 0xd8: /* wrgsbase (f3 0f ae /3) */
8146 && (prefixes
& PREFIX_REPZ
)
8147 && !(prefixes
& PREFIX_LOCK
)
8148 && (s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_FSGSBASE
)) {
8149 TCGv base
, treg
, src
, dst
;
8151 /* Preserve hflags bits by testing CR4 at runtime. */
8152 tcg_gen_movi_i32(cpu_tmp2_i32
, CR4_FSGSBASE_MASK
);
8153 gen_helper_cr4_testbit(cpu_env
, cpu_tmp2_i32
);
8155 base
= cpu_seg_base
[modrm
& 8 ? R_GS
: R_FS
];
8156 treg
= cpu_regs
[(modrm
& 7) | REX_B(s
)];
8160 dst
= base
, src
= treg
;
8163 dst
= treg
, src
= base
;
8166 if (s
->dflag
== MO_32
) {
8167 tcg_gen_ext32u_tl(dst
, src
);
8169 tcg_gen_mov_tl(dst
, src
);
8175 case 0xf8: /* sfence / pcommit */
8176 if (prefixes
& PREFIX_DATA
) {
8178 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_PCOMMIT
)
8179 || (prefixes
& PREFIX_LOCK
)) {
8185 case 0xf9 ... 0xff: /* sfence */
8186 if (!(s
->cpuid_features
& CPUID_SSE
)
8187 || (prefixes
& PREFIX_LOCK
)) {
8190 tcg_gen_mb(TCG_MO_ST_ST
| TCG_BAR_SC
);
8192 case 0xe8 ... 0xef: /* lfence */
8193 if (!(s
->cpuid_features
& CPUID_SSE
)
8194 || (prefixes
& PREFIX_LOCK
)) {
8197 tcg_gen_mb(TCG_MO_LD_LD
| TCG_BAR_SC
);
8199 case 0xf0 ... 0xf7: /* mfence */
8200 if (!(s
->cpuid_features
& CPUID_SSE2
)
8201 || (prefixes
& PREFIX_LOCK
)) {
8204 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8212 case 0x10d: /* 3DNow! prefetch(w) */
8213 modrm
= cpu_ldub_code(env
, s
->pc
++);
8214 mod
= (modrm
>> 6) & 3;
8217 gen_nop_modrm(env
, s
, modrm
);
8219 case 0x1aa: /* rsm */
8220 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_RSM
);
8221 if (!(s
->flags
& HF_SMM_MASK
))
8223 gen_update_cc_op(s
);
8224 gen_jmp_im(s
->pc
- s
->cs_base
);
8225 gen_helper_rsm(cpu_env
);
8228 case 0x1b8: /* SSE4.2 popcnt */
8229 if ((prefixes
& (PREFIX_REPZ
| PREFIX_LOCK
| PREFIX_REPNZ
)) !=
8232 if (!(s
->cpuid_ext_features
& CPUID_EXT_POPCNT
))
8235 modrm
= cpu_ldub_code(env
, s
->pc
++);
8236 reg
= ((modrm
>> 3) & 7) | rex_r
;
8238 if (s
->prefix
& PREFIX_DATA
) {
8241 ot
= mo_64_32(dflag
);
8244 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
8245 gen_extu(ot
, cpu_T0
);
8246 tcg_gen_mov_tl(cpu_cc_src
, cpu_T0
);
8247 tcg_gen_ctpop_tl(cpu_T0
, cpu_T0
);
8248 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
8250 set_cc_op(s
, CC_OP_POPCNT
);
8252 case 0x10e ... 0x10f:
8253 /* 3DNow! instructions, ignore prefixes */
8254 s
->prefix
&= ~(PREFIX_REPZ
| PREFIX_REPNZ
| PREFIX_DATA
);
8255 case 0x110 ... 0x117:
8256 case 0x128 ... 0x12f:
8257 case 0x138 ... 0x13a:
8258 case 0x150 ... 0x179:
8259 case 0x17c ... 0x17f:
8261 case 0x1c4 ... 0x1c6:
8262 case 0x1d0 ... 0x1fe:
8263 gen_sse(env
, s
, b
, pc_start
, rex_r
);
8270 gen_illegal_opcode(s
);
8273 gen_unknown_opcode(env
, s
);
8277 void tcg_x86_init(void)
8279 static const char reg_names
[CPU_NB_REGS
][4] = {
8280 #ifdef TARGET_X86_64
8308 static const char seg_base_names
[6][8] = {
8316 static const char bnd_regl_names
[4][8] = {
8317 "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb"
8319 static const char bnd_regu_names
[4][8] = {
8320 "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub"
8323 static bool initialized
;
8330 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
8331 tcg_ctx
.tcg_env
= cpu_env
;
8332 cpu_cc_op
= tcg_global_mem_new_i32(cpu_env
,
8333 offsetof(CPUX86State
, cc_op
), "cc_op");
8334 cpu_cc_dst
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_dst
),
8336 cpu_cc_src
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_src
),
8338 cpu_cc_src2
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_src2
),
8341 for (i
= 0; i
< CPU_NB_REGS
; ++i
) {
8342 cpu_regs
[i
] = tcg_global_mem_new(cpu_env
,
8343 offsetof(CPUX86State
, regs
[i
]),
8347 for (i
= 0; i
< 6; ++i
) {
8349 = tcg_global_mem_new(cpu_env
,
8350 offsetof(CPUX86State
, segs
[i
].base
),
8354 for (i
= 0; i
< 4; ++i
) {
8356 = tcg_global_mem_new_i64(cpu_env
,
8357 offsetof(CPUX86State
, bnd_regs
[i
].lb
),
8360 = tcg_global_mem_new_i64(cpu_env
,
8361 offsetof(CPUX86State
, bnd_regs
[i
].ub
),
8366 /* generate intermediate code for basic block 'tb'. */
8367 void gen_intermediate_code(CPUX86State
*env
, TranslationBlock
*tb
)
8369 X86CPU
*cpu
= x86_env_get_cpu(env
);
8370 CPUState
*cs
= CPU(cpu
);
8371 DisasContext dc1
, *dc
= &dc1
;
8372 target_ulong pc_ptr
;
8374 target_ulong pc_start
;
8375 target_ulong cs_base
;
8379 /* generate intermediate code */
8381 cs_base
= tb
->cs_base
;
8384 dc
->pe
= (flags
>> HF_PE_SHIFT
) & 1;
8385 dc
->code32
= (flags
>> HF_CS32_SHIFT
) & 1;
8386 dc
->ss32
= (flags
>> HF_SS32_SHIFT
) & 1;
8387 dc
->addseg
= (flags
>> HF_ADDSEG_SHIFT
) & 1;
8389 dc
->vm86
= (flags
>> VM_SHIFT
) & 1;
8390 dc
->cpl
= (flags
>> HF_CPL_SHIFT
) & 3;
8391 dc
->iopl
= (flags
>> IOPL_SHIFT
) & 3;
8392 dc
->tf
= (flags
>> TF_SHIFT
) & 1;
8393 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
8394 dc
->cc_op
= CC_OP_DYNAMIC
;
8395 dc
->cc_op_dirty
= false;
8396 dc
->cs_base
= cs_base
;
8398 dc
->popl_esp_hack
= 0;
8399 /* select memory access functions */
8401 #ifdef CONFIG_SOFTMMU
8402 dc
->mem_index
= cpu_mmu_index(env
, false);
8404 dc
->cpuid_features
= env
->features
[FEAT_1_EDX
];
8405 dc
->cpuid_ext_features
= env
->features
[FEAT_1_ECX
];
8406 dc
->cpuid_ext2_features
= env
->features
[FEAT_8000_0001_EDX
];
8407 dc
->cpuid_ext3_features
= env
->features
[FEAT_8000_0001_ECX
];
8408 dc
->cpuid_7_0_ebx_features
= env
->features
[FEAT_7_0_EBX
];
8409 dc
->cpuid_xsave_features
= env
->features
[FEAT_XSAVE
];
8410 #ifdef TARGET_X86_64
8411 dc
->lma
= (flags
>> HF_LMA_SHIFT
) & 1;
8412 dc
->code64
= (flags
>> HF_CS64_SHIFT
) & 1;
8415 dc
->jmp_opt
= !(dc
->tf
|| cs
->singlestep_enabled
||
8416 (flags
& HF_INHIBIT_IRQ_MASK
));
8417 /* Do not optimize repz jumps at all in icount mode, because
8418 rep movsS instructions are execured with different paths
8419 in !repz_opt and repz_opt modes. The first one was used
8420 always except single step mode. And this setting
8421 disables jumps optimization and control paths become
8422 equivalent in run and single step modes.
8423 Now there will be no jump optimization for repz in
8424 record/replay modes and there will always be an
8425 additional step for ecx=0 when icount is enabled.
8427 dc
->repz_opt
= !dc
->jmp_opt
&& !(tb
->cflags
& CF_USE_ICOUNT
);
8429 /* check addseg logic */
8430 if (!dc
->addseg
&& (dc
->vm86
|| !dc
->pe
|| !dc
->code32
))
8431 printf("ERROR addseg\n");
8434 cpu_T0
= tcg_temp_new();
8435 cpu_T1
= tcg_temp_new();
8436 cpu_A0
= tcg_temp_new();
8438 cpu_tmp0
= tcg_temp_new();
8439 cpu_tmp1_i64
= tcg_temp_new_i64();
8440 cpu_tmp2_i32
= tcg_temp_new_i32();
8441 cpu_tmp3_i32
= tcg_temp_new_i32();
8442 cpu_tmp4
= tcg_temp_new();
8443 cpu_ptr0
= tcg_temp_new_ptr();
8444 cpu_ptr1
= tcg_temp_new_ptr();
8445 cpu_cc_srcT
= tcg_temp_local_new();
8447 dc
->is_jmp
= DISAS_NEXT
;
8450 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
8451 if (max_insns
== 0) {
8452 max_insns
= CF_COUNT_MASK
;
8454 if (max_insns
> TCG_MAX_INSNS
) {
8455 max_insns
= TCG_MAX_INSNS
;
8460 tcg_gen_insn_start(pc_ptr
, dc
->cc_op
);
8463 /* If RF is set, suppress an internally generated breakpoint. */
8464 if (unlikely(cpu_breakpoint_test(cs
, pc_ptr
,
8465 tb
->flags
& HF_RF_MASK
8466 ? BP_GDB
: BP_ANY
))) {
8467 gen_debug(dc
, pc_ptr
- dc
->cs_base
);
8468 /* The address covered by the breakpoint must be included in
8469 [tb->pc, tb->pc + tb->size) in order to for it to be
8470 properly cleared -- thus we increment the PC here so that
8471 the logic setting tb->size below does the right thing. */
8473 goto done_generating
;
8475 if (num_insns
== max_insns
&& (tb
->cflags
& CF_LAST_IO
)) {
8479 pc_ptr
= disas_insn(env
, dc
, pc_ptr
);
8480 /* stop translation if indicated */
8483 /* if single step mode, we generate only one instruction and
8484 generate an exception */
8485 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
8486 the flag and abort the translation to give the irqs a
8487 change to be happen */
8488 if (dc
->tf
|| dc
->singlestep_enabled
||
8489 (flags
& HF_INHIBIT_IRQ_MASK
)) {
8490 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8494 /* Do not cross the boundary of the pages in icount mode,
8495 it can cause an exception. Do it only when boundary is
8496 crossed by the first instruction in the block.
8497 If current instruction already crossed the bound - it's ok,
8498 because an exception hasn't stopped this code.
8500 if ((tb
->cflags
& CF_USE_ICOUNT
)
8501 && ((pc_ptr
& TARGET_PAGE_MASK
)
8502 != ((pc_ptr
+ TARGET_MAX_INSN_SIZE
- 1) & TARGET_PAGE_MASK
)
8503 || (pc_ptr
& ~TARGET_PAGE_MASK
) == 0)) {
8504 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8508 /* if too long translation, stop generation too */
8509 if (tcg_op_buf_full() ||
8510 (pc_ptr
- pc_start
) >= (TARGET_PAGE_SIZE
- 32) ||
8511 num_insns
>= max_insns
) {
8512 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8517 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8522 if (tb
->cflags
& CF_LAST_IO
)
8525 gen_tb_end(tb
, num_insns
);
8528 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)
8529 && qemu_log_in_addr_range(pc_start
)) {
8532 qemu_log("----------------\n");
8533 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
8534 #ifdef TARGET_X86_64
8539 disas_flags
= !dc
->code32
;
8540 log_target_disas(cs
, pc_start
, pc_ptr
- pc_start
, disas_flags
);
8546 tb
->size
= pc_ptr
- pc_start
;
8547 tb
->icount
= num_insns
;
8550 void restore_state_to_opc(CPUX86State
*env
, TranslationBlock
*tb
,
8553 int cc_op
= data
[1];
8554 env
->eip
= data
[0] - tb
->cs_base
;
8555 if (cc_op
!= CC_OP_DYNAMIC
) {