4 * Copyright (c) 2003 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 #include "qemu/osdep.h"
21 #include "qemu/host-utils.h"
23 #include "disas/disas.h"
24 #include "exec/exec-all.h"
26 #include "exec/cpu_ldst.h"
27 #include "exec/translator.h"
29 #include "exec/helper-proto.h"
30 #include "exec/helper-gen.h"
32 #include "trace-tcg.h"
35 #define PREFIX_REPZ 0x01
36 #define PREFIX_REPNZ 0x02
37 #define PREFIX_LOCK 0x04
38 #define PREFIX_DATA 0x08
39 #define PREFIX_ADR 0x10
40 #define PREFIX_VEX 0x20
43 #define CODE64(s) ((s)->code64)
44 #define REX_X(s) ((s)->rex_x)
45 #define REX_B(s) ((s)->rex_b)
60 /* For a switch indexed by MODRM, match all memory operands for a given OP. */
61 #define CASE_MODRM_MEM_OP(OP) \
62 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
63 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
64 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7
66 #define CASE_MODRM_OP(OP) \
67 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
68 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
69 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7: \
70 case (3 << 6) | (OP << 3) | 0 ... (3 << 6) | (OP << 3) | 7
72 //#define MACRO_TEST 1
74 /* global register indexes */
75 static TCGv cpu_cc_dst
, cpu_cc_src
, cpu_cc_src2
;
76 static TCGv_i32 cpu_cc_op
;
77 static TCGv cpu_regs
[CPU_NB_REGS
];
78 static TCGv cpu_seg_base
[6];
79 static TCGv_i64 cpu_bndl
[4];
80 static TCGv_i64 cpu_bndu
[4];
82 static TCGv_ptr cpu_ptr0
, cpu_ptr1
;
83 static TCGv_i32 cpu_tmp2_i32
, cpu_tmp3_i32
;
84 static TCGv_i64 cpu_tmp1_i64
;
86 #include "exec/gen-icount.h"
89 static int x86_64_hregs
;
92 typedef struct DisasContext
{
93 DisasContextBase base
;
95 /* current insn context */
96 int override
; /* -1 if no override */
100 target_ulong pc_start
;
101 target_ulong pc
; /* pc = eip + cs_base */
102 /* current block context */
103 target_ulong cs_base
; /* base of CS segment */
104 int pe
; /* protected mode */
105 int code32
; /* 32 bit code segment */
107 int lma
; /* long mode active */
108 int code64
; /* 64 bit code segment */
111 int vex_l
; /* vex vector length */
112 int vex_v
; /* vex vvvv register, without 1's complement. */
113 int ss32
; /* 32 bit stack segment */
114 CCOp cc_op
; /* current CC operation */
116 int addseg
; /* non zero if either DS/ES/SS have a non zero base */
117 int f_st
; /* currently unused */
118 int vm86
; /* vm86 mode */
121 int tf
; /* TF cpu flag */
122 int jmp_opt
; /* use direct block chaining for direct jumps */
123 int repz_opt
; /* optimize jumps within repz instructions */
124 int mem_index
; /* select memory access functions */
125 uint64_t flags
; /* all execution flags */
126 int popl_esp_hack
; /* for correct popl with esp base handling */
127 int rip_offset
; /* only used in x86_64, but left for simplicity */
129 int cpuid_ext_features
;
130 int cpuid_ext2_features
;
131 int cpuid_ext3_features
;
132 int cpuid_7_0_ebx_features
;
133 int cpuid_xsave_features
;
135 /* TCG local temps */
141 /* TCG local register indexes (only used inside old micro ops) */
148 static void gen_eob(DisasContext
*s
);
149 static void gen_jr(DisasContext
*s
, TCGv dest
);
150 static void gen_jmp(DisasContext
*s
, target_ulong eip
);
151 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
);
152 static void gen_op(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
);
154 /* i386 arith/logic operations */
174 OP_SHL1
, /* undocumented */
190 /* I386 int registers */
191 OR_EAX
, /* MUST be even numbered */
200 OR_TMP0
= 16, /* temporary operand register */
202 OR_A0
, /* temporary register used when doing address evaluation */
212 /* Bit set if the global variable is live after setting CC_OP to X. */
213 static const uint8_t cc_op_live
[CC_OP_NB
] = {
214 [CC_OP_DYNAMIC
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
215 [CC_OP_EFLAGS
] = USES_CC_SRC
,
216 [CC_OP_MULB
... CC_OP_MULQ
] = USES_CC_DST
| USES_CC_SRC
,
217 [CC_OP_ADDB
... CC_OP_ADDQ
] = USES_CC_DST
| USES_CC_SRC
,
218 [CC_OP_ADCB
... CC_OP_ADCQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
219 [CC_OP_SUBB
... CC_OP_SUBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRCT
,
220 [CC_OP_SBBB
... CC_OP_SBBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
221 [CC_OP_LOGICB
... CC_OP_LOGICQ
] = USES_CC_DST
,
222 [CC_OP_INCB
... CC_OP_INCQ
] = USES_CC_DST
| USES_CC_SRC
,
223 [CC_OP_DECB
... CC_OP_DECQ
] = USES_CC_DST
| USES_CC_SRC
,
224 [CC_OP_SHLB
... CC_OP_SHLQ
] = USES_CC_DST
| USES_CC_SRC
,
225 [CC_OP_SARB
... CC_OP_SARQ
] = USES_CC_DST
| USES_CC_SRC
,
226 [CC_OP_BMILGB
... CC_OP_BMILGQ
] = USES_CC_DST
| USES_CC_SRC
,
227 [CC_OP_ADCX
] = USES_CC_DST
| USES_CC_SRC
,
228 [CC_OP_ADOX
] = USES_CC_SRC
| USES_CC_SRC2
,
229 [CC_OP_ADCOX
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
231 [CC_OP_POPCNT
] = USES_CC_SRC
,
234 static void set_cc_op(DisasContext
*s
, CCOp op
)
238 if (s
->cc_op
== op
) {
242 /* Discard CC computation that will no longer be used. */
243 dead
= cc_op_live
[s
->cc_op
] & ~cc_op_live
[op
];
244 if (dead
& USES_CC_DST
) {
245 tcg_gen_discard_tl(cpu_cc_dst
);
247 if (dead
& USES_CC_SRC
) {
248 tcg_gen_discard_tl(cpu_cc_src
);
250 if (dead
& USES_CC_SRC2
) {
251 tcg_gen_discard_tl(cpu_cc_src2
);
253 if (dead
& USES_CC_SRCT
) {
254 tcg_gen_discard_tl(s
->cc_srcT
);
257 if (op
== CC_OP_DYNAMIC
) {
258 /* The DYNAMIC setting is translator only, and should never be
259 stored. Thus we always consider it clean. */
260 s
->cc_op_dirty
= false;
262 /* Discard any computed CC_OP value (see shifts). */
263 if (s
->cc_op
== CC_OP_DYNAMIC
) {
264 tcg_gen_discard_i32(cpu_cc_op
);
266 s
->cc_op_dirty
= true;
271 static void gen_update_cc_op(DisasContext
*s
)
273 if (s
->cc_op_dirty
) {
274 tcg_gen_movi_i32(cpu_cc_op
, s
->cc_op
);
275 s
->cc_op_dirty
= false;
281 #define NB_OP_SIZES 4
283 #else /* !TARGET_X86_64 */
285 #define NB_OP_SIZES 3
287 #endif /* !TARGET_X86_64 */
289 #if defined(HOST_WORDS_BIGENDIAN)
290 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
291 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
292 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
293 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
294 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
296 #define REG_B_OFFSET 0
297 #define REG_H_OFFSET 1
298 #define REG_W_OFFSET 0
299 #define REG_L_OFFSET 0
300 #define REG_LH_OFFSET 4
303 /* In instruction encodings for byte register accesses the
304 * register number usually indicates "low 8 bits of register N";
305 * however there are some special cases where N 4..7 indicates
306 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
307 * true for this special case, false otherwise.
309 static inline bool byte_reg_is_xH(int reg
)
315 if (reg
>= 8 || x86_64_hregs
) {
322 /* Select the size of a push/pop operation. */
323 static inline TCGMemOp
mo_pushpop(DisasContext
*s
, TCGMemOp ot
)
326 return ot
== MO_16
? MO_16
: MO_64
;
332 /* Select the size of the stack pointer. */
333 static inline TCGMemOp
mo_stacksize(DisasContext
*s
)
335 return CODE64(s
) ? MO_64
: s
->ss32
? MO_32
: MO_16
;
338 /* Select only size 64 else 32. Used for SSE operand sizes. */
339 static inline TCGMemOp
mo_64_32(TCGMemOp ot
)
342 return ot
== MO_64
? MO_64
: MO_32
;
348 /* Select size 8 if lsb of B is clear, else OT. Used for decoding
349 byte vs word opcodes. */
350 static inline TCGMemOp
mo_b_d(int b
, TCGMemOp ot
)
352 return b
& 1 ? ot
: MO_8
;
355 /* Select size 8 if lsb of B is clear, else OT capped at 32.
356 Used for decoding operand size of port opcodes. */
357 static inline TCGMemOp
mo_b_d32(int b
, TCGMemOp ot
)
359 return b
& 1 ? (ot
== MO_16
? MO_16
: MO_32
) : MO_8
;
362 static void gen_op_mov_reg_v(TCGMemOp ot
, int reg
, TCGv t0
)
366 if (!byte_reg_is_xH(reg
)) {
367 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 8);
369 tcg_gen_deposit_tl(cpu_regs
[reg
- 4], cpu_regs
[reg
- 4], t0
, 8, 8);
373 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 16);
376 /* For x86_64, this sets the higher half of register to zero.
377 For i386, this is equivalent to a mov. */
378 tcg_gen_ext32u_tl(cpu_regs
[reg
], t0
);
382 tcg_gen_mov_tl(cpu_regs
[reg
], t0
);
390 static inline void gen_op_mov_v_reg(TCGMemOp ot
, TCGv t0
, int reg
)
392 if (ot
== MO_8
&& byte_reg_is_xH(reg
)) {
393 tcg_gen_extract_tl(t0
, cpu_regs
[reg
- 4], 8, 8);
395 tcg_gen_mov_tl(t0
, cpu_regs
[reg
]);
399 static void gen_add_A0_im(DisasContext
*s
, int val
)
401 tcg_gen_addi_tl(s
->A0
, s
->A0
, val
);
403 tcg_gen_ext32u_tl(s
->A0
, s
->A0
);
407 static inline void gen_op_jmp_v(TCGv dest
)
409 tcg_gen_st_tl(dest
, cpu_env
, offsetof(CPUX86State
, eip
));
413 void gen_op_add_reg_im(DisasContext
*s
, TCGMemOp size
, int reg
, int32_t val
)
415 tcg_gen_addi_tl(s
->tmp0
, cpu_regs
[reg
], val
);
416 gen_op_mov_reg_v(size
, reg
, s
->tmp0
);
419 static inline void gen_op_add_reg_T0(DisasContext
*s
, TCGMemOp size
, int reg
)
421 tcg_gen_add_tl(s
->tmp0
, cpu_regs
[reg
], s
->T0
);
422 gen_op_mov_reg_v(size
, reg
, s
->tmp0
);
425 static inline void gen_op_ld_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
427 tcg_gen_qemu_ld_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
430 static inline void gen_op_st_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
432 tcg_gen_qemu_st_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
435 static inline void gen_op_st_rm_T0_A0(DisasContext
*s
, int idx
, int d
)
438 gen_op_st_v(s
, idx
, s
->T0
, s
->A0
);
440 gen_op_mov_reg_v(idx
, d
, s
->T0
);
444 static inline void gen_jmp_im(DisasContext
*s
, target_ulong pc
)
446 tcg_gen_movi_tl(s
->tmp0
, pc
);
447 gen_op_jmp_v(s
->tmp0
);
450 /* Compute SEG:REG into A0. SEG is selected from the override segment
451 (OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to
452 indicate no override. */
453 static void gen_lea_v_seg(DisasContext
*s
, TCGMemOp aflag
, TCGv a0
,
454 int def_seg
, int ovr_seg
)
460 tcg_gen_mov_tl(s
->A0
, a0
);
467 if (ovr_seg
< 0 && s
->addseg
) {
471 tcg_gen_ext32u_tl(s
->A0
, a0
);
477 tcg_gen_ext16u_tl(s
->A0
, a0
);
492 TCGv seg
= cpu_seg_base
[ovr_seg
];
494 if (aflag
== MO_64
) {
495 tcg_gen_add_tl(s
->A0
, a0
, seg
);
496 } else if (CODE64(s
)) {
497 tcg_gen_ext32u_tl(s
->A0
, a0
);
498 tcg_gen_add_tl(s
->A0
, s
->A0
, seg
);
500 tcg_gen_add_tl(s
->A0
, a0
, seg
);
501 tcg_gen_ext32u_tl(s
->A0
, s
->A0
);
506 static inline void gen_string_movl_A0_ESI(DisasContext
*s
)
508 gen_lea_v_seg(s
, s
->aflag
, cpu_regs
[R_ESI
], R_DS
, s
->override
);
511 static inline void gen_string_movl_A0_EDI(DisasContext
*s
)
513 gen_lea_v_seg(s
, s
->aflag
, cpu_regs
[R_EDI
], R_ES
, -1);
516 static inline void gen_op_movl_T0_Dshift(DisasContext
*s
, TCGMemOp ot
)
518 tcg_gen_ld32s_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, df
));
519 tcg_gen_shli_tl(s
->T0
, s
->T0
, ot
);
522 static TCGv
gen_ext_tl(TCGv dst
, TCGv src
, TCGMemOp size
, bool sign
)
527 tcg_gen_ext8s_tl(dst
, src
);
529 tcg_gen_ext8u_tl(dst
, src
);
534 tcg_gen_ext16s_tl(dst
, src
);
536 tcg_gen_ext16u_tl(dst
, src
);
542 tcg_gen_ext32s_tl(dst
, src
);
544 tcg_gen_ext32u_tl(dst
, src
);
553 static void gen_extu(TCGMemOp ot
, TCGv reg
)
555 gen_ext_tl(reg
, reg
, ot
, false);
558 static void gen_exts(TCGMemOp ot
, TCGv reg
)
560 gen_ext_tl(reg
, reg
, ot
, true);
564 void gen_op_jnz_ecx(DisasContext
*s
, TCGMemOp size
, TCGLabel
*label1
)
566 tcg_gen_mov_tl(s
->tmp0
, cpu_regs
[R_ECX
]);
567 gen_extu(size
, s
->tmp0
);
568 tcg_gen_brcondi_tl(TCG_COND_NE
, s
->tmp0
, 0, label1
);
572 void gen_op_jz_ecx(DisasContext
*s
, TCGMemOp size
, TCGLabel
*label1
)
574 tcg_gen_mov_tl(s
->tmp0
, cpu_regs
[R_ECX
]);
575 gen_extu(size
, s
->tmp0
);
576 tcg_gen_brcondi_tl(TCG_COND_EQ
, s
->tmp0
, 0, label1
);
579 static void gen_helper_in_func(TCGMemOp ot
, TCGv v
, TCGv_i32 n
)
583 gen_helper_inb(v
, cpu_env
, n
);
586 gen_helper_inw(v
, cpu_env
, n
);
589 gen_helper_inl(v
, cpu_env
, n
);
596 static void gen_helper_out_func(TCGMemOp ot
, TCGv_i32 v
, TCGv_i32 n
)
600 gen_helper_outb(cpu_env
, v
, n
);
603 gen_helper_outw(cpu_env
, v
, n
);
606 gen_helper_outl(cpu_env
, v
, n
);
613 static void gen_check_io(DisasContext
*s
, TCGMemOp ot
, target_ulong cur_eip
,
616 target_ulong next_eip
;
618 if (s
->pe
&& (s
->cpl
> s
->iopl
|| s
->vm86
)) {
619 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
622 gen_helper_check_iob(cpu_env
, cpu_tmp2_i32
);
625 gen_helper_check_iow(cpu_env
, cpu_tmp2_i32
);
628 gen_helper_check_iol(cpu_env
, cpu_tmp2_i32
);
634 if(s
->flags
& HF_SVMI_MASK
) {
636 gen_jmp_im(s
, cur_eip
);
637 svm_flags
|= (1 << (4 + ot
));
638 next_eip
= s
->pc
- s
->cs_base
;
639 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
640 gen_helper_svm_check_io(cpu_env
, cpu_tmp2_i32
,
641 tcg_const_i32(svm_flags
),
642 tcg_const_i32(next_eip
- cur_eip
));
646 static inline void gen_movs(DisasContext
*s
, TCGMemOp ot
)
648 gen_string_movl_A0_ESI(s
);
649 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
650 gen_string_movl_A0_EDI(s
);
651 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
652 gen_op_movl_T0_Dshift(s
, ot
);
653 gen_op_add_reg_T0(s
, s
->aflag
, R_ESI
);
654 gen_op_add_reg_T0(s
, s
->aflag
, R_EDI
);
657 static void gen_op_update1_cc(DisasContext
*s
)
659 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
662 static void gen_op_update2_cc(DisasContext
*s
)
664 tcg_gen_mov_tl(cpu_cc_src
, s
->T1
);
665 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
668 static void gen_op_update3_cc(DisasContext
*s
, TCGv reg
)
670 tcg_gen_mov_tl(cpu_cc_src2
, reg
);
671 tcg_gen_mov_tl(cpu_cc_src
, s
->T1
);
672 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
675 static inline void gen_op_testl_T0_T1_cc(DisasContext
*s
)
677 tcg_gen_and_tl(cpu_cc_dst
, s
->T0
, s
->T1
);
680 static void gen_op_update_neg_cc(DisasContext
*s
)
682 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
683 tcg_gen_neg_tl(cpu_cc_src
, s
->T0
);
684 tcg_gen_movi_tl(s
->cc_srcT
, 0);
687 /* compute all eflags to cc_src */
688 static void gen_compute_eflags(DisasContext
*s
)
690 TCGv zero
, dst
, src1
, src2
;
693 if (s
->cc_op
== CC_OP_EFLAGS
) {
696 if (s
->cc_op
== CC_OP_CLR
) {
697 tcg_gen_movi_tl(cpu_cc_src
, CC_Z
| CC_P
);
698 set_cc_op(s
, CC_OP_EFLAGS
);
707 /* Take care to not read values that are not live. */
708 live
= cc_op_live
[s
->cc_op
] & ~USES_CC_SRCT
;
709 dead
= live
^ (USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
);
711 zero
= tcg_const_tl(0);
712 if (dead
& USES_CC_DST
) {
715 if (dead
& USES_CC_SRC
) {
718 if (dead
& USES_CC_SRC2
) {
724 gen_helper_cc_compute_all(cpu_cc_src
, dst
, src1
, src2
, cpu_cc_op
);
725 set_cc_op(s
, CC_OP_EFLAGS
);
732 typedef struct CCPrepare
{
742 /* compute eflags.C to reg */
743 static CCPrepare
gen_prepare_eflags_c(DisasContext
*s
, TCGv reg
)
749 case CC_OP_SUBB
... CC_OP_SUBQ
:
750 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
751 size
= s
->cc_op
- CC_OP_SUBB
;
752 t1
= gen_ext_tl(s
->tmp0
, cpu_cc_src
, size
, false);
753 /* If no temporary was used, be careful not to alias t1 and t0. */
754 t0
= t1
== cpu_cc_src
? s
->tmp0
: reg
;
755 tcg_gen_mov_tl(t0
, s
->cc_srcT
);
759 case CC_OP_ADDB
... CC_OP_ADDQ
:
760 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
761 size
= s
->cc_op
- CC_OP_ADDB
;
762 t1
= gen_ext_tl(s
->tmp0
, cpu_cc_src
, size
, false);
763 t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
765 return (CCPrepare
) { .cond
= TCG_COND_LTU
, .reg
= t0
,
766 .reg2
= t1
, .mask
= -1, .use_reg2
= true };
768 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
771 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
773 case CC_OP_INCB
... CC_OP_INCQ
:
774 case CC_OP_DECB
... CC_OP_DECQ
:
775 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
776 .mask
= -1, .no_setcond
= true };
778 case CC_OP_SHLB
... CC_OP_SHLQ
:
779 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
780 size
= s
->cc_op
- CC_OP_SHLB
;
781 shift
= (8 << size
) - 1;
782 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
783 .mask
= (target_ulong
)1 << shift
};
785 case CC_OP_MULB
... CC_OP_MULQ
:
786 return (CCPrepare
) { .cond
= TCG_COND_NE
,
787 .reg
= cpu_cc_src
, .mask
= -1 };
789 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
790 size
= s
->cc_op
- CC_OP_BMILGB
;
791 t0
= gen_ext_tl(reg
, cpu_cc_src
, size
, false);
792 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
796 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_dst
,
797 .mask
= -1, .no_setcond
= true };
800 case CC_OP_SARB
... CC_OP_SARQ
:
802 return (CCPrepare
) { .cond
= TCG_COND_NE
,
803 .reg
= cpu_cc_src
, .mask
= CC_C
};
806 /* The need to compute only C from CC_OP_DYNAMIC is important
807 in efficiently implementing e.g. INC at the start of a TB. */
809 gen_helper_cc_compute_c(reg
, cpu_cc_dst
, cpu_cc_src
,
810 cpu_cc_src2
, cpu_cc_op
);
811 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
812 .mask
= -1, .no_setcond
= true };
816 /* compute eflags.P to reg */
817 static CCPrepare
gen_prepare_eflags_p(DisasContext
*s
, TCGv reg
)
819 gen_compute_eflags(s
);
820 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
824 /* compute eflags.S to reg */
825 static CCPrepare
gen_prepare_eflags_s(DisasContext
*s
, TCGv reg
)
829 gen_compute_eflags(s
);
835 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
839 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
842 TCGMemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
843 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, true);
844 return (CCPrepare
) { .cond
= TCG_COND_LT
, .reg
= t0
, .mask
= -1 };
849 /* compute eflags.O to reg */
850 static CCPrepare
gen_prepare_eflags_o(DisasContext
*s
, TCGv reg
)
855 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src2
,
856 .mask
= -1, .no_setcond
= true };
859 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
861 gen_compute_eflags(s
);
862 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
867 /* compute eflags.Z to reg */
868 static CCPrepare
gen_prepare_eflags_z(DisasContext
*s
, TCGv reg
)
872 gen_compute_eflags(s
);
878 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
881 return (CCPrepare
) { .cond
= TCG_COND_ALWAYS
, .mask
= -1 };
883 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= cpu_cc_src
,
887 TCGMemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
888 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
889 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
894 /* perform a conditional store into register 'reg' according to jump opcode
895 value 'b'. In the fast case, T0 is guaranted not to be used. */
896 static CCPrepare
gen_prepare_cc(DisasContext
*s
, int b
, TCGv reg
)
898 int inv
, jcc_op
, cond
;
904 jcc_op
= (b
>> 1) & 7;
907 case CC_OP_SUBB
... CC_OP_SUBQ
:
908 /* We optimize relational operators for the cmp/jcc case. */
909 size
= s
->cc_op
- CC_OP_SUBB
;
912 tcg_gen_mov_tl(s
->tmp4
, s
->cc_srcT
);
913 gen_extu(size
, s
->tmp4
);
914 t0
= gen_ext_tl(s
->tmp0
, cpu_cc_src
, size
, false);
915 cc
= (CCPrepare
) { .cond
= TCG_COND_LEU
, .reg
= s
->tmp4
,
916 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
925 tcg_gen_mov_tl(s
->tmp4
, s
->cc_srcT
);
926 gen_exts(size
, s
->tmp4
);
927 t0
= gen_ext_tl(s
->tmp0
, cpu_cc_src
, size
, true);
928 cc
= (CCPrepare
) { .cond
= cond
, .reg
= s
->tmp4
,
929 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
939 /* This actually generates good code for JC, JZ and JS. */
942 cc
= gen_prepare_eflags_o(s
, reg
);
945 cc
= gen_prepare_eflags_c(s
, reg
);
948 cc
= gen_prepare_eflags_z(s
, reg
);
951 gen_compute_eflags(s
);
952 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
953 .mask
= CC_Z
| CC_C
};
956 cc
= gen_prepare_eflags_s(s
, reg
);
959 cc
= gen_prepare_eflags_p(s
, reg
);
962 gen_compute_eflags(s
);
963 if (reg
== cpu_cc_src
) {
966 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
967 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
968 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
973 gen_compute_eflags(s
);
974 if (reg
== cpu_cc_src
) {
977 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
978 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
979 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
980 .mask
= CC_S
| CC_Z
};
987 cc
.cond
= tcg_invert_cond(cc
.cond
);
992 static void gen_setcc1(DisasContext
*s
, int b
, TCGv reg
)
994 CCPrepare cc
= gen_prepare_cc(s
, b
, reg
);
997 if (cc
.cond
== TCG_COND_EQ
) {
998 tcg_gen_xori_tl(reg
, cc
.reg
, 1);
1000 tcg_gen_mov_tl(reg
, cc
.reg
);
1005 if (cc
.cond
== TCG_COND_NE
&& !cc
.use_reg2
&& cc
.imm
== 0 &&
1006 cc
.mask
!= 0 && (cc
.mask
& (cc
.mask
- 1)) == 0) {
1007 tcg_gen_shri_tl(reg
, cc
.reg
, ctztl(cc
.mask
));
1008 tcg_gen_andi_tl(reg
, reg
, 1);
1011 if (cc
.mask
!= -1) {
1012 tcg_gen_andi_tl(reg
, cc
.reg
, cc
.mask
);
1016 tcg_gen_setcond_tl(cc
.cond
, reg
, cc
.reg
, cc
.reg2
);
1018 tcg_gen_setcondi_tl(cc
.cond
, reg
, cc
.reg
, cc
.imm
);
1022 static inline void gen_compute_eflags_c(DisasContext
*s
, TCGv reg
)
1024 gen_setcc1(s
, JCC_B
<< 1, reg
);
1027 /* generate a conditional jump to label 'l1' according to jump opcode
1028 value 'b'. In the fast case, T0 is guaranted not to be used. */
1029 static inline void gen_jcc1_noeob(DisasContext
*s
, int b
, TCGLabel
*l1
)
1031 CCPrepare cc
= gen_prepare_cc(s
, b
, s
->T0
);
1033 if (cc
.mask
!= -1) {
1034 tcg_gen_andi_tl(s
->T0
, cc
.reg
, cc
.mask
);
1038 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1040 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1044 /* Generate a conditional jump to label 'l1' according to jump opcode
1045 value 'b'. In the fast case, T0 is guaranted not to be used.
1046 A translation block must end soon. */
1047 static inline void gen_jcc1(DisasContext
*s
, int b
, TCGLabel
*l1
)
1049 CCPrepare cc
= gen_prepare_cc(s
, b
, s
->T0
);
1051 gen_update_cc_op(s
);
1052 if (cc
.mask
!= -1) {
1053 tcg_gen_andi_tl(s
->T0
, cc
.reg
, cc
.mask
);
1056 set_cc_op(s
, CC_OP_DYNAMIC
);
1058 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1060 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1064 /* XXX: does not work with gdbstub "ice" single step - not a
1066 static TCGLabel
*gen_jz_ecx_string(DisasContext
*s
, target_ulong next_eip
)
1068 TCGLabel
*l1
= gen_new_label();
1069 TCGLabel
*l2
= gen_new_label();
1070 gen_op_jnz_ecx(s
, s
->aflag
, l1
);
1072 gen_jmp_tb(s
, next_eip
, 1);
1077 static inline void gen_stos(DisasContext
*s
, TCGMemOp ot
)
1079 gen_op_mov_v_reg(MO_32
, s
->T0
, R_EAX
);
1080 gen_string_movl_A0_EDI(s
);
1081 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
1082 gen_op_movl_T0_Dshift(s
, ot
);
1083 gen_op_add_reg_T0(s
, s
->aflag
, R_EDI
);
1086 static inline void gen_lods(DisasContext
*s
, TCGMemOp ot
)
1088 gen_string_movl_A0_ESI(s
);
1089 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1090 gen_op_mov_reg_v(ot
, R_EAX
, s
->T0
);
1091 gen_op_movl_T0_Dshift(s
, ot
);
1092 gen_op_add_reg_T0(s
, s
->aflag
, R_ESI
);
1095 static inline void gen_scas(DisasContext
*s
, TCGMemOp ot
)
1097 gen_string_movl_A0_EDI(s
);
1098 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
1099 gen_op(s
, OP_CMPL
, ot
, R_EAX
);
1100 gen_op_movl_T0_Dshift(s
, ot
);
1101 gen_op_add_reg_T0(s
, s
->aflag
, R_EDI
);
1104 static inline void gen_cmps(DisasContext
*s
, TCGMemOp ot
)
1106 gen_string_movl_A0_EDI(s
);
1107 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
1108 gen_string_movl_A0_ESI(s
);
1109 gen_op(s
, OP_CMPL
, ot
, OR_TMP0
);
1110 gen_op_movl_T0_Dshift(s
, ot
);
1111 gen_op_add_reg_T0(s
, s
->aflag
, R_ESI
);
1112 gen_op_add_reg_T0(s
, s
->aflag
, R_EDI
);
1115 static void gen_bpt_io(DisasContext
*s
, TCGv_i32 t_port
, int ot
)
1117 if (s
->flags
& HF_IOBPT_MASK
) {
1118 TCGv_i32 t_size
= tcg_const_i32(1 << ot
);
1119 TCGv t_next
= tcg_const_tl(s
->pc
- s
->cs_base
);
1121 gen_helper_bpt_io(cpu_env
, t_port
, t_size
, t_next
);
1122 tcg_temp_free_i32(t_size
);
1123 tcg_temp_free(t_next
);
1128 static inline void gen_ins(DisasContext
*s
, TCGMemOp ot
)
1130 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
1133 gen_string_movl_A0_EDI(s
);
1134 /* Note: we must do this dummy write first to be restartable in
1135 case of page fault. */
1136 tcg_gen_movi_tl(s
->T0
, 0);
1137 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
1138 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_EDX
]);
1139 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1140 gen_helper_in_func(ot
, s
->T0
, cpu_tmp2_i32
);
1141 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
1142 gen_op_movl_T0_Dshift(s
, ot
);
1143 gen_op_add_reg_T0(s
, s
->aflag
, R_EDI
);
1144 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
1145 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
1150 static inline void gen_outs(DisasContext
*s
, TCGMemOp ot
)
1152 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
1155 gen_string_movl_A0_ESI(s
);
1156 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1158 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_EDX
]);
1159 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1160 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, s
->T0
);
1161 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1162 gen_op_movl_T0_Dshift(s
, ot
);
1163 gen_op_add_reg_T0(s
, s
->aflag
, R_ESI
);
1164 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
1165 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
1170 /* same method as Valgrind : we generate jumps to current or next
1172 #define GEN_REPZ(op) \
1173 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1174 target_ulong cur_eip, target_ulong next_eip) \
1177 gen_update_cc_op(s); \
1178 l2 = gen_jz_ecx_string(s, next_eip); \
1179 gen_ ## op(s, ot); \
1180 gen_op_add_reg_im(s, s->aflag, R_ECX, -1); \
1181 /* a loop would cause two single step exceptions if ECX = 1 \
1182 before rep string_insn */ \
1184 gen_op_jz_ecx(s, s->aflag, l2); \
1185 gen_jmp(s, cur_eip); \
1188 #define GEN_REPZ2(op) \
1189 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1190 target_ulong cur_eip, \
1191 target_ulong next_eip, \
1195 gen_update_cc_op(s); \
1196 l2 = gen_jz_ecx_string(s, next_eip); \
1197 gen_ ## op(s, ot); \
1198 gen_op_add_reg_im(s, s->aflag, R_ECX, -1); \
1199 gen_update_cc_op(s); \
1200 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
1202 gen_op_jz_ecx(s, s->aflag, l2); \
1203 gen_jmp(s, cur_eip); \
1214 static void gen_helper_fp_arith_ST0_FT0(int op
)
1218 gen_helper_fadd_ST0_FT0(cpu_env
);
1221 gen_helper_fmul_ST0_FT0(cpu_env
);
1224 gen_helper_fcom_ST0_FT0(cpu_env
);
1227 gen_helper_fcom_ST0_FT0(cpu_env
);
1230 gen_helper_fsub_ST0_FT0(cpu_env
);
1233 gen_helper_fsubr_ST0_FT0(cpu_env
);
1236 gen_helper_fdiv_ST0_FT0(cpu_env
);
1239 gen_helper_fdivr_ST0_FT0(cpu_env
);
1244 /* NOTE the exception in "r" op ordering */
1245 static void gen_helper_fp_arith_STN_ST0(int op
, int opreg
)
1247 TCGv_i32 tmp
= tcg_const_i32(opreg
);
1250 gen_helper_fadd_STN_ST0(cpu_env
, tmp
);
1253 gen_helper_fmul_STN_ST0(cpu_env
, tmp
);
1256 gen_helper_fsubr_STN_ST0(cpu_env
, tmp
);
1259 gen_helper_fsub_STN_ST0(cpu_env
, tmp
);
1262 gen_helper_fdivr_STN_ST0(cpu_env
, tmp
);
1265 gen_helper_fdiv_STN_ST0(cpu_env
, tmp
);
1270 /* if d == OR_TMP0, it means memory operand (address in A0) */
1271 static void gen_op(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
)
1274 gen_op_mov_v_reg(ot
, s1
->T0
, d
);
1275 } else if (!(s1
->prefix
& PREFIX_LOCK
)) {
1276 gen_op_ld_v(s1
, ot
, s1
->T0
, s1
->A0
);
1280 gen_compute_eflags_c(s1
, s1
->tmp4
);
1281 if (s1
->prefix
& PREFIX_LOCK
) {
1282 tcg_gen_add_tl(s1
->T0
, s1
->tmp4
, s1
->T1
);
1283 tcg_gen_atomic_add_fetch_tl(s1
->T0
, s1
->A0
, s1
->T0
,
1284 s1
->mem_index
, ot
| MO_LE
);
1286 tcg_gen_add_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1287 tcg_gen_add_tl(s1
->T0
, s1
->T0
, s1
->tmp4
);
1288 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1290 gen_op_update3_cc(s1
, s1
->tmp4
);
1291 set_cc_op(s1
, CC_OP_ADCB
+ ot
);
1294 gen_compute_eflags_c(s1
, s1
->tmp4
);
1295 if (s1
->prefix
& PREFIX_LOCK
) {
1296 tcg_gen_add_tl(s1
->T0
, s1
->T1
, s1
->tmp4
);
1297 tcg_gen_neg_tl(s1
->T0
, s1
->T0
);
1298 tcg_gen_atomic_add_fetch_tl(s1
->T0
, s1
->A0
, s1
->T0
,
1299 s1
->mem_index
, ot
| MO_LE
);
1301 tcg_gen_sub_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1302 tcg_gen_sub_tl(s1
->T0
, s1
->T0
, s1
->tmp4
);
1303 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1305 gen_op_update3_cc(s1
, s1
->tmp4
);
1306 set_cc_op(s1
, CC_OP_SBBB
+ ot
);
1309 if (s1
->prefix
& PREFIX_LOCK
) {
1310 tcg_gen_atomic_add_fetch_tl(s1
->T0
, s1
->A0
, s1
->T1
,
1311 s1
->mem_index
, ot
| MO_LE
);
1313 tcg_gen_add_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1314 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1316 gen_op_update2_cc(s1
);
1317 set_cc_op(s1
, CC_OP_ADDB
+ ot
);
1320 if (s1
->prefix
& PREFIX_LOCK
) {
1321 tcg_gen_neg_tl(s1
->T0
, s1
->T1
);
1322 tcg_gen_atomic_fetch_add_tl(s1
->cc_srcT
, s1
->A0
, s1
->T0
,
1323 s1
->mem_index
, ot
| MO_LE
);
1324 tcg_gen_sub_tl(s1
->T0
, s1
->cc_srcT
, s1
->T1
);
1326 tcg_gen_mov_tl(s1
->cc_srcT
, s1
->T0
);
1327 tcg_gen_sub_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1328 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1330 gen_op_update2_cc(s1
);
1331 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1335 if (s1
->prefix
& PREFIX_LOCK
) {
1336 tcg_gen_atomic_and_fetch_tl(s1
->T0
, s1
->A0
, s1
->T1
,
1337 s1
->mem_index
, ot
| MO_LE
);
1339 tcg_gen_and_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1340 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1342 gen_op_update1_cc(s1
);
1343 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1346 if (s1
->prefix
& PREFIX_LOCK
) {
1347 tcg_gen_atomic_or_fetch_tl(s1
->T0
, s1
->A0
, s1
->T1
,
1348 s1
->mem_index
, ot
| MO_LE
);
1350 tcg_gen_or_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1351 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1353 gen_op_update1_cc(s1
);
1354 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1357 if (s1
->prefix
& PREFIX_LOCK
) {
1358 tcg_gen_atomic_xor_fetch_tl(s1
->T0
, s1
->A0
, s1
->T1
,
1359 s1
->mem_index
, ot
| MO_LE
);
1361 tcg_gen_xor_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1362 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1364 gen_op_update1_cc(s1
);
1365 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1368 tcg_gen_mov_tl(cpu_cc_src
, s1
->T1
);
1369 tcg_gen_mov_tl(s1
->cc_srcT
, s1
->T0
);
1370 tcg_gen_sub_tl(cpu_cc_dst
, s1
->T0
, s1
->T1
);
1371 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1376 /* if d == OR_TMP0, it means memory operand (address in A0) */
1377 static void gen_inc(DisasContext
*s1
, TCGMemOp ot
, int d
, int c
)
1379 if (s1
->prefix
& PREFIX_LOCK
) {
1380 tcg_gen_movi_tl(s1
->T0
, c
> 0 ? 1 : -1);
1381 tcg_gen_atomic_add_fetch_tl(s1
->T0
, s1
->A0
, s1
->T0
,
1382 s1
->mem_index
, ot
| MO_LE
);
1385 gen_op_mov_v_reg(ot
, s1
->T0
, d
);
1387 gen_op_ld_v(s1
, ot
, s1
->T0
, s1
->A0
);
1389 tcg_gen_addi_tl(s1
->T0
, s1
->T0
, (c
> 0 ? 1 : -1));
1390 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1393 gen_compute_eflags_c(s1
, cpu_cc_src
);
1394 tcg_gen_mov_tl(cpu_cc_dst
, s1
->T0
);
1395 set_cc_op(s1
, (c
> 0 ? CC_OP_INCB
: CC_OP_DECB
) + ot
);
1398 static void gen_shift_flags(DisasContext
*s
, TCGMemOp ot
, TCGv result
,
1399 TCGv shm1
, TCGv count
, bool is_right
)
1401 TCGv_i32 z32
, s32
, oldop
;
1404 /* Store the results into the CC variables. If we know that the
1405 variable must be dead, store unconditionally. Otherwise we'll
1406 need to not disrupt the current contents. */
1407 z_tl
= tcg_const_tl(0);
1408 if (cc_op_live
[s
->cc_op
] & USES_CC_DST
) {
1409 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_dst
, count
, z_tl
,
1410 result
, cpu_cc_dst
);
1412 tcg_gen_mov_tl(cpu_cc_dst
, result
);
1414 if (cc_op_live
[s
->cc_op
] & USES_CC_SRC
) {
1415 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_src
, count
, z_tl
,
1418 tcg_gen_mov_tl(cpu_cc_src
, shm1
);
1420 tcg_temp_free(z_tl
);
1422 /* Get the two potential CC_OP values into temporaries. */
1423 tcg_gen_movi_i32(cpu_tmp2_i32
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1424 if (s
->cc_op
== CC_OP_DYNAMIC
) {
1427 tcg_gen_movi_i32(cpu_tmp3_i32
, s
->cc_op
);
1428 oldop
= cpu_tmp3_i32
;
1431 /* Conditionally store the CC_OP value. */
1432 z32
= tcg_const_i32(0);
1433 s32
= tcg_temp_new_i32();
1434 tcg_gen_trunc_tl_i32(s32
, count
);
1435 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, s32
, z32
, cpu_tmp2_i32
, oldop
);
1436 tcg_temp_free_i32(z32
);
1437 tcg_temp_free_i32(s32
);
1439 /* The CC_OP value is no longer predictable. */
1440 set_cc_op(s
, CC_OP_DYNAMIC
);
1443 static void gen_shift_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1444 int is_right
, int is_arith
)
1446 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1449 if (op1
== OR_TMP0
) {
1450 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1452 gen_op_mov_v_reg(ot
, s
->T0
, op1
);
1455 tcg_gen_andi_tl(s
->T1
, s
->T1
, mask
);
1456 tcg_gen_subi_tl(s
->tmp0
, s
->T1
, 1);
1460 gen_exts(ot
, s
->T0
);
1461 tcg_gen_sar_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1462 tcg_gen_sar_tl(s
->T0
, s
->T0
, s
->T1
);
1464 gen_extu(ot
, s
->T0
);
1465 tcg_gen_shr_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1466 tcg_gen_shr_tl(s
->T0
, s
->T0
, s
->T1
);
1469 tcg_gen_shl_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1470 tcg_gen_shl_tl(s
->T0
, s
->T0
, s
->T1
);
1474 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1476 gen_shift_flags(s
, ot
, s
->T0
, s
->tmp0
, s
->T1
, is_right
);
1479 static void gen_shift_rm_im(DisasContext
*s
, TCGMemOp ot
, int op1
, int op2
,
1480 int is_right
, int is_arith
)
1482 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1486 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1488 gen_op_mov_v_reg(ot
, s
->T0
, op1
);
1494 gen_exts(ot
, s
->T0
);
1495 tcg_gen_sari_tl(s
->tmp4
, s
->T0
, op2
- 1);
1496 tcg_gen_sari_tl(s
->T0
, s
->T0
, op2
);
1498 gen_extu(ot
, s
->T0
);
1499 tcg_gen_shri_tl(s
->tmp4
, s
->T0
, op2
- 1);
1500 tcg_gen_shri_tl(s
->T0
, s
->T0
, op2
);
1503 tcg_gen_shli_tl(s
->tmp4
, s
->T0
, op2
- 1);
1504 tcg_gen_shli_tl(s
->T0
, s
->T0
, op2
);
1509 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1511 /* update eflags if non zero shift */
1513 tcg_gen_mov_tl(cpu_cc_src
, s
->tmp4
);
1514 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
1515 set_cc_op(s
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1519 static void gen_rot_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
, int is_right
)
1521 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1525 if (op1
== OR_TMP0
) {
1526 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1528 gen_op_mov_v_reg(ot
, s
->T0
, op1
);
1531 tcg_gen_andi_tl(s
->T1
, s
->T1
, mask
);
1535 /* Replicate the 8-bit input so that a 32-bit rotate works. */
1536 tcg_gen_ext8u_tl(s
->T0
, s
->T0
);
1537 tcg_gen_muli_tl(s
->T0
, s
->T0
, 0x01010101);
1540 /* Replicate the 16-bit input so that a 32-bit rotate works. */
1541 tcg_gen_deposit_tl(s
->T0
, s
->T0
, s
->T0
, 16, 16);
1544 #ifdef TARGET_X86_64
1546 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
1547 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, s
->T1
);
1549 tcg_gen_rotr_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1551 tcg_gen_rotl_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1553 tcg_gen_extu_i32_tl(s
->T0
, cpu_tmp2_i32
);
1558 tcg_gen_rotr_tl(s
->T0
, s
->T0
, s
->T1
);
1560 tcg_gen_rotl_tl(s
->T0
, s
->T0
, s
->T1
);
1566 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1568 /* We'll need the flags computed into CC_SRC. */
1569 gen_compute_eflags(s
);
1571 /* The value that was "rotated out" is now present at the other end
1572 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1573 since we've computed the flags into CC_SRC, these variables are
1576 tcg_gen_shri_tl(cpu_cc_src2
, s
->T0
, mask
- 1);
1577 tcg_gen_shri_tl(cpu_cc_dst
, s
->T0
, mask
);
1578 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1580 tcg_gen_shri_tl(cpu_cc_src2
, s
->T0
, mask
);
1581 tcg_gen_andi_tl(cpu_cc_dst
, s
->T0
, 1);
1583 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1584 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1586 /* Now conditionally store the new CC_OP value. If the shift count
1587 is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1588 Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1589 exactly as we computed above. */
1590 t0
= tcg_const_i32(0);
1591 t1
= tcg_temp_new_i32();
1592 tcg_gen_trunc_tl_i32(t1
, s
->T1
);
1593 tcg_gen_movi_i32(cpu_tmp2_i32
, CC_OP_ADCOX
);
1594 tcg_gen_movi_i32(cpu_tmp3_i32
, CC_OP_EFLAGS
);
1595 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, t1
, t0
,
1596 cpu_tmp2_i32
, cpu_tmp3_i32
);
1597 tcg_temp_free_i32(t0
);
1598 tcg_temp_free_i32(t1
);
1600 /* The CC_OP value is no longer predictable. */
1601 set_cc_op(s
, CC_OP_DYNAMIC
);
1604 static void gen_rot_rm_im(DisasContext
*s
, TCGMemOp ot
, int op1
, int op2
,
1607 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1611 if (op1
== OR_TMP0
) {
1612 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1614 gen_op_mov_v_reg(ot
, s
->T0
, op1
);
1620 #ifdef TARGET_X86_64
1622 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
1624 tcg_gen_rotri_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, op2
);
1626 tcg_gen_rotli_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, op2
);
1628 tcg_gen_extu_i32_tl(s
->T0
, cpu_tmp2_i32
);
1633 tcg_gen_rotri_tl(s
->T0
, s
->T0
, op2
);
1635 tcg_gen_rotli_tl(s
->T0
, s
->T0
, op2
);
1646 shift
= mask
+ 1 - shift
;
1648 gen_extu(ot
, s
->T0
);
1649 tcg_gen_shli_tl(s
->tmp0
, s
->T0
, shift
);
1650 tcg_gen_shri_tl(s
->T0
, s
->T0
, mask
+ 1 - shift
);
1651 tcg_gen_or_tl(s
->T0
, s
->T0
, s
->tmp0
);
1657 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1660 /* Compute the flags into CC_SRC. */
1661 gen_compute_eflags(s
);
1663 /* The value that was "rotated out" is now present at the other end
1664 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1665 since we've computed the flags into CC_SRC, these variables are
1668 tcg_gen_shri_tl(cpu_cc_src2
, s
->T0
, mask
- 1);
1669 tcg_gen_shri_tl(cpu_cc_dst
, s
->T0
, mask
);
1670 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1672 tcg_gen_shri_tl(cpu_cc_src2
, s
->T0
, mask
);
1673 tcg_gen_andi_tl(cpu_cc_dst
, s
->T0
, 1);
1675 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1676 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1677 set_cc_op(s
, CC_OP_ADCOX
);
1681 /* XXX: add faster immediate = 1 case */
1682 static void gen_rotc_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1685 gen_compute_eflags(s
);
1686 assert(s
->cc_op
== CC_OP_EFLAGS
);
1690 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1692 gen_op_mov_v_reg(ot
, s
->T0
, op1
);
1697 gen_helper_rcrb(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1700 gen_helper_rcrw(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1703 gen_helper_rcrl(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1705 #ifdef TARGET_X86_64
1707 gen_helper_rcrq(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1716 gen_helper_rclb(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1719 gen_helper_rclw(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1722 gen_helper_rcll(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1724 #ifdef TARGET_X86_64
1726 gen_helper_rclq(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1734 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1737 /* XXX: add faster immediate case */
1738 static void gen_shiftd_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1739 bool is_right
, TCGv count_in
)
1741 target_ulong mask
= (ot
== MO_64
? 63 : 31);
1745 if (op1
== OR_TMP0
) {
1746 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1748 gen_op_mov_v_reg(ot
, s
->T0
, op1
);
1751 count
= tcg_temp_new();
1752 tcg_gen_andi_tl(count
, count_in
, mask
);
1756 /* Note: we implement the Intel behaviour for shift count > 16.
1757 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A
1758 portion by constructing it as a 32-bit value. */
1760 tcg_gen_deposit_tl(s
->tmp0
, s
->T0
, s
->T1
, 16, 16);
1761 tcg_gen_mov_tl(s
->T1
, s
->T0
);
1762 tcg_gen_mov_tl(s
->T0
, s
->tmp0
);
1764 tcg_gen_deposit_tl(s
->T1
, s
->T0
, s
->T1
, 16, 16);
1767 #ifdef TARGET_X86_64
1769 /* Concatenate the two 32-bit values and use a 64-bit shift. */
1770 tcg_gen_subi_tl(s
->tmp0
, count
, 1);
1772 tcg_gen_concat_tl_i64(s
->T0
, s
->T0
, s
->T1
);
1773 tcg_gen_shr_i64(s
->tmp0
, s
->T0
, s
->tmp0
);
1774 tcg_gen_shr_i64(s
->T0
, s
->T0
, count
);
1776 tcg_gen_concat_tl_i64(s
->T0
, s
->T1
, s
->T0
);
1777 tcg_gen_shl_i64(s
->tmp0
, s
->T0
, s
->tmp0
);
1778 tcg_gen_shl_i64(s
->T0
, s
->T0
, count
);
1779 tcg_gen_shri_i64(s
->tmp0
, s
->tmp0
, 32);
1780 tcg_gen_shri_i64(s
->T0
, s
->T0
, 32);
1785 tcg_gen_subi_tl(s
->tmp0
, count
, 1);
1787 tcg_gen_shr_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1789 tcg_gen_subfi_tl(s
->tmp4
, mask
+ 1, count
);
1790 tcg_gen_shr_tl(s
->T0
, s
->T0
, count
);
1791 tcg_gen_shl_tl(s
->T1
, s
->T1
, s
->tmp4
);
1793 tcg_gen_shl_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1795 /* Only needed if count > 16, for Intel behaviour. */
1796 tcg_gen_subfi_tl(s
->tmp4
, 33, count
);
1797 tcg_gen_shr_tl(s
->tmp4
, s
->T1
, s
->tmp4
);
1798 tcg_gen_or_tl(s
->tmp0
, s
->tmp0
, s
->tmp4
);
1801 tcg_gen_subfi_tl(s
->tmp4
, mask
+ 1, count
);
1802 tcg_gen_shl_tl(s
->T0
, s
->T0
, count
);
1803 tcg_gen_shr_tl(s
->T1
, s
->T1
, s
->tmp4
);
1805 tcg_gen_movi_tl(s
->tmp4
, 0);
1806 tcg_gen_movcond_tl(TCG_COND_EQ
, s
->T1
, count
, s
->tmp4
,
1808 tcg_gen_or_tl(s
->T0
, s
->T0
, s
->T1
);
1813 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1815 gen_shift_flags(s
, ot
, s
->T0
, s
->tmp0
, count
, is_right
);
1816 tcg_temp_free(count
);
1819 static void gen_shift(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
, int s
)
1822 gen_op_mov_v_reg(ot
, s1
->T1
, s
);
1825 gen_rot_rm_T1(s1
, ot
, d
, 0);
1828 gen_rot_rm_T1(s1
, ot
, d
, 1);
1832 gen_shift_rm_T1(s1
, ot
, d
, 0, 0);
1835 gen_shift_rm_T1(s1
, ot
, d
, 1, 0);
1838 gen_shift_rm_T1(s1
, ot
, d
, 1, 1);
1841 gen_rotc_rm_T1(s1
, ot
, d
, 0);
1844 gen_rotc_rm_T1(s1
, ot
, d
, 1);
1849 static void gen_shifti(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
, int c
)
1853 gen_rot_rm_im(s1
, ot
, d
, c
, 0);
1856 gen_rot_rm_im(s1
, ot
, d
, c
, 1);
1860 gen_shift_rm_im(s1
, ot
, d
, c
, 0, 0);
1863 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 0);
1866 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 1);
1869 /* currently not optimized */
1870 tcg_gen_movi_tl(s1
->T1
, c
);
1871 gen_shift(s1
, op
, ot
, d
, OR_TMP1
);
1876 #define X86_MAX_INSN_LENGTH 15
1878 static uint64_t advance_pc(CPUX86State
*env
, DisasContext
*s
, int num_bytes
)
1880 uint64_t pc
= s
->pc
;
1883 if (unlikely(s
->pc
- s
->pc_start
> X86_MAX_INSN_LENGTH
)) {
1884 /* If the instruction's 16th byte is on a different page than the 1st, a
1885 * page fault on the second page wins over the general protection fault
1886 * caused by the instruction being too long.
1887 * This can happen even if the operand is only one byte long!
1889 if (((s
->pc
- 1) ^ (pc
- 1)) & TARGET_PAGE_MASK
) {
1890 volatile uint8_t unused
=
1891 cpu_ldub_code(env
, (s
->pc
- 1) & TARGET_PAGE_MASK
);
1894 siglongjmp(s
->jmpbuf
, 1);
1900 static inline uint8_t x86_ldub_code(CPUX86State
*env
, DisasContext
*s
)
1902 return cpu_ldub_code(env
, advance_pc(env
, s
, 1));
1905 static inline int16_t x86_ldsw_code(CPUX86State
*env
, DisasContext
*s
)
1907 return cpu_ldsw_code(env
, advance_pc(env
, s
, 2));
1910 static inline uint16_t x86_lduw_code(CPUX86State
*env
, DisasContext
*s
)
1912 return cpu_lduw_code(env
, advance_pc(env
, s
, 2));
1915 static inline uint32_t x86_ldl_code(CPUX86State
*env
, DisasContext
*s
)
1917 return cpu_ldl_code(env
, advance_pc(env
, s
, 4));
1920 #ifdef TARGET_X86_64
1921 static inline uint64_t x86_ldq_code(CPUX86State
*env
, DisasContext
*s
)
1923 return cpu_ldq_code(env
, advance_pc(env
, s
, 8));
1927 /* Decompose an address. */
1929 typedef struct AddressParts
{
1937 static AddressParts
gen_lea_modrm_0(CPUX86State
*env
, DisasContext
*s
,
1940 int def_seg
, base
, index
, scale
, mod
, rm
;
1949 mod
= (modrm
>> 6) & 3;
1951 base
= rm
| REX_B(s
);
1954 /* Normally filtered out earlier, but including this path
1955 simplifies multi-byte nop, as well as bndcl, bndcu, bndcn. */
1964 int code
= x86_ldub_code(env
, s
);
1965 scale
= (code
>> 6) & 3;
1966 index
= ((code
>> 3) & 7) | REX_X(s
);
1968 index
= -1; /* no index */
1970 base
= (code
& 7) | REX_B(s
);
1976 if ((base
& 7) == 5) {
1978 disp
= (int32_t)x86_ldl_code(env
, s
);
1979 if (CODE64(s
) && !havesib
) {
1981 disp
+= s
->pc
+ s
->rip_offset
;
1986 disp
= (int8_t)x86_ldub_code(env
, s
);
1990 disp
= (int32_t)x86_ldl_code(env
, s
);
1994 /* For correct popl handling with esp. */
1995 if (base
== R_ESP
&& s
->popl_esp_hack
) {
1996 disp
+= s
->popl_esp_hack
;
1998 if (base
== R_EBP
|| base
== R_ESP
) {
2007 disp
= x86_lduw_code(env
, s
);
2010 } else if (mod
== 1) {
2011 disp
= (int8_t)x86_ldub_code(env
, s
);
2013 disp
= (int16_t)x86_lduw_code(env
, s
);
2057 return (AddressParts
){ def_seg
, base
, index
, scale
, disp
};
2060 /* Compute the address, with a minimum number of TCG ops. */
2061 static TCGv
gen_lea_modrm_1(DisasContext
*s
, AddressParts a
)
2067 ea
= cpu_regs
[a
.index
];
2069 tcg_gen_shli_tl(s
->A0
, cpu_regs
[a
.index
], a
.scale
);
2073 tcg_gen_add_tl(s
->A0
, ea
, cpu_regs
[a
.base
]);
2076 } else if (a
.base
>= 0) {
2077 ea
= cpu_regs
[a
.base
];
2080 tcg_gen_movi_tl(s
->A0
, a
.disp
);
2082 } else if (a
.disp
!= 0) {
2083 tcg_gen_addi_tl(s
->A0
, ea
, a
.disp
);
2090 static void gen_lea_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2092 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
2093 TCGv ea
= gen_lea_modrm_1(s
, a
);
2094 gen_lea_v_seg(s
, s
->aflag
, ea
, a
.def_seg
, s
->override
);
2097 static void gen_nop_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2099 (void)gen_lea_modrm_0(env
, s
, modrm
);
2102 /* Used for BNDCL, BNDCU, BNDCN. */
2103 static void gen_bndck(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2104 TCGCond cond
, TCGv_i64 bndv
)
2106 TCGv ea
= gen_lea_modrm_1(s
, gen_lea_modrm_0(env
, s
, modrm
));
2108 tcg_gen_extu_tl_i64(cpu_tmp1_i64
, ea
);
2110 tcg_gen_ext32u_i64(cpu_tmp1_i64
, cpu_tmp1_i64
);
2112 tcg_gen_setcond_i64(cond
, cpu_tmp1_i64
, cpu_tmp1_i64
, bndv
);
2113 tcg_gen_extrl_i64_i32(cpu_tmp2_i32
, cpu_tmp1_i64
);
2114 gen_helper_bndck(cpu_env
, cpu_tmp2_i32
);
2117 /* used for LEA and MOV AX, mem */
2118 static void gen_add_A0_ds_seg(DisasContext
*s
)
2120 gen_lea_v_seg(s
, s
->aflag
, s
->A0
, R_DS
, s
->override
);
2123 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2125 static void gen_ldst_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2126 TCGMemOp ot
, int reg
, int is_store
)
2130 mod
= (modrm
>> 6) & 3;
2131 rm
= (modrm
& 7) | REX_B(s
);
2135 gen_op_mov_v_reg(ot
, s
->T0
, reg
);
2136 gen_op_mov_reg_v(ot
, rm
, s
->T0
);
2138 gen_op_mov_v_reg(ot
, s
->T0
, rm
);
2140 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
2143 gen_lea_modrm(env
, s
, modrm
);
2146 gen_op_mov_v_reg(ot
, s
->T0
, reg
);
2147 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
2149 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
2151 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
2156 static inline uint32_t insn_get(CPUX86State
*env
, DisasContext
*s
, TCGMemOp ot
)
2162 ret
= x86_ldub_code(env
, s
);
2165 ret
= x86_lduw_code(env
, s
);
2168 #ifdef TARGET_X86_64
2171 ret
= x86_ldl_code(env
, s
);
2179 static inline int insn_const_size(TCGMemOp ot
)
2188 static inline bool use_goto_tb(DisasContext
*s
, target_ulong pc
)
2190 #ifndef CONFIG_USER_ONLY
2191 return (pc
& TARGET_PAGE_MASK
) == (s
->base
.tb
->pc
& TARGET_PAGE_MASK
) ||
2192 (pc
& TARGET_PAGE_MASK
) == (s
->pc_start
& TARGET_PAGE_MASK
);
2198 static inline void gen_goto_tb(DisasContext
*s
, int tb_num
, target_ulong eip
)
2200 target_ulong pc
= s
->cs_base
+ eip
;
2202 if (use_goto_tb(s
, pc
)) {
2203 /* jump to same page: we can use a direct jump */
2204 tcg_gen_goto_tb(tb_num
);
2206 tcg_gen_exit_tb(s
->base
.tb
, tb_num
);
2207 s
->base
.is_jmp
= DISAS_NORETURN
;
2209 /* jump to another page */
2215 static inline void gen_jcc(DisasContext
*s
, int b
,
2216 target_ulong val
, target_ulong next_eip
)
2221 l1
= gen_new_label();
2224 gen_goto_tb(s
, 0, next_eip
);
2227 gen_goto_tb(s
, 1, val
);
2229 l1
= gen_new_label();
2230 l2
= gen_new_label();
2233 gen_jmp_im(s
, next_eip
);
2243 static void gen_cmovcc1(CPUX86State
*env
, DisasContext
*s
, TCGMemOp ot
, int b
,
2248 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
2250 cc
= gen_prepare_cc(s
, b
, s
->T1
);
2251 if (cc
.mask
!= -1) {
2252 TCGv t0
= tcg_temp_new();
2253 tcg_gen_andi_tl(t0
, cc
.reg
, cc
.mask
);
2257 cc
.reg2
= tcg_const_tl(cc
.imm
);
2260 tcg_gen_movcond_tl(cc
.cond
, s
->T0
, cc
.reg
, cc
.reg2
,
2261 s
->T0
, cpu_regs
[reg
]);
2262 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
2264 if (cc
.mask
!= -1) {
2265 tcg_temp_free(cc
.reg
);
2268 tcg_temp_free(cc
.reg2
);
2272 static inline void gen_op_movl_T0_seg(DisasContext
*s
, int seg_reg
)
2274 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
2275 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2278 static inline void gen_op_movl_seg_T0_vm(DisasContext
*s
, int seg_reg
)
2280 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
2281 tcg_gen_st32_tl(s
->T0
, cpu_env
,
2282 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2283 tcg_gen_shli_tl(cpu_seg_base
[seg_reg
], s
->T0
, 4);
2286 /* move T0 to seg_reg and compute if the CPU state may change. Never
2287 call this function with seg_reg == R_CS */
2288 static void gen_movl_seg_T0(DisasContext
*s
, int seg_reg
)
2290 if (s
->pe
&& !s
->vm86
) {
2291 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
2292 gen_helper_load_seg(cpu_env
, tcg_const_i32(seg_reg
), cpu_tmp2_i32
);
2293 /* abort translation because the addseg value may change or
2294 because ss32 may change. For R_SS, translation must always
2295 stop as a special handling must be done to disable hardware
2296 interrupts for the next instruction */
2297 if (seg_reg
== R_SS
|| (s
->code32
&& seg_reg
< R_FS
)) {
2298 s
->base
.is_jmp
= DISAS_TOO_MANY
;
2301 gen_op_movl_seg_T0_vm(s
, seg_reg
);
2302 if (seg_reg
== R_SS
) {
2303 s
->base
.is_jmp
= DISAS_TOO_MANY
;
2308 static inline int svm_is_rep(int prefixes
)
2310 return ((prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) ? 8 : 0);
2314 gen_svm_check_intercept_param(DisasContext
*s
, target_ulong pc_start
,
2315 uint32_t type
, uint64_t param
)
2317 /* no SVM activated; fast case */
2318 if (likely(!(s
->flags
& HF_SVMI_MASK
)))
2320 gen_update_cc_op(s
);
2321 gen_jmp_im(s
, pc_start
- s
->cs_base
);
2322 gen_helper_svm_check_intercept_param(cpu_env
, tcg_const_i32(type
),
2323 tcg_const_i64(param
));
2327 gen_svm_check_intercept(DisasContext
*s
, target_ulong pc_start
, uint64_t type
)
2329 gen_svm_check_intercept_param(s
, pc_start
, type
, 0);
2332 static inline void gen_stack_update(DisasContext
*s
, int addend
)
2334 gen_op_add_reg_im(s
, mo_stacksize(s
), R_ESP
, addend
);
2337 /* Generate a push. It depends on ss32, addseg and dflag. */
2338 static void gen_push_v(DisasContext
*s
, TCGv val
)
2340 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2341 TCGMemOp a_ot
= mo_stacksize(s
);
2342 int size
= 1 << d_ot
;
2343 TCGv new_esp
= s
->A0
;
2345 tcg_gen_subi_tl(s
->A0
, cpu_regs
[R_ESP
], size
);
2350 tcg_gen_mov_tl(new_esp
, s
->A0
);
2352 gen_lea_v_seg(s
, a_ot
, s
->A0
, R_SS
, -1);
2355 gen_op_st_v(s
, d_ot
, val
, s
->A0
);
2356 gen_op_mov_reg_v(a_ot
, R_ESP
, new_esp
);
2359 /* two step pop is necessary for precise exceptions */
2360 static TCGMemOp
gen_pop_T0(DisasContext
*s
)
2362 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2364 gen_lea_v_seg(s
, mo_stacksize(s
), cpu_regs
[R_ESP
], R_SS
, -1);
2365 gen_op_ld_v(s
, d_ot
, s
->T0
, s
->A0
);
2370 static inline void gen_pop_update(DisasContext
*s
, TCGMemOp ot
)
2372 gen_stack_update(s
, 1 << ot
);
2375 static inline void gen_stack_A0(DisasContext
*s
)
2377 gen_lea_v_seg(s
, s
->ss32
? MO_32
: MO_16
, cpu_regs
[R_ESP
], R_SS
, -1);
2380 static void gen_pusha(DisasContext
*s
)
2382 TCGMemOp s_ot
= s
->ss32
? MO_32
: MO_16
;
2383 TCGMemOp d_ot
= s
->dflag
;
2384 int size
= 1 << d_ot
;
2387 for (i
= 0; i
< 8; i
++) {
2388 tcg_gen_addi_tl(s
->A0
, cpu_regs
[R_ESP
], (i
- 8) * size
);
2389 gen_lea_v_seg(s
, s_ot
, s
->A0
, R_SS
, -1);
2390 gen_op_st_v(s
, d_ot
, cpu_regs
[7 - i
], s
->A0
);
2393 gen_stack_update(s
, -8 * size
);
2396 static void gen_popa(DisasContext
*s
)
2398 TCGMemOp s_ot
= s
->ss32
? MO_32
: MO_16
;
2399 TCGMemOp d_ot
= s
->dflag
;
2400 int size
= 1 << d_ot
;
2403 for (i
= 0; i
< 8; i
++) {
2404 /* ESP is not reloaded */
2405 if (7 - i
== R_ESP
) {
2408 tcg_gen_addi_tl(s
->A0
, cpu_regs
[R_ESP
], i
* size
);
2409 gen_lea_v_seg(s
, s_ot
, s
->A0
, R_SS
, -1);
2410 gen_op_ld_v(s
, d_ot
, s
->T0
, s
->A0
);
2411 gen_op_mov_reg_v(d_ot
, 7 - i
, s
->T0
);
2414 gen_stack_update(s
, 8 * size
);
2417 static void gen_enter(DisasContext
*s
, int esp_addend
, int level
)
2419 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2420 TCGMemOp a_ot
= CODE64(s
) ? MO_64
: s
->ss32
? MO_32
: MO_16
;
2421 int size
= 1 << d_ot
;
2423 /* Push BP; compute FrameTemp into T1. */
2424 tcg_gen_subi_tl(s
->T1
, cpu_regs
[R_ESP
], size
);
2425 gen_lea_v_seg(s
, a_ot
, s
->T1
, R_SS
, -1);
2426 gen_op_st_v(s
, d_ot
, cpu_regs
[R_EBP
], s
->A0
);
2432 /* Copy level-1 pointers from the previous frame. */
2433 for (i
= 1; i
< level
; ++i
) {
2434 tcg_gen_subi_tl(s
->A0
, cpu_regs
[R_EBP
], size
* i
);
2435 gen_lea_v_seg(s
, a_ot
, s
->A0
, R_SS
, -1);
2436 gen_op_ld_v(s
, d_ot
, s
->tmp0
, s
->A0
);
2438 tcg_gen_subi_tl(s
->A0
, s
->T1
, size
* i
);
2439 gen_lea_v_seg(s
, a_ot
, s
->A0
, R_SS
, -1);
2440 gen_op_st_v(s
, d_ot
, s
->tmp0
, s
->A0
);
2443 /* Push the current FrameTemp as the last level. */
2444 tcg_gen_subi_tl(s
->A0
, s
->T1
, size
* level
);
2445 gen_lea_v_seg(s
, a_ot
, s
->A0
, R_SS
, -1);
2446 gen_op_st_v(s
, d_ot
, s
->T1
, s
->A0
);
2449 /* Copy the FrameTemp value to EBP. */
2450 gen_op_mov_reg_v(a_ot
, R_EBP
, s
->T1
);
2452 /* Compute the final value of ESP. */
2453 tcg_gen_subi_tl(s
->T1
, s
->T1
, esp_addend
+ size
* level
);
2454 gen_op_mov_reg_v(a_ot
, R_ESP
, s
->T1
);
2457 static void gen_leave(DisasContext
*s
)
2459 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2460 TCGMemOp a_ot
= mo_stacksize(s
);
2462 gen_lea_v_seg(s
, a_ot
, cpu_regs
[R_EBP
], R_SS
, -1);
2463 gen_op_ld_v(s
, d_ot
, s
->T0
, s
->A0
);
2465 tcg_gen_addi_tl(s
->T1
, cpu_regs
[R_EBP
], 1 << d_ot
);
2467 gen_op_mov_reg_v(d_ot
, R_EBP
, s
->T0
);
2468 gen_op_mov_reg_v(a_ot
, R_ESP
, s
->T1
);
2471 static void gen_exception(DisasContext
*s
, int trapno
, target_ulong cur_eip
)
2473 gen_update_cc_op(s
);
2474 gen_jmp_im(s
, cur_eip
);
2475 gen_helper_raise_exception(cpu_env
, tcg_const_i32(trapno
));
2476 s
->base
.is_jmp
= DISAS_NORETURN
;
2479 /* Generate #UD for the current instruction. The assumption here is that
2480 the instruction is known, but it isn't allowed in the current cpu mode. */
2481 static void gen_illegal_opcode(DisasContext
*s
)
2483 gen_exception(s
, EXCP06_ILLOP
, s
->pc_start
- s
->cs_base
);
2486 /* Similarly, except that the assumption here is that we don't decode
2487 the instruction at all -- either a missing opcode, an unimplemented
2488 feature, or just a bogus instruction stream. */
2489 static void gen_unknown_opcode(CPUX86State
*env
, DisasContext
*s
)
2491 gen_illegal_opcode(s
);
2493 if (qemu_loglevel_mask(LOG_UNIMP
)) {
2494 target_ulong pc
= s
->pc_start
, end
= s
->pc
;
2496 qemu_log("ILLOPC: " TARGET_FMT_lx
":", pc
);
2497 for (; pc
< end
; ++pc
) {
2498 qemu_log(" %02x", cpu_ldub_code(env
, pc
));
2505 /* an interrupt is different from an exception because of the
2507 static void gen_interrupt(DisasContext
*s
, int intno
,
2508 target_ulong cur_eip
, target_ulong next_eip
)
2510 gen_update_cc_op(s
);
2511 gen_jmp_im(s
, cur_eip
);
2512 gen_helper_raise_interrupt(cpu_env
, tcg_const_i32(intno
),
2513 tcg_const_i32(next_eip
- cur_eip
));
2514 s
->base
.is_jmp
= DISAS_NORETURN
;
2517 static void gen_debug(DisasContext
*s
, target_ulong cur_eip
)
2519 gen_update_cc_op(s
);
2520 gen_jmp_im(s
, cur_eip
);
2521 gen_helper_debug(cpu_env
);
2522 s
->base
.is_jmp
= DISAS_NORETURN
;
2525 static void gen_set_hflag(DisasContext
*s
, uint32_t mask
)
2527 if ((s
->flags
& mask
) == 0) {
2528 TCGv_i32 t
= tcg_temp_new_i32();
2529 tcg_gen_ld_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2530 tcg_gen_ori_i32(t
, t
, mask
);
2531 tcg_gen_st_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2532 tcg_temp_free_i32(t
);
2537 static void gen_reset_hflag(DisasContext
*s
, uint32_t mask
)
2539 if (s
->flags
& mask
) {
2540 TCGv_i32 t
= tcg_temp_new_i32();
2541 tcg_gen_ld_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2542 tcg_gen_andi_i32(t
, t
, ~mask
);
2543 tcg_gen_st_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2544 tcg_temp_free_i32(t
);
2549 /* Clear BND registers during legacy branches. */
2550 static void gen_bnd_jmp(DisasContext
*s
)
2552 /* Clear the registers only if BND prefix is missing, MPX is enabled,
2553 and if the BNDREGs are known to be in use (non-zero) already.
2554 The helper itself will check BNDPRESERVE at runtime. */
2555 if ((s
->prefix
& PREFIX_REPNZ
) == 0
2556 && (s
->flags
& HF_MPX_EN_MASK
) != 0
2557 && (s
->flags
& HF_MPX_IU_MASK
) != 0) {
2558 gen_helper_bnd_jmp(cpu_env
);
2562 /* Generate an end of block. Trace exception is also generated if needed.
2563 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set.
2564 If RECHECK_TF, emit a rechecking helper for #DB, ignoring the state of
2565 S->TF. This is used by the syscall/sysret insns. */
2567 do_gen_eob_worker(DisasContext
*s
, bool inhibit
, bool recheck_tf
, bool jr
)
2569 gen_update_cc_op(s
);
2571 /* If several instructions disable interrupts, only the first does it. */
2572 if (inhibit
&& !(s
->flags
& HF_INHIBIT_IRQ_MASK
)) {
2573 gen_set_hflag(s
, HF_INHIBIT_IRQ_MASK
);
2575 gen_reset_hflag(s
, HF_INHIBIT_IRQ_MASK
);
2578 if (s
->base
.tb
->flags
& HF_RF_MASK
) {
2579 gen_helper_reset_rf(cpu_env
);
2581 if (s
->base
.singlestep_enabled
) {
2582 gen_helper_debug(cpu_env
);
2583 } else if (recheck_tf
) {
2584 gen_helper_rechecking_single_step(cpu_env
);
2585 tcg_gen_exit_tb(NULL
, 0);
2587 gen_helper_single_step(cpu_env
);
2589 tcg_gen_lookup_and_goto_ptr();
2591 tcg_gen_exit_tb(NULL
, 0);
2593 s
->base
.is_jmp
= DISAS_NORETURN
;
2597 gen_eob_worker(DisasContext
*s
, bool inhibit
, bool recheck_tf
)
2599 do_gen_eob_worker(s
, inhibit
, recheck_tf
, false);
2603 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set. */
2604 static void gen_eob_inhibit_irq(DisasContext
*s
, bool inhibit
)
2606 gen_eob_worker(s
, inhibit
, false);
2609 /* End of block, resetting the inhibit irq flag. */
2610 static void gen_eob(DisasContext
*s
)
2612 gen_eob_worker(s
, false, false);
2615 /* Jump to register */
2616 static void gen_jr(DisasContext
*s
, TCGv dest
)
2618 do_gen_eob_worker(s
, false, false, true);
2621 /* generate a jump to eip. No segment change must happen before as a
2622 direct call to the next block may occur */
2623 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
)
2625 gen_update_cc_op(s
);
2626 set_cc_op(s
, CC_OP_DYNAMIC
);
2628 gen_goto_tb(s
, tb_num
, eip
);
2635 static void gen_jmp(DisasContext
*s
, target_ulong eip
)
2637 gen_jmp_tb(s
, eip
, 0);
2640 static inline void gen_ldq_env_A0(DisasContext
*s
, int offset
)
2642 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, s
->A0
, s
->mem_index
, MO_LEQ
);
2643 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2646 static inline void gen_stq_env_A0(DisasContext
*s
, int offset
)
2648 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2649 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, s
->A0
, s
->mem_index
, MO_LEQ
);
2652 static inline void gen_ldo_env_A0(DisasContext
*s
, int offset
)
2654 int mem_index
= s
->mem_index
;
2655 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, s
->A0
, mem_index
, MO_LEQ
);
2656 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2657 tcg_gen_addi_tl(s
->tmp0
, s
->A0
, 8);
2658 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, s
->tmp0
, mem_index
, MO_LEQ
);
2659 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2662 static inline void gen_sto_env_A0(DisasContext
*s
, int offset
)
2664 int mem_index
= s
->mem_index
;
2665 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2666 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, s
->A0
, mem_index
, MO_LEQ
);
2667 tcg_gen_addi_tl(s
->tmp0
, s
->A0
, 8);
2668 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2669 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, s
->tmp0
, mem_index
, MO_LEQ
);
2672 static inline void gen_op_movo(int d_offset
, int s_offset
)
2674 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2675 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2676 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2677 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2680 static inline void gen_op_movq(int d_offset
, int s_offset
)
2682 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
);
2683 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2686 static inline void gen_op_movl(int d_offset
, int s_offset
)
2688 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
, s_offset
);
2689 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, d_offset
);
2692 static inline void gen_op_movq_env_0(int d_offset
)
2694 tcg_gen_movi_i64(cpu_tmp1_i64
, 0);
2695 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2698 typedef void (*SSEFunc_i_ep
)(TCGv_i32 val
, TCGv_ptr env
, TCGv_ptr reg
);
2699 typedef void (*SSEFunc_l_ep
)(TCGv_i64 val
, TCGv_ptr env
, TCGv_ptr reg
);
2700 typedef void (*SSEFunc_0_epi
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i32 val
);
2701 typedef void (*SSEFunc_0_epl
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i64 val
);
2702 typedef void (*SSEFunc_0_epp
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
);
2703 typedef void (*SSEFunc_0_eppi
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2705 typedef void (*SSEFunc_0_ppi
)(TCGv_ptr reg_a
, TCGv_ptr reg_b
, TCGv_i32 val
);
2706 typedef void (*SSEFunc_0_eppt
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2709 #define SSE_SPECIAL ((void *)1)
2710 #define SSE_DUMMY ((void *)2)
2712 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2713 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2714 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2716 static const SSEFunc_0_epp sse_op_table1
[256][4] = {
2717 /* 3DNow! extensions */
2718 [0x0e] = { SSE_DUMMY
}, /* femms */
2719 [0x0f] = { SSE_DUMMY
}, /* pf... */
2720 /* pure SSE operations */
2721 [0x10] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2722 [0x11] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2723 [0x12] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd, movsldup, movddup */
2724 [0x13] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd */
2725 [0x14] = { gen_helper_punpckldq_xmm
, gen_helper_punpcklqdq_xmm
},
2726 [0x15] = { gen_helper_punpckhdq_xmm
, gen_helper_punpckhqdq_xmm
},
2727 [0x16] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd, movshdup */
2728 [0x17] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd */
2730 [0x28] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2731 [0x29] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2732 [0x2a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2733 [0x2b] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movntps, movntpd, movntss, movntsd */
2734 [0x2c] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2735 [0x2d] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2736 [0x2e] = { gen_helper_ucomiss
, gen_helper_ucomisd
},
2737 [0x2f] = { gen_helper_comiss
, gen_helper_comisd
},
2738 [0x50] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movmskps, movmskpd */
2739 [0x51] = SSE_FOP(sqrt
),
2740 [0x52] = { gen_helper_rsqrtps
, NULL
, gen_helper_rsqrtss
, NULL
},
2741 [0x53] = { gen_helper_rcpps
, NULL
, gen_helper_rcpss
, NULL
},
2742 [0x54] = { gen_helper_pand_xmm
, gen_helper_pand_xmm
}, /* andps, andpd */
2743 [0x55] = { gen_helper_pandn_xmm
, gen_helper_pandn_xmm
}, /* andnps, andnpd */
2744 [0x56] = { gen_helper_por_xmm
, gen_helper_por_xmm
}, /* orps, orpd */
2745 [0x57] = { gen_helper_pxor_xmm
, gen_helper_pxor_xmm
}, /* xorps, xorpd */
2746 [0x58] = SSE_FOP(add
),
2747 [0x59] = SSE_FOP(mul
),
2748 [0x5a] = { gen_helper_cvtps2pd
, gen_helper_cvtpd2ps
,
2749 gen_helper_cvtss2sd
, gen_helper_cvtsd2ss
},
2750 [0x5b] = { gen_helper_cvtdq2ps
, gen_helper_cvtps2dq
, gen_helper_cvttps2dq
},
2751 [0x5c] = SSE_FOP(sub
),
2752 [0x5d] = SSE_FOP(min
),
2753 [0x5e] = SSE_FOP(div
),
2754 [0x5f] = SSE_FOP(max
),
2756 [0xc2] = SSE_FOP(cmpeq
),
2757 [0xc6] = { (SSEFunc_0_epp
)gen_helper_shufps
,
2758 (SSEFunc_0_epp
)gen_helper_shufpd
}, /* XXX: casts */
2760 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */
2761 [0x38] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2762 [0x3a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2764 /* MMX ops and their SSE extensions */
2765 [0x60] = MMX_OP2(punpcklbw
),
2766 [0x61] = MMX_OP2(punpcklwd
),
2767 [0x62] = MMX_OP2(punpckldq
),
2768 [0x63] = MMX_OP2(packsswb
),
2769 [0x64] = MMX_OP2(pcmpgtb
),
2770 [0x65] = MMX_OP2(pcmpgtw
),
2771 [0x66] = MMX_OP2(pcmpgtl
),
2772 [0x67] = MMX_OP2(packuswb
),
2773 [0x68] = MMX_OP2(punpckhbw
),
2774 [0x69] = MMX_OP2(punpckhwd
),
2775 [0x6a] = MMX_OP2(punpckhdq
),
2776 [0x6b] = MMX_OP2(packssdw
),
2777 [0x6c] = { NULL
, gen_helper_punpcklqdq_xmm
},
2778 [0x6d] = { NULL
, gen_helper_punpckhqdq_xmm
},
2779 [0x6e] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movd mm, ea */
2780 [0x6f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, , movqdu */
2781 [0x70] = { (SSEFunc_0_epp
)gen_helper_pshufw_mmx
,
2782 (SSEFunc_0_epp
)gen_helper_pshufd_xmm
,
2783 (SSEFunc_0_epp
)gen_helper_pshufhw_xmm
,
2784 (SSEFunc_0_epp
)gen_helper_pshuflw_xmm
}, /* XXX: casts */
2785 [0x71] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftw */
2786 [0x72] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftd */
2787 [0x73] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftq */
2788 [0x74] = MMX_OP2(pcmpeqb
),
2789 [0x75] = MMX_OP2(pcmpeqw
),
2790 [0x76] = MMX_OP2(pcmpeql
),
2791 [0x77] = { SSE_DUMMY
}, /* emms */
2792 [0x78] = { NULL
, SSE_SPECIAL
, NULL
, SSE_SPECIAL
}, /* extrq_i, insertq_i */
2793 [0x79] = { NULL
, gen_helper_extrq_r
, NULL
, gen_helper_insertq_r
},
2794 [0x7c] = { NULL
, gen_helper_haddpd
, NULL
, gen_helper_haddps
},
2795 [0x7d] = { NULL
, gen_helper_hsubpd
, NULL
, gen_helper_hsubps
},
2796 [0x7e] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movd, movd, , movq */
2797 [0x7f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, movdqu */
2798 [0xc4] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pinsrw */
2799 [0xc5] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pextrw */
2800 [0xd0] = { NULL
, gen_helper_addsubpd
, NULL
, gen_helper_addsubps
},
2801 [0xd1] = MMX_OP2(psrlw
),
2802 [0xd2] = MMX_OP2(psrld
),
2803 [0xd3] = MMX_OP2(psrlq
),
2804 [0xd4] = MMX_OP2(paddq
),
2805 [0xd5] = MMX_OP2(pmullw
),
2806 [0xd6] = { NULL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2807 [0xd7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pmovmskb */
2808 [0xd8] = MMX_OP2(psubusb
),
2809 [0xd9] = MMX_OP2(psubusw
),
2810 [0xda] = MMX_OP2(pminub
),
2811 [0xdb] = MMX_OP2(pand
),
2812 [0xdc] = MMX_OP2(paddusb
),
2813 [0xdd] = MMX_OP2(paddusw
),
2814 [0xde] = MMX_OP2(pmaxub
),
2815 [0xdf] = MMX_OP2(pandn
),
2816 [0xe0] = MMX_OP2(pavgb
),
2817 [0xe1] = MMX_OP2(psraw
),
2818 [0xe2] = MMX_OP2(psrad
),
2819 [0xe3] = MMX_OP2(pavgw
),
2820 [0xe4] = MMX_OP2(pmulhuw
),
2821 [0xe5] = MMX_OP2(pmulhw
),
2822 [0xe6] = { NULL
, gen_helper_cvttpd2dq
, gen_helper_cvtdq2pd
, gen_helper_cvtpd2dq
},
2823 [0xe7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movntq, movntq */
2824 [0xe8] = MMX_OP2(psubsb
),
2825 [0xe9] = MMX_OP2(psubsw
),
2826 [0xea] = MMX_OP2(pminsw
),
2827 [0xeb] = MMX_OP2(por
),
2828 [0xec] = MMX_OP2(paddsb
),
2829 [0xed] = MMX_OP2(paddsw
),
2830 [0xee] = MMX_OP2(pmaxsw
),
2831 [0xef] = MMX_OP2(pxor
),
2832 [0xf0] = { NULL
, NULL
, NULL
, SSE_SPECIAL
}, /* lddqu */
2833 [0xf1] = MMX_OP2(psllw
),
2834 [0xf2] = MMX_OP2(pslld
),
2835 [0xf3] = MMX_OP2(psllq
),
2836 [0xf4] = MMX_OP2(pmuludq
),
2837 [0xf5] = MMX_OP2(pmaddwd
),
2838 [0xf6] = MMX_OP2(psadbw
),
2839 [0xf7] = { (SSEFunc_0_epp
)gen_helper_maskmov_mmx
,
2840 (SSEFunc_0_epp
)gen_helper_maskmov_xmm
}, /* XXX: casts */
2841 [0xf8] = MMX_OP2(psubb
),
2842 [0xf9] = MMX_OP2(psubw
),
2843 [0xfa] = MMX_OP2(psubl
),
2844 [0xfb] = MMX_OP2(psubq
),
2845 [0xfc] = MMX_OP2(paddb
),
2846 [0xfd] = MMX_OP2(paddw
),
2847 [0xfe] = MMX_OP2(paddl
),
2850 static const SSEFunc_0_epp sse_op_table2
[3 * 8][2] = {
2851 [0 + 2] = MMX_OP2(psrlw
),
2852 [0 + 4] = MMX_OP2(psraw
),
2853 [0 + 6] = MMX_OP2(psllw
),
2854 [8 + 2] = MMX_OP2(psrld
),
2855 [8 + 4] = MMX_OP2(psrad
),
2856 [8 + 6] = MMX_OP2(pslld
),
2857 [16 + 2] = MMX_OP2(psrlq
),
2858 [16 + 3] = { NULL
, gen_helper_psrldq_xmm
},
2859 [16 + 6] = MMX_OP2(psllq
),
2860 [16 + 7] = { NULL
, gen_helper_pslldq_xmm
},
2863 static const SSEFunc_0_epi sse_op_table3ai
[] = {
2864 gen_helper_cvtsi2ss
,
2868 #ifdef TARGET_X86_64
2869 static const SSEFunc_0_epl sse_op_table3aq
[] = {
2870 gen_helper_cvtsq2ss
,
2875 static const SSEFunc_i_ep sse_op_table3bi
[] = {
2876 gen_helper_cvttss2si
,
2877 gen_helper_cvtss2si
,
2878 gen_helper_cvttsd2si
,
2882 #ifdef TARGET_X86_64
2883 static const SSEFunc_l_ep sse_op_table3bq
[] = {
2884 gen_helper_cvttss2sq
,
2885 gen_helper_cvtss2sq
,
2886 gen_helper_cvttsd2sq
,
2891 static const SSEFunc_0_epp sse_op_table4
[8][4] = {
2902 static const SSEFunc_0_epp sse_op_table5
[256] = {
2903 [0x0c] = gen_helper_pi2fw
,
2904 [0x0d] = gen_helper_pi2fd
,
2905 [0x1c] = gen_helper_pf2iw
,
2906 [0x1d] = gen_helper_pf2id
,
2907 [0x8a] = gen_helper_pfnacc
,
2908 [0x8e] = gen_helper_pfpnacc
,
2909 [0x90] = gen_helper_pfcmpge
,
2910 [0x94] = gen_helper_pfmin
,
2911 [0x96] = gen_helper_pfrcp
,
2912 [0x97] = gen_helper_pfrsqrt
,
2913 [0x9a] = gen_helper_pfsub
,
2914 [0x9e] = gen_helper_pfadd
,
2915 [0xa0] = gen_helper_pfcmpgt
,
2916 [0xa4] = gen_helper_pfmax
,
2917 [0xa6] = gen_helper_movq
, /* pfrcpit1; no need to actually increase precision */
2918 [0xa7] = gen_helper_movq
, /* pfrsqit1 */
2919 [0xaa] = gen_helper_pfsubr
,
2920 [0xae] = gen_helper_pfacc
,
2921 [0xb0] = gen_helper_pfcmpeq
,
2922 [0xb4] = gen_helper_pfmul
,
2923 [0xb6] = gen_helper_movq
, /* pfrcpit2 */
2924 [0xb7] = gen_helper_pmulhrw_mmx
,
2925 [0xbb] = gen_helper_pswapd
,
2926 [0xbf] = gen_helper_pavgb_mmx
/* pavgusb */
2929 struct SSEOpHelper_epp
{
2930 SSEFunc_0_epp op
[2];
2934 struct SSEOpHelper_eppi
{
2935 SSEFunc_0_eppi op
[2];
2939 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
2940 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
2941 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
2942 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
2943 #define PCLMULQDQ_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, \
2944 CPUID_EXT_PCLMULQDQ }
2945 #define AESNI_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_AES }
2947 static const struct SSEOpHelper_epp sse_op_table6
[256] = {
2948 [0x00] = SSSE3_OP(pshufb
),
2949 [0x01] = SSSE3_OP(phaddw
),
2950 [0x02] = SSSE3_OP(phaddd
),
2951 [0x03] = SSSE3_OP(phaddsw
),
2952 [0x04] = SSSE3_OP(pmaddubsw
),
2953 [0x05] = SSSE3_OP(phsubw
),
2954 [0x06] = SSSE3_OP(phsubd
),
2955 [0x07] = SSSE3_OP(phsubsw
),
2956 [0x08] = SSSE3_OP(psignb
),
2957 [0x09] = SSSE3_OP(psignw
),
2958 [0x0a] = SSSE3_OP(psignd
),
2959 [0x0b] = SSSE3_OP(pmulhrsw
),
2960 [0x10] = SSE41_OP(pblendvb
),
2961 [0x14] = SSE41_OP(blendvps
),
2962 [0x15] = SSE41_OP(blendvpd
),
2963 [0x17] = SSE41_OP(ptest
),
2964 [0x1c] = SSSE3_OP(pabsb
),
2965 [0x1d] = SSSE3_OP(pabsw
),
2966 [0x1e] = SSSE3_OP(pabsd
),
2967 [0x20] = SSE41_OP(pmovsxbw
),
2968 [0x21] = SSE41_OP(pmovsxbd
),
2969 [0x22] = SSE41_OP(pmovsxbq
),
2970 [0x23] = SSE41_OP(pmovsxwd
),
2971 [0x24] = SSE41_OP(pmovsxwq
),
2972 [0x25] = SSE41_OP(pmovsxdq
),
2973 [0x28] = SSE41_OP(pmuldq
),
2974 [0x29] = SSE41_OP(pcmpeqq
),
2975 [0x2a] = SSE41_SPECIAL
, /* movntqda */
2976 [0x2b] = SSE41_OP(packusdw
),
2977 [0x30] = SSE41_OP(pmovzxbw
),
2978 [0x31] = SSE41_OP(pmovzxbd
),
2979 [0x32] = SSE41_OP(pmovzxbq
),
2980 [0x33] = SSE41_OP(pmovzxwd
),
2981 [0x34] = SSE41_OP(pmovzxwq
),
2982 [0x35] = SSE41_OP(pmovzxdq
),
2983 [0x37] = SSE42_OP(pcmpgtq
),
2984 [0x38] = SSE41_OP(pminsb
),
2985 [0x39] = SSE41_OP(pminsd
),
2986 [0x3a] = SSE41_OP(pminuw
),
2987 [0x3b] = SSE41_OP(pminud
),
2988 [0x3c] = SSE41_OP(pmaxsb
),
2989 [0x3d] = SSE41_OP(pmaxsd
),
2990 [0x3e] = SSE41_OP(pmaxuw
),
2991 [0x3f] = SSE41_OP(pmaxud
),
2992 [0x40] = SSE41_OP(pmulld
),
2993 [0x41] = SSE41_OP(phminposuw
),
2994 [0xdb] = AESNI_OP(aesimc
),
2995 [0xdc] = AESNI_OP(aesenc
),
2996 [0xdd] = AESNI_OP(aesenclast
),
2997 [0xde] = AESNI_OP(aesdec
),
2998 [0xdf] = AESNI_OP(aesdeclast
),
3001 static const struct SSEOpHelper_eppi sse_op_table7
[256] = {
3002 [0x08] = SSE41_OP(roundps
),
3003 [0x09] = SSE41_OP(roundpd
),
3004 [0x0a] = SSE41_OP(roundss
),
3005 [0x0b] = SSE41_OP(roundsd
),
3006 [0x0c] = SSE41_OP(blendps
),
3007 [0x0d] = SSE41_OP(blendpd
),
3008 [0x0e] = SSE41_OP(pblendw
),
3009 [0x0f] = SSSE3_OP(palignr
),
3010 [0x14] = SSE41_SPECIAL
, /* pextrb */
3011 [0x15] = SSE41_SPECIAL
, /* pextrw */
3012 [0x16] = SSE41_SPECIAL
, /* pextrd/pextrq */
3013 [0x17] = SSE41_SPECIAL
, /* extractps */
3014 [0x20] = SSE41_SPECIAL
, /* pinsrb */
3015 [0x21] = SSE41_SPECIAL
, /* insertps */
3016 [0x22] = SSE41_SPECIAL
, /* pinsrd/pinsrq */
3017 [0x40] = SSE41_OP(dpps
),
3018 [0x41] = SSE41_OP(dppd
),
3019 [0x42] = SSE41_OP(mpsadbw
),
3020 [0x44] = PCLMULQDQ_OP(pclmulqdq
),
3021 [0x60] = SSE42_OP(pcmpestrm
),
3022 [0x61] = SSE42_OP(pcmpestri
),
3023 [0x62] = SSE42_OP(pcmpistrm
),
3024 [0x63] = SSE42_OP(pcmpistri
),
3025 [0xdf] = AESNI_OP(aeskeygenassist
),
3028 static void gen_sse(CPUX86State
*env
, DisasContext
*s
, int b
,
3029 target_ulong pc_start
, int rex_r
)
3031 int b1
, op1_offset
, op2_offset
, is_xmm
, val
;
3032 int modrm
, mod
, rm
, reg
;
3033 SSEFunc_0_epp sse_fn_epp
;
3034 SSEFunc_0_eppi sse_fn_eppi
;
3035 SSEFunc_0_ppi sse_fn_ppi
;
3036 SSEFunc_0_eppt sse_fn_eppt
;
3040 if (s
->prefix
& PREFIX_DATA
)
3042 else if (s
->prefix
& PREFIX_REPZ
)
3044 else if (s
->prefix
& PREFIX_REPNZ
)
3048 sse_fn_epp
= sse_op_table1
[b
][b1
];
3052 if ((b
<= 0x5f && b
>= 0x10) || b
== 0xc6 || b
== 0xc2) {
3062 /* simple MMX/SSE operation */
3063 if (s
->flags
& HF_TS_MASK
) {
3064 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
3067 if (s
->flags
& HF_EM_MASK
) {
3069 gen_illegal_opcode(s
);
3073 && !(s
->flags
& HF_OSFXSR_MASK
)
3074 && ((b
!= 0x38 && b
!= 0x3a) || (s
->prefix
& PREFIX_DATA
))) {
3078 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
)) {
3079 /* If we were fully decoding this we might use illegal_op. */
3083 gen_helper_emms(cpu_env
);
3088 gen_helper_emms(cpu_env
);
3091 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3092 the static cpu state) */
3094 gen_helper_enter_mmx(cpu_env
);
3097 modrm
= x86_ldub_code(env
, s
);
3098 reg
= ((modrm
>> 3) & 7);
3101 mod
= (modrm
>> 6) & 3;
3102 if (sse_fn_epp
== SSE_SPECIAL
) {
3105 case 0x0e7: /* movntq */
3109 gen_lea_modrm(env
, s
, modrm
);
3110 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3112 case 0x1e7: /* movntdq */
3113 case 0x02b: /* movntps */
3114 case 0x12b: /* movntps */
3117 gen_lea_modrm(env
, s
, modrm
);
3118 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3120 case 0x3f0: /* lddqu */
3123 gen_lea_modrm(env
, s
, modrm
);
3124 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3126 case 0x22b: /* movntss */
3127 case 0x32b: /* movntsd */
3130 gen_lea_modrm(env
, s
, modrm
);
3132 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3133 xmm_regs
[reg
].ZMM_Q(0)));
3135 tcg_gen_ld32u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
3136 xmm_regs
[reg
].ZMM_L(0)));
3137 gen_op_st_v(s
, MO_32
, s
->T0
, s
->A0
);
3140 case 0x6e: /* movd mm, ea */
3141 #ifdef TARGET_X86_64
3142 if (s
->dflag
== MO_64
) {
3143 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3144 tcg_gen_st_tl(s
->T0
, cpu_env
,
3145 offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3149 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3150 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3151 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3152 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
3153 gen_helper_movl_mm_T0_mmx(cpu_ptr0
, cpu_tmp2_i32
);
3156 case 0x16e: /* movd xmm, ea */
3157 #ifdef TARGET_X86_64
3158 if (s
->dflag
== MO_64
) {
3159 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3160 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3161 offsetof(CPUX86State
,xmm_regs
[reg
]));
3162 gen_helper_movq_mm_T0_xmm(cpu_ptr0
, s
->T0
);
3166 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3167 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3168 offsetof(CPUX86State
,xmm_regs
[reg
]));
3169 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
3170 gen_helper_movl_mm_T0_xmm(cpu_ptr0
, cpu_tmp2_i32
);
3173 case 0x6f: /* movq mm, ea */
3175 gen_lea_modrm(env
, s
, modrm
);
3176 gen_ldq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3179 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
3180 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3181 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
3182 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3185 case 0x010: /* movups */
3186 case 0x110: /* movupd */
3187 case 0x028: /* movaps */
3188 case 0x128: /* movapd */
3189 case 0x16f: /* movdqa xmm, ea */
3190 case 0x26f: /* movdqu xmm, ea */
3192 gen_lea_modrm(env
, s
, modrm
);
3193 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3195 rm
= (modrm
& 7) | REX_B(s
);
3196 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[reg
]),
3197 offsetof(CPUX86State
,xmm_regs
[rm
]));
3200 case 0x210: /* movss xmm, ea */
3202 gen_lea_modrm(env
, s
, modrm
);
3203 gen_op_ld_v(s
, MO_32
, s
->T0
, s
->A0
);
3204 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3205 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(0)));
3206 tcg_gen_movi_tl(s
->T0
, 0);
3207 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3208 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(1)));
3209 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3210 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(2)));
3211 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3212 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(3)));
3214 rm
= (modrm
& 7) | REX_B(s
);
3215 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)),
3216 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)));
3219 case 0x310: /* movsd xmm, ea */
3221 gen_lea_modrm(env
, s
, modrm
);
3222 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3223 xmm_regs
[reg
].ZMM_Q(0)));
3224 tcg_gen_movi_tl(s
->T0
, 0);
3225 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3226 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(2)));
3227 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3228 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(3)));
3230 rm
= (modrm
& 7) | REX_B(s
);
3231 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3232 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3235 case 0x012: /* movlps */
3236 case 0x112: /* movlpd */
3238 gen_lea_modrm(env
, s
, modrm
);
3239 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3240 xmm_regs
[reg
].ZMM_Q(0)));
3243 rm
= (modrm
& 7) | REX_B(s
);
3244 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3245 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(1)));
3248 case 0x212: /* movsldup */
3250 gen_lea_modrm(env
, s
, modrm
);
3251 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3253 rm
= (modrm
& 7) | REX_B(s
);
3254 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)),
3255 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)));
3256 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)),
3257 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(2)));
3259 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)),
3260 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3261 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)),
3262 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)));
3264 case 0x312: /* movddup */
3266 gen_lea_modrm(env
, s
, modrm
);
3267 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3268 xmm_regs
[reg
].ZMM_Q(0)));
3270 rm
= (modrm
& 7) | REX_B(s
);
3271 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3272 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3274 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)),
3275 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3277 case 0x016: /* movhps */
3278 case 0x116: /* movhpd */
3280 gen_lea_modrm(env
, s
, modrm
);
3281 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3282 xmm_regs
[reg
].ZMM_Q(1)));
3285 rm
= (modrm
& 7) | REX_B(s
);
3286 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)),
3287 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3290 case 0x216: /* movshdup */
3292 gen_lea_modrm(env
, s
, modrm
);
3293 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3295 rm
= (modrm
& 7) | REX_B(s
);
3296 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)),
3297 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(1)));
3298 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)),
3299 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(3)));
3301 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)),
3302 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)));
3303 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)),
3304 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)));
3309 int bit_index
, field_length
;
3311 if (b1
== 1 && reg
!= 0)
3313 field_length
= x86_ldub_code(env
, s
) & 0x3F;
3314 bit_index
= x86_ldub_code(env
, s
) & 0x3F;
3315 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3316 offsetof(CPUX86State
,xmm_regs
[reg
]));
3318 gen_helper_extrq_i(cpu_env
, cpu_ptr0
,
3319 tcg_const_i32(bit_index
),
3320 tcg_const_i32(field_length
));
3322 gen_helper_insertq_i(cpu_env
, cpu_ptr0
,
3323 tcg_const_i32(bit_index
),
3324 tcg_const_i32(field_length
));
3327 case 0x7e: /* movd ea, mm */
3328 #ifdef TARGET_X86_64
3329 if (s
->dflag
== MO_64
) {
3330 tcg_gen_ld_i64(s
->T0
, cpu_env
,
3331 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3332 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3336 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
3337 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_L(0)));
3338 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3341 case 0x17e: /* movd ea, xmm */
3342 #ifdef TARGET_X86_64
3343 if (s
->dflag
== MO_64
) {
3344 tcg_gen_ld_i64(s
->T0
, cpu_env
,
3345 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3346 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3350 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
3351 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3352 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3355 case 0x27e: /* movq xmm, ea */
3357 gen_lea_modrm(env
, s
, modrm
);
3358 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3359 xmm_regs
[reg
].ZMM_Q(0)));
3361 rm
= (modrm
& 7) | REX_B(s
);
3362 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3363 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3365 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)));
3367 case 0x7f: /* movq ea, mm */
3369 gen_lea_modrm(env
, s
, modrm
);
3370 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3373 gen_op_movq(offsetof(CPUX86State
,fpregs
[rm
].mmx
),
3374 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3377 case 0x011: /* movups */
3378 case 0x111: /* movupd */
3379 case 0x029: /* movaps */
3380 case 0x129: /* movapd */
3381 case 0x17f: /* movdqa ea, xmm */
3382 case 0x27f: /* movdqu ea, xmm */
3384 gen_lea_modrm(env
, s
, modrm
);
3385 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3387 rm
= (modrm
& 7) | REX_B(s
);
3388 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[rm
]),
3389 offsetof(CPUX86State
,xmm_regs
[reg
]));
3392 case 0x211: /* movss ea, xmm */
3394 gen_lea_modrm(env
, s
, modrm
);
3395 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
3396 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(0)));
3397 gen_op_st_v(s
, MO_32
, s
->T0
, s
->A0
);
3399 rm
= (modrm
& 7) | REX_B(s
);
3400 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)),
3401 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3404 case 0x311: /* movsd ea, xmm */
3406 gen_lea_modrm(env
, s
, modrm
);
3407 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3408 xmm_regs
[reg
].ZMM_Q(0)));
3410 rm
= (modrm
& 7) | REX_B(s
);
3411 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)),
3412 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3415 case 0x013: /* movlps */
3416 case 0x113: /* movlpd */
3418 gen_lea_modrm(env
, s
, modrm
);
3419 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3420 xmm_regs
[reg
].ZMM_Q(0)));
3425 case 0x017: /* movhps */
3426 case 0x117: /* movhpd */
3428 gen_lea_modrm(env
, s
, modrm
);
3429 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3430 xmm_regs
[reg
].ZMM_Q(1)));
3435 case 0x71: /* shift mm, im */
3438 case 0x171: /* shift xmm, im */
3444 val
= x86_ldub_code(env
, s
);
3446 tcg_gen_movi_tl(s
->T0
, val
);
3447 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3448 offsetof(CPUX86State
, xmm_t0
.ZMM_L(0)));
3449 tcg_gen_movi_tl(s
->T0
, 0);
3450 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3451 offsetof(CPUX86State
, xmm_t0
.ZMM_L(1)));
3452 op1_offset
= offsetof(CPUX86State
,xmm_t0
);
3454 tcg_gen_movi_tl(s
->T0
, val
);
3455 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3456 offsetof(CPUX86State
, mmx_t0
.MMX_L(0)));
3457 tcg_gen_movi_tl(s
->T0
, 0);
3458 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3459 offsetof(CPUX86State
, mmx_t0
.MMX_L(1)));
3460 op1_offset
= offsetof(CPUX86State
,mmx_t0
);
3462 sse_fn_epp
= sse_op_table2
[((b
- 1) & 3) * 8 +
3463 (((modrm
>> 3)) & 7)][b1
];
3468 rm
= (modrm
& 7) | REX_B(s
);
3469 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3472 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3474 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3475 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op1_offset
);
3476 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3478 case 0x050: /* movmskps */
3479 rm
= (modrm
& 7) | REX_B(s
);
3480 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3481 offsetof(CPUX86State
,xmm_regs
[rm
]));
3482 gen_helper_movmskps(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3483 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3485 case 0x150: /* movmskpd */
3486 rm
= (modrm
& 7) | REX_B(s
);
3487 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3488 offsetof(CPUX86State
,xmm_regs
[rm
]));
3489 gen_helper_movmskpd(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3490 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3492 case 0x02a: /* cvtpi2ps */
3493 case 0x12a: /* cvtpi2pd */
3494 gen_helper_enter_mmx(cpu_env
);
3496 gen_lea_modrm(env
, s
, modrm
);
3497 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3498 gen_ldq_env_A0(s
, op2_offset
);
3501 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3503 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3504 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3505 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3508 gen_helper_cvtpi2ps(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3512 gen_helper_cvtpi2pd(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3516 case 0x22a: /* cvtsi2ss */
3517 case 0x32a: /* cvtsi2sd */
3518 ot
= mo_64_32(s
->dflag
);
3519 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3520 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3521 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3523 SSEFunc_0_epi sse_fn_epi
= sse_op_table3ai
[(b
>> 8) & 1];
3524 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
3525 sse_fn_epi(cpu_env
, cpu_ptr0
, cpu_tmp2_i32
);
3527 #ifdef TARGET_X86_64
3528 SSEFunc_0_epl sse_fn_epl
= sse_op_table3aq
[(b
>> 8) & 1];
3529 sse_fn_epl(cpu_env
, cpu_ptr0
, s
->T0
);
3535 case 0x02c: /* cvttps2pi */
3536 case 0x12c: /* cvttpd2pi */
3537 case 0x02d: /* cvtps2pi */
3538 case 0x12d: /* cvtpd2pi */
3539 gen_helper_enter_mmx(cpu_env
);
3541 gen_lea_modrm(env
, s
, modrm
);
3542 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3543 gen_ldo_env_A0(s
, op2_offset
);
3545 rm
= (modrm
& 7) | REX_B(s
);
3546 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3548 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
);
3549 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3550 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3553 gen_helper_cvttps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3556 gen_helper_cvttpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3559 gen_helper_cvtps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3562 gen_helper_cvtpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3566 case 0x22c: /* cvttss2si */
3567 case 0x32c: /* cvttsd2si */
3568 case 0x22d: /* cvtss2si */
3569 case 0x32d: /* cvtsd2si */
3570 ot
= mo_64_32(s
->dflag
);
3572 gen_lea_modrm(env
, s
, modrm
);
3574 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.ZMM_Q(0)));
3576 gen_op_ld_v(s
, MO_32
, s
->T0
, s
->A0
);
3577 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3578 offsetof(CPUX86State
, xmm_t0
.ZMM_L(0)));
3580 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3582 rm
= (modrm
& 7) | REX_B(s
);
3583 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3585 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3587 SSEFunc_i_ep sse_fn_i_ep
=
3588 sse_op_table3bi
[((b
>> 7) & 2) | (b
& 1)];
3589 sse_fn_i_ep(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3590 tcg_gen_extu_i32_tl(s
->T0
, cpu_tmp2_i32
);
3592 #ifdef TARGET_X86_64
3593 SSEFunc_l_ep sse_fn_l_ep
=
3594 sse_op_table3bq
[((b
>> 7) & 2) | (b
& 1)];
3595 sse_fn_l_ep(s
->T0
, cpu_env
, cpu_ptr0
);
3600 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
3602 case 0xc4: /* pinsrw */
3605 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
3606 val
= x86_ldub_code(env
, s
);
3609 tcg_gen_st16_tl(s
->T0
, cpu_env
,
3610 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_W(val
)));
3613 tcg_gen_st16_tl(s
->T0
, cpu_env
,
3614 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_W(val
)));
3617 case 0xc5: /* pextrw */
3621 ot
= mo_64_32(s
->dflag
);
3622 val
= x86_ldub_code(env
, s
);
3625 rm
= (modrm
& 7) | REX_B(s
);
3626 tcg_gen_ld16u_tl(s
->T0
, cpu_env
,
3627 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_W(val
)));
3631 tcg_gen_ld16u_tl(s
->T0
, cpu_env
,
3632 offsetof(CPUX86State
,fpregs
[rm
].mmx
.MMX_W(val
)));
3634 reg
= ((modrm
>> 3) & 7) | rex_r
;
3635 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
3637 case 0x1d6: /* movq ea, xmm */
3639 gen_lea_modrm(env
, s
, modrm
);
3640 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3641 xmm_regs
[reg
].ZMM_Q(0)));
3643 rm
= (modrm
& 7) | REX_B(s
);
3644 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)),
3645 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3646 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(1)));
3649 case 0x2d6: /* movq2dq */
3650 gen_helper_enter_mmx(cpu_env
);
3652 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3653 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3654 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)));
3656 case 0x3d6: /* movdq2q */
3657 gen_helper_enter_mmx(cpu_env
);
3658 rm
= (modrm
& 7) | REX_B(s
);
3659 gen_op_movq(offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
),
3660 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3662 case 0xd7: /* pmovmskb */
3667 rm
= (modrm
& 7) | REX_B(s
);
3668 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[rm
]));
3669 gen_helper_pmovmskb_xmm(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3672 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3673 gen_helper_pmovmskb_mmx(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3675 reg
= ((modrm
>> 3) & 7) | rex_r
;
3676 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3682 if ((b
& 0xf0) == 0xf0) {
3685 modrm
= x86_ldub_code(env
, s
);
3687 reg
= ((modrm
>> 3) & 7) | rex_r
;
3688 mod
= (modrm
>> 6) & 3;
3693 sse_fn_epp
= sse_op_table6
[b
].op
[b1
];
3697 if (!(s
->cpuid_ext_features
& sse_op_table6
[b
].ext_mask
))
3701 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3703 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
3705 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3706 gen_lea_modrm(env
, s
, modrm
);
3708 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3709 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3710 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3711 gen_ldq_env_A0(s
, op2_offset
+
3712 offsetof(ZMMReg
, ZMM_Q(0)));
3714 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3715 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3716 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, s
->A0
,
3717 s
->mem_index
, MO_LEUL
);
3718 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, op2_offset
+
3719 offsetof(ZMMReg
, ZMM_L(0)));
3721 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3722 tcg_gen_qemu_ld_tl(s
->tmp0
, s
->A0
,
3723 s
->mem_index
, MO_LEUW
);
3724 tcg_gen_st16_tl(s
->tmp0
, cpu_env
, op2_offset
+
3725 offsetof(ZMMReg
, ZMM_W(0)));
3727 case 0x2a: /* movntqda */
3728 gen_ldo_env_A0(s
, op1_offset
);
3731 gen_ldo_env_A0(s
, op2_offset
);
3735 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
3737 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3739 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3740 gen_lea_modrm(env
, s
, modrm
);
3741 gen_ldq_env_A0(s
, op2_offset
);
3744 if (sse_fn_epp
== SSE_SPECIAL
) {
3748 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3749 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3750 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3753 set_cc_op(s
, CC_OP_EFLAGS
);
3760 /* Various integer extensions at 0f 38 f[0-f]. */
3761 b
= modrm
| (b1
<< 8);
3762 modrm
= x86_ldub_code(env
, s
);
3763 reg
= ((modrm
>> 3) & 7) | rex_r
;
3766 case 0x3f0: /* crc32 Gd,Eb */
3767 case 0x3f1: /* crc32 Gd,Ey */
3769 if (!(s
->cpuid_ext_features
& CPUID_EXT_SSE42
)) {
3772 if ((b
& 0xff) == 0xf0) {
3774 } else if (s
->dflag
!= MO_64
) {
3775 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3780 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[reg
]);
3781 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3782 gen_helper_crc32(s
->T0
, cpu_tmp2_i32
,
3783 s
->T0
, tcg_const_i32(8 << ot
));
3785 ot
= mo_64_32(s
->dflag
);
3786 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
3789 case 0x1f0: /* crc32 or movbe */
3791 /* For these insns, the f3 prefix is supposed to have priority
3792 over the 66 prefix, but that's not what we implement above
3794 if (s
->prefix
& PREFIX_REPNZ
) {
3798 case 0x0f0: /* movbe Gy,My */
3799 case 0x0f1: /* movbe My,Gy */
3800 if (!(s
->cpuid_ext_features
& CPUID_EXT_MOVBE
)) {
3803 if (s
->dflag
!= MO_64
) {
3804 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3809 gen_lea_modrm(env
, s
, modrm
);
3811 tcg_gen_qemu_ld_tl(s
->T0
, s
->A0
,
3812 s
->mem_index
, ot
| MO_BE
);
3813 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
3815 tcg_gen_qemu_st_tl(cpu_regs
[reg
], s
->A0
,
3816 s
->mem_index
, ot
| MO_BE
);
3820 case 0x0f2: /* andn Gy, By, Ey */
3821 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3822 || !(s
->prefix
& PREFIX_VEX
)
3826 ot
= mo_64_32(s
->dflag
);
3827 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3828 tcg_gen_andc_tl(s
->T0
, s
->T0
, cpu_regs
[s
->vex_v
]);
3829 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
3830 gen_op_update1_cc(s
);
3831 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3834 case 0x0f7: /* bextr Gy, Ey, By */
3835 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3836 || !(s
->prefix
& PREFIX_VEX
)
3840 ot
= mo_64_32(s
->dflag
);
3844 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3845 /* Extract START, and shift the operand.
3846 Shifts larger than operand size get zeros. */
3847 tcg_gen_ext8u_tl(s
->A0
, cpu_regs
[s
->vex_v
]);
3848 tcg_gen_shr_tl(s
->T0
, s
->T0
, s
->A0
);
3850 bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3851 zero
= tcg_const_tl(0);
3852 tcg_gen_movcond_tl(TCG_COND_LEU
, s
->T0
, s
->A0
, bound
,
3854 tcg_temp_free(zero
);
3856 /* Extract the LEN into a mask. Lengths larger than
3857 operand size get all ones. */
3858 tcg_gen_extract_tl(s
->A0
, cpu_regs
[s
->vex_v
], 8, 8);
3859 tcg_gen_movcond_tl(TCG_COND_LEU
, s
->A0
, s
->A0
, bound
,
3861 tcg_temp_free(bound
);
3862 tcg_gen_movi_tl(s
->T1
, 1);
3863 tcg_gen_shl_tl(s
->T1
, s
->T1
, s
->A0
);
3864 tcg_gen_subi_tl(s
->T1
, s
->T1
, 1);
3865 tcg_gen_and_tl(s
->T0
, s
->T0
, s
->T1
);
3867 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
3868 gen_op_update1_cc(s
);
3869 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3873 case 0x0f5: /* bzhi Gy, Ey, By */
3874 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3875 || !(s
->prefix
& PREFIX_VEX
)
3879 ot
= mo_64_32(s
->dflag
);
3880 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3881 tcg_gen_ext8u_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
3883 TCGv bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3884 /* Note that since we're using BMILG (in order to get O
3885 cleared) we need to store the inverse into C. */
3886 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_cc_src
,
3888 tcg_gen_movcond_tl(TCG_COND_GT
, s
->T1
, s
->T1
,
3889 bound
, bound
, s
->T1
);
3890 tcg_temp_free(bound
);
3892 tcg_gen_movi_tl(s
->A0
, -1);
3893 tcg_gen_shl_tl(s
->A0
, s
->A0
, s
->T1
);
3894 tcg_gen_andc_tl(s
->T0
, s
->T0
, s
->A0
);
3895 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
3896 gen_op_update1_cc(s
);
3897 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
3900 case 0x3f6: /* mulx By, Gy, rdx, Ey */
3901 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3902 || !(s
->prefix
& PREFIX_VEX
)
3906 ot
= mo_64_32(s
->dflag
);
3907 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3910 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
3911 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EDX
]);
3912 tcg_gen_mulu2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
3913 cpu_tmp2_i32
, cpu_tmp3_i32
);
3914 tcg_gen_extu_i32_tl(cpu_regs
[s
->vex_v
], cpu_tmp2_i32
);
3915 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp3_i32
);
3917 #ifdef TARGET_X86_64
3919 tcg_gen_mulu2_i64(s
->T0
, s
->T1
,
3920 s
->T0
, cpu_regs
[R_EDX
]);
3921 tcg_gen_mov_i64(cpu_regs
[s
->vex_v
], s
->T0
);
3922 tcg_gen_mov_i64(cpu_regs
[reg
], s
->T1
);
3928 case 0x3f5: /* pdep Gy, By, Ey */
3929 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3930 || !(s
->prefix
& PREFIX_VEX
)
3934 ot
= mo_64_32(s
->dflag
);
3935 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3936 /* Note that by zero-extending the mask operand, we
3937 automatically handle zero-extending the result. */
3939 tcg_gen_mov_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
3941 tcg_gen_ext32u_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
3943 gen_helper_pdep(cpu_regs
[reg
], s
->T0
, s
->T1
);
3946 case 0x2f5: /* pext Gy, By, Ey */
3947 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3948 || !(s
->prefix
& PREFIX_VEX
)
3952 ot
= mo_64_32(s
->dflag
);
3953 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3954 /* Note that by zero-extending the mask operand, we
3955 automatically handle zero-extending the result. */
3957 tcg_gen_mov_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
3959 tcg_gen_ext32u_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
3961 gen_helper_pext(cpu_regs
[reg
], s
->T0
, s
->T1
);
3964 case 0x1f6: /* adcx Gy, Ey */
3965 case 0x2f6: /* adox Gy, Ey */
3966 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_ADX
)) {
3969 TCGv carry_in
, carry_out
, zero
;
3972 ot
= mo_64_32(s
->dflag
);
3973 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3975 /* Re-use the carry-out from a previous round. */
3977 carry_out
= (b
== 0x1f6 ? cpu_cc_dst
: cpu_cc_src2
);
3981 carry_in
= cpu_cc_dst
;
3982 end_op
= CC_OP_ADCX
;
3984 end_op
= CC_OP_ADCOX
;
3989 end_op
= CC_OP_ADCOX
;
3991 carry_in
= cpu_cc_src2
;
3992 end_op
= CC_OP_ADOX
;
3996 end_op
= CC_OP_ADCOX
;
3997 carry_in
= carry_out
;
4000 end_op
= (b
== 0x1f6 ? CC_OP_ADCX
: CC_OP_ADOX
);
4003 /* If we can't reuse carry-out, get it out of EFLAGS. */
4005 if (s
->cc_op
!= CC_OP_ADCX
&& s
->cc_op
!= CC_OP_ADOX
) {
4006 gen_compute_eflags(s
);
4009 tcg_gen_extract_tl(carry_in
, cpu_cc_src
,
4010 ctz32(b
== 0x1f6 ? CC_C
: CC_O
), 1);
4014 #ifdef TARGET_X86_64
4016 /* If we know TL is 64-bit, and we want a 32-bit
4017 result, just do everything in 64-bit arithmetic. */
4018 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_regs
[reg
]);
4019 tcg_gen_ext32u_i64(s
->T0
, s
->T0
);
4020 tcg_gen_add_i64(s
->T0
, s
->T0
, cpu_regs
[reg
]);
4021 tcg_gen_add_i64(s
->T0
, s
->T0
, carry_in
);
4022 tcg_gen_ext32u_i64(cpu_regs
[reg
], s
->T0
);
4023 tcg_gen_shri_i64(carry_out
, s
->T0
, 32);
4027 /* Otherwise compute the carry-out in two steps. */
4028 zero
= tcg_const_tl(0);
4029 tcg_gen_add2_tl(s
->T0
, carry_out
,
4032 tcg_gen_add2_tl(cpu_regs
[reg
], carry_out
,
4033 cpu_regs
[reg
], carry_out
,
4035 tcg_temp_free(zero
);
4038 set_cc_op(s
, end_op
);
4042 case 0x1f7: /* shlx Gy, Ey, By */
4043 case 0x2f7: /* sarx Gy, Ey, By */
4044 case 0x3f7: /* shrx Gy, Ey, By */
4045 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4046 || !(s
->prefix
& PREFIX_VEX
)
4050 ot
= mo_64_32(s
->dflag
);
4051 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4053 tcg_gen_andi_tl(s
->T1
, cpu_regs
[s
->vex_v
], 63);
4055 tcg_gen_andi_tl(s
->T1
, cpu_regs
[s
->vex_v
], 31);
4058 tcg_gen_shl_tl(s
->T0
, s
->T0
, s
->T1
);
4059 } else if (b
== 0x2f7) {
4061 tcg_gen_ext32s_tl(s
->T0
, s
->T0
);
4063 tcg_gen_sar_tl(s
->T0
, s
->T0
, s
->T1
);
4066 tcg_gen_ext32u_tl(s
->T0
, s
->T0
);
4068 tcg_gen_shr_tl(s
->T0
, s
->T0
, s
->T1
);
4070 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
4076 case 0x3f3: /* Group 17 */
4077 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
4078 || !(s
->prefix
& PREFIX_VEX
)
4082 ot
= mo_64_32(s
->dflag
);
4083 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4085 tcg_gen_mov_tl(cpu_cc_src
, s
->T0
);
4087 case 1: /* blsr By,Ey */
4088 tcg_gen_subi_tl(s
->T1
, s
->T0
, 1);
4089 tcg_gen_and_tl(s
->T0
, s
->T0
, s
->T1
);
4091 case 2: /* blsmsk By,Ey */
4092 tcg_gen_subi_tl(s
->T1
, s
->T0
, 1);
4093 tcg_gen_xor_tl(s
->T0
, s
->T0
, s
->T1
);
4095 case 3: /* blsi By, Ey */
4096 tcg_gen_neg_tl(s
->T1
, s
->T0
);
4097 tcg_gen_and_tl(s
->T0
, s
->T0
, s
->T1
);
4102 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
4103 gen_op_mov_reg_v(ot
, s
->vex_v
, s
->T0
);
4104 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4115 modrm
= x86_ldub_code(env
, s
);
4117 reg
= ((modrm
>> 3) & 7) | rex_r
;
4118 mod
= (modrm
>> 6) & 3;
4123 sse_fn_eppi
= sse_op_table7
[b
].op
[b1
];
4127 if (!(s
->cpuid_ext_features
& sse_op_table7
[b
].ext_mask
))
4132 if (sse_fn_eppi
== SSE_SPECIAL
) {
4133 ot
= mo_64_32(s
->dflag
);
4134 rm
= (modrm
& 7) | REX_B(s
);
4136 gen_lea_modrm(env
, s
, modrm
);
4137 reg
= ((modrm
>> 3) & 7) | rex_r
;
4138 val
= x86_ldub_code(env
, s
);
4140 case 0x14: /* pextrb */
4141 tcg_gen_ld8u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
4142 xmm_regs
[reg
].ZMM_B(val
& 15)));
4144 gen_op_mov_reg_v(ot
, rm
, s
->T0
);
4146 tcg_gen_qemu_st_tl(s
->T0
, s
->A0
,
4147 s
->mem_index
, MO_UB
);
4150 case 0x15: /* pextrw */
4151 tcg_gen_ld16u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
4152 xmm_regs
[reg
].ZMM_W(val
& 7)));
4154 gen_op_mov_reg_v(ot
, rm
, s
->T0
);
4156 tcg_gen_qemu_st_tl(s
->T0
, s
->A0
,
4157 s
->mem_index
, MO_LEUW
);
4161 if (ot
== MO_32
) { /* pextrd */
4162 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4163 offsetof(CPUX86State
,
4164 xmm_regs
[reg
].ZMM_L(val
& 3)));
4166 tcg_gen_extu_i32_tl(cpu_regs
[rm
], cpu_tmp2_i32
);
4168 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, s
->A0
,
4169 s
->mem_index
, MO_LEUL
);
4171 } else { /* pextrq */
4172 #ifdef TARGET_X86_64
4173 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
4174 offsetof(CPUX86State
,
4175 xmm_regs
[reg
].ZMM_Q(val
& 1)));
4177 tcg_gen_mov_i64(cpu_regs
[rm
], cpu_tmp1_i64
);
4179 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, s
->A0
,
4180 s
->mem_index
, MO_LEQ
);
4187 case 0x17: /* extractps */
4188 tcg_gen_ld32u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
4189 xmm_regs
[reg
].ZMM_L(val
& 3)));
4191 gen_op_mov_reg_v(ot
, rm
, s
->T0
);
4193 tcg_gen_qemu_st_tl(s
->T0
, s
->A0
,
4194 s
->mem_index
, MO_LEUL
);
4197 case 0x20: /* pinsrb */
4199 gen_op_mov_v_reg(MO_32
, s
->T0
, rm
);
4201 tcg_gen_qemu_ld_tl(s
->T0
, s
->A0
,
4202 s
->mem_index
, MO_UB
);
4204 tcg_gen_st8_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
4205 xmm_regs
[reg
].ZMM_B(val
& 15)));
4207 case 0x21: /* insertps */
4209 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4210 offsetof(CPUX86State
,xmm_regs
[rm
]
4211 .ZMM_L((val
>> 6) & 3)));
4213 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, s
->A0
,
4214 s
->mem_index
, MO_LEUL
);
4216 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4217 offsetof(CPUX86State
,xmm_regs
[reg
]
4218 .ZMM_L((val
>> 4) & 3)));
4220 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4221 cpu_env
, offsetof(CPUX86State
,
4222 xmm_regs
[reg
].ZMM_L(0)));
4224 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4225 cpu_env
, offsetof(CPUX86State
,
4226 xmm_regs
[reg
].ZMM_L(1)));
4228 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4229 cpu_env
, offsetof(CPUX86State
,
4230 xmm_regs
[reg
].ZMM_L(2)));
4232 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4233 cpu_env
, offsetof(CPUX86State
,
4234 xmm_regs
[reg
].ZMM_L(3)));
4237 if (ot
== MO_32
) { /* pinsrd */
4239 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[rm
]);
4241 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, s
->A0
,
4242 s
->mem_index
, MO_LEUL
);
4244 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4245 offsetof(CPUX86State
,
4246 xmm_regs
[reg
].ZMM_L(val
& 3)));
4247 } else { /* pinsrq */
4248 #ifdef TARGET_X86_64
4250 gen_op_mov_v_reg(ot
, cpu_tmp1_i64
, rm
);
4252 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, s
->A0
,
4253 s
->mem_index
, MO_LEQ
);
4255 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
4256 offsetof(CPUX86State
,
4257 xmm_regs
[reg
].ZMM_Q(val
& 1)));
4268 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4270 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
4272 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4273 gen_lea_modrm(env
, s
, modrm
);
4274 gen_ldo_env_A0(s
, op2_offset
);
4277 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4279 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4281 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4282 gen_lea_modrm(env
, s
, modrm
);
4283 gen_ldq_env_A0(s
, op2_offset
);
4286 val
= x86_ldub_code(env
, s
);
4288 if ((b
& 0xfc) == 0x60) { /* pcmpXstrX */
4289 set_cc_op(s
, CC_OP_EFLAGS
);
4291 if (s
->dflag
== MO_64
) {
4292 /* The helper must use entire 64-bit gp registers */
4297 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4298 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4299 sse_fn_eppi(cpu_env
, cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4303 /* Various integer extensions at 0f 3a f[0-f]. */
4304 b
= modrm
| (b1
<< 8);
4305 modrm
= x86_ldub_code(env
, s
);
4306 reg
= ((modrm
>> 3) & 7) | rex_r
;
4309 case 0x3f0: /* rorx Gy,Ey, Ib */
4310 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4311 || !(s
->prefix
& PREFIX_VEX
)
4315 ot
= mo_64_32(s
->dflag
);
4316 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4317 b
= x86_ldub_code(env
, s
);
4319 tcg_gen_rotri_tl(s
->T0
, s
->T0
, b
& 63);
4321 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
4322 tcg_gen_rotri_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, b
& 31);
4323 tcg_gen_extu_i32_tl(s
->T0
, cpu_tmp2_i32
);
4325 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
4335 gen_unknown_opcode(env
, s
);
4339 /* generic MMX or SSE operation */
4341 case 0x70: /* pshufx insn */
4342 case 0xc6: /* pshufx insn */
4343 case 0xc2: /* compare insns */
4350 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4354 gen_lea_modrm(env
, s
, modrm
);
4355 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4361 /* Most sse scalar operations. */
4364 } else if (b1
== 3) {
4369 case 0x2e: /* ucomis[sd] */
4370 case 0x2f: /* comis[sd] */
4382 gen_op_ld_v(s
, MO_32
, s
->T0
, s
->A0
);
4383 tcg_gen_st32_tl(s
->T0
, cpu_env
,
4384 offsetof(CPUX86State
,xmm_t0
.ZMM_L(0)));
4388 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.ZMM_D(0)));
4391 /* 128 bit access */
4392 gen_ldo_env_A0(s
, op2_offset
);
4396 rm
= (modrm
& 7) | REX_B(s
);
4397 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
4400 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4402 gen_lea_modrm(env
, s
, modrm
);
4403 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4404 gen_ldq_env_A0(s
, op2_offset
);
4407 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4411 case 0x0f: /* 3DNow! data insns */
4412 val
= x86_ldub_code(env
, s
);
4413 sse_fn_epp
= sse_op_table5
[val
];
4417 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
)) {
4420 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4421 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4422 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4424 case 0x70: /* pshufx insn */
4425 case 0xc6: /* pshufx insn */
4426 val
= x86_ldub_code(env
, s
);
4427 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4428 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4429 /* XXX: introduce a new table? */
4430 sse_fn_ppi
= (SSEFunc_0_ppi
)sse_fn_epp
;
4431 sse_fn_ppi(cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4435 val
= x86_ldub_code(env
, s
);
4438 sse_fn_epp
= sse_op_table4
[val
][b1
];
4440 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4441 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4442 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4445 /* maskmov : we must prepare A0 */
4448 tcg_gen_mov_tl(s
->A0
, cpu_regs
[R_EDI
]);
4449 gen_extu(s
->aflag
, s
->A0
);
4450 gen_add_A0_ds_seg(s
);
4452 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4453 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4454 /* XXX: introduce a new table? */
4455 sse_fn_eppt
= (SSEFunc_0_eppt
)sse_fn_epp
;
4456 sse_fn_eppt(cpu_env
, cpu_ptr0
, cpu_ptr1
, s
->A0
);
4459 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4460 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4461 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4464 if (b
== 0x2e || b
== 0x2f) {
4465 set_cc_op(s
, CC_OP_EFLAGS
);
4470 /* convert one instruction. s->base.is_jmp is set if the translation must
4471 be stopped. Return the next pc value */
4472 static target_ulong
disas_insn(DisasContext
*s
, CPUState
*cpu
)
4474 CPUX86State
*env
= cpu
->env_ptr
;
4477 TCGMemOp ot
, aflag
, dflag
;
4478 int modrm
, reg
, rm
, mod
, op
, opreg
, val
;
4479 target_ulong next_eip
, tval
;
4481 target_ulong pc_start
= s
->base
.pc_next
;
4483 s
->pc_start
= s
->pc
= pc_start
;
4485 #ifdef TARGET_X86_64
4490 s
->rip_offset
= 0; /* for relative ip address */
4493 if (sigsetjmp(s
->jmpbuf
, 0) != 0) {
4494 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
4503 b
= x86_ldub_code(env
, s
);
4504 /* Collect prefixes. */
4507 prefixes
|= PREFIX_REPZ
;
4510 prefixes
|= PREFIX_REPNZ
;
4513 prefixes
|= PREFIX_LOCK
;
4534 prefixes
|= PREFIX_DATA
;
4537 prefixes
|= PREFIX_ADR
;
4539 #ifdef TARGET_X86_64
4543 rex_w
= (b
>> 3) & 1;
4544 rex_r
= (b
& 0x4) << 1;
4545 s
->rex_x
= (b
& 0x2) << 2;
4546 REX_B(s
) = (b
& 0x1) << 3;
4547 x86_64_hregs
= 1; /* select uniform byte register addressing */
4552 case 0xc5: /* 2-byte VEX */
4553 case 0xc4: /* 3-byte VEX */
4554 /* VEX prefixes cannot be used except in 32-bit mode.
4555 Otherwise the instruction is LES or LDS. */
4556 if (s
->code32
&& !s
->vm86
) {
4557 static const int pp_prefix
[4] = {
4558 0, PREFIX_DATA
, PREFIX_REPZ
, PREFIX_REPNZ
4560 int vex3
, vex2
= x86_ldub_code(env
, s
);
4562 if (!CODE64(s
) && (vex2
& 0xc0) != 0xc0) {
4563 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4564 otherwise the instruction is LES or LDS. */
4565 s
->pc
--; /* rewind the advance_pc() x86_ldub_code() did */
4569 /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
4570 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
4571 | PREFIX_LOCK
| PREFIX_DATA
)) {
4574 #ifdef TARGET_X86_64
4579 rex_r
= (~vex2
>> 4) & 8;
4581 /* 2-byte VEX prefix: RVVVVlpp, implied 0f leading opcode byte */
4583 b
= x86_ldub_code(env
, s
) | 0x100;
4585 /* 3-byte VEX prefix: RXBmmmmm wVVVVlpp */
4586 #ifdef TARGET_X86_64
4587 s
->rex_x
= (~vex2
>> 3) & 8;
4588 s
->rex_b
= (~vex2
>> 2) & 8;
4590 vex3
= x86_ldub_code(env
, s
);
4591 rex_w
= (vex3
>> 7) & 1;
4592 switch (vex2
& 0x1f) {
4593 case 0x01: /* Implied 0f leading opcode bytes. */
4594 b
= x86_ldub_code(env
, s
) | 0x100;
4596 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4599 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4602 default: /* Reserved for future use. */
4606 s
->vex_v
= (~vex3
>> 3) & 0xf;
4607 s
->vex_l
= (vex3
>> 2) & 1;
4608 prefixes
|= pp_prefix
[vex3
& 3] | PREFIX_VEX
;
4613 /* Post-process prefixes. */
4615 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit
4616 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4617 over 0x66 if both are present. */
4618 dflag
= (rex_w
> 0 ? MO_64
: prefixes
& PREFIX_DATA
? MO_16
: MO_32
);
4619 /* In 64-bit mode, 0x67 selects 32-bit addressing. */
4620 aflag
= (prefixes
& PREFIX_ADR
? MO_32
: MO_64
);
4622 /* In 16/32-bit mode, 0x66 selects the opposite data size. */
4623 if (s
->code32
^ ((prefixes
& PREFIX_DATA
) != 0)) {
4628 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */
4629 if (s
->code32
^ ((prefixes
& PREFIX_ADR
) != 0)) {
4636 s
->prefix
= prefixes
;
4640 /* now check op code */
4644 /**************************/
4645 /* extended op code */
4646 b
= x86_ldub_code(env
, s
) | 0x100;
4649 /**************************/
4664 ot
= mo_b_d(b
, dflag
);
4667 case 0: /* OP Ev, Gv */
4668 modrm
= x86_ldub_code(env
, s
);
4669 reg
= ((modrm
>> 3) & 7) | rex_r
;
4670 mod
= (modrm
>> 6) & 3;
4671 rm
= (modrm
& 7) | REX_B(s
);
4673 gen_lea_modrm(env
, s
, modrm
);
4675 } else if (op
== OP_XORL
&& rm
== reg
) {
4677 /* xor reg, reg optimisation */
4678 set_cc_op(s
, CC_OP_CLR
);
4679 tcg_gen_movi_tl(s
->T0
, 0);
4680 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
4685 gen_op_mov_v_reg(ot
, s
->T1
, reg
);
4686 gen_op(s
, op
, ot
, opreg
);
4688 case 1: /* OP Gv, Ev */
4689 modrm
= x86_ldub_code(env
, s
);
4690 mod
= (modrm
>> 6) & 3;
4691 reg
= ((modrm
>> 3) & 7) | rex_r
;
4692 rm
= (modrm
& 7) | REX_B(s
);
4694 gen_lea_modrm(env
, s
, modrm
);
4695 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
4696 } else if (op
== OP_XORL
&& rm
== reg
) {
4699 gen_op_mov_v_reg(ot
, s
->T1
, rm
);
4701 gen_op(s
, op
, ot
, reg
);
4703 case 2: /* OP A, Iv */
4704 val
= insn_get(env
, s
, ot
);
4705 tcg_gen_movi_tl(s
->T1
, val
);
4706 gen_op(s
, op
, ot
, OR_EAX
);
4716 case 0x80: /* GRP1 */
4722 ot
= mo_b_d(b
, dflag
);
4724 modrm
= x86_ldub_code(env
, s
);
4725 mod
= (modrm
>> 6) & 3;
4726 rm
= (modrm
& 7) | REX_B(s
);
4727 op
= (modrm
>> 3) & 7;
4733 s
->rip_offset
= insn_const_size(ot
);
4734 gen_lea_modrm(env
, s
, modrm
);
4745 val
= insn_get(env
, s
, ot
);
4748 val
= (int8_t)insn_get(env
, s
, MO_8
);
4751 tcg_gen_movi_tl(s
->T1
, val
);
4752 gen_op(s
, op
, ot
, opreg
);
4756 /**************************/
4757 /* inc, dec, and other misc arith */
4758 case 0x40 ... 0x47: /* inc Gv */
4760 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), 1);
4762 case 0x48 ... 0x4f: /* dec Gv */
4764 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), -1);
4766 case 0xf6: /* GRP3 */
4768 ot
= mo_b_d(b
, dflag
);
4770 modrm
= x86_ldub_code(env
, s
);
4771 mod
= (modrm
>> 6) & 3;
4772 rm
= (modrm
& 7) | REX_B(s
);
4773 op
= (modrm
>> 3) & 7;
4776 s
->rip_offset
= insn_const_size(ot
);
4778 gen_lea_modrm(env
, s
, modrm
);
4779 /* For those below that handle locked memory, don't load here. */
4780 if (!(s
->prefix
& PREFIX_LOCK
)
4782 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
4785 gen_op_mov_v_reg(ot
, s
->T0
, rm
);
4790 val
= insn_get(env
, s
, ot
);
4791 tcg_gen_movi_tl(s
->T1
, val
);
4792 gen_op_testl_T0_T1_cc(s
);
4793 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4796 if (s
->prefix
& PREFIX_LOCK
) {
4800 tcg_gen_movi_tl(s
->T0
, ~0);
4801 tcg_gen_atomic_xor_fetch_tl(s
->T0
, s
->A0
, s
->T0
,
4802 s
->mem_index
, ot
| MO_LE
);
4804 tcg_gen_not_tl(s
->T0
, s
->T0
);
4806 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
4808 gen_op_mov_reg_v(ot
, rm
, s
->T0
);
4813 if (s
->prefix
& PREFIX_LOCK
) {
4815 TCGv a0
, t0
, t1
, t2
;
4820 a0
= tcg_temp_local_new();
4821 t0
= tcg_temp_local_new();
4822 label1
= gen_new_label();
4824 tcg_gen_mov_tl(a0
, s
->A0
);
4825 tcg_gen_mov_tl(t0
, s
->T0
);
4827 gen_set_label(label1
);
4828 t1
= tcg_temp_new();
4829 t2
= tcg_temp_new();
4830 tcg_gen_mov_tl(t2
, t0
);
4831 tcg_gen_neg_tl(t1
, t0
);
4832 tcg_gen_atomic_cmpxchg_tl(t0
, a0
, t0
, t1
,
4833 s
->mem_index
, ot
| MO_LE
);
4835 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t2
, label1
);
4839 tcg_gen_mov_tl(s
->T0
, t0
);
4842 tcg_gen_neg_tl(s
->T0
, s
->T0
);
4844 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
4846 gen_op_mov_reg_v(ot
, rm
, s
->T0
);
4849 gen_op_update_neg_cc(s
);
4850 set_cc_op(s
, CC_OP_SUBB
+ ot
);
4855 gen_op_mov_v_reg(MO_8
, s
->T1
, R_EAX
);
4856 tcg_gen_ext8u_tl(s
->T0
, s
->T0
);
4857 tcg_gen_ext8u_tl(s
->T1
, s
->T1
);
4858 /* XXX: use 32 bit mul which could be faster */
4859 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
4860 gen_op_mov_reg_v(MO_16
, R_EAX
, s
->T0
);
4861 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
4862 tcg_gen_andi_tl(cpu_cc_src
, s
->T0
, 0xff00);
4863 set_cc_op(s
, CC_OP_MULB
);
4866 gen_op_mov_v_reg(MO_16
, s
->T1
, R_EAX
);
4867 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
4868 tcg_gen_ext16u_tl(s
->T1
, s
->T1
);
4869 /* XXX: use 32 bit mul which could be faster */
4870 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
4871 gen_op_mov_reg_v(MO_16
, R_EAX
, s
->T0
);
4872 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
4873 tcg_gen_shri_tl(s
->T0
, s
->T0
, 16);
4874 gen_op_mov_reg_v(MO_16
, R_EDX
, s
->T0
);
4875 tcg_gen_mov_tl(cpu_cc_src
, s
->T0
);
4876 set_cc_op(s
, CC_OP_MULW
);
4880 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
4881 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
4882 tcg_gen_mulu2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4883 cpu_tmp2_i32
, cpu_tmp3_i32
);
4884 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
4885 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
4886 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4887 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4888 set_cc_op(s
, CC_OP_MULL
);
4890 #ifdef TARGET_X86_64
4892 tcg_gen_mulu2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4893 s
->T0
, cpu_regs
[R_EAX
]);
4894 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4895 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4896 set_cc_op(s
, CC_OP_MULQ
);
4904 gen_op_mov_v_reg(MO_8
, s
->T1
, R_EAX
);
4905 tcg_gen_ext8s_tl(s
->T0
, s
->T0
);
4906 tcg_gen_ext8s_tl(s
->T1
, s
->T1
);
4907 /* XXX: use 32 bit mul which could be faster */
4908 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
4909 gen_op_mov_reg_v(MO_16
, R_EAX
, s
->T0
);
4910 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
4911 tcg_gen_ext8s_tl(s
->tmp0
, s
->T0
);
4912 tcg_gen_sub_tl(cpu_cc_src
, s
->T0
, s
->tmp0
);
4913 set_cc_op(s
, CC_OP_MULB
);
4916 gen_op_mov_v_reg(MO_16
, s
->T1
, R_EAX
);
4917 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
4918 tcg_gen_ext16s_tl(s
->T1
, s
->T1
);
4919 /* XXX: use 32 bit mul which could be faster */
4920 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
4921 gen_op_mov_reg_v(MO_16
, R_EAX
, s
->T0
);
4922 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
4923 tcg_gen_ext16s_tl(s
->tmp0
, s
->T0
);
4924 tcg_gen_sub_tl(cpu_cc_src
, s
->T0
, s
->tmp0
);
4925 tcg_gen_shri_tl(s
->T0
, s
->T0
, 16);
4926 gen_op_mov_reg_v(MO_16
, R_EDX
, s
->T0
);
4927 set_cc_op(s
, CC_OP_MULW
);
4931 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
4932 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
4933 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4934 cpu_tmp2_i32
, cpu_tmp3_i32
);
4935 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
4936 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
4937 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
4938 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4939 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
4940 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
4941 set_cc_op(s
, CC_OP_MULL
);
4943 #ifdef TARGET_X86_64
4945 tcg_gen_muls2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4946 s
->T0
, cpu_regs
[R_EAX
]);
4947 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4948 tcg_gen_sari_tl(cpu_cc_src
, cpu_regs
[R_EAX
], 63);
4949 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_regs
[R_EDX
]);
4950 set_cc_op(s
, CC_OP_MULQ
);
4958 gen_helper_divb_AL(cpu_env
, s
->T0
);
4961 gen_helper_divw_AX(cpu_env
, s
->T0
);
4965 gen_helper_divl_EAX(cpu_env
, s
->T0
);
4967 #ifdef TARGET_X86_64
4969 gen_helper_divq_EAX(cpu_env
, s
->T0
);
4977 gen_helper_idivb_AL(cpu_env
, s
->T0
);
4980 gen_helper_idivw_AX(cpu_env
, s
->T0
);
4984 gen_helper_idivl_EAX(cpu_env
, s
->T0
);
4986 #ifdef TARGET_X86_64
4988 gen_helper_idivq_EAX(cpu_env
, s
->T0
);
4998 case 0xfe: /* GRP4 */
4999 case 0xff: /* GRP5 */
5000 ot
= mo_b_d(b
, dflag
);
5002 modrm
= x86_ldub_code(env
, s
);
5003 mod
= (modrm
>> 6) & 3;
5004 rm
= (modrm
& 7) | REX_B(s
);
5005 op
= (modrm
>> 3) & 7;
5006 if (op
>= 2 && b
== 0xfe) {
5010 if (op
== 2 || op
== 4) {
5011 /* operand size for jumps is 64 bit */
5013 } else if (op
== 3 || op
== 5) {
5014 ot
= dflag
!= MO_16
? MO_32
+ (rex_w
== 1) : MO_16
;
5015 } else if (op
== 6) {
5016 /* default push size is 64 bit */
5017 ot
= mo_pushpop(s
, dflag
);
5021 gen_lea_modrm(env
, s
, modrm
);
5022 if (op
>= 2 && op
!= 3 && op
!= 5)
5023 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
5025 gen_op_mov_v_reg(ot
, s
->T0
, rm
);
5029 case 0: /* inc Ev */
5034 gen_inc(s
, ot
, opreg
, 1);
5036 case 1: /* dec Ev */
5041 gen_inc(s
, ot
, opreg
, -1);
5043 case 2: /* call Ev */
5044 /* XXX: optimize if memory (no 'and' is necessary) */
5045 if (dflag
== MO_16
) {
5046 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
5048 next_eip
= s
->pc
- s
->cs_base
;
5049 tcg_gen_movi_tl(s
->T1
, next_eip
);
5050 gen_push_v(s
, s
->T1
);
5051 gen_op_jmp_v(s
->T0
);
5055 case 3: /* lcall Ev */
5056 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
5057 gen_add_A0_im(s
, 1 << ot
);
5058 gen_op_ld_v(s
, MO_16
, s
->T0
, s
->A0
);
5060 if (s
->pe
&& !s
->vm86
) {
5061 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
5062 gen_helper_lcall_protected(cpu_env
, cpu_tmp2_i32
, s
->T1
,
5063 tcg_const_i32(dflag
- 1),
5064 tcg_const_tl(s
->pc
- s
->cs_base
));
5066 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
5067 gen_helper_lcall_real(cpu_env
, cpu_tmp2_i32
, s
->T1
,
5068 tcg_const_i32(dflag
- 1),
5069 tcg_const_i32(s
->pc
- s
->cs_base
));
5071 tcg_gen_ld_tl(s
->tmp4
, cpu_env
, offsetof(CPUX86State
, eip
));
5074 case 4: /* jmp Ev */
5075 if (dflag
== MO_16
) {
5076 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
5078 gen_op_jmp_v(s
->T0
);
5082 case 5: /* ljmp Ev */
5083 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
5084 gen_add_A0_im(s
, 1 << ot
);
5085 gen_op_ld_v(s
, MO_16
, s
->T0
, s
->A0
);
5087 if (s
->pe
&& !s
->vm86
) {
5088 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
5089 gen_helper_ljmp_protected(cpu_env
, cpu_tmp2_i32
, s
->T1
,
5090 tcg_const_tl(s
->pc
- s
->cs_base
));
5092 gen_op_movl_seg_T0_vm(s
, R_CS
);
5093 gen_op_jmp_v(s
->T1
);
5095 tcg_gen_ld_tl(s
->tmp4
, cpu_env
, offsetof(CPUX86State
, eip
));
5098 case 6: /* push Ev */
5099 gen_push_v(s
, s
->T0
);
5106 case 0x84: /* test Ev, Gv */
5108 ot
= mo_b_d(b
, dflag
);
5110 modrm
= x86_ldub_code(env
, s
);
5111 reg
= ((modrm
>> 3) & 7) | rex_r
;
5113 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5114 gen_op_mov_v_reg(ot
, s
->T1
, reg
);
5115 gen_op_testl_T0_T1_cc(s
);
5116 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5119 case 0xa8: /* test eAX, Iv */
5121 ot
= mo_b_d(b
, dflag
);
5122 val
= insn_get(env
, s
, ot
);
5124 gen_op_mov_v_reg(ot
, s
->T0
, OR_EAX
);
5125 tcg_gen_movi_tl(s
->T1
, val
);
5126 gen_op_testl_T0_T1_cc(s
);
5127 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5130 case 0x98: /* CWDE/CBW */
5132 #ifdef TARGET_X86_64
5134 gen_op_mov_v_reg(MO_32
, s
->T0
, R_EAX
);
5135 tcg_gen_ext32s_tl(s
->T0
, s
->T0
);
5136 gen_op_mov_reg_v(MO_64
, R_EAX
, s
->T0
);
5140 gen_op_mov_v_reg(MO_16
, s
->T0
, R_EAX
);
5141 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5142 gen_op_mov_reg_v(MO_32
, R_EAX
, s
->T0
);
5145 gen_op_mov_v_reg(MO_8
, s
->T0
, R_EAX
);
5146 tcg_gen_ext8s_tl(s
->T0
, s
->T0
);
5147 gen_op_mov_reg_v(MO_16
, R_EAX
, s
->T0
);
5153 case 0x99: /* CDQ/CWD */
5155 #ifdef TARGET_X86_64
5157 gen_op_mov_v_reg(MO_64
, s
->T0
, R_EAX
);
5158 tcg_gen_sari_tl(s
->T0
, s
->T0
, 63);
5159 gen_op_mov_reg_v(MO_64
, R_EDX
, s
->T0
);
5163 gen_op_mov_v_reg(MO_32
, s
->T0
, R_EAX
);
5164 tcg_gen_ext32s_tl(s
->T0
, s
->T0
);
5165 tcg_gen_sari_tl(s
->T0
, s
->T0
, 31);
5166 gen_op_mov_reg_v(MO_32
, R_EDX
, s
->T0
);
5169 gen_op_mov_v_reg(MO_16
, s
->T0
, R_EAX
);
5170 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5171 tcg_gen_sari_tl(s
->T0
, s
->T0
, 15);
5172 gen_op_mov_reg_v(MO_16
, R_EDX
, s
->T0
);
5178 case 0x1af: /* imul Gv, Ev */
5179 case 0x69: /* imul Gv, Ev, I */
5182 modrm
= x86_ldub_code(env
, s
);
5183 reg
= ((modrm
>> 3) & 7) | rex_r
;
5185 s
->rip_offset
= insn_const_size(ot
);
5188 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5190 val
= insn_get(env
, s
, ot
);
5191 tcg_gen_movi_tl(s
->T1
, val
);
5192 } else if (b
== 0x6b) {
5193 val
= (int8_t)insn_get(env
, s
, MO_8
);
5194 tcg_gen_movi_tl(s
->T1
, val
);
5196 gen_op_mov_v_reg(ot
, s
->T1
, reg
);
5199 #ifdef TARGET_X86_64
5201 tcg_gen_muls2_i64(cpu_regs
[reg
], s
->T1
, s
->T0
, s
->T1
);
5202 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5203 tcg_gen_sari_tl(cpu_cc_src
, cpu_cc_dst
, 63);
5204 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, s
->T1
);
5208 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
5209 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, s
->T1
);
5210 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
5211 cpu_tmp2_i32
, cpu_tmp3_i32
);
5212 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
5213 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
5214 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5215 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
5216 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
5219 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5220 tcg_gen_ext16s_tl(s
->T1
, s
->T1
);
5221 /* XXX: use 32 bit mul which could be faster */
5222 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
5223 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
5224 tcg_gen_ext16s_tl(s
->tmp0
, s
->T0
);
5225 tcg_gen_sub_tl(cpu_cc_src
, s
->T0
, s
->tmp0
);
5226 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
5229 set_cc_op(s
, CC_OP_MULB
+ ot
);
5232 case 0x1c1: /* xadd Ev, Gv */
5233 ot
= mo_b_d(b
, dflag
);
5234 modrm
= x86_ldub_code(env
, s
);
5235 reg
= ((modrm
>> 3) & 7) | rex_r
;
5236 mod
= (modrm
>> 6) & 3;
5237 gen_op_mov_v_reg(ot
, s
->T0
, reg
);
5239 rm
= (modrm
& 7) | REX_B(s
);
5240 gen_op_mov_v_reg(ot
, s
->T1
, rm
);
5241 tcg_gen_add_tl(s
->T0
, s
->T0
, s
->T1
);
5242 gen_op_mov_reg_v(ot
, reg
, s
->T1
);
5243 gen_op_mov_reg_v(ot
, rm
, s
->T0
);
5245 gen_lea_modrm(env
, s
, modrm
);
5246 if (s
->prefix
& PREFIX_LOCK
) {
5247 tcg_gen_atomic_fetch_add_tl(s
->T1
, s
->A0
, s
->T0
,
5248 s
->mem_index
, ot
| MO_LE
);
5249 tcg_gen_add_tl(s
->T0
, s
->T0
, s
->T1
);
5251 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
5252 tcg_gen_add_tl(s
->T0
, s
->T0
, s
->T1
);
5253 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
5255 gen_op_mov_reg_v(ot
, reg
, s
->T1
);
5257 gen_op_update2_cc(s
);
5258 set_cc_op(s
, CC_OP_ADDB
+ ot
);
5261 case 0x1b1: /* cmpxchg Ev, Gv */
5263 TCGv oldv
, newv
, cmpv
;
5265 ot
= mo_b_d(b
, dflag
);
5266 modrm
= x86_ldub_code(env
, s
);
5267 reg
= ((modrm
>> 3) & 7) | rex_r
;
5268 mod
= (modrm
>> 6) & 3;
5269 oldv
= tcg_temp_new();
5270 newv
= tcg_temp_new();
5271 cmpv
= tcg_temp_new();
5272 gen_op_mov_v_reg(ot
, newv
, reg
);
5273 tcg_gen_mov_tl(cmpv
, cpu_regs
[R_EAX
]);
5275 if (s
->prefix
& PREFIX_LOCK
) {
5279 gen_lea_modrm(env
, s
, modrm
);
5280 tcg_gen_atomic_cmpxchg_tl(oldv
, s
->A0
, cmpv
, newv
,
5281 s
->mem_index
, ot
| MO_LE
);
5282 gen_op_mov_reg_v(ot
, R_EAX
, oldv
);
5285 rm
= (modrm
& 7) | REX_B(s
);
5286 gen_op_mov_v_reg(ot
, oldv
, rm
);
5288 gen_lea_modrm(env
, s
, modrm
);
5289 gen_op_ld_v(s
, ot
, oldv
, s
->A0
);
5290 rm
= 0; /* avoid warning */
5294 /* store value = (old == cmp ? new : old); */
5295 tcg_gen_movcond_tl(TCG_COND_EQ
, newv
, oldv
, cmpv
, newv
, oldv
);
5297 gen_op_mov_reg_v(ot
, R_EAX
, oldv
);
5298 gen_op_mov_reg_v(ot
, rm
, newv
);
5300 /* Perform an unconditional store cycle like physical cpu;
5301 must be before changing accumulator to ensure
5302 idempotency if the store faults and the instruction
5304 gen_op_st_v(s
, ot
, newv
, s
->A0
);
5305 gen_op_mov_reg_v(ot
, R_EAX
, oldv
);
5308 tcg_gen_mov_tl(cpu_cc_src
, oldv
);
5309 tcg_gen_mov_tl(s
->cc_srcT
, cmpv
);
5310 tcg_gen_sub_tl(cpu_cc_dst
, cmpv
, oldv
);
5311 set_cc_op(s
, CC_OP_SUBB
+ ot
);
5312 tcg_temp_free(oldv
);
5313 tcg_temp_free(newv
);
5314 tcg_temp_free(cmpv
);
5317 case 0x1c7: /* cmpxchg8b */
5318 modrm
= x86_ldub_code(env
, s
);
5319 mod
= (modrm
>> 6) & 3;
5320 if ((mod
== 3) || ((modrm
& 0x38) != 0x8))
5322 #ifdef TARGET_X86_64
5323 if (dflag
== MO_64
) {
5324 if (!(s
->cpuid_ext_features
& CPUID_EXT_CX16
))
5326 gen_lea_modrm(env
, s
, modrm
);
5327 if ((s
->prefix
& PREFIX_LOCK
) && (tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
5328 gen_helper_cmpxchg16b(cpu_env
, s
->A0
);
5330 gen_helper_cmpxchg16b_unlocked(cpu_env
, s
->A0
);
5335 if (!(s
->cpuid_features
& CPUID_CX8
))
5337 gen_lea_modrm(env
, s
, modrm
);
5338 if ((s
->prefix
& PREFIX_LOCK
) && (tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
5339 gen_helper_cmpxchg8b(cpu_env
, s
->A0
);
5341 gen_helper_cmpxchg8b_unlocked(cpu_env
, s
->A0
);
5344 set_cc_op(s
, CC_OP_EFLAGS
);
5347 /**************************/
5349 case 0x50 ... 0x57: /* push */
5350 gen_op_mov_v_reg(MO_32
, s
->T0
, (b
& 7) | REX_B(s
));
5351 gen_push_v(s
, s
->T0
);
5353 case 0x58 ... 0x5f: /* pop */
5355 /* NOTE: order is important for pop %sp */
5356 gen_pop_update(s
, ot
);
5357 gen_op_mov_reg_v(ot
, (b
& 7) | REX_B(s
), s
->T0
);
5359 case 0x60: /* pusha */
5364 case 0x61: /* popa */
5369 case 0x68: /* push Iv */
5371 ot
= mo_pushpop(s
, dflag
);
5373 val
= insn_get(env
, s
, ot
);
5375 val
= (int8_t)insn_get(env
, s
, MO_8
);
5376 tcg_gen_movi_tl(s
->T0
, val
);
5377 gen_push_v(s
, s
->T0
);
5379 case 0x8f: /* pop Ev */
5380 modrm
= x86_ldub_code(env
, s
);
5381 mod
= (modrm
>> 6) & 3;
5384 /* NOTE: order is important for pop %sp */
5385 gen_pop_update(s
, ot
);
5386 rm
= (modrm
& 7) | REX_B(s
);
5387 gen_op_mov_reg_v(ot
, rm
, s
->T0
);
5389 /* NOTE: order is important too for MMU exceptions */
5390 s
->popl_esp_hack
= 1 << ot
;
5391 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5392 s
->popl_esp_hack
= 0;
5393 gen_pop_update(s
, ot
);
5396 case 0xc8: /* enter */
5399 val
= x86_lduw_code(env
, s
);
5400 level
= x86_ldub_code(env
, s
);
5401 gen_enter(s
, val
, level
);
5404 case 0xc9: /* leave */
5407 case 0x06: /* push es */
5408 case 0x0e: /* push cs */
5409 case 0x16: /* push ss */
5410 case 0x1e: /* push ds */
5413 gen_op_movl_T0_seg(s
, b
>> 3);
5414 gen_push_v(s
, s
->T0
);
5416 case 0x1a0: /* push fs */
5417 case 0x1a8: /* push gs */
5418 gen_op_movl_T0_seg(s
, (b
>> 3) & 7);
5419 gen_push_v(s
, s
->T0
);
5421 case 0x07: /* pop es */
5422 case 0x17: /* pop ss */
5423 case 0x1f: /* pop ds */
5428 gen_movl_seg_T0(s
, reg
);
5429 gen_pop_update(s
, ot
);
5430 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5431 if (s
->base
.is_jmp
) {
5432 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
5435 gen_eob_inhibit_irq(s
, true);
5441 case 0x1a1: /* pop fs */
5442 case 0x1a9: /* pop gs */
5444 gen_movl_seg_T0(s
, (b
>> 3) & 7);
5445 gen_pop_update(s
, ot
);
5446 if (s
->base
.is_jmp
) {
5447 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
5452 /**************************/
5455 case 0x89: /* mov Gv, Ev */
5456 ot
= mo_b_d(b
, dflag
);
5457 modrm
= x86_ldub_code(env
, s
);
5458 reg
= ((modrm
>> 3) & 7) | rex_r
;
5460 /* generate a generic store */
5461 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
5464 case 0xc7: /* mov Ev, Iv */
5465 ot
= mo_b_d(b
, dflag
);
5466 modrm
= x86_ldub_code(env
, s
);
5467 mod
= (modrm
>> 6) & 3;
5469 s
->rip_offset
= insn_const_size(ot
);
5470 gen_lea_modrm(env
, s
, modrm
);
5472 val
= insn_get(env
, s
, ot
);
5473 tcg_gen_movi_tl(s
->T0
, val
);
5475 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
5477 gen_op_mov_reg_v(ot
, (modrm
& 7) | REX_B(s
), s
->T0
);
5481 case 0x8b: /* mov Ev, Gv */
5482 ot
= mo_b_d(b
, dflag
);
5483 modrm
= x86_ldub_code(env
, s
);
5484 reg
= ((modrm
>> 3) & 7) | rex_r
;
5486 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5487 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
5489 case 0x8e: /* mov seg, Gv */
5490 modrm
= x86_ldub_code(env
, s
);
5491 reg
= (modrm
>> 3) & 7;
5492 if (reg
>= 6 || reg
== R_CS
)
5494 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
5495 gen_movl_seg_T0(s
, reg
);
5496 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5497 if (s
->base
.is_jmp
) {
5498 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
5501 gen_eob_inhibit_irq(s
, true);
5507 case 0x8c: /* mov Gv, seg */
5508 modrm
= x86_ldub_code(env
, s
);
5509 reg
= (modrm
>> 3) & 7;
5510 mod
= (modrm
>> 6) & 3;
5513 gen_op_movl_T0_seg(s
, reg
);
5514 ot
= mod
== 3 ? dflag
: MO_16
;
5515 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5518 case 0x1b6: /* movzbS Gv, Eb */
5519 case 0x1b7: /* movzwS Gv, Eb */
5520 case 0x1be: /* movsbS Gv, Eb */
5521 case 0x1bf: /* movswS Gv, Eb */
5526 /* d_ot is the size of destination */
5528 /* ot is the size of source */
5529 ot
= (b
& 1) + MO_8
;
5530 /* s_ot is the sign+size of source */
5531 s_ot
= b
& 8 ? MO_SIGN
| ot
: ot
;
5533 modrm
= x86_ldub_code(env
, s
);
5534 reg
= ((modrm
>> 3) & 7) | rex_r
;
5535 mod
= (modrm
>> 6) & 3;
5536 rm
= (modrm
& 7) | REX_B(s
);
5539 if (s_ot
== MO_SB
&& byte_reg_is_xH(rm
)) {
5540 tcg_gen_sextract_tl(s
->T0
, cpu_regs
[rm
- 4], 8, 8);
5542 gen_op_mov_v_reg(ot
, s
->T0
, rm
);
5545 tcg_gen_ext8u_tl(s
->T0
, s
->T0
);
5548 tcg_gen_ext8s_tl(s
->T0
, s
->T0
);
5551 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
5555 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5559 gen_op_mov_reg_v(d_ot
, reg
, s
->T0
);
5561 gen_lea_modrm(env
, s
, modrm
);
5562 gen_op_ld_v(s
, s_ot
, s
->T0
, s
->A0
);
5563 gen_op_mov_reg_v(d_ot
, reg
, s
->T0
);
5568 case 0x8d: /* lea */
5569 modrm
= x86_ldub_code(env
, s
);
5570 mod
= (modrm
>> 6) & 3;
5573 reg
= ((modrm
>> 3) & 7) | rex_r
;
5575 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
5576 TCGv ea
= gen_lea_modrm_1(s
, a
);
5577 gen_lea_v_seg(s
, s
->aflag
, ea
, -1, -1);
5578 gen_op_mov_reg_v(dflag
, reg
, s
->A0
);
5582 case 0xa0: /* mov EAX, Ov */
5584 case 0xa2: /* mov Ov, EAX */
5587 target_ulong offset_addr
;
5589 ot
= mo_b_d(b
, dflag
);
5591 #ifdef TARGET_X86_64
5593 offset_addr
= x86_ldq_code(env
, s
);
5597 offset_addr
= insn_get(env
, s
, s
->aflag
);
5600 tcg_gen_movi_tl(s
->A0
, offset_addr
);
5601 gen_add_A0_ds_seg(s
);
5603 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
5604 gen_op_mov_reg_v(ot
, R_EAX
, s
->T0
);
5606 gen_op_mov_v_reg(ot
, s
->T0
, R_EAX
);
5607 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
5611 case 0xd7: /* xlat */
5612 tcg_gen_mov_tl(s
->A0
, cpu_regs
[R_EBX
]);
5613 tcg_gen_ext8u_tl(s
->T0
, cpu_regs
[R_EAX
]);
5614 tcg_gen_add_tl(s
->A0
, s
->A0
, s
->T0
);
5615 gen_extu(s
->aflag
, s
->A0
);
5616 gen_add_A0_ds_seg(s
);
5617 gen_op_ld_v(s
, MO_8
, s
->T0
, s
->A0
);
5618 gen_op_mov_reg_v(MO_8
, R_EAX
, s
->T0
);
5620 case 0xb0 ... 0xb7: /* mov R, Ib */
5621 val
= insn_get(env
, s
, MO_8
);
5622 tcg_gen_movi_tl(s
->T0
, val
);
5623 gen_op_mov_reg_v(MO_8
, (b
& 7) | REX_B(s
), s
->T0
);
5625 case 0xb8 ... 0xbf: /* mov R, Iv */
5626 #ifdef TARGET_X86_64
5627 if (dflag
== MO_64
) {
5630 tmp
= x86_ldq_code(env
, s
);
5631 reg
= (b
& 7) | REX_B(s
);
5632 tcg_gen_movi_tl(s
->T0
, tmp
);
5633 gen_op_mov_reg_v(MO_64
, reg
, s
->T0
);
5638 val
= insn_get(env
, s
, ot
);
5639 reg
= (b
& 7) | REX_B(s
);
5640 tcg_gen_movi_tl(s
->T0
, val
);
5641 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
5645 case 0x91 ... 0x97: /* xchg R, EAX */
5648 reg
= (b
& 7) | REX_B(s
);
5652 case 0x87: /* xchg Ev, Gv */
5653 ot
= mo_b_d(b
, dflag
);
5654 modrm
= x86_ldub_code(env
, s
);
5655 reg
= ((modrm
>> 3) & 7) | rex_r
;
5656 mod
= (modrm
>> 6) & 3;
5658 rm
= (modrm
& 7) | REX_B(s
);
5660 gen_op_mov_v_reg(ot
, s
->T0
, reg
);
5661 gen_op_mov_v_reg(ot
, s
->T1
, rm
);
5662 gen_op_mov_reg_v(ot
, rm
, s
->T0
);
5663 gen_op_mov_reg_v(ot
, reg
, s
->T1
);
5665 gen_lea_modrm(env
, s
, modrm
);
5666 gen_op_mov_v_reg(ot
, s
->T0
, reg
);
5667 /* for xchg, lock is implicit */
5668 tcg_gen_atomic_xchg_tl(s
->T1
, s
->A0
, s
->T0
,
5669 s
->mem_index
, ot
| MO_LE
);
5670 gen_op_mov_reg_v(ot
, reg
, s
->T1
);
5673 case 0xc4: /* les Gv */
5674 /* In CODE64 this is VEX3; see above. */
5677 case 0xc5: /* lds Gv */
5678 /* In CODE64 this is VEX2; see above. */
5681 case 0x1b2: /* lss Gv */
5684 case 0x1b4: /* lfs Gv */
5687 case 0x1b5: /* lgs Gv */
5690 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
5691 modrm
= x86_ldub_code(env
, s
);
5692 reg
= ((modrm
>> 3) & 7) | rex_r
;
5693 mod
= (modrm
>> 6) & 3;
5696 gen_lea_modrm(env
, s
, modrm
);
5697 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
5698 gen_add_A0_im(s
, 1 << ot
);
5699 /* load the segment first to handle exceptions properly */
5700 gen_op_ld_v(s
, MO_16
, s
->T0
, s
->A0
);
5701 gen_movl_seg_T0(s
, op
);
5702 /* then put the data */
5703 gen_op_mov_reg_v(ot
, reg
, s
->T1
);
5704 if (s
->base
.is_jmp
) {
5705 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
5710 /************************/
5718 ot
= mo_b_d(b
, dflag
);
5719 modrm
= x86_ldub_code(env
, s
);
5720 mod
= (modrm
>> 6) & 3;
5721 op
= (modrm
>> 3) & 7;
5727 gen_lea_modrm(env
, s
, modrm
);
5730 opreg
= (modrm
& 7) | REX_B(s
);
5735 gen_shift(s
, op
, ot
, opreg
, OR_ECX
);
5738 shift
= x86_ldub_code(env
, s
);
5740 gen_shifti(s
, op
, ot
, opreg
, shift
);
5755 case 0x1a4: /* shld imm */
5759 case 0x1a5: /* shld cl */
5763 case 0x1ac: /* shrd imm */
5767 case 0x1ad: /* shrd cl */
5772 modrm
= x86_ldub_code(env
, s
);
5773 mod
= (modrm
>> 6) & 3;
5774 rm
= (modrm
& 7) | REX_B(s
);
5775 reg
= ((modrm
>> 3) & 7) | rex_r
;
5777 gen_lea_modrm(env
, s
, modrm
);
5782 gen_op_mov_v_reg(ot
, s
->T1
, reg
);
5785 TCGv imm
= tcg_const_tl(x86_ldub_code(env
, s
));
5786 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, imm
);
5789 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, cpu_regs
[R_ECX
]);
5793 /************************/
5796 if (s
->flags
& (HF_EM_MASK
| HF_TS_MASK
)) {
5797 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5798 /* XXX: what to do if illegal op ? */
5799 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
5802 modrm
= x86_ldub_code(env
, s
);
5803 mod
= (modrm
>> 6) & 3;
5805 op
= ((b
& 7) << 3) | ((modrm
>> 3) & 7);
5808 gen_lea_modrm(env
, s
, modrm
);
5810 case 0x00 ... 0x07: /* fxxxs */
5811 case 0x10 ... 0x17: /* fixxxl */
5812 case 0x20 ... 0x27: /* fxxxl */
5813 case 0x30 ... 0x37: /* fixxx */
5820 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, s
->A0
,
5821 s
->mem_index
, MO_LEUL
);
5822 gen_helper_flds_FT0(cpu_env
, cpu_tmp2_i32
);
5825 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, s
->A0
,
5826 s
->mem_index
, MO_LEUL
);
5827 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
5830 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, s
->A0
,
5831 s
->mem_index
, MO_LEQ
);
5832 gen_helper_fldl_FT0(cpu_env
, cpu_tmp1_i64
);
5836 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, s
->A0
,
5837 s
->mem_index
, MO_LESW
);
5838 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
5842 gen_helper_fp_arith_ST0_FT0(op1
);
5844 /* fcomp needs pop */
5845 gen_helper_fpop(cpu_env
);
5849 case 0x08: /* flds */
5850 case 0x0a: /* fsts */
5851 case 0x0b: /* fstps */
5852 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5853 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5854 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5859 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, s
->A0
,
5860 s
->mem_index
, MO_LEUL
);
5861 gen_helper_flds_ST0(cpu_env
, cpu_tmp2_i32
);
5864 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, s
->A0
,
5865 s
->mem_index
, MO_LEUL
);
5866 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
5869 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, s
->A0
,
5870 s
->mem_index
, MO_LEQ
);
5871 gen_helper_fldl_ST0(cpu_env
, cpu_tmp1_i64
);
5875 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, s
->A0
,
5876 s
->mem_index
, MO_LESW
);
5877 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
5882 /* XXX: the corresponding CPUID bit must be tested ! */
5885 gen_helper_fisttl_ST0(cpu_tmp2_i32
, cpu_env
);
5886 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, s
->A0
,
5887 s
->mem_index
, MO_LEUL
);
5890 gen_helper_fisttll_ST0(cpu_tmp1_i64
, cpu_env
);
5891 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, s
->A0
,
5892 s
->mem_index
, MO_LEQ
);
5896 gen_helper_fistt_ST0(cpu_tmp2_i32
, cpu_env
);
5897 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, s
->A0
,
5898 s
->mem_index
, MO_LEUW
);
5901 gen_helper_fpop(cpu_env
);
5906 gen_helper_fsts_ST0(cpu_tmp2_i32
, cpu_env
);
5907 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, s
->A0
,
5908 s
->mem_index
, MO_LEUL
);
5911 gen_helper_fistl_ST0(cpu_tmp2_i32
, cpu_env
);
5912 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, s
->A0
,
5913 s
->mem_index
, MO_LEUL
);
5916 gen_helper_fstl_ST0(cpu_tmp1_i64
, cpu_env
);
5917 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, s
->A0
,
5918 s
->mem_index
, MO_LEQ
);
5922 gen_helper_fist_ST0(cpu_tmp2_i32
, cpu_env
);
5923 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, s
->A0
,
5924 s
->mem_index
, MO_LEUW
);
5928 gen_helper_fpop(cpu_env
);
5932 case 0x0c: /* fldenv mem */
5933 gen_helper_fldenv(cpu_env
, s
->A0
, tcg_const_i32(dflag
- 1));
5935 case 0x0d: /* fldcw mem */
5936 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, s
->A0
,
5937 s
->mem_index
, MO_LEUW
);
5938 gen_helper_fldcw(cpu_env
, cpu_tmp2_i32
);
5940 case 0x0e: /* fnstenv mem */
5941 gen_helper_fstenv(cpu_env
, s
->A0
, tcg_const_i32(dflag
- 1));
5943 case 0x0f: /* fnstcw mem */
5944 gen_helper_fnstcw(cpu_tmp2_i32
, cpu_env
);
5945 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, s
->A0
,
5946 s
->mem_index
, MO_LEUW
);
5948 case 0x1d: /* fldt mem */
5949 gen_helper_fldt_ST0(cpu_env
, s
->A0
);
5951 case 0x1f: /* fstpt mem */
5952 gen_helper_fstt_ST0(cpu_env
, s
->A0
);
5953 gen_helper_fpop(cpu_env
);
5955 case 0x2c: /* frstor mem */
5956 gen_helper_frstor(cpu_env
, s
->A0
, tcg_const_i32(dflag
- 1));
5958 case 0x2e: /* fnsave mem */
5959 gen_helper_fsave(cpu_env
, s
->A0
, tcg_const_i32(dflag
- 1));
5961 case 0x2f: /* fnstsw mem */
5962 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
5963 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, s
->A0
,
5964 s
->mem_index
, MO_LEUW
);
5966 case 0x3c: /* fbld */
5967 gen_helper_fbld_ST0(cpu_env
, s
->A0
);
5969 case 0x3e: /* fbstp */
5970 gen_helper_fbst_ST0(cpu_env
, s
->A0
);
5971 gen_helper_fpop(cpu_env
);
5973 case 0x3d: /* fildll */
5974 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, s
->A0
, s
->mem_index
, MO_LEQ
);
5975 gen_helper_fildll_ST0(cpu_env
, cpu_tmp1_i64
);
5977 case 0x3f: /* fistpll */
5978 gen_helper_fistll_ST0(cpu_tmp1_i64
, cpu_env
);
5979 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, s
->A0
, s
->mem_index
, MO_LEQ
);
5980 gen_helper_fpop(cpu_env
);
5986 /* register float ops */
5990 case 0x08: /* fld sti */
5991 gen_helper_fpush(cpu_env
);
5992 gen_helper_fmov_ST0_STN(cpu_env
,
5993 tcg_const_i32((opreg
+ 1) & 7));
5995 case 0x09: /* fxchg sti */
5996 case 0x29: /* fxchg4 sti, undocumented op */
5997 case 0x39: /* fxchg7 sti, undocumented op */
5998 gen_helper_fxchg_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6000 case 0x0a: /* grp d9/2 */
6003 /* check exceptions (FreeBSD FPU probe) */
6004 gen_helper_fwait(cpu_env
);
6010 case 0x0c: /* grp d9/4 */
6013 gen_helper_fchs_ST0(cpu_env
);
6016 gen_helper_fabs_ST0(cpu_env
);
6019 gen_helper_fldz_FT0(cpu_env
);
6020 gen_helper_fcom_ST0_FT0(cpu_env
);
6023 gen_helper_fxam_ST0(cpu_env
);
6029 case 0x0d: /* grp d9/5 */
6033 gen_helper_fpush(cpu_env
);
6034 gen_helper_fld1_ST0(cpu_env
);
6037 gen_helper_fpush(cpu_env
);
6038 gen_helper_fldl2t_ST0(cpu_env
);
6041 gen_helper_fpush(cpu_env
);
6042 gen_helper_fldl2e_ST0(cpu_env
);
6045 gen_helper_fpush(cpu_env
);
6046 gen_helper_fldpi_ST0(cpu_env
);
6049 gen_helper_fpush(cpu_env
);
6050 gen_helper_fldlg2_ST0(cpu_env
);
6053 gen_helper_fpush(cpu_env
);
6054 gen_helper_fldln2_ST0(cpu_env
);
6057 gen_helper_fpush(cpu_env
);
6058 gen_helper_fldz_ST0(cpu_env
);
6065 case 0x0e: /* grp d9/6 */
6068 gen_helper_f2xm1(cpu_env
);
6071 gen_helper_fyl2x(cpu_env
);
6074 gen_helper_fptan(cpu_env
);
6076 case 3: /* fpatan */
6077 gen_helper_fpatan(cpu_env
);
6079 case 4: /* fxtract */
6080 gen_helper_fxtract(cpu_env
);
6082 case 5: /* fprem1 */
6083 gen_helper_fprem1(cpu_env
);
6085 case 6: /* fdecstp */
6086 gen_helper_fdecstp(cpu_env
);
6089 case 7: /* fincstp */
6090 gen_helper_fincstp(cpu_env
);
6094 case 0x0f: /* grp d9/7 */
6097 gen_helper_fprem(cpu_env
);
6099 case 1: /* fyl2xp1 */
6100 gen_helper_fyl2xp1(cpu_env
);
6103 gen_helper_fsqrt(cpu_env
);
6105 case 3: /* fsincos */
6106 gen_helper_fsincos(cpu_env
);
6108 case 5: /* fscale */
6109 gen_helper_fscale(cpu_env
);
6111 case 4: /* frndint */
6112 gen_helper_frndint(cpu_env
);
6115 gen_helper_fsin(cpu_env
);
6119 gen_helper_fcos(cpu_env
);
6123 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6124 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6125 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6131 gen_helper_fp_arith_STN_ST0(op1
, opreg
);
6133 gen_helper_fpop(cpu_env
);
6135 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6136 gen_helper_fp_arith_ST0_FT0(op1
);
6140 case 0x02: /* fcom */
6141 case 0x22: /* fcom2, undocumented op */
6142 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6143 gen_helper_fcom_ST0_FT0(cpu_env
);
6145 case 0x03: /* fcomp */
6146 case 0x23: /* fcomp3, undocumented op */
6147 case 0x32: /* fcomp5, undocumented op */
6148 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6149 gen_helper_fcom_ST0_FT0(cpu_env
);
6150 gen_helper_fpop(cpu_env
);
6152 case 0x15: /* da/5 */
6154 case 1: /* fucompp */
6155 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6156 gen_helper_fucom_ST0_FT0(cpu_env
);
6157 gen_helper_fpop(cpu_env
);
6158 gen_helper_fpop(cpu_env
);
6166 case 0: /* feni (287 only, just do nop here) */
6168 case 1: /* fdisi (287 only, just do nop here) */
6171 gen_helper_fclex(cpu_env
);
6173 case 3: /* fninit */
6174 gen_helper_fninit(cpu_env
);
6176 case 4: /* fsetpm (287 only, just do nop here) */
6182 case 0x1d: /* fucomi */
6183 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6186 gen_update_cc_op(s
);
6187 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6188 gen_helper_fucomi_ST0_FT0(cpu_env
);
6189 set_cc_op(s
, CC_OP_EFLAGS
);
6191 case 0x1e: /* fcomi */
6192 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6195 gen_update_cc_op(s
);
6196 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6197 gen_helper_fcomi_ST0_FT0(cpu_env
);
6198 set_cc_op(s
, CC_OP_EFLAGS
);
6200 case 0x28: /* ffree sti */
6201 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6203 case 0x2a: /* fst sti */
6204 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6206 case 0x2b: /* fstp sti */
6207 case 0x0b: /* fstp1 sti, undocumented op */
6208 case 0x3a: /* fstp8 sti, undocumented op */
6209 case 0x3b: /* fstp9 sti, undocumented op */
6210 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6211 gen_helper_fpop(cpu_env
);
6213 case 0x2c: /* fucom st(i) */
6214 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6215 gen_helper_fucom_ST0_FT0(cpu_env
);
6217 case 0x2d: /* fucomp st(i) */
6218 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6219 gen_helper_fucom_ST0_FT0(cpu_env
);
6220 gen_helper_fpop(cpu_env
);
6222 case 0x33: /* de/3 */
6224 case 1: /* fcompp */
6225 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6226 gen_helper_fcom_ST0_FT0(cpu_env
);
6227 gen_helper_fpop(cpu_env
);
6228 gen_helper_fpop(cpu_env
);
6234 case 0x38: /* ffreep sti, undocumented op */
6235 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6236 gen_helper_fpop(cpu_env
);
6238 case 0x3c: /* df/4 */
6241 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
6242 tcg_gen_extu_i32_tl(s
->T0
, cpu_tmp2_i32
);
6243 gen_op_mov_reg_v(MO_16
, R_EAX
, s
->T0
);
6249 case 0x3d: /* fucomip */
6250 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6253 gen_update_cc_op(s
);
6254 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6255 gen_helper_fucomi_ST0_FT0(cpu_env
);
6256 gen_helper_fpop(cpu_env
);
6257 set_cc_op(s
, CC_OP_EFLAGS
);
6259 case 0x3e: /* fcomip */
6260 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6263 gen_update_cc_op(s
);
6264 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6265 gen_helper_fcomi_ST0_FT0(cpu_env
);
6266 gen_helper_fpop(cpu_env
);
6267 set_cc_op(s
, CC_OP_EFLAGS
);
6269 case 0x10 ... 0x13: /* fcmovxx */
6274 static const uint8_t fcmov_cc
[8] = {
6281 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6284 op1
= fcmov_cc
[op
& 3] | (((op
>> 3) & 1) ^ 1);
6285 l1
= gen_new_label();
6286 gen_jcc1_noeob(s
, op1
, l1
);
6287 gen_helper_fmov_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6296 /************************/
6299 case 0xa4: /* movsS */
6301 ot
= mo_b_d(b
, dflag
);
6302 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6303 gen_repz_movs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6309 case 0xaa: /* stosS */
6311 ot
= mo_b_d(b
, dflag
);
6312 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6313 gen_repz_stos(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6318 case 0xac: /* lodsS */
6320 ot
= mo_b_d(b
, dflag
);
6321 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6322 gen_repz_lods(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6327 case 0xae: /* scasS */
6329 ot
= mo_b_d(b
, dflag
);
6330 if (prefixes
& PREFIX_REPNZ
) {
6331 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6332 } else if (prefixes
& PREFIX_REPZ
) {
6333 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6339 case 0xa6: /* cmpsS */
6341 ot
= mo_b_d(b
, dflag
);
6342 if (prefixes
& PREFIX_REPNZ
) {
6343 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6344 } else if (prefixes
& PREFIX_REPZ
) {
6345 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6350 case 0x6c: /* insS */
6352 ot
= mo_b_d32(b
, dflag
);
6353 tcg_gen_ext16u_tl(s
->T0
, cpu_regs
[R_EDX
]);
6354 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6355 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
) | 4);
6356 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6357 gen_repz_ins(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6360 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6361 gen_jmp(s
, s
->pc
- s
->cs_base
);
6365 case 0x6e: /* outsS */
6367 ot
= mo_b_d32(b
, dflag
);
6368 tcg_gen_ext16u_tl(s
->T0
, cpu_regs
[R_EDX
]);
6369 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6370 svm_is_rep(prefixes
) | 4);
6371 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6372 gen_repz_outs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6375 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6376 gen_jmp(s
, s
->pc
- s
->cs_base
);
6381 /************************/
6386 ot
= mo_b_d32(b
, dflag
);
6387 val
= x86_ldub_code(env
, s
);
6388 tcg_gen_movi_tl(s
->T0
, val
);
6389 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6390 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6391 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6394 tcg_gen_movi_i32(cpu_tmp2_i32
, val
);
6395 gen_helper_in_func(ot
, s
->T1
, cpu_tmp2_i32
);
6396 gen_op_mov_reg_v(ot
, R_EAX
, s
->T1
);
6397 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6398 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6400 gen_jmp(s
, s
->pc
- s
->cs_base
);
6405 ot
= mo_b_d32(b
, dflag
);
6406 val
= x86_ldub_code(env
, s
);
6407 tcg_gen_movi_tl(s
->T0
, val
);
6408 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6409 svm_is_rep(prefixes
));
6410 gen_op_mov_v_reg(ot
, s
->T1
, R_EAX
);
6412 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6415 tcg_gen_movi_i32(cpu_tmp2_i32
, val
);
6416 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, s
->T1
);
6417 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6418 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6419 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6421 gen_jmp(s
, s
->pc
- s
->cs_base
);
6426 ot
= mo_b_d32(b
, dflag
);
6427 tcg_gen_ext16u_tl(s
->T0
, cpu_regs
[R_EDX
]);
6428 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6429 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6430 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6433 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
6434 gen_helper_in_func(ot
, s
->T1
, cpu_tmp2_i32
);
6435 gen_op_mov_reg_v(ot
, R_EAX
, s
->T1
);
6436 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6437 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6439 gen_jmp(s
, s
->pc
- s
->cs_base
);
6444 ot
= mo_b_d32(b
, dflag
);
6445 tcg_gen_ext16u_tl(s
->T0
, cpu_regs
[R_EDX
]);
6446 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6447 svm_is_rep(prefixes
));
6448 gen_op_mov_v_reg(ot
, s
->T1
, R_EAX
);
6450 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6453 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
6454 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, s
->T1
);
6455 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6456 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6457 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6459 gen_jmp(s
, s
->pc
- s
->cs_base
);
6463 /************************/
6465 case 0xc2: /* ret im */
6466 val
= x86_ldsw_code(env
, s
);
6468 gen_stack_update(s
, val
+ (1 << ot
));
6469 /* Note that gen_pop_T0 uses a zero-extending load. */
6470 gen_op_jmp_v(s
->T0
);
6474 case 0xc3: /* ret */
6476 gen_pop_update(s
, ot
);
6477 /* Note that gen_pop_T0 uses a zero-extending load. */
6478 gen_op_jmp_v(s
->T0
);
6482 case 0xca: /* lret im */
6483 val
= x86_ldsw_code(env
, s
);
6485 if (s
->pe
&& !s
->vm86
) {
6486 gen_update_cc_op(s
);
6487 gen_jmp_im(s
, pc_start
- s
->cs_base
);
6488 gen_helper_lret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6489 tcg_const_i32(val
));
6493 gen_op_ld_v(s
, dflag
, s
->T0
, s
->A0
);
6494 /* NOTE: keeping EIP updated is not a problem in case of
6496 gen_op_jmp_v(s
->T0
);
6498 gen_add_A0_im(s
, 1 << dflag
);
6499 gen_op_ld_v(s
, dflag
, s
->T0
, s
->A0
);
6500 gen_op_movl_seg_T0_vm(s
, R_CS
);
6501 /* add stack offset */
6502 gen_stack_update(s
, val
+ (2 << dflag
));
6506 case 0xcb: /* lret */
6509 case 0xcf: /* iret */
6510 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IRET
);
6513 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6514 set_cc_op(s
, CC_OP_EFLAGS
);
6515 } else if (s
->vm86
) {
6517 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6519 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6520 set_cc_op(s
, CC_OP_EFLAGS
);
6523 gen_helper_iret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6524 tcg_const_i32(s
->pc
- s
->cs_base
));
6525 set_cc_op(s
, CC_OP_EFLAGS
);
6529 case 0xe8: /* call im */
6531 if (dflag
!= MO_16
) {
6532 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6534 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6536 next_eip
= s
->pc
- s
->cs_base
;
6538 if (dflag
== MO_16
) {
6540 } else if (!CODE64(s
)) {
6543 tcg_gen_movi_tl(s
->T0
, next_eip
);
6544 gen_push_v(s
, s
->T0
);
6549 case 0x9a: /* lcall im */
6551 unsigned int selector
, offset
;
6556 offset
= insn_get(env
, s
, ot
);
6557 selector
= insn_get(env
, s
, MO_16
);
6559 tcg_gen_movi_tl(s
->T0
, selector
);
6560 tcg_gen_movi_tl(s
->T1
, offset
);
6563 case 0xe9: /* jmp im */
6564 if (dflag
!= MO_16
) {
6565 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6567 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6569 tval
+= s
->pc
- s
->cs_base
;
6570 if (dflag
== MO_16
) {
6572 } else if (!CODE64(s
)) {
6578 case 0xea: /* ljmp im */
6580 unsigned int selector
, offset
;
6585 offset
= insn_get(env
, s
, ot
);
6586 selector
= insn_get(env
, s
, MO_16
);
6588 tcg_gen_movi_tl(s
->T0
, selector
);
6589 tcg_gen_movi_tl(s
->T1
, offset
);
6592 case 0xeb: /* jmp Jb */
6593 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6594 tval
+= s
->pc
- s
->cs_base
;
6595 if (dflag
== MO_16
) {
6600 case 0x70 ... 0x7f: /* jcc Jb */
6601 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6603 case 0x180 ... 0x18f: /* jcc Jv */
6604 if (dflag
!= MO_16
) {
6605 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6607 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6610 next_eip
= s
->pc
- s
->cs_base
;
6612 if (dflag
== MO_16
) {
6616 gen_jcc(s
, b
, tval
, next_eip
);
6619 case 0x190 ... 0x19f: /* setcc Gv */
6620 modrm
= x86_ldub_code(env
, s
);
6621 gen_setcc1(s
, b
, s
->T0
);
6622 gen_ldst_modrm(env
, s
, modrm
, MO_8
, OR_TMP0
, 1);
6624 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6625 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6629 modrm
= x86_ldub_code(env
, s
);
6630 reg
= ((modrm
>> 3) & 7) | rex_r
;
6631 gen_cmovcc1(env
, s
, ot
, b
, modrm
, reg
);
6634 /************************/
6636 case 0x9c: /* pushf */
6637 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_PUSHF
);
6638 if (s
->vm86
&& s
->iopl
!= 3) {
6639 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6641 gen_update_cc_op(s
);
6642 gen_helper_read_eflags(s
->T0
, cpu_env
);
6643 gen_push_v(s
, s
->T0
);
6646 case 0x9d: /* popf */
6647 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_POPF
);
6648 if (s
->vm86
&& s
->iopl
!= 3) {
6649 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6653 if (dflag
!= MO_16
) {
6654 gen_helper_write_eflags(cpu_env
, s
->T0
,
6655 tcg_const_i32((TF_MASK
| AC_MASK
|
6660 gen_helper_write_eflags(cpu_env
, s
->T0
,
6661 tcg_const_i32((TF_MASK
| AC_MASK
|
6663 IF_MASK
| IOPL_MASK
)
6667 if (s
->cpl
<= s
->iopl
) {
6668 if (dflag
!= MO_16
) {
6669 gen_helper_write_eflags(cpu_env
, s
->T0
,
6670 tcg_const_i32((TF_MASK
|
6676 gen_helper_write_eflags(cpu_env
, s
->T0
,
6677 tcg_const_i32((TF_MASK
|
6685 if (dflag
!= MO_16
) {
6686 gen_helper_write_eflags(cpu_env
, s
->T0
,
6687 tcg_const_i32((TF_MASK
| AC_MASK
|
6688 ID_MASK
| NT_MASK
)));
6690 gen_helper_write_eflags(cpu_env
, s
->T0
,
6691 tcg_const_i32((TF_MASK
| AC_MASK
|
6697 gen_pop_update(s
, ot
);
6698 set_cc_op(s
, CC_OP_EFLAGS
);
6699 /* abort translation because TF/AC flag may change */
6700 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
6704 case 0x9e: /* sahf */
6705 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6707 gen_op_mov_v_reg(MO_8
, s
->T0
, R_AH
);
6708 gen_compute_eflags(s
);
6709 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, CC_O
);
6710 tcg_gen_andi_tl(s
->T0
, s
->T0
, CC_S
| CC_Z
| CC_A
| CC_P
| CC_C
);
6711 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, s
->T0
);
6713 case 0x9f: /* lahf */
6714 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6716 gen_compute_eflags(s
);
6717 /* Note: gen_compute_eflags() only gives the condition codes */
6718 tcg_gen_ori_tl(s
->T0
, cpu_cc_src
, 0x02);
6719 gen_op_mov_reg_v(MO_8
, R_AH
, s
->T0
);
6721 case 0xf5: /* cmc */
6722 gen_compute_eflags(s
);
6723 tcg_gen_xori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6725 case 0xf8: /* clc */
6726 gen_compute_eflags(s
);
6727 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_C
);
6729 case 0xf9: /* stc */
6730 gen_compute_eflags(s
);
6731 tcg_gen_ori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6733 case 0xfc: /* cld */
6734 tcg_gen_movi_i32(cpu_tmp2_i32
, 1);
6735 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6737 case 0xfd: /* std */
6738 tcg_gen_movi_i32(cpu_tmp2_i32
, -1);
6739 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6742 /************************/
6743 /* bit operations */
6744 case 0x1ba: /* bt/bts/btr/btc Gv, im */
6746 modrm
= x86_ldub_code(env
, s
);
6747 op
= (modrm
>> 3) & 7;
6748 mod
= (modrm
>> 6) & 3;
6749 rm
= (modrm
& 7) | REX_B(s
);
6752 gen_lea_modrm(env
, s
, modrm
);
6753 if (!(s
->prefix
& PREFIX_LOCK
)) {
6754 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
6757 gen_op_mov_v_reg(ot
, s
->T0
, rm
);
6760 val
= x86_ldub_code(env
, s
);
6761 tcg_gen_movi_tl(s
->T1
, val
);
6766 case 0x1a3: /* bt Gv, Ev */
6769 case 0x1ab: /* bts */
6772 case 0x1b3: /* btr */
6775 case 0x1bb: /* btc */
6779 modrm
= x86_ldub_code(env
, s
);
6780 reg
= ((modrm
>> 3) & 7) | rex_r
;
6781 mod
= (modrm
>> 6) & 3;
6782 rm
= (modrm
& 7) | REX_B(s
);
6783 gen_op_mov_v_reg(MO_32
, s
->T1
, reg
);
6785 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
6786 /* specific case: we need to add a displacement */
6787 gen_exts(ot
, s
->T1
);
6788 tcg_gen_sari_tl(s
->tmp0
, s
->T1
, 3 + ot
);
6789 tcg_gen_shli_tl(s
->tmp0
, s
->tmp0
, ot
);
6790 tcg_gen_add_tl(s
->A0
, gen_lea_modrm_1(s
, a
), s
->tmp0
);
6791 gen_lea_v_seg(s
, s
->aflag
, s
->A0
, a
.def_seg
, s
->override
);
6792 if (!(s
->prefix
& PREFIX_LOCK
)) {
6793 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
6796 gen_op_mov_v_reg(ot
, s
->T0
, rm
);
6799 tcg_gen_andi_tl(s
->T1
, s
->T1
, (1 << (3 + ot
)) - 1);
6800 tcg_gen_movi_tl(s
->tmp0
, 1);
6801 tcg_gen_shl_tl(s
->tmp0
, s
->tmp0
, s
->T1
);
6802 if (s
->prefix
& PREFIX_LOCK
) {
6805 /* Needs no atomic ops; we surpressed the normal
6806 memory load for LOCK above so do it now. */
6807 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
6810 tcg_gen_atomic_fetch_or_tl(s
->T0
, s
->A0
, s
->tmp0
,
6811 s
->mem_index
, ot
| MO_LE
);
6814 tcg_gen_not_tl(s
->tmp0
, s
->tmp0
);
6815 tcg_gen_atomic_fetch_and_tl(s
->T0
, s
->A0
, s
->tmp0
,
6816 s
->mem_index
, ot
| MO_LE
);
6820 tcg_gen_atomic_fetch_xor_tl(s
->T0
, s
->A0
, s
->tmp0
,
6821 s
->mem_index
, ot
| MO_LE
);
6824 tcg_gen_shr_tl(s
->tmp4
, s
->T0
, s
->T1
);
6826 tcg_gen_shr_tl(s
->tmp4
, s
->T0
, s
->T1
);
6829 /* Data already loaded; nothing to do. */
6832 tcg_gen_or_tl(s
->T0
, s
->T0
, s
->tmp0
);
6835 tcg_gen_andc_tl(s
->T0
, s
->T0
, s
->tmp0
);
6839 tcg_gen_xor_tl(s
->T0
, s
->T0
, s
->tmp0
);
6844 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
6846 gen_op_mov_reg_v(ot
, rm
, s
->T0
);
6851 /* Delay all CC updates until after the store above. Note that
6852 C is the result of the test, Z is unchanged, and the others
6853 are all undefined. */
6855 case CC_OP_MULB
... CC_OP_MULQ
:
6856 case CC_OP_ADDB
... CC_OP_ADDQ
:
6857 case CC_OP_ADCB
... CC_OP_ADCQ
:
6858 case CC_OP_SUBB
... CC_OP_SUBQ
:
6859 case CC_OP_SBBB
... CC_OP_SBBQ
:
6860 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
6861 case CC_OP_INCB
... CC_OP_INCQ
:
6862 case CC_OP_DECB
... CC_OP_DECQ
:
6863 case CC_OP_SHLB
... CC_OP_SHLQ
:
6864 case CC_OP_SARB
... CC_OP_SARQ
:
6865 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
6866 /* Z was going to be computed from the non-zero status of CC_DST.
6867 We can get that same Z value (and the new C value) by leaving
6868 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
6870 tcg_gen_mov_tl(cpu_cc_src
, s
->tmp4
);
6871 set_cc_op(s
, ((s
->cc_op
- CC_OP_MULB
) & 3) + CC_OP_SARB
);
6874 /* Otherwise, generate EFLAGS and replace the C bit. */
6875 gen_compute_eflags(s
);
6876 tcg_gen_deposit_tl(cpu_cc_src
, cpu_cc_src
, s
->tmp4
,
6881 case 0x1bc: /* bsf / tzcnt */
6882 case 0x1bd: /* bsr / lzcnt */
6884 modrm
= x86_ldub_code(env
, s
);
6885 reg
= ((modrm
>> 3) & 7) | rex_r
;
6886 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
6887 gen_extu(ot
, s
->T0
);
6889 /* Note that lzcnt and tzcnt are in different extensions. */
6890 if ((prefixes
& PREFIX_REPZ
)
6892 ? s
->cpuid_ext3_features
& CPUID_EXT3_ABM
6893 : s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)) {
6895 /* For lzcnt/tzcnt, C bit is defined related to the input. */
6896 tcg_gen_mov_tl(cpu_cc_src
, s
->T0
);
6898 /* For lzcnt, reduce the target_ulong result by the
6899 number of zeros that we expect to find at the top. */
6900 tcg_gen_clzi_tl(s
->T0
, s
->T0
, TARGET_LONG_BITS
);
6901 tcg_gen_subi_tl(s
->T0
, s
->T0
, TARGET_LONG_BITS
- size
);
6903 /* For tzcnt, a zero input must return the operand size. */
6904 tcg_gen_ctzi_tl(s
->T0
, s
->T0
, size
);
6906 /* For lzcnt/tzcnt, Z bit is defined related to the result. */
6907 gen_op_update1_cc(s
);
6908 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
6910 /* For bsr/bsf, only the Z bit is defined and it is related
6911 to the input and not the result. */
6912 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
6913 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
6915 /* ??? The manual says that the output is undefined when the
6916 input is zero, but real hardware leaves it unchanged, and
6917 real programs appear to depend on that. Accomplish this
6918 by passing the output as the value to return upon zero. */
6920 /* For bsr, return the bit index of the first 1 bit,
6921 not the count of leading zeros. */
6922 tcg_gen_xori_tl(s
->T1
, cpu_regs
[reg
], TARGET_LONG_BITS
- 1);
6923 tcg_gen_clz_tl(s
->T0
, s
->T0
, s
->T1
);
6924 tcg_gen_xori_tl(s
->T0
, s
->T0
, TARGET_LONG_BITS
- 1);
6926 tcg_gen_ctz_tl(s
->T0
, s
->T0
, cpu_regs
[reg
]);
6929 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
6931 /************************/
6933 case 0x27: /* daa */
6936 gen_update_cc_op(s
);
6937 gen_helper_daa(cpu_env
);
6938 set_cc_op(s
, CC_OP_EFLAGS
);
6940 case 0x2f: /* das */
6943 gen_update_cc_op(s
);
6944 gen_helper_das(cpu_env
);
6945 set_cc_op(s
, CC_OP_EFLAGS
);
6947 case 0x37: /* aaa */
6950 gen_update_cc_op(s
);
6951 gen_helper_aaa(cpu_env
);
6952 set_cc_op(s
, CC_OP_EFLAGS
);
6954 case 0x3f: /* aas */
6957 gen_update_cc_op(s
);
6958 gen_helper_aas(cpu_env
);
6959 set_cc_op(s
, CC_OP_EFLAGS
);
6961 case 0xd4: /* aam */
6964 val
= x86_ldub_code(env
, s
);
6966 gen_exception(s
, EXCP00_DIVZ
, pc_start
- s
->cs_base
);
6968 gen_helper_aam(cpu_env
, tcg_const_i32(val
));
6969 set_cc_op(s
, CC_OP_LOGICB
);
6972 case 0xd5: /* aad */
6975 val
= x86_ldub_code(env
, s
);
6976 gen_helper_aad(cpu_env
, tcg_const_i32(val
));
6977 set_cc_op(s
, CC_OP_LOGICB
);
6979 /************************/
6981 case 0x90: /* nop */
6982 /* XXX: correct lock test for all insn */
6983 if (prefixes
& PREFIX_LOCK
) {
6986 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
6988 goto do_xchg_reg_eax
;
6990 if (prefixes
& PREFIX_REPZ
) {
6991 gen_update_cc_op(s
);
6992 gen_jmp_im(s
, pc_start
- s
->cs_base
);
6993 gen_helper_pause(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
6994 s
->base
.is_jmp
= DISAS_NORETURN
;
6997 case 0x9b: /* fwait */
6998 if ((s
->flags
& (HF_MP_MASK
| HF_TS_MASK
)) ==
6999 (HF_MP_MASK
| HF_TS_MASK
)) {
7000 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7002 gen_helper_fwait(cpu_env
);
7005 case 0xcc: /* int3 */
7006 gen_interrupt(s
, EXCP03_INT3
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
7008 case 0xcd: /* int N */
7009 val
= x86_ldub_code(env
, s
);
7010 if (s
->vm86
&& s
->iopl
!= 3) {
7011 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7013 gen_interrupt(s
, val
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
7016 case 0xce: /* into */
7019 gen_update_cc_op(s
);
7020 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7021 gen_helper_into(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7024 case 0xf1: /* icebp (undocumented, exits to external debugger) */
7025 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_ICEBP
);
7027 gen_debug(s
, pc_start
- s
->cs_base
);
7030 tb_flush(CPU(x86_env_get_cpu(env
)));
7031 qemu_set_log(CPU_LOG_INT
| CPU_LOG_TB_IN_ASM
);
7035 case 0xfa: /* cli */
7037 if (s
->cpl
<= s
->iopl
) {
7038 gen_helper_cli(cpu_env
);
7040 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7044 gen_helper_cli(cpu_env
);
7046 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7050 case 0xfb: /* sti */
7051 if (s
->vm86
? s
->iopl
== 3 : s
->cpl
<= s
->iopl
) {
7052 gen_helper_sti(cpu_env
);
7053 /* interruptions are enabled only the first insn after sti */
7054 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7055 gen_eob_inhibit_irq(s
, true);
7057 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7060 case 0x62: /* bound */
7064 modrm
= x86_ldub_code(env
, s
);
7065 reg
= (modrm
>> 3) & 7;
7066 mod
= (modrm
>> 6) & 3;
7069 gen_op_mov_v_reg(ot
, s
->T0
, reg
);
7070 gen_lea_modrm(env
, s
, modrm
);
7071 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
7073 gen_helper_boundw(cpu_env
, s
->A0
, cpu_tmp2_i32
);
7075 gen_helper_boundl(cpu_env
, s
->A0
, cpu_tmp2_i32
);
7078 case 0x1c8 ... 0x1cf: /* bswap reg */
7079 reg
= (b
& 7) | REX_B(s
);
7080 #ifdef TARGET_X86_64
7081 if (dflag
== MO_64
) {
7082 gen_op_mov_v_reg(MO_64
, s
->T0
, reg
);
7083 tcg_gen_bswap64_i64(s
->T0
, s
->T0
);
7084 gen_op_mov_reg_v(MO_64
, reg
, s
->T0
);
7088 gen_op_mov_v_reg(MO_32
, s
->T0
, reg
);
7089 tcg_gen_ext32u_tl(s
->T0
, s
->T0
);
7090 tcg_gen_bswap32_tl(s
->T0
, s
->T0
);
7091 gen_op_mov_reg_v(MO_32
, reg
, s
->T0
);
7094 case 0xd6: /* salc */
7097 gen_compute_eflags_c(s
, s
->T0
);
7098 tcg_gen_neg_tl(s
->T0
, s
->T0
);
7099 gen_op_mov_reg_v(MO_8
, R_EAX
, s
->T0
);
7101 case 0xe0: /* loopnz */
7102 case 0xe1: /* loopz */
7103 case 0xe2: /* loop */
7104 case 0xe3: /* jecxz */
7106 TCGLabel
*l1
, *l2
, *l3
;
7108 tval
= (int8_t)insn_get(env
, s
, MO_8
);
7109 next_eip
= s
->pc
- s
->cs_base
;
7111 if (dflag
== MO_16
) {
7115 l1
= gen_new_label();
7116 l2
= gen_new_label();
7117 l3
= gen_new_label();
7120 case 0: /* loopnz */
7122 gen_op_add_reg_im(s
, s
->aflag
, R_ECX
, -1);
7123 gen_op_jz_ecx(s
, s
->aflag
, l3
);
7124 gen_jcc1(s
, (JCC_Z
<< 1) | (b
^ 1), l1
);
7127 gen_op_add_reg_im(s
, s
->aflag
, R_ECX
, -1);
7128 gen_op_jnz_ecx(s
, s
->aflag
, l1
);
7132 gen_op_jz_ecx(s
, s
->aflag
, l1
);
7137 gen_jmp_im(s
, next_eip
);
7141 gen_jmp_im(s
, tval
);
7146 case 0x130: /* wrmsr */
7147 case 0x132: /* rdmsr */
7149 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7151 gen_update_cc_op(s
);
7152 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7154 gen_helper_rdmsr(cpu_env
);
7156 gen_helper_wrmsr(cpu_env
);
7160 case 0x131: /* rdtsc */
7161 gen_update_cc_op(s
);
7162 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7163 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7166 gen_helper_rdtsc(cpu_env
);
7167 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7169 gen_jmp(s
, s
->pc
- s
->cs_base
);
7172 case 0x133: /* rdpmc */
7173 gen_update_cc_op(s
);
7174 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7175 gen_helper_rdpmc(cpu_env
);
7177 case 0x134: /* sysenter */
7178 /* For Intel SYSENTER is valid on 64-bit */
7179 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7182 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7184 gen_helper_sysenter(cpu_env
);
7188 case 0x135: /* sysexit */
7189 /* For Intel SYSEXIT is valid on 64-bit */
7190 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7193 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7195 gen_helper_sysexit(cpu_env
, tcg_const_i32(dflag
- 1));
7199 #ifdef TARGET_X86_64
7200 case 0x105: /* syscall */
7201 /* XXX: is it usable in real mode ? */
7202 gen_update_cc_op(s
);
7203 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7204 gen_helper_syscall(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7205 /* TF handling for the syscall insn is different. The TF bit is checked
7206 after the syscall insn completes. This allows #DB to not be
7207 generated after one has entered CPL0 if TF is set in FMASK. */
7208 gen_eob_worker(s
, false, true);
7210 case 0x107: /* sysret */
7212 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7214 gen_helper_sysret(cpu_env
, tcg_const_i32(dflag
- 1));
7215 /* condition codes are modified only in long mode */
7217 set_cc_op(s
, CC_OP_EFLAGS
);
7219 /* TF handling for the sysret insn is different. The TF bit is
7220 checked after the sysret insn completes. This allows #DB to be
7221 generated "as if" the syscall insn in userspace has just
7223 gen_eob_worker(s
, false, true);
7227 case 0x1a2: /* cpuid */
7228 gen_update_cc_op(s
);
7229 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7230 gen_helper_cpuid(cpu_env
);
7232 case 0xf4: /* hlt */
7234 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7236 gen_update_cc_op(s
);
7237 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7238 gen_helper_hlt(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7239 s
->base
.is_jmp
= DISAS_NORETURN
;
7243 modrm
= x86_ldub_code(env
, s
);
7244 mod
= (modrm
>> 6) & 3;
7245 op
= (modrm
>> 3) & 7;
7248 if (!s
->pe
|| s
->vm86
)
7250 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_READ
);
7251 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
7252 offsetof(CPUX86State
, ldt
.selector
));
7253 ot
= mod
== 3 ? dflag
: MO_16
;
7254 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7257 if (!s
->pe
|| s
->vm86
)
7260 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7262 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_WRITE
);
7263 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7264 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
7265 gen_helper_lldt(cpu_env
, cpu_tmp2_i32
);
7269 if (!s
->pe
|| s
->vm86
)
7271 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_READ
);
7272 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
7273 offsetof(CPUX86State
, tr
.selector
));
7274 ot
= mod
== 3 ? dflag
: MO_16
;
7275 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7278 if (!s
->pe
|| s
->vm86
)
7281 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7283 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_WRITE
);
7284 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7285 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, s
->T0
);
7286 gen_helper_ltr(cpu_env
, cpu_tmp2_i32
);
7291 if (!s
->pe
|| s
->vm86
)
7293 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7294 gen_update_cc_op(s
);
7296 gen_helper_verr(cpu_env
, s
->T0
);
7298 gen_helper_verw(cpu_env
, s
->T0
);
7300 set_cc_op(s
, CC_OP_EFLAGS
);
7308 modrm
= x86_ldub_code(env
, s
);
7310 CASE_MODRM_MEM_OP(0): /* sgdt */
7311 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_READ
);
7312 gen_lea_modrm(env
, s
, modrm
);
7313 tcg_gen_ld32u_tl(s
->T0
,
7314 cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7315 gen_op_st_v(s
, MO_16
, s
->T0
, s
->A0
);
7316 gen_add_A0_im(s
, 2);
7317 tcg_gen_ld_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7318 if (dflag
== MO_16
) {
7319 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xffffff);
7321 gen_op_st_v(s
, CODE64(s
) + MO_32
, s
->T0
, s
->A0
);
7324 case 0xc8: /* monitor */
7325 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) || s
->cpl
!= 0) {
7328 gen_update_cc_op(s
);
7329 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7330 tcg_gen_mov_tl(s
->A0
, cpu_regs
[R_EAX
]);
7331 gen_extu(s
->aflag
, s
->A0
);
7332 gen_add_A0_ds_seg(s
);
7333 gen_helper_monitor(cpu_env
, s
->A0
);
7336 case 0xc9: /* mwait */
7337 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) || s
->cpl
!= 0) {
7340 gen_update_cc_op(s
);
7341 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7342 gen_helper_mwait(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7346 case 0xca: /* clac */
7347 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
)
7351 gen_helper_clac(cpu_env
);
7352 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7356 case 0xcb: /* stac */
7357 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
)
7361 gen_helper_stac(cpu_env
);
7362 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7366 CASE_MODRM_MEM_OP(1): /* sidt */
7367 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_READ
);
7368 gen_lea_modrm(env
, s
, modrm
);
7369 tcg_gen_ld32u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7370 gen_op_st_v(s
, MO_16
, s
->T0
, s
->A0
);
7371 gen_add_A0_im(s
, 2);
7372 tcg_gen_ld_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, idt
.base
));
7373 if (dflag
== MO_16
) {
7374 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xffffff);
7376 gen_op_st_v(s
, CODE64(s
) + MO_32
, s
->T0
, s
->A0
);
7379 case 0xd0: /* xgetbv */
7380 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
7381 || (s
->prefix
& (PREFIX_LOCK
| PREFIX_DATA
7382 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
7385 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_ECX
]);
7386 gen_helper_xgetbv(cpu_tmp1_i64
, cpu_env
, cpu_tmp2_i32
);
7387 tcg_gen_extr_i64_tl(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
], cpu_tmp1_i64
);
7390 case 0xd1: /* xsetbv */
7391 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
7392 || (s
->prefix
& (PREFIX_LOCK
| PREFIX_DATA
7393 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
7397 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7400 tcg_gen_concat_tl_i64(cpu_tmp1_i64
, cpu_regs
[R_EAX
],
7402 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_ECX
]);
7403 gen_helper_xsetbv(cpu_env
, cpu_tmp2_i32
, cpu_tmp1_i64
);
7404 /* End TB because translation flags may change. */
7405 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7409 case 0xd8: /* VMRUN */
7410 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7414 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7417 gen_update_cc_op(s
);
7418 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7419 gen_helper_vmrun(cpu_env
, tcg_const_i32(s
->aflag
- 1),
7420 tcg_const_i32(s
->pc
- pc_start
));
7421 tcg_gen_exit_tb(NULL
, 0);
7422 s
->base
.is_jmp
= DISAS_NORETURN
;
7425 case 0xd9: /* VMMCALL */
7426 if (!(s
->flags
& HF_SVME_MASK
)) {
7429 gen_update_cc_op(s
);
7430 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7431 gen_helper_vmmcall(cpu_env
);
7434 case 0xda: /* VMLOAD */
7435 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7439 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7442 gen_update_cc_op(s
);
7443 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7444 gen_helper_vmload(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7447 case 0xdb: /* VMSAVE */
7448 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7452 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7455 gen_update_cc_op(s
);
7456 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7457 gen_helper_vmsave(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7460 case 0xdc: /* STGI */
7461 if ((!(s
->flags
& HF_SVME_MASK
)
7462 && !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
))
7467 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7470 gen_update_cc_op(s
);
7471 gen_helper_stgi(cpu_env
);
7472 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7476 case 0xdd: /* CLGI */
7477 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7481 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7484 gen_update_cc_op(s
);
7485 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7486 gen_helper_clgi(cpu_env
);
7489 case 0xde: /* SKINIT */
7490 if ((!(s
->flags
& HF_SVME_MASK
)
7491 && !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
))
7495 gen_update_cc_op(s
);
7496 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7497 gen_helper_skinit(cpu_env
);
7500 case 0xdf: /* INVLPGA */
7501 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7505 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7508 gen_update_cc_op(s
);
7509 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7510 gen_helper_invlpga(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7513 CASE_MODRM_MEM_OP(2): /* lgdt */
7515 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7518 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_WRITE
);
7519 gen_lea_modrm(env
, s
, modrm
);
7520 gen_op_ld_v(s
, MO_16
, s
->T1
, s
->A0
);
7521 gen_add_A0_im(s
, 2);
7522 gen_op_ld_v(s
, CODE64(s
) + MO_32
, s
->T0
, s
->A0
);
7523 if (dflag
== MO_16
) {
7524 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xffffff);
7526 tcg_gen_st_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7527 tcg_gen_st32_tl(s
->T1
, cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7530 CASE_MODRM_MEM_OP(3): /* lidt */
7532 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7535 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_WRITE
);
7536 gen_lea_modrm(env
, s
, modrm
);
7537 gen_op_ld_v(s
, MO_16
, s
->T1
, s
->A0
);
7538 gen_add_A0_im(s
, 2);
7539 gen_op_ld_v(s
, CODE64(s
) + MO_32
, s
->T0
, s
->A0
);
7540 if (dflag
== MO_16
) {
7541 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xffffff);
7543 tcg_gen_st_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, idt
.base
));
7544 tcg_gen_st32_tl(s
->T1
, cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7547 CASE_MODRM_OP(4): /* smsw */
7548 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_CR0
);
7549 tcg_gen_ld_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, cr
[0]));
7551 mod
= (modrm
>> 6) & 3;
7552 ot
= (mod
!= 3 ? MO_16
: s
->dflag
);
7556 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7558 case 0xee: /* rdpkru */
7559 if (prefixes
& PREFIX_LOCK
) {
7562 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_ECX
]);
7563 gen_helper_rdpkru(cpu_tmp1_i64
, cpu_env
, cpu_tmp2_i32
);
7564 tcg_gen_extr_i64_tl(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
], cpu_tmp1_i64
);
7566 case 0xef: /* wrpkru */
7567 if (prefixes
& PREFIX_LOCK
) {
7570 tcg_gen_concat_tl_i64(cpu_tmp1_i64
, cpu_regs
[R_EAX
],
7572 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_ECX
]);
7573 gen_helper_wrpkru(cpu_env
, cpu_tmp2_i32
, cpu_tmp1_i64
);
7575 CASE_MODRM_OP(6): /* lmsw */
7577 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7580 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7581 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7582 gen_helper_lmsw(cpu_env
, s
->T0
);
7583 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7587 CASE_MODRM_MEM_OP(7): /* invlpg */
7589 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7592 gen_update_cc_op(s
);
7593 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7594 gen_lea_modrm(env
, s
, modrm
);
7595 gen_helper_invlpg(cpu_env
, s
->A0
);
7596 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7600 case 0xf8: /* swapgs */
7601 #ifdef TARGET_X86_64
7604 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7606 tcg_gen_mov_tl(s
->T0
, cpu_seg_base
[R_GS
]);
7607 tcg_gen_ld_tl(cpu_seg_base
[R_GS
], cpu_env
,
7608 offsetof(CPUX86State
, kernelgsbase
));
7609 tcg_gen_st_tl(s
->T0
, cpu_env
,
7610 offsetof(CPUX86State
, kernelgsbase
));
7617 case 0xf9: /* rdtscp */
7618 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_RDTSCP
)) {
7621 gen_update_cc_op(s
);
7622 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7623 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7626 gen_helper_rdtscp(cpu_env
);
7627 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7629 gen_jmp(s
, s
->pc
- s
->cs_base
);
7638 case 0x108: /* invd */
7639 case 0x109: /* wbinvd */
7641 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7643 gen_svm_check_intercept(s
, pc_start
, (b
& 2) ? SVM_EXIT_INVD
: SVM_EXIT_WBINVD
);
7647 case 0x63: /* arpl or movslS (x86_64) */
7648 #ifdef TARGET_X86_64
7651 /* d_ot is the size of destination */
7654 modrm
= x86_ldub_code(env
, s
);
7655 reg
= ((modrm
>> 3) & 7) | rex_r
;
7656 mod
= (modrm
>> 6) & 3;
7657 rm
= (modrm
& 7) | REX_B(s
);
7660 gen_op_mov_v_reg(MO_32
, s
->T0
, rm
);
7662 if (d_ot
== MO_64
) {
7663 tcg_gen_ext32s_tl(s
->T0
, s
->T0
);
7665 gen_op_mov_reg_v(d_ot
, reg
, s
->T0
);
7667 gen_lea_modrm(env
, s
, modrm
);
7668 gen_op_ld_v(s
, MO_32
| MO_SIGN
, s
->T0
, s
->A0
);
7669 gen_op_mov_reg_v(d_ot
, reg
, s
->T0
);
7675 TCGv t0
, t1
, t2
, a0
;
7677 if (!s
->pe
|| s
->vm86
)
7679 t0
= tcg_temp_local_new();
7680 t1
= tcg_temp_local_new();
7681 t2
= tcg_temp_local_new();
7683 modrm
= x86_ldub_code(env
, s
);
7684 reg
= (modrm
>> 3) & 7;
7685 mod
= (modrm
>> 6) & 3;
7688 gen_lea_modrm(env
, s
, modrm
);
7689 gen_op_ld_v(s
, ot
, t0
, s
->A0
);
7690 a0
= tcg_temp_local_new();
7691 tcg_gen_mov_tl(a0
, s
->A0
);
7693 gen_op_mov_v_reg(ot
, t0
, rm
);
7696 gen_op_mov_v_reg(ot
, t1
, reg
);
7697 tcg_gen_andi_tl(s
->tmp0
, t0
, 3);
7698 tcg_gen_andi_tl(t1
, t1
, 3);
7699 tcg_gen_movi_tl(t2
, 0);
7700 label1
= gen_new_label();
7701 tcg_gen_brcond_tl(TCG_COND_GE
, s
->tmp0
, t1
, label1
);
7702 tcg_gen_andi_tl(t0
, t0
, ~3);
7703 tcg_gen_or_tl(t0
, t0
, t1
);
7704 tcg_gen_movi_tl(t2
, CC_Z
);
7705 gen_set_label(label1
);
7707 gen_op_st_v(s
, ot
, t0
, a0
);
7710 gen_op_mov_reg_v(ot
, rm
, t0
);
7712 gen_compute_eflags(s
);
7713 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_Z
);
7714 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, t2
);
7720 case 0x102: /* lar */
7721 case 0x103: /* lsl */
7725 if (!s
->pe
|| s
->vm86
)
7727 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
7728 modrm
= x86_ldub_code(env
, s
);
7729 reg
= ((modrm
>> 3) & 7) | rex_r
;
7730 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7731 t0
= tcg_temp_local_new();
7732 gen_update_cc_op(s
);
7734 gen_helper_lar(t0
, cpu_env
, s
->T0
);
7736 gen_helper_lsl(t0
, cpu_env
, s
->T0
);
7738 tcg_gen_andi_tl(s
->tmp0
, cpu_cc_src
, CC_Z
);
7739 label1
= gen_new_label();
7740 tcg_gen_brcondi_tl(TCG_COND_EQ
, s
->tmp0
, 0, label1
);
7741 gen_op_mov_reg_v(ot
, reg
, t0
);
7742 gen_set_label(label1
);
7743 set_cc_op(s
, CC_OP_EFLAGS
);
7748 modrm
= x86_ldub_code(env
, s
);
7749 mod
= (modrm
>> 6) & 3;
7750 op
= (modrm
>> 3) & 7;
7752 case 0: /* prefetchnta */
7753 case 1: /* prefetchnt0 */
7754 case 2: /* prefetchnt0 */
7755 case 3: /* prefetchnt0 */
7758 gen_nop_modrm(env
, s
, modrm
);
7759 /* nothing more to do */
7761 default: /* nop (multi byte) */
7762 gen_nop_modrm(env
, s
, modrm
);
7767 modrm
= x86_ldub_code(env
, s
);
7768 if (s
->flags
& HF_MPX_EN_MASK
) {
7769 mod
= (modrm
>> 6) & 3;
7770 reg
= ((modrm
>> 3) & 7) | rex_r
;
7771 if (prefixes
& PREFIX_REPZ
) {
7774 || (prefixes
& PREFIX_LOCK
)
7775 || s
->aflag
== MO_16
) {
7778 gen_bndck(env
, s
, modrm
, TCG_COND_LTU
, cpu_bndl
[reg
]);
7779 } else if (prefixes
& PREFIX_REPNZ
) {
7782 || (prefixes
& PREFIX_LOCK
)
7783 || s
->aflag
== MO_16
) {
7786 TCGv_i64 notu
= tcg_temp_new_i64();
7787 tcg_gen_not_i64(notu
, cpu_bndu
[reg
]);
7788 gen_bndck(env
, s
, modrm
, TCG_COND_GTU
, notu
);
7789 tcg_temp_free_i64(notu
);
7790 } else if (prefixes
& PREFIX_DATA
) {
7791 /* bndmov -- from reg/mem */
7792 if (reg
>= 4 || s
->aflag
== MO_16
) {
7796 int reg2
= (modrm
& 7) | REX_B(s
);
7797 if (reg2
>= 4 || (prefixes
& PREFIX_LOCK
)) {
7800 if (s
->flags
& HF_MPX_IU_MASK
) {
7801 tcg_gen_mov_i64(cpu_bndl
[reg
], cpu_bndl
[reg2
]);
7802 tcg_gen_mov_i64(cpu_bndu
[reg
], cpu_bndu
[reg2
]);
7805 gen_lea_modrm(env
, s
, modrm
);
7807 tcg_gen_qemu_ld_i64(cpu_bndl
[reg
], s
->A0
,
7808 s
->mem_index
, MO_LEQ
);
7809 tcg_gen_addi_tl(s
->A0
, s
->A0
, 8);
7810 tcg_gen_qemu_ld_i64(cpu_bndu
[reg
], s
->A0
,
7811 s
->mem_index
, MO_LEQ
);
7813 tcg_gen_qemu_ld_i64(cpu_bndl
[reg
], s
->A0
,
7814 s
->mem_index
, MO_LEUL
);
7815 tcg_gen_addi_tl(s
->A0
, s
->A0
, 4);
7816 tcg_gen_qemu_ld_i64(cpu_bndu
[reg
], s
->A0
,
7817 s
->mem_index
, MO_LEUL
);
7819 /* bnd registers are now in-use */
7820 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7822 } else if (mod
!= 3) {
7824 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7826 || (prefixes
& PREFIX_LOCK
)
7827 || s
->aflag
== MO_16
7832 tcg_gen_addi_tl(s
->A0
, cpu_regs
[a
.base
], a
.disp
);
7834 tcg_gen_movi_tl(s
->A0
, 0);
7836 gen_lea_v_seg(s
, s
->aflag
, s
->A0
, a
.def_seg
, s
->override
);
7838 tcg_gen_mov_tl(s
->T0
, cpu_regs
[a
.index
]);
7840 tcg_gen_movi_tl(s
->T0
, 0);
7843 gen_helper_bndldx64(cpu_bndl
[reg
], cpu_env
, s
->A0
, s
->T0
);
7844 tcg_gen_ld_i64(cpu_bndu
[reg
], cpu_env
,
7845 offsetof(CPUX86State
, mmx_t0
.MMX_Q(0)));
7847 gen_helper_bndldx32(cpu_bndu
[reg
], cpu_env
, s
->A0
, s
->T0
);
7848 tcg_gen_ext32u_i64(cpu_bndl
[reg
], cpu_bndu
[reg
]);
7849 tcg_gen_shri_i64(cpu_bndu
[reg
], cpu_bndu
[reg
], 32);
7851 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7854 gen_nop_modrm(env
, s
, modrm
);
7857 modrm
= x86_ldub_code(env
, s
);
7858 if (s
->flags
& HF_MPX_EN_MASK
) {
7859 mod
= (modrm
>> 6) & 3;
7860 reg
= ((modrm
>> 3) & 7) | rex_r
;
7861 if (mod
!= 3 && (prefixes
& PREFIX_REPZ
)) {
7864 || (prefixes
& PREFIX_LOCK
)
7865 || s
->aflag
== MO_16
) {
7868 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7870 tcg_gen_extu_tl_i64(cpu_bndl
[reg
], cpu_regs
[a
.base
]);
7872 tcg_gen_ext32u_i64(cpu_bndl
[reg
], cpu_bndl
[reg
]);
7874 } else if (a
.base
== -1) {
7875 /* no base register has lower bound of 0 */
7876 tcg_gen_movi_i64(cpu_bndl
[reg
], 0);
7878 /* rip-relative generates #ud */
7881 tcg_gen_not_tl(s
->A0
, gen_lea_modrm_1(s
, a
));
7883 tcg_gen_ext32u_tl(s
->A0
, s
->A0
);
7885 tcg_gen_extu_tl_i64(cpu_bndu
[reg
], s
->A0
);
7886 /* bnd registers are now in-use */
7887 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7889 } else if (prefixes
& PREFIX_REPNZ
) {
7892 || (prefixes
& PREFIX_LOCK
)
7893 || s
->aflag
== MO_16
) {
7896 gen_bndck(env
, s
, modrm
, TCG_COND_GTU
, cpu_bndu
[reg
]);
7897 } else if (prefixes
& PREFIX_DATA
) {
7898 /* bndmov -- to reg/mem */
7899 if (reg
>= 4 || s
->aflag
== MO_16
) {
7903 int reg2
= (modrm
& 7) | REX_B(s
);
7904 if (reg2
>= 4 || (prefixes
& PREFIX_LOCK
)) {
7907 if (s
->flags
& HF_MPX_IU_MASK
) {
7908 tcg_gen_mov_i64(cpu_bndl
[reg2
], cpu_bndl
[reg
]);
7909 tcg_gen_mov_i64(cpu_bndu
[reg2
], cpu_bndu
[reg
]);
7912 gen_lea_modrm(env
, s
, modrm
);
7914 tcg_gen_qemu_st_i64(cpu_bndl
[reg
], s
->A0
,
7915 s
->mem_index
, MO_LEQ
);
7916 tcg_gen_addi_tl(s
->A0
, s
->A0
, 8);
7917 tcg_gen_qemu_st_i64(cpu_bndu
[reg
], s
->A0
,
7918 s
->mem_index
, MO_LEQ
);
7920 tcg_gen_qemu_st_i64(cpu_bndl
[reg
], s
->A0
,
7921 s
->mem_index
, MO_LEUL
);
7922 tcg_gen_addi_tl(s
->A0
, s
->A0
, 4);
7923 tcg_gen_qemu_st_i64(cpu_bndu
[reg
], s
->A0
,
7924 s
->mem_index
, MO_LEUL
);
7927 } else if (mod
!= 3) {
7929 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7931 || (prefixes
& PREFIX_LOCK
)
7932 || s
->aflag
== MO_16
7937 tcg_gen_addi_tl(s
->A0
, cpu_regs
[a
.base
], a
.disp
);
7939 tcg_gen_movi_tl(s
->A0
, 0);
7941 gen_lea_v_seg(s
, s
->aflag
, s
->A0
, a
.def_seg
, s
->override
);
7943 tcg_gen_mov_tl(s
->T0
, cpu_regs
[a
.index
]);
7945 tcg_gen_movi_tl(s
->T0
, 0);
7948 gen_helper_bndstx64(cpu_env
, s
->A0
, s
->T0
,
7949 cpu_bndl
[reg
], cpu_bndu
[reg
]);
7951 gen_helper_bndstx32(cpu_env
, s
->A0
, s
->T0
,
7952 cpu_bndl
[reg
], cpu_bndu
[reg
]);
7956 gen_nop_modrm(env
, s
, modrm
);
7958 case 0x119: case 0x11c ... 0x11f: /* nop (multi byte) */
7959 modrm
= x86_ldub_code(env
, s
);
7960 gen_nop_modrm(env
, s
, modrm
);
7962 case 0x120: /* mov reg, crN */
7963 case 0x122: /* mov crN, reg */
7965 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7967 modrm
= x86_ldub_code(env
, s
);
7968 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7969 * AMD documentation (24594.pdf) and testing of
7970 * intel 386 and 486 processors all show that the mod bits
7971 * are assumed to be 1's, regardless of actual values.
7973 rm
= (modrm
& 7) | REX_B(s
);
7974 reg
= ((modrm
>> 3) & 7) | rex_r
;
7979 if ((prefixes
& PREFIX_LOCK
) && (reg
== 0) &&
7980 (s
->cpuid_ext3_features
& CPUID_EXT3_CR8LEG
)) {
7989 gen_update_cc_op(s
);
7990 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7992 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7995 gen_op_mov_v_reg(ot
, s
->T0
, rm
);
7996 gen_helper_write_crN(cpu_env
, tcg_const_i32(reg
),
7998 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
8001 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8004 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
8007 gen_helper_read_crN(s
->T0
, cpu_env
, tcg_const_i32(reg
));
8008 gen_op_mov_reg_v(ot
, rm
, s
->T0
);
8009 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
8019 case 0x121: /* mov reg, drN */
8020 case 0x123: /* mov drN, reg */
8022 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
8024 modrm
= x86_ldub_code(env
, s
);
8025 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
8026 * AMD documentation (24594.pdf) and testing of
8027 * intel 386 and 486 processors all show that the mod bits
8028 * are assumed to be 1's, regardless of actual values.
8030 rm
= (modrm
& 7) | REX_B(s
);
8031 reg
= ((modrm
>> 3) & 7) | rex_r
;
8040 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_DR0
+ reg
);
8041 gen_op_mov_v_reg(ot
, s
->T0
, rm
);
8042 tcg_gen_movi_i32(cpu_tmp2_i32
, reg
);
8043 gen_helper_set_dr(cpu_env
, cpu_tmp2_i32
, s
->T0
);
8044 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8047 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_DR0
+ reg
);
8048 tcg_gen_movi_i32(cpu_tmp2_i32
, reg
);
8049 gen_helper_get_dr(s
->T0
, cpu_env
, cpu_tmp2_i32
);
8050 gen_op_mov_reg_v(ot
, rm
, s
->T0
);
8054 case 0x106: /* clts */
8056 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
8058 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
8059 gen_helper_clts(cpu_env
);
8060 /* abort block because static cpu state changed */
8061 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8065 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
8066 case 0x1c3: /* MOVNTI reg, mem */
8067 if (!(s
->cpuid_features
& CPUID_SSE2
))
8069 ot
= mo_64_32(dflag
);
8070 modrm
= x86_ldub_code(env
, s
);
8071 mod
= (modrm
>> 6) & 3;
8074 reg
= ((modrm
>> 3) & 7) | rex_r
;
8075 /* generate a generic store */
8076 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
8079 modrm
= x86_ldub_code(env
, s
);
8081 CASE_MODRM_MEM_OP(0): /* fxsave */
8082 if (!(s
->cpuid_features
& CPUID_FXSR
)
8083 || (prefixes
& PREFIX_LOCK
)) {
8086 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
8087 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8090 gen_lea_modrm(env
, s
, modrm
);
8091 gen_helper_fxsave(cpu_env
, s
->A0
);
8094 CASE_MODRM_MEM_OP(1): /* fxrstor */
8095 if (!(s
->cpuid_features
& CPUID_FXSR
)
8096 || (prefixes
& PREFIX_LOCK
)) {
8099 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
8100 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8103 gen_lea_modrm(env
, s
, modrm
);
8104 gen_helper_fxrstor(cpu_env
, s
->A0
);
8107 CASE_MODRM_MEM_OP(2): /* ldmxcsr */
8108 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
)) {
8111 if (s
->flags
& HF_TS_MASK
) {
8112 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8115 gen_lea_modrm(env
, s
, modrm
);
8116 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, s
->A0
, s
->mem_index
, MO_LEUL
);
8117 gen_helper_ldmxcsr(cpu_env
, cpu_tmp2_i32
);
8120 CASE_MODRM_MEM_OP(3): /* stmxcsr */
8121 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
)) {
8124 if (s
->flags
& HF_TS_MASK
) {
8125 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8128 gen_lea_modrm(env
, s
, modrm
);
8129 tcg_gen_ld32u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, mxcsr
));
8130 gen_op_st_v(s
, MO_32
, s
->T0
, s
->A0
);
8133 CASE_MODRM_MEM_OP(4): /* xsave */
8134 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8135 || (prefixes
& (PREFIX_LOCK
| PREFIX_DATA
8136 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
8139 gen_lea_modrm(env
, s
, modrm
);
8140 tcg_gen_concat_tl_i64(cpu_tmp1_i64
, cpu_regs
[R_EAX
],
8142 gen_helper_xsave(cpu_env
, s
->A0
, cpu_tmp1_i64
);
8145 CASE_MODRM_MEM_OP(5): /* xrstor */
8146 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8147 || (prefixes
& (PREFIX_LOCK
| PREFIX_DATA
8148 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
8151 gen_lea_modrm(env
, s
, modrm
);
8152 tcg_gen_concat_tl_i64(cpu_tmp1_i64
, cpu_regs
[R_EAX
],
8154 gen_helper_xrstor(cpu_env
, s
->A0
, cpu_tmp1_i64
);
8155 /* XRSTOR is how MPX is enabled, which changes how
8156 we translate. Thus we need to end the TB. */
8157 gen_update_cc_op(s
);
8158 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8162 CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */
8163 if (prefixes
& PREFIX_LOCK
) {
8166 if (prefixes
& PREFIX_DATA
) {
8168 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLWB
)) {
8171 gen_nop_modrm(env
, s
, modrm
);
8174 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8175 || (s
->cpuid_xsave_features
& CPUID_XSAVE_XSAVEOPT
) == 0
8176 || (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
))) {
8179 gen_lea_modrm(env
, s
, modrm
);
8180 tcg_gen_concat_tl_i64(cpu_tmp1_i64
, cpu_regs
[R_EAX
],
8182 gen_helper_xsaveopt(cpu_env
, s
->A0
, cpu_tmp1_i64
);
8186 CASE_MODRM_MEM_OP(7): /* clflush / clflushopt */
8187 if (prefixes
& PREFIX_LOCK
) {
8190 if (prefixes
& PREFIX_DATA
) {
8192 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLFLUSHOPT
)) {
8197 if ((s
->prefix
& (PREFIX_REPZ
| PREFIX_REPNZ
))
8198 || !(s
->cpuid_features
& CPUID_CLFLUSH
)) {
8202 gen_nop_modrm(env
, s
, modrm
);
8205 case 0xc0 ... 0xc7: /* rdfsbase (f3 0f ae /0) */
8206 case 0xc8 ... 0xcf: /* rdgsbase (f3 0f ae /1) */
8207 case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */
8208 case 0xd8 ... 0xdf: /* wrgsbase (f3 0f ae /3) */
8210 && (prefixes
& PREFIX_REPZ
)
8211 && !(prefixes
& PREFIX_LOCK
)
8212 && (s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_FSGSBASE
)) {
8213 TCGv base
, treg
, src
, dst
;
8215 /* Preserve hflags bits by testing CR4 at runtime. */
8216 tcg_gen_movi_i32(cpu_tmp2_i32
, CR4_FSGSBASE_MASK
);
8217 gen_helper_cr4_testbit(cpu_env
, cpu_tmp2_i32
);
8219 base
= cpu_seg_base
[modrm
& 8 ? R_GS
: R_FS
];
8220 treg
= cpu_regs
[(modrm
& 7) | REX_B(s
)];
8224 dst
= base
, src
= treg
;
8227 dst
= treg
, src
= base
;
8230 if (s
->dflag
== MO_32
) {
8231 tcg_gen_ext32u_tl(dst
, src
);
8233 tcg_gen_mov_tl(dst
, src
);
8239 case 0xf8: /* sfence / pcommit */
8240 if (prefixes
& PREFIX_DATA
) {
8242 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_PCOMMIT
)
8243 || (prefixes
& PREFIX_LOCK
)) {
8249 case 0xf9 ... 0xff: /* sfence */
8250 if (!(s
->cpuid_features
& CPUID_SSE
)
8251 || (prefixes
& PREFIX_LOCK
)) {
8254 tcg_gen_mb(TCG_MO_ST_ST
| TCG_BAR_SC
);
8256 case 0xe8 ... 0xef: /* lfence */
8257 if (!(s
->cpuid_features
& CPUID_SSE
)
8258 || (prefixes
& PREFIX_LOCK
)) {
8261 tcg_gen_mb(TCG_MO_LD_LD
| TCG_BAR_SC
);
8263 case 0xf0 ... 0xf7: /* mfence */
8264 if (!(s
->cpuid_features
& CPUID_SSE2
)
8265 || (prefixes
& PREFIX_LOCK
)) {
8268 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8276 case 0x10d: /* 3DNow! prefetch(w) */
8277 modrm
= x86_ldub_code(env
, s
);
8278 mod
= (modrm
>> 6) & 3;
8281 gen_nop_modrm(env
, s
, modrm
);
8283 case 0x1aa: /* rsm */
8284 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_RSM
);
8285 if (!(s
->flags
& HF_SMM_MASK
))
8287 gen_update_cc_op(s
);
8288 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8289 gen_helper_rsm(cpu_env
);
8292 case 0x1b8: /* SSE4.2 popcnt */
8293 if ((prefixes
& (PREFIX_REPZ
| PREFIX_LOCK
| PREFIX_REPNZ
)) !=
8296 if (!(s
->cpuid_ext_features
& CPUID_EXT_POPCNT
))
8299 modrm
= x86_ldub_code(env
, s
);
8300 reg
= ((modrm
>> 3) & 7) | rex_r
;
8302 if (s
->prefix
& PREFIX_DATA
) {
8305 ot
= mo_64_32(dflag
);
8308 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
8309 gen_extu(ot
, s
->T0
);
8310 tcg_gen_mov_tl(cpu_cc_src
, s
->T0
);
8311 tcg_gen_ctpop_tl(s
->T0
, s
->T0
);
8312 gen_op_mov_reg_v(ot
, reg
, s
->T0
);
8314 set_cc_op(s
, CC_OP_POPCNT
);
8316 case 0x10e ... 0x10f:
8317 /* 3DNow! instructions, ignore prefixes */
8318 s
->prefix
&= ~(PREFIX_REPZ
| PREFIX_REPNZ
| PREFIX_DATA
);
8320 case 0x110 ... 0x117:
8321 case 0x128 ... 0x12f:
8322 case 0x138 ... 0x13a:
8323 case 0x150 ... 0x179:
8324 case 0x17c ... 0x17f:
8326 case 0x1c4 ... 0x1c6:
8327 case 0x1d0 ... 0x1fe:
8328 gen_sse(env
, s
, b
, pc_start
, rex_r
);
8335 gen_illegal_opcode(s
);
8338 gen_unknown_opcode(env
, s
);
8342 void tcg_x86_init(void)
8344 static const char reg_names
[CPU_NB_REGS
][4] = {
8345 #ifdef TARGET_X86_64
8373 static const char seg_base_names
[6][8] = {
8381 static const char bnd_regl_names
[4][8] = {
8382 "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb"
8384 static const char bnd_regu_names
[4][8] = {
8385 "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub"
8389 cpu_cc_op
= tcg_global_mem_new_i32(cpu_env
,
8390 offsetof(CPUX86State
, cc_op
), "cc_op");
8391 cpu_cc_dst
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_dst
),
8393 cpu_cc_src
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_src
),
8395 cpu_cc_src2
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_src2
),
8398 for (i
= 0; i
< CPU_NB_REGS
; ++i
) {
8399 cpu_regs
[i
] = tcg_global_mem_new(cpu_env
,
8400 offsetof(CPUX86State
, regs
[i
]),
8404 for (i
= 0; i
< 6; ++i
) {
8406 = tcg_global_mem_new(cpu_env
,
8407 offsetof(CPUX86State
, segs
[i
].base
),
8411 for (i
= 0; i
< 4; ++i
) {
8413 = tcg_global_mem_new_i64(cpu_env
,
8414 offsetof(CPUX86State
, bnd_regs
[i
].lb
),
8417 = tcg_global_mem_new_i64(cpu_env
,
8418 offsetof(CPUX86State
, bnd_regs
[i
].ub
),
8423 static void i386_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cpu
)
8425 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8426 CPUX86State
*env
= cpu
->env_ptr
;
8427 uint32_t flags
= dc
->base
.tb
->flags
;
8428 target_ulong cs_base
= dc
->base
.tb
->cs_base
;
8430 dc
->pe
= (flags
>> HF_PE_SHIFT
) & 1;
8431 dc
->code32
= (flags
>> HF_CS32_SHIFT
) & 1;
8432 dc
->ss32
= (flags
>> HF_SS32_SHIFT
) & 1;
8433 dc
->addseg
= (flags
>> HF_ADDSEG_SHIFT
) & 1;
8435 dc
->vm86
= (flags
>> VM_SHIFT
) & 1;
8436 dc
->cpl
= (flags
>> HF_CPL_SHIFT
) & 3;
8437 dc
->iopl
= (flags
>> IOPL_SHIFT
) & 3;
8438 dc
->tf
= (flags
>> TF_SHIFT
) & 1;
8439 dc
->cc_op
= CC_OP_DYNAMIC
;
8440 dc
->cc_op_dirty
= false;
8441 dc
->cs_base
= cs_base
;
8442 dc
->popl_esp_hack
= 0;
8443 /* select memory access functions */
8445 #ifdef CONFIG_SOFTMMU
8446 dc
->mem_index
= cpu_mmu_index(env
, false);
8448 dc
->cpuid_features
= env
->features
[FEAT_1_EDX
];
8449 dc
->cpuid_ext_features
= env
->features
[FEAT_1_ECX
];
8450 dc
->cpuid_ext2_features
= env
->features
[FEAT_8000_0001_EDX
];
8451 dc
->cpuid_ext3_features
= env
->features
[FEAT_8000_0001_ECX
];
8452 dc
->cpuid_7_0_ebx_features
= env
->features
[FEAT_7_0_EBX
];
8453 dc
->cpuid_xsave_features
= env
->features
[FEAT_XSAVE
];
8454 #ifdef TARGET_X86_64
8455 dc
->lma
= (flags
>> HF_LMA_SHIFT
) & 1;
8456 dc
->code64
= (flags
>> HF_CS64_SHIFT
) & 1;
8459 dc
->jmp_opt
= !(dc
->tf
|| dc
->base
.singlestep_enabled
||
8460 (flags
& HF_INHIBIT_IRQ_MASK
));
8461 /* Do not optimize repz jumps at all in icount mode, because
8462 rep movsS instructions are execured with different paths
8463 in !repz_opt and repz_opt modes. The first one was used
8464 always except single step mode. And this setting
8465 disables jumps optimization and control paths become
8466 equivalent in run and single step modes.
8467 Now there will be no jump optimization for repz in
8468 record/replay modes and there will always be an
8469 additional step for ecx=0 when icount is enabled.
8471 dc
->repz_opt
= !dc
->jmp_opt
&& !(tb_cflags(dc
->base
.tb
) & CF_USE_ICOUNT
);
8473 /* check addseg logic */
8474 if (!dc
->addseg
&& (dc
->vm86
|| !dc
->pe
|| !dc
->code32
))
8475 printf("ERROR addseg\n");
8478 dc
->T0
= tcg_temp_new();
8479 dc
->T1
= tcg_temp_new();
8480 dc
->A0
= tcg_temp_new();
8482 dc
->tmp0
= tcg_temp_new();
8483 cpu_tmp1_i64
= tcg_temp_new_i64();
8484 cpu_tmp2_i32
= tcg_temp_new_i32();
8485 cpu_tmp3_i32
= tcg_temp_new_i32();
8486 dc
->tmp4
= tcg_temp_new();
8487 cpu_ptr0
= tcg_temp_new_ptr();
8488 cpu_ptr1
= tcg_temp_new_ptr();
8489 dc
->cc_srcT
= tcg_temp_local_new();
8492 static void i386_tr_tb_start(DisasContextBase
*db
, CPUState
*cpu
)
8496 static void i386_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
8498 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8500 tcg_gen_insn_start(dc
->base
.pc_next
, dc
->cc_op
);
8503 static bool i386_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cpu
,
8504 const CPUBreakpoint
*bp
)
8506 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8507 /* If RF is set, suppress an internally generated breakpoint. */
8508 int flags
= dc
->base
.tb
->flags
& HF_RF_MASK
? BP_GDB
: BP_ANY
;
8509 if (bp
->flags
& flags
) {
8510 gen_debug(dc
, dc
->base
.pc_next
- dc
->cs_base
);
8511 dc
->base
.is_jmp
= DISAS_NORETURN
;
8512 /* The address covered by the breakpoint must be included in
8513 [tb->pc, tb->pc + tb->size) in order to for it to be
8514 properly cleared -- thus we increment the PC here so that
8515 the generic logic setting tb->size later does the right thing. */
8516 dc
->base
.pc_next
+= 1;
8523 static void i386_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
8525 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8526 target_ulong pc_next
= disas_insn(dc
, cpu
);
8528 if (dc
->tf
|| (dc
->base
.tb
->flags
& HF_INHIBIT_IRQ_MASK
)) {
8529 /* if single step mode, we generate only one instruction and
8530 generate an exception */
8531 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
8532 the flag and abort the translation to give the irqs a
8534 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
8535 } else if ((tb_cflags(dc
->base
.tb
) & CF_USE_ICOUNT
)
8536 && ((dc
->base
.pc_next
& TARGET_PAGE_MASK
)
8537 != ((dc
->base
.pc_next
+ TARGET_MAX_INSN_SIZE
- 1)
8539 || (dc
->base
.pc_next
& ~TARGET_PAGE_MASK
) == 0)) {
8540 /* Do not cross the boundary of the pages in icount mode,
8541 it can cause an exception. Do it only when boundary is
8542 crossed by the first instruction in the block.
8543 If current instruction already crossed the bound - it's ok,
8544 because an exception hasn't stopped this code.
8546 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
8547 } else if ((pc_next
- dc
->base
.pc_first
) >= (TARGET_PAGE_SIZE
- 32)) {
8548 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
8551 dc
->base
.pc_next
= pc_next
;
8554 static void i386_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cpu
)
8556 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8558 if (dc
->base
.is_jmp
== DISAS_TOO_MANY
) {
8559 gen_jmp_im(dc
, dc
->base
.pc_next
- dc
->cs_base
);
8564 static void i386_tr_disas_log(const DisasContextBase
*dcbase
,
8567 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8569 qemu_log("IN: %s\n", lookup_symbol(dc
->base
.pc_first
));
8570 log_target_disas(cpu
, dc
->base
.pc_first
, dc
->base
.tb
->size
);
8573 static const TranslatorOps i386_tr_ops
= {
8574 .init_disas_context
= i386_tr_init_disas_context
,
8575 .tb_start
= i386_tr_tb_start
,
8576 .insn_start
= i386_tr_insn_start
,
8577 .breakpoint_check
= i386_tr_breakpoint_check
,
8578 .translate_insn
= i386_tr_translate_insn
,
8579 .tb_stop
= i386_tr_tb_stop
,
8580 .disas_log
= i386_tr_disas_log
,
8583 /* generate intermediate code for basic block 'tb'. */
8584 void gen_intermediate_code(CPUState
*cpu
, TranslationBlock
*tb
)
8588 translator_loop(&i386_tr_ops
, &dc
.base
, cpu
, tb
);
8591 void restore_state_to_opc(CPUX86State
*env
, TranslationBlock
*tb
,
8594 int cc_op
= data
[1];
8595 env
->eip
= data
[0] - tb
->cs_base
;
8596 if (cc_op
!= CC_OP_DYNAMIC
) {