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"
25 #include "exec/cpu_ldst.h"
27 #include "exec/helper-proto.h"
28 #include "exec/helper-gen.h"
30 #include "trace-tcg.h"
34 #define PREFIX_REPZ 0x01
35 #define PREFIX_REPNZ 0x02
36 #define PREFIX_LOCK 0x04
37 #define PREFIX_DATA 0x08
38 #define PREFIX_ADR 0x10
39 #define PREFIX_VEX 0x20
42 #define CODE64(s) ((s)->code64)
43 #define REX_X(s) ((s)->rex_x)
44 #define REX_B(s) ((s)->rex_b)
59 /* For a switch indexed by MODRM, match all memory operands for a given OP. */
60 #define CASE_MEM_OP(OP) \
61 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
62 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
63 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7
65 //#define MACRO_TEST 1
67 /* global register indexes */
68 static TCGv_ptr cpu_env
;
70 static TCGv cpu_cc_dst
, cpu_cc_src
, cpu_cc_src2
, cpu_cc_srcT
;
71 static TCGv_i32 cpu_cc_op
;
72 static TCGv cpu_regs
[CPU_NB_REGS
];
73 static TCGv cpu_seg_base
[6];
74 static TCGv_i64 cpu_bndl
[4];
75 static TCGv_i64 cpu_bndu
[4];
77 static TCGv cpu_T0
, cpu_T1
;
78 /* local register indexes (only used inside old micro ops) */
79 static TCGv cpu_tmp0
, cpu_tmp4
;
80 static TCGv_ptr cpu_ptr0
, cpu_ptr1
;
81 static TCGv_i32 cpu_tmp2_i32
, cpu_tmp3_i32
;
82 static TCGv_i64 cpu_tmp1_i64
;
84 #include "exec/gen-icount.h"
87 static int x86_64_hregs
;
90 typedef struct DisasContext
{
91 /* current insn context */
92 int override
; /* -1 if no override */
96 target_ulong pc
; /* pc = eip + cs_base */
97 int is_jmp
; /* 1 = means jump (stop translation), 2 means CPU
98 static state change (stop translation) */
99 /* current block context */
100 target_ulong cs_base
; /* base of CS segment */
101 int pe
; /* protected mode */
102 int code32
; /* 32 bit code segment */
104 int lma
; /* long mode active */
105 int code64
; /* 64 bit code segment */
108 int vex_l
; /* vex vector length */
109 int vex_v
; /* vex vvvv register, without 1's compliment. */
110 int ss32
; /* 32 bit stack segment */
111 CCOp cc_op
; /* current CC operation */
113 int addseg
; /* non zero if either DS/ES/SS have a non zero base */
114 int f_st
; /* currently unused */
115 int vm86
; /* vm86 mode */
118 int tf
; /* TF cpu flag */
119 int singlestep_enabled
; /* "hardware" single step enabled */
120 int jmp_opt
; /* use direct block chaining for direct jumps */
121 int repz_opt
; /* optimize jumps within repz instructions */
122 int mem_index
; /* select memory access functions */
123 uint64_t flags
; /* all execution flags */
124 struct TranslationBlock
*tb
;
125 int popl_esp_hack
; /* for correct popl with esp base handling */
126 int rip_offset
; /* only used in x86_64, but left for simplicity */
128 int cpuid_ext_features
;
129 int cpuid_ext2_features
;
130 int cpuid_ext3_features
;
131 int cpuid_7_0_ebx_features
;
132 int cpuid_xsave_features
;
135 static void gen_eob(DisasContext
*s
);
136 static void gen_jmp(DisasContext
*s
, target_ulong eip
);
137 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
);
138 static void gen_op(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
);
140 /* i386 arith/logic operations */
160 OP_SHL1
, /* undocumented */
176 /* I386 int registers */
177 OR_EAX
, /* MUST be even numbered */
186 OR_TMP0
= 16, /* temporary operand register */
188 OR_A0
, /* temporary register used when doing address evaluation */
198 /* Bit set if the global variable is live after setting CC_OP to X. */
199 static const uint8_t cc_op_live
[CC_OP_NB
] = {
200 [CC_OP_DYNAMIC
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
201 [CC_OP_EFLAGS
] = USES_CC_SRC
,
202 [CC_OP_MULB
... CC_OP_MULQ
] = USES_CC_DST
| USES_CC_SRC
,
203 [CC_OP_ADDB
... CC_OP_ADDQ
] = USES_CC_DST
| USES_CC_SRC
,
204 [CC_OP_ADCB
... CC_OP_ADCQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
205 [CC_OP_SUBB
... CC_OP_SUBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRCT
,
206 [CC_OP_SBBB
... CC_OP_SBBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
207 [CC_OP_LOGICB
... CC_OP_LOGICQ
] = USES_CC_DST
,
208 [CC_OP_INCB
... CC_OP_INCQ
] = USES_CC_DST
| USES_CC_SRC
,
209 [CC_OP_DECB
... CC_OP_DECQ
] = USES_CC_DST
| USES_CC_SRC
,
210 [CC_OP_SHLB
... CC_OP_SHLQ
] = USES_CC_DST
| USES_CC_SRC
,
211 [CC_OP_SARB
... CC_OP_SARQ
] = USES_CC_DST
| USES_CC_SRC
,
212 [CC_OP_BMILGB
... CC_OP_BMILGQ
] = USES_CC_DST
| USES_CC_SRC
,
213 [CC_OP_ADCX
] = USES_CC_DST
| USES_CC_SRC
,
214 [CC_OP_ADOX
] = USES_CC_SRC
| USES_CC_SRC2
,
215 [CC_OP_ADCOX
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
219 static void set_cc_op(DisasContext
*s
, CCOp op
)
223 if (s
->cc_op
== op
) {
227 /* Discard CC computation that will no longer be used. */
228 dead
= cc_op_live
[s
->cc_op
] & ~cc_op_live
[op
];
229 if (dead
& USES_CC_DST
) {
230 tcg_gen_discard_tl(cpu_cc_dst
);
232 if (dead
& USES_CC_SRC
) {
233 tcg_gen_discard_tl(cpu_cc_src
);
235 if (dead
& USES_CC_SRC2
) {
236 tcg_gen_discard_tl(cpu_cc_src2
);
238 if (dead
& USES_CC_SRCT
) {
239 tcg_gen_discard_tl(cpu_cc_srcT
);
242 if (op
== CC_OP_DYNAMIC
) {
243 /* The DYNAMIC setting is translator only, and should never be
244 stored. Thus we always consider it clean. */
245 s
->cc_op_dirty
= false;
247 /* Discard any computed CC_OP value (see shifts). */
248 if (s
->cc_op
== CC_OP_DYNAMIC
) {
249 tcg_gen_discard_i32(cpu_cc_op
);
251 s
->cc_op_dirty
= true;
256 static void gen_update_cc_op(DisasContext
*s
)
258 if (s
->cc_op_dirty
) {
259 tcg_gen_movi_i32(cpu_cc_op
, s
->cc_op
);
260 s
->cc_op_dirty
= false;
266 #define NB_OP_SIZES 4
268 #else /* !TARGET_X86_64 */
270 #define NB_OP_SIZES 3
272 #endif /* !TARGET_X86_64 */
274 #if defined(HOST_WORDS_BIGENDIAN)
275 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
276 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
277 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
278 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
279 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
281 #define REG_B_OFFSET 0
282 #define REG_H_OFFSET 1
283 #define REG_W_OFFSET 0
284 #define REG_L_OFFSET 0
285 #define REG_LH_OFFSET 4
288 /* In instruction encodings for byte register accesses the
289 * register number usually indicates "low 8 bits of register N";
290 * however there are some special cases where N 4..7 indicates
291 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
292 * true for this special case, false otherwise.
294 static inline bool byte_reg_is_xH(int reg
)
300 if (reg
>= 8 || x86_64_hregs
) {
307 /* Select the size of a push/pop operation. */
308 static inline TCGMemOp
mo_pushpop(DisasContext
*s
, TCGMemOp ot
)
311 return ot
== MO_16
? MO_16
: MO_64
;
317 /* Select the size of the stack pointer. */
318 static inline TCGMemOp
mo_stacksize(DisasContext
*s
)
320 return CODE64(s
) ? MO_64
: s
->ss32
? MO_32
: MO_16
;
323 /* Select only size 64 else 32. Used for SSE operand sizes. */
324 static inline TCGMemOp
mo_64_32(TCGMemOp ot
)
327 return ot
== MO_64
? MO_64
: MO_32
;
333 /* Select size 8 if lsb of B is clear, else OT. Used for decoding
334 byte vs word opcodes. */
335 static inline TCGMemOp
mo_b_d(int b
, TCGMemOp ot
)
337 return b
& 1 ? ot
: MO_8
;
340 /* Select size 8 if lsb of B is clear, else OT capped at 32.
341 Used for decoding operand size of port opcodes. */
342 static inline TCGMemOp
mo_b_d32(int b
, TCGMemOp ot
)
344 return b
& 1 ? (ot
== MO_16
? MO_16
: MO_32
) : MO_8
;
347 static void gen_op_mov_reg_v(TCGMemOp ot
, int reg
, TCGv t0
)
351 if (!byte_reg_is_xH(reg
)) {
352 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 8);
354 tcg_gen_deposit_tl(cpu_regs
[reg
- 4], cpu_regs
[reg
- 4], t0
, 8, 8);
358 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 16);
361 /* For x86_64, this sets the higher half of register to zero.
362 For i386, this is equivalent to a mov. */
363 tcg_gen_ext32u_tl(cpu_regs
[reg
], t0
);
367 tcg_gen_mov_tl(cpu_regs
[reg
], t0
);
375 static inline void gen_op_mov_v_reg(TCGMemOp ot
, TCGv t0
, int reg
)
377 if (ot
== MO_8
&& byte_reg_is_xH(reg
)) {
378 tcg_gen_shri_tl(t0
, cpu_regs
[reg
- 4], 8);
379 tcg_gen_ext8u_tl(t0
, t0
);
381 tcg_gen_mov_tl(t0
, cpu_regs
[reg
]);
385 static void gen_add_A0_im(DisasContext
*s
, int val
)
387 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, val
);
389 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
393 static inline void gen_op_jmp_v(TCGv dest
)
395 tcg_gen_st_tl(dest
, cpu_env
, offsetof(CPUX86State
, eip
));
398 static inline void gen_op_add_reg_im(TCGMemOp size
, int reg
, int32_t val
)
400 tcg_gen_addi_tl(cpu_tmp0
, cpu_regs
[reg
], val
);
401 gen_op_mov_reg_v(size
, reg
, cpu_tmp0
);
404 static inline void gen_op_add_reg_T0(TCGMemOp size
, int reg
)
406 tcg_gen_add_tl(cpu_tmp0
, cpu_regs
[reg
], cpu_T0
);
407 gen_op_mov_reg_v(size
, reg
, cpu_tmp0
);
410 static inline void gen_op_ld_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
412 tcg_gen_qemu_ld_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
415 static inline void gen_op_st_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
417 tcg_gen_qemu_st_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
420 static inline void gen_op_st_rm_T0_A0(DisasContext
*s
, int idx
, int d
)
423 gen_op_st_v(s
, idx
, cpu_T0
, cpu_A0
);
425 gen_op_mov_reg_v(idx
, d
, cpu_T0
);
429 static inline void gen_jmp_im(target_ulong pc
)
431 tcg_gen_movi_tl(cpu_tmp0
, pc
);
432 gen_op_jmp_v(cpu_tmp0
);
435 /* Compute SEG:REG into A0. SEG is selected from the override segment
436 (OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to
437 indicate no override. */
438 static void gen_lea_v_seg(DisasContext
*s
, TCGMemOp aflag
, TCGv a0
,
439 int def_seg
, int ovr_seg
)
445 tcg_gen_mov_tl(cpu_A0
, a0
);
456 tcg_gen_ext32u_tl(cpu_A0
, a0
);
466 tcg_gen_ext16u_tl(cpu_A0
, a0
);
467 /* ADDSEG will only be false in 16-bit mode for LEA. */
478 TCGv seg
= cpu_seg_base
[ovr_seg
];
480 if (aflag
== MO_64
) {
481 tcg_gen_add_tl(cpu_A0
, a0
, seg
);
482 } else if (CODE64(s
)) {
483 tcg_gen_ext32u_tl(cpu_A0
, a0
);
484 tcg_gen_add_tl(cpu_A0
, cpu_A0
, seg
);
486 tcg_gen_add_tl(cpu_A0
, a0
, seg
);
487 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
492 static inline void gen_string_movl_A0_ESI(DisasContext
*s
)
494 gen_lea_v_seg(s
, s
->aflag
, cpu_regs
[R_ESI
], R_DS
, s
->override
);
497 static inline void gen_string_movl_A0_EDI(DisasContext
*s
)
499 gen_lea_v_seg(s
, s
->aflag
, cpu_regs
[R_EDI
], R_ES
, -1);
502 static inline void gen_op_movl_T0_Dshift(TCGMemOp ot
)
504 tcg_gen_ld32s_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, df
));
505 tcg_gen_shli_tl(cpu_T0
, cpu_T0
, ot
);
508 static TCGv
gen_ext_tl(TCGv dst
, TCGv src
, TCGMemOp size
, bool sign
)
513 tcg_gen_ext8s_tl(dst
, src
);
515 tcg_gen_ext8u_tl(dst
, src
);
520 tcg_gen_ext16s_tl(dst
, src
);
522 tcg_gen_ext16u_tl(dst
, src
);
528 tcg_gen_ext32s_tl(dst
, src
);
530 tcg_gen_ext32u_tl(dst
, src
);
539 static void gen_extu(TCGMemOp ot
, TCGv reg
)
541 gen_ext_tl(reg
, reg
, ot
, false);
544 static void gen_exts(TCGMemOp ot
, TCGv reg
)
546 gen_ext_tl(reg
, reg
, ot
, true);
549 static inline void gen_op_jnz_ecx(TCGMemOp size
, TCGLabel
*label1
)
551 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[R_ECX
]);
552 gen_extu(size
, cpu_tmp0
);
553 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_tmp0
, 0, label1
);
556 static inline void gen_op_jz_ecx(TCGMemOp size
, TCGLabel
*label1
)
558 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[R_ECX
]);
559 gen_extu(size
, cpu_tmp0
);
560 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
563 static void gen_helper_in_func(TCGMemOp ot
, TCGv v
, TCGv_i32 n
)
567 gen_helper_inb(v
, cpu_env
, n
);
570 gen_helper_inw(v
, cpu_env
, n
);
573 gen_helper_inl(v
, cpu_env
, n
);
580 static void gen_helper_out_func(TCGMemOp ot
, TCGv_i32 v
, TCGv_i32 n
)
584 gen_helper_outb(cpu_env
, v
, n
);
587 gen_helper_outw(cpu_env
, v
, n
);
590 gen_helper_outl(cpu_env
, v
, n
);
597 static void gen_check_io(DisasContext
*s
, TCGMemOp ot
, target_ulong cur_eip
,
600 target_ulong next_eip
;
602 if (s
->pe
&& (s
->cpl
> s
->iopl
|| s
->vm86
)) {
603 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
606 gen_helper_check_iob(cpu_env
, cpu_tmp2_i32
);
609 gen_helper_check_iow(cpu_env
, cpu_tmp2_i32
);
612 gen_helper_check_iol(cpu_env
, cpu_tmp2_i32
);
618 if(s
->flags
& HF_SVMI_MASK
) {
621 svm_flags
|= (1 << (4 + ot
));
622 next_eip
= s
->pc
- s
->cs_base
;
623 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
624 gen_helper_svm_check_io(cpu_env
, cpu_tmp2_i32
,
625 tcg_const_i32(svm_flags
),
626 tcg_const_i32(next_eip
- cur_eip
));
630 static inline void gen_movs(DisasContext
*s
, TCGMemOp ot
)
632 gen_string_movl_A0_ESI(s
);
633 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
634 gen_string_movl_A0_EDI(s
);
635 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
636 gen_op_movl_T0_Dshift(ot
);
637 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
638 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
641 static void gen_op_update1_cc(void)
643 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
646 static void gen_op_update2_cc(void)
648 tcg_gen_mov_tl(cpu_cc_src
, cpu_T1
);
649 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
652 static void gen_op_update3_cc(TCGv reg
)
654 tcg_gen_mov_tl(cpu_cc_src2
, reg
);
655 tcg_gen_mov_tl(cpu_cc_src
, cpu_T1
);
656 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
659 static inline void gen_op_testl_T0_T1_cc(void)
661 tcg_gen_and_tl(cpu_cc_dst
, cpu_T0
, cpu_T1
);
664 static void gen_op_update_neg_cc(void)
666 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
667 tcg_gen_neg_tl(cpu_cc_src
, cpu_T0
);
668 tcg_gen_movi_tl(cpu_cc_srcT
, 0);
671 /* compute all eflags to cc_src */
672 static void gen_compute_eflags(DisasContext
*s
)
674 TCGv zero
, dst
, src1
, src2
;
677 if (s
->cc_op
== CC_OP_EFLAGS
) {
680 if (s
->cc_op
== CC_OP_CLR
) {
681 tcg_gen_movi_tl(cpu_cc_src
, CC_Z
| CC_P
);
682 set_cc_op(s
, CC_OP_EFLAGS
);
691 /* Take care to not read values that are not live. */
692 live
= cc_op_live
[s
->cc_op
] & ~USES_CC_SRCT
;
693 dead
= live
^ (USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
);
695 zero
= tcg_const_tl(0);
696 if (dead
& USES_CC_DST
) {
699 if (dead
& USES_CC_SRC
) {
702 if (dead
& USES_CC_SRC2
) {
708 gen_helper_cc_compute_all(cpu_cc_src
, dst
, src1
, src2
, cpu_cc_op
);
709 set_cc_op(s
, CC_OP_EFLAGS
);
716 typedef struct CCPrepare
{
726 /* compute eflags.C to reg */
727 static CCPrepare
gen_prepare_eflags_c(DisasContext
*s
, TCGv reg
)
733 case CC_OP_SUBB
... CC_OP_SUBQ
:
734 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
735 size
= s
->cc_op
- CC_OP_SUBB
;
736 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
737 /* If no temporary was used, be careful not to alias t1 and t0. */
738 t0
= TCGV_EQUAL(t1
, cpu_cc_src
) ? cpu_tmp0
: reg
;
739 tcg_gen_mov_tl(t0
, cpu_cc_srcT
);
743 case CC_OP_ADDB
... CC_OP_ADDQ
:
744 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
745 size
= s
->cc_op
- CC_OP_ADDB
;
746 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
747 t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
749 return (CCPrepare
) { .cond
= TCG_COND_LTU
, .reg
= t0
,
750 .reg2
= t1
, .mask
= -1, .use_reg2
= true };
752 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
754 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
756 case CC_OP_INCB
... CC_OP_INCQ
:
757 case CC_OP_DECB
... CC_OP_DECQ
:
758 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
759 .mask
= -1, .no_setcond
= true };
761 case CC_OP_SHLB
... CC_OP_SHLQ
:
762 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
763 size
= s
->cc_op
- CC_OP_SHLB
;
764 shift
= (8 << size
) - 1;
765 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
766 .mask
= (target_ulong
)1 << shift
};
768 case CC_OP_MULB
... CC_OP_MULQ
:
769 return (CCPrepare
) { .cond
= TCG_COND_NE
,
770 .reg
= cpu_cc_src
, .mask
= -1 };
772 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
773 size
= s
->cc_op
- CC_OP_BMILGB
;
774 t0
= gen_ext_tl(reg
, cpu_cc_src
, size
, false);
775 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
779 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_dst
,
780 .mask
= -1, .no_setcond
= true };
783 case CC_OP_SARB
... CC_OP_SARQ
:
785 return (CCPrepare
) { .cond
= TCG_COND_NE
,
786 .reg
= cpu_cc_src
, .mask
= CC_C
};
789 /* The need to compute only C from CC_OP_DYNAMIC is important
790 in efficiently implementing e.g. INC at the start of a TB. */
792 gen_helper_cc_compute_c(reg
, cpu_cc_dst
, cpu_cc_src
,
793 cpu_cc_src2
, cpu_cc_op
);
794 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
795 .mask
= -1, .no_setcond
= true };
799 /* compute eflags.P to reg */
800 static CCPrepare
gen_prepare_eflags_p(DisasContext
*s
, TCGv reg
)
802 gen_compute_eflags(s
);
803 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
807 /* compute eflags.S to reg */
808 static CCPrepare
gen_prepare_eflags_s(DisasContext
*s
, TCGv reg
)
812 gen_compute_eflags(s
);
818 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
821 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
824 TCGMemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
825 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, true);
826 return (CCPrepare
) { .cond
= TCG_COND_LT
, .reg
= t0
, .mask
= -1 };
831 /* compute eflags.O to reg */
832 static CCPrepare
gen_prepare_eflags_o(DisasContext
*s
, TCGv reg
)
837 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src2
,
838 .mask
= -1, .no_setcond
= true };
840 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
842 gen_compute_eflags(s
);
843 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
848 /* compute eflags.Z to reg */
849 static CCPrepare
gen_prepare_eflags_z(DisasContext
*s
, TCGv reg
)
853 gen_compute_eflags(s
);
859 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
862 return (CCPrepare
) { .cond
= TCG_COND_ALWAYS
, .mask
= -1 };
865 TCGMemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
866 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
867 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
872 /* perform a conditional store into register 'reg' according to jump opcode
873 value 'b'. In the fast case, T0 is guaranted not to be used. */
874 static CCPrepare
gen_prepare_cc(DisasContext
*s
, int b
, TCGv reg
)
876 int inv
, jcc_op
, cond
;
882 jcc_op
= (b
>> 1) & 7;
885 case CC_OP_SUBB
... CC_OP_SUBQ
:
886 /* We optimize relational operators for the cmp/jcc case. */
887 size
= s
->cc_op
- CC_OP_SUBB
;
890 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
891 gen_extu(size
, cpu_tmp4
);
892 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
893 cc
= (CCPrepare
) { .cond
= TCG_COND_LEU
, .reg
= cpu_tmp4
,
894 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
903 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
904 gen_exts(size
, cpu_tmp4
);
905 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, true);
906 cc
= (CCPrepare
) { .cond
= cond
, .reg
= cpu_tmp4
,
907 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
917 /* This actually generates good code for JC, JZ and JS. */
920 cc
= gen_prepare_eflags_o(s
, reg
);
923 cc
= gen_prepare_eflags_c(s
, reg
);
926 cc
= gen_prepare_eflags_z(s
, reg
);
929 gen_compute_eflags(s
);
930 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
931 .mask
= CC_Z
| CC_C
};
934 cc
= gen_prepare_eflags_s(s
, reg
);
937 cc
= gen_prepare_eflags_p(s
, reg
);
940 gen_compute_eflags(s
);
941 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
944 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
945 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
946 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
951 gen_compute_eflags(s
);
952 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
955 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
956 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
957 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
958 .mask
= CC_S
| CC_Z
};
965 cc
.cond
= tcg_invert_cond(cc
.cond
);
970 static void gen_setcc1(DisasContext
*s
, int b
, TCGv reg
)
972 CCPrepare cc
= gen_prepare_cc(s
, b
, reg
);
975 if (cc
.cond
== TCG_COND_EQ
) {
976 tcg_gen_xori_tl(reg
, cc
.reg
, 1);
978 tcg_gen_mov_tl(reg
, cc
.reg
);
983 if (cc
.cond
== TCG_COND_NE
&& !cc
.use_reg2
&& cc
.imm
== 0 &&
984 cc
.mask
!= 0 && (cc
.mask
& (cc
.mask
- 1)) == 0) {
985 tcg_gen_shri_tl(reg
, cc
.reg
, ctztl(cc
.mask
));
986 tcg_gen_andi_tl(reg
, reg
, 1);
990 tcg_gen_andi_tl(reg
, cc
.reg
, cc
.mask
);
994 tcg_gen_setcond_tl(cc
.cond
, reg
, cc
.reg
, cc
.reg2
);
996 tcg_gen_setcondi_tl(cc
.cond
, reg
, cc
.reg
, cc
.imm
);
1000 static inline void gen_compute_eflags_c(DisasContext
*s
, TCGv reg
)
1002 gen_setcc1(s
, JCC_B
<< 1, reg
);
1005 /* generate a conditional jump to label 'l1' according to jump opcode
1006 value 'b'. In the fast case, T0 is guaranted not to be used. */
1007 static inline void gen_jcc1_noeob(DisasContext
*s
, int b
, TCGLabel
*l1
)
1009 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T0
);
1011 if (cc
.mask
!= -1) {
1012 tcg_gen_andi_tl(cpu_T0
, cc
.reg
, cc
.mask
);
1016 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1018 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1022 /* Generate a conditional jump to label 'l1' according to jump opcode
1023 value 'b'. In the fast case, T0 is guaranted not to be used.
1024 A translation block must end soon. */
1025 static inline void gen_jcc1(DisasContext
*s
, int b
, TCGLabel
*l1
)
1027 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T0
);
1029 gen_update_cc_op(s
);
1030 if (cc
.mask
!= -1) {
1031 tcg_gen_andi_tl(cpu_T0
, cc
.reg
, cc
.mask
);
1034 set_cc_op(s
, CC_OP_DYNAMIC
);
1036 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1038 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1042 /* XXX: does not work with gdbstub "ice" single step - not a
1044 static TCGLabel
*gen_jz_ecx_string(DisasContext
*s
, target_ulong next_eip
)
1046 TCGLabel
*l1
= gen_new_label();
1047 TCGLabel
*l2
= gen_new_label();
1048 gen_op_jnz_ecx(s
->aflag
, l1
);
1050 gen_jmp_tb(s
, next_eip
, 1);
1055 static inline void gen_stos(DisasContext
*s
, TCGMemOp ot
)
1057 gen_op_mov_v_reg(MO_32
, cpu_T0
, R_EAX
);
1058 gen_string_movl_A0_EDI(s
);
1059 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
1060 gen_op_movl_T0_Dshift(ot
);
1061 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1064 static inline void gen_lods(DisasContext
*s
, TCGMemOp ot
)
1066 gen_string_movl_A0_ESI(s
);
1067 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1068 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T0
);
1069 gen_op_movl_T0_Dshift(ot
);
1070 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1073 static inline void gen_scas(DisasContext
*s
, TCGMemOp ot
)
1075 gen_string_movl_A0_EDI(s
);
1076 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
1077 gen_op(s
, OP_CMPL
, ot
, R_EAX
);
1078 gen_op_movl_T0_Dshift(ot
);
1079 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1082 static inline void gen_cmps(DisasContext
*s
, TCGMemOp ot
)
1084 gen_string_movl_A0_EDI(s
);
1085 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
1086 gen_string_movl_A0_ESI(s
);
1087 gen_op(s
, OP_CMPL
, ot
, OR_TMP0
);
1088 gen_op_movl_T0_Dshift(ot
);
1089 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1090 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1093 static void gen_bpt_io(DisasContext
*s
, TCGv_i32 t_port
, int ot
)
1095 if (s
->flags
& HF_IOBPT_MASK
) {
1096 TCGv_i32 t_size
= tcg_const_i32(1 << ot
);
1097 TCGv t_next
= tcg_const_tl(s
->pc
- s
->cs_base
);
1099 gen_helper_bpt_io(cpu_env
, t_port
, t_size
, t_next
);
1100 tcg_temp_free_i32(t_size
);
1101 tcg_temp_free(t_next
);
1106 static inline void gen_ins(DisasContext
*s
, TCGMemOp ot
)
1108 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1111 gen_string_movl_A0_EDI(s
);
1112 /* Note: we must do this dummy write first to be restartable in
1113 case of page fault. */
1114 tcg_gen_movi_tl(cpu_T0
, 0);
1115 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
1116 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_EDX
]);
1117 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1118 gen_helper_in_func(ot
, cpu_T0
, cpu_tmp2_i32
);
1119 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
1120 gen_op_movl_T0_Dshift(ot
);
1121 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1122 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
1123 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1128 static inline void gen_outs(DisasContext
*s
, TCGMemOp ot
)
1130 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1133 gen_string_movl_A0_ESI(s
);
1134 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1136 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_EDX
]);
1137 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1138 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T0
);
1139 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1140 gen_op_movl_T0_Dshift(ot
);
1141 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1142 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
1143 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1148 /* same method as Valgrind : we generate jumps to current or next
1150 #define GEN_REPZ(op) \
1151 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1152 target_ulong cur_eip, target_ulong next_eip) \
1155 gen_update_cc_op(s); \
1156 l2 = gen_jz_ecx_string(s, next_eip); \
1157 gen_ ## op(s, ot); \
1158 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1159 /* a loop would cause two single step exceptions if ECX = 1 \
1160 before rep string_insn */ \
1162 gen_op_jz_ecx(s->aflag, l2); \
1163 gen_jmp(s, cur_eip); \
1166 #define GEN_REPZ2(op) \
1167 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1168 target_ulong cur_eip, \
1169 target_ulong next_eip, \
1173 gen_update_cc_op(s); \
1174 l2 = gen_jz_ecx_string(s, next_eip); \
1175 gen_ ## op(s, ot); \
1176 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1177 gen_update_cc_op(s); \
1178 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
1180 gen_op_jz_ecx(s->aflag, l2); \
1181 gen_jmp(s, cur_eip); \
1192 static void gen_helper_fp_arith_ST0_FT0(int op
)
1196 gen_helper_fadd_ST0_FT0(cpu_env
);
1199 gen_helper_fmul_ST0_FT0(cpu_env
);
1202 gen_helper_fcom_ST0_FT0(cpu_env
);
1205 gen_helper_fcom_ST0_FT0(cpu_env
);
1208 gen_helper_fsub_ST0_FT0(cpu_env
);
1211 gen_helper_fsubr_ST0_FT0(cpu_env
);
1214 gen_helper_fdiv_ST0_FT0(cpu_env
);
1217 gen_helper_fdivr_ST0_FT0(cpu_env
);
1222 /* NOTE the exception in "r" op ordering */
1223 static void gen_helper_fp_arith_STN_ST0(int op
, int opreg
)
1225 TCGv_i32 tmp
= tcg_const_i32(opreg
);
1228 gen_helper_fadd_STN_ST0(cpu_env
, tmp
);
1231 gen_helper_fmul_STN_ST0(cpu_env
, tmp
);
1234 gen_helper_fsubr_STN_ST0(cpu_env
, tmp
);
1237 gen_helper_fsub_STN_ST0(cpu_env
, tmp
);
1240 gen_helper_fdivr_STN_ST0(cpu_env
, tmp
);
1243 gen_helper_fdiv_STN_ST0(cpu_env
, tmp
);
1248 /* if d == OR_TMP0, it means memory operand (address in A0) */
1249 static void gen_op(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
)
1252 gen_op_mov_v_reg(ot
, cpu_T0
, d
);
1254 gen_op_ld_v(s1
, ot
, cpu_T0
, cpu_A0
);
1258 gen_compute_eflags_c(s1
, cpu_tmp4
);
1259 tcg_gen_add_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1260 tcg_gen_add_tl(cpu_T0
, cpu_T0
, cpu_tmp4
);
1261 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1262 gen_op_update3_cc(cpu_tmp4
);
1263 set_cc_op(s1
, CC_OP_ADCB
+ ot
);
1266 gen_compute_eflags_c(s1
, cpu_tmp4
);
1267 tcg_gen_sub_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1268 tcg_gen_sub_tl(cpu_T0
, cpu_T0
, cpu_tmp4
);
1269 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1270 gen_op_update3_cc(cpu_tmp4
);
1271 set_cc_op(s1
, CC_OP_SBBB
+ ot
);
1274 tcg_gen_add_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1275 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1276 gen_op_update2_cc();
1277 set_cc_op(s1
, CC_OP_ADDB
+ ot
);
1280 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T0
);
1281 tcg_gen_sub_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1282 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1283 gen_op_update2_cc();
1284 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1288 tcg_gen_and_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1289 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1290 gen_op_update1_cc();
1291 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1294 tcg_gen_or_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1295 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1296 gen_op_update1_cc();
1297 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1300 tcg_gen_xor_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1301 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1302 gen_op_update1_cc();
1303 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1306 tcg_gen_mov_tl(cpu_cc_src
, cpu_T1
);
1307 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T0
);
1308 tcg_gen_sub_tl(cpu_cc_dst
, cpu_T0
, cpu_T1
);
1309 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1314 /* if d == OR_TMP0, it means memory operand (address in A0) */
1315 static void gen_inc(DisasContext
*s1
, TCGMemOp ot
, int d
, int c
)
1318 gen_op_mov_v_reg(ot
, cpu_T0
, d
);
1320 gen_op_ld_v(s1
, ot
, cpu_T0
, cpu_A0
);
1322 gen_compute_eflags_c(s1
, cpu_cc_src
);
1324 tcg_gen_addi_tl(cpu_T0
, cpu_T0
, 1);
1325 set_cc_op(s1
, CC_OP_INCB
+ ot
);
1327 tcg_gen_addi_tl(cpu_T0
, cpu_T0
, -1);
1328 set_cc_op(s1
, CC_OP_DECB
+ ot
);
1330 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1331 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
1334 static void gen_shift_flags(DisasContext
*s
, TCGMemOp ot
, TCGv result
,
1335 TCGv shm1
, TCGv count
, bool is_right
)
1337 TCGv_i32 z32
, s32
, oldop
;
1340 /* Store the results into the CC variables. If we know that the
1341 variable must be dead, store unconditionally. Otherwise we'll
1342 need to not disrupt the current contents. */
1343 z_tl
= tcg_const_tl(0);
1344 if (cc_op_live
[s
->cc_op
] & USES_CC_DST
) {
1345 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_dst
, count
, z_tl
,
1346 result
, cpu_cc_dst
);
1348 tcg_gen_mov_tl(cpu_cc_dst
, result
);
1350 if (cc_op_live
[s
->cc_op
] & USES_CC_SRC
) {
1351 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_src
, count
, z_tl
,
1354 tcg_gen_mov_tl(cpu_cc_src
, shm1
);
1356 tcg_temp_free(z_tl
);
1358 /* Get the two potential CC_OP values into temporaries. */
1359 tcg_gen_movi_i32(cpu_tmp2_i32
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1360 if (s
->cc_op
== CC_OP_DYNAMIC
) {
1363 tcg_gen_movi_i32(cpu_tmp3_i32
, s
->cc_op
);
1364 oldop
= cpu_tmp3_i32
;
1367 /* Conditionally store the CC_OP value. */
1368 z32
= tcg_const_i32(0);
1369 s32
= tcg_temp_new_i32();
1370 tcg_gen_trunc_tl_i32(s32
, count
);
1371 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, s32
, z32
, cpu_tmp2_i32
, oldop
);
1372 tcg_temp_free_i32(z32
);
1373 tcg_temp_free_i32(s32
);
1375 /* The CC_OP value is no longer predictable. */
1376 set_cc_op(s
, CC_OP_DYNAMIC
);
1379 static void gen_shift_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1380 int is_right
, int is_arith
)
1382 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1385 if (op1
== OR_TMP0
) {
1386 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1388 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1391 tcg_gen_andi_tl(cpu_T1
, cpu_T1
, mask
);
1392 tcg_gen_subi_tl(cpu_tmp0
, cpu_T1
, 1);
1396 gen_exts(ot
, cpu_T0
);
1397 tcg_gen_sar_tl(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1398 tcg_gen_sar_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1400 gen_extu(ot
, cpu_T0
);
1401 tcg_gen_shr_tl(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1402 tcg_gen_shr_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1405 tcg_gen_shl_tl(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1406 tcg_gen_shl_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1410 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1412 gen_shift_flags(s
, ot
, cpu_T0
, cpu_tmp0
, cpu_T1
, is_right
);
1415 static void gen_shift_rm_im(DisasContext
*s
, TCGMemOp ot
, int op1
, int op2
,
1416 int is_right
, int is_arith
)
1418 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1422 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1424 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1430 gen_exts(ot
, cpu_T0
);
1431 tcg_gen_sari_tl(cpu_tmp4
, cpu_T0
, op2
- 1);
1432 tcg_gen_sari_tl(cpu_T0
, cpu_T0
, op2
);
1434 gen_extu(ot
, cpu_T0
);
1435 tcg_gen_shri_tl(cpu_tmp4
, cpu_T0
, op2
- 1);
1436 tcg_gen_shri_tl(cpu_T0
, cpu_T0
, op2
);
1439 tcg_gen_shli_tl(cpu_tmp4
, cpu_T0
, op2
- 1);
1440 tcg_gen_shli_tl(cpu_T0
, cpu_T0
, op2
);
1445 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1447 /* update eflags if non zero shift */
1449 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
1450 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
1451 set_cc_op(s
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1455 static void gen_rot_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
, int is_right
)
1457 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1461 if (op1
== OR_TMP0
) {
1462 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1464 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1467 tcg_gen_andi_tl(cpu_T1
, cpu_T1
, mask
);
1471 /* Replicate the 8-bit input so that a 32-bit rotate works. */
1472 tcg_gen_ext8u_tl(cpu_T0
, cpu_T0
);
1473 tcg_gen_muli_tl(cpu_T0
, cpu_T0
, 0x01010101);
1476 /* Replicate the 16-bit input so that a 32-bit rotate works. */
1477 tcg_gen_deposit_tl(cpu_T0
, cpu_T0
, cpu_T0
, 16, 16);
1480 #ifdef TARGET_X86_64
1482 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
1483 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T1
);
1485 tcg_gen_rotr_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1487 tcg_gen_rotl_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1489 tcg_gen_extu_i32_tl(cpu_T0
, cpu_tmp2_i32
);
1494 tcg_gen_rotr_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1496 tcg_gen_rotl_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1502 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1504 /* We'll need the flags computed into CC_SRC. */
1505 gen_compute_eflags(s
);
1507 /* The value that was "rotated out" is now present at the other end
1508 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1509 since we've computed the flags into CC_SRC, these variables are
1512 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T0
, mask
- 1);
1513 tcg_gen_shri_tl(cpu_cc_dst
, cpu_T0
, mask
);
1514 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1516 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T0
, mask
);
1517 tcg_gen_andi_tl(cpu_cc_dst
, cpu_T0
, 1);
1519 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1520 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1522 /* Now conditionally store the new CC_OP value. If the shift count
1523 is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1524 Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1525 exactly as we computed above. */
1526 t0
= tcg_const_i32(0);
1527 t1
= tcg_temp_new_i32();
1528 tcg_gen_trunc_tl_i32(t1
, cpu_T1
);
1529 tcg_gen_movi_i32(cpu_tmp2_i32
, CC_OP_ADCOX
);
1530 tcg_gen_movi_i32(cpu_tmp3_i32
, CC_OP_EFLAGS
);
1531 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, t1
, t0
,
1532 cpu_tmp2_i32
, cpu_tmp3_i32
);
1533 tcg_temp_free_i32(t0
);
1534 tcg_temp_free_i32(t1
);
1536 /* The CC_OP value is no longer predictable. */
1537 set_cc_op(s
, CC_OP_DYNAMIC
);
1540 static void gen_rot_rm_im(DisasContext
*s
, TCGMemOp ot
, int op1
, int op2
,
1543 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1547 if (op1
== OR_TMP0
) {
1548 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1550 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1556 #ifdef TARGET_X86_64
1558 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
1560 tcg_gen_rotri_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, op2
);
1562 tcg_gen_rotli_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, op2
);
1564 tcg_gen_extu_i32_tl(cpu_T0
, cpu_tmp2_i32
);
1569 tcg_gen_rotri_tl(cpu_T0
, cpu_T0
, op2
);
1571 tcg_gen_rotli_tl(cpu_T0
, cpu_T0
, op2
);
1582 shift
= mask
+ 1 - shift
;
1584 gen_extu(ot
, cpu_T0
);
1585 tcg_gen_shli_tl(cpu_tmp0
, cpu_T0
, shift
);
1586 tcg_gen_shri_tl(cpu_T0
, cpu_T0
, mask
+ 1 - shift
);
1587 tcg_gen_or_tl(cpu_T0
, cpu_T0
, cpu_tmp0
);
1593 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1596 /* Compute the flags into CC_SRC. */
1597 gen_compute_eflags(s
);
1599 /* The value that was "rotated out" is now present at the other end
1600 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1601 since we've computed the flags into CC_SRC, these variables are
1604 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T0
, mask
- 1);
1605 tcg_gen_shri_tl(cpu_cc_dst
, cpu_T0
, mask
);
1606 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1608 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T0
, mask
);
1609 tcg_gen_andi_tl(cpu_cc_dst
, cpu_T0
, 1);
1611 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1612 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1613 set_cc_op(s
, CC_OP_ADCOX
);
1617 /* XXX: add faster immediate = 1 case */
1618 static void gen_rotc_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1621 gen_compute_eflags(s
);
1622 assert(s
->cc_op
== CC_OP_EFLAGS
);
1626 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1628 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1633 gen_helper_rcrb(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1636 gen_helper_rcrw(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1639 gen_helper_rcrl(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1641 #ifdef TARGET_X86_64
1643 gen_helper_rcrq(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1652 gen_helper_rclb(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1655 gen_helper_rclw(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1658 gen_helper_rcll(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1660 #ifdef TARGET_X86_64
1662 gen_helper_rclq(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1670 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1673 /* XXX: add faster immediate case */
1674 static void gen_shiftd_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1675 bool is_right
, TCGv count_in
)
1677 target_ulong mask
= (ot
== MO_64
? 63 : 31);
1681 if (op1
== OR_TMP0
) {
1682 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1684 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1687 count
= tcg_temp_new();
1688 tcg_gen_andi_tl(count
, count_in
, mask
);
1692 /* Note: we implement the Intel behaviour for shift count > 16.
1693 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A
1694 portion by constructing it as a 32-bit value. */
1696 tcg_gen_deposit_tl(cpu_tmp0
, cpu_T0
, cpu_T1
, 16, 16);
1697 tcg_gen_mov_tl(cpu_T1
, cpu_T0
);
1698 tcg_gen_mov_tl(cpu_T0
, cpu_tmp0
);
1700 tcg_gen_deposit_tl(cpu_T1
, cpu_T0
, cpu_T1
, 16, 16);
1703 #ifdef TARGET_X86_64
1705 /* Concatenate the two 32-bit values and use a 64-bit shift. */
1706 tcg_gen_subi_tl(cpu_tmp0
, count
, 1);
1708 tcg_gen_concat_tl_i64(cpu_T0
, cpu_T0
, cpu_T1
);
1709 tcg_gen_shr_i64(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1710 tcg_gen_shr_i64(cpu_T0
, cpu_T0
, count
);
1712 tcg_gen_concat_tl_i64(cpu_T0
, cpu_T1
, cpu_T0
);
1713 tcg_gen_shl_i64(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1714 tcg_gen_shl_i64(cpu_T0
, cpu_T0
, count
);
1715 tcg_gen_shri_i64(cpu_tmp0
, cpu_tmp0
, 32);
1716 tcg_gen_shri_i64(cpu_T0
, cpu_T0
, 32);
1721 tcg_gen_subi_tl(cpu_tmp0
, count
, 1);
1723 tcg_gen_shr_tl(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1725 tcg_gen_subfi_tl(cpu_tmp4
, mask
+ 1, count
);
1726 tcg_gen_shr_tl(cpu_T0
, cpu_T0
, count
);
1727 tcg_gen_shl_tl(cpu_T1
, cpu_T1
, cpu_tmp4
);
1729 tcg_gen_shl_tl(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1731 /* Only needed if count > 16, for Intel behaviour. */
1732 tcg_gen_subfi_tl(cpu_tmp4
, 33, count
);
1733 tcg_gen_shr_tl(cpu_tmp4
, cpu_T1
, cpu_tmp4
);
1734 tcg_gen_or_tl(cpu_tmp0
, cpu_tmp0
, cpu_tmp4
);
1737 tcg_gen_subfi_tl(cpu_tmp4
, mask
+ 1, count
);
1738 tcg_gen_shl_tl(cpu_T0
, cpu_T0
, count
);
1739 tcg_gen_shr_tl(cpu_T1
, cpu_T1
, cpu_tmp4
);
1741 tcg_gen_movi_tl(cpu_tmp4
, 0);
1742 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_T1
, count
, cpu_tmp4
,
1744 tcg_gen_or_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1749 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1751 gen_shift_flags(s
, ot
, cpu_T0
, cpu_tmp0
, count
, is_right
);
1752 tcg_temp_free(count
);
1755 static void gen_shift(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
, int s
)
1758 gen_op_mov_v_reg(ot
, cpu_T1
, s
);
1761 gen_rot_rm_T1(s1
, ot
, d
, 0);
1764 gen_rot_rm_T1(s1
, ot
, d
, 1);
1768 gen_shift_rm_T1(s1
, ot
, d
, 0, 0);
1771 gen_shift_rm_T1(s1
, ot
, d
, 1, 0);
1774 gen_shift_rm_T1(s1
, ot
, d
, 1, 1);
1777 gen_rotc_rm_T1(s1
, ot
, d
, 0);
1780 gen_rotc_rm_T1(s1
, ot
, d
, 1);
1785 static void gen_shifti(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
, int c
)
1789 gen_rot_rm_im(s1
, ot
, d
, c
, 0);
1792 gen_rot_rm_im(s1
, ot
, d
, c
, 1);
1796 gen_shift_rm_im(s1
, ot
, d
, c
, 0, 0);
1799 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 0);
1802 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 1);
1805 /* currently not optimized */
1806 tcg_gen_movi_tl(cpu_T1
, c
);
1807 gen_shift(s1
, op
, ot
, d
, OR_TMP1
);
1812 /* Decompose an address. */
1814 typedef struct AddressParts
{
1822 static AddressParts
gen_lea_modrm_0(CPUX86State
*env
, DisasContext
*s
,
1825 int def_seg
, base
, index
, scale
, mod
, rm
;
1834 mod
= (modrm
>> 6) & 3;
1836 base
= rm
| REX_B(s
);
1839 /* Normally filtered out earlier, but including this path
1840 simplifies multi-byte nop, as well as bndcl, bndcu, bndcn. */
1849 int code
= cpu_ldub_code(env
, s
->pc
++);
1850 scale
= (code
>> 6) & 3;
1851 index
= ((code
>> 3) & 7) | REX_X(s
);
1853 index
= -1; /* no index */
1855 base
= (code
& 7) | REX_B(s
);
1861 if ((base
& 7) == 5) {
1863 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
1865 if (CODE64(s
) && !havesib
) {
1867 disp
+= s
->pc
+ s
->rip_offset
;
1872 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
1876 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
1881 /* For correct popl handling with esp. */
1882 if (base
== R_ESP
&& s
->popl_esp_hack
) {
1883 disp
+= s
->popl_esp_hack
;
1885 if (base
== R_EBP
|| base
== R_ESP
) {
1894 disp
= cpu_lduw_code(env
, s
->pc
);
1898 } else if (mod
== 1) {
1899 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
1901 disp
= (int16_t)cpu_lduw_code(env
, s
->pc
);
1946 return (AddressParts
){ def_seg
, base
, index
, scale
, disp
};
1949 /* Compute the address, with a minimum number of TCG ops. */
1950 static TCGv
gen_lea_modrm_1(AddressParts a
)
1957 ea
= cpu_regs
[a
.index
];
1959 tcg_gen_shli_tl(cpu_A0
, cpu_regs
[a
.index
], a
.scale
);
1963 tcg_gen_add_tl(cpu_A0
, ea
, cpu_regs
[a
.base
]);
1966 } else if (a
.base
>= 0) {
1967 ea
= cpu_regs
[a
.base
];
1969 if (TCGV_IS_UNUSED(ea
)) {
1970 tcg_gen_movi_tl(cpu_A0
, a
.disp
);
1972 } else if (a
.disp
!= 0) {
1973 tcg_gen_addi_tl(cpu_A0
, ea
, a
.disp
);
1980 static void gen_lea_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
1982 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
1983 TCGv ea
= gen_lea_modrm_1(a
);
1984 gen_lea_v_seg(s
, s
->aflag
, ea
, a
.def_seg
, s
->override
);
1987 static void gen_nop_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
1989 (void)gen_lea_modrm_0(env
, s
, modrm
);
1992 /* Used for BNDCL, BNDCU, BNDCN. */
1993 static void gen_bndck(CPUX86State
*env
, DisasContext
*s
, int modrm
,
1994 TCGCond cond
, TCGv_i64 bndv
)
1996 TCGv ea
= gen_lea_modrm_1(gen_lea_modrm_0(env
, s
, modrm
));
1998 tcg_gen_extu_tl_i64(cpu_tmp1_i64
, ea
);
2000 tcg_gen_ext32u_i64(cpu_tmp1_i64
, cpu_tmp1_i64
);
2002 tcg_gen_setcond_i64(cond
, cpu_tmp1_i64
, cpu_tmp1_i64
, bndv
);
2003 tcg_gen_extrl_i64_i32(cpu_tmp2_i32
, cpu_tmp1_i64
);
2004 gen_helper_bndck(cpu_env
, cpu_tmp2_i32
);
2007 /* used for LEA and MOV AX, mem */
2008 static void gen_add_A0_ds_seg(DisasContext
*s
)
2010 gen_lea_v_seg(s
, s
->aflag
, cpu_A0
, R_DS
, s
->override
);
2013 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2015 static void gen_ldst_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2016 TCGMemOp ot
, int reg
, int is_store
)
2020 mod
= (modrm
>> 6) & 3;
2021 rm
= (modrm
& 7) | REX_B(s
);
2025 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
2026 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
2028 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
2030 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
2033 gen_lea_modrm(env
, s
, modrm
);
2036 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
2037 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
2039 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
2041 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
2046 static inline uint32_t insn_get(CPUX86State
*env
, DisasContext
*s
, TCGMemOp ot
)
2052 ret
= cpu_ldub_code(env
, s
->pc
);
2056 ret
= cpu_lduw_code(env
, s
->pc
);
2060 #ifdef TARGET_X86_64
2063 ret
= cpu_ldl_code(env
, s
->pc
);
2072 static inline int insn_const_size(TCGMemOp ot
)
2081 static inline void gen_goto_tb(DisasContext
*s
, int tb_num
, target_ulong eip
)
2083 TranslationBlock
*tb
;
2086 pc
= s
->cs_base
+ eip
;
2088 /* NOTE: we handle the case where the TB spans two pages here */
2089 if ((pc
& TARGET_PAGE_MASK
) == (tb
->pc
& TARGET_PAGE_MASK
) ||
2090 (pc
& TARGET_PAGE_MASK
) == ((s
->pc
- 1) & TARGET_PAGE_MASK
)) {
2091 /* jump to same page: we can use a direct jump */
2092 tcg_gen_goto_tb(tb_num
);
2094 tcg_gen_exit_tb((uintptr_t)tb
+ tb_num
);
2096 /* jump to another page: currently not optimized */
2102 static inline void gen_jcc(DisasContext
*s
, int b
,
2103 target_ulong val
, target_ulong next_eip
)
2108 l1
= gen_new_label();
2111 gen_goto_tb(s
, 0, next_eip
);
2114 gen_goto_tb(s
, 1, val
);
2115 s
->is_jmp
= DISAS_TB_JUMP
;
2117 l1
= gen_new_label();
2118 l2
= gen_new_label();
2121 gen_jmp_im(next_eip
);
2131 static void gen_cmovcc1(CPUX86State
*env
, DisasContext
*s
, TCGMemOp ot
, int b
,
2136 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
2138 cc
= gen_prepare_cc(s
, b
, cpu_T1
);
2139 if (cc
.mask
!= -1) {
2140 TCGv t0
= tcg_temp_new();
2141 tcg_gen_andi_tl(t0
, cc
.reg
, cc
.mask
);
2145 cc
.reg2
= tcg_const_tl(cc
.imm
);
2148 tcg_gen_movcond_tl(cc
.cond
, cpu_T0
, cc
.reg
, cc
.reg2
,
2149 cpu_T0
, cpu_regs
[reg
]);
2150 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
2152 if (cc
.mask
!= -1) {
2153 tcg_temp_free(cc
.reg
);
2156 tcg_temp_free(cc
.reg2
);
2160 static inline void gen_op_movl_T0_seg(int seg_reg
)
2162 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
,
2163 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2166 static inline void gen_op_movl_seg_T0_vm(int seg_reg
)
2168 tcg_gen_ext16u_tl(cpu_T0
, cpu_T0
);
2169 tcg_gen_st32_tl(cpu_T0
, cpu_env
,
2170 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2171 tcg_gen_shli_tl(cpu_seg_base
[seg_reg
], cpu_T0
, 4);
2174 /* move T0 to seg_reg and compute if the CPU state may change. Never
2175 call this function with seg_reg == R_CS */
2176 static void gen_movl_seg_T0(DisasContext
*s
, int seg_reg
)
2178 if (s
->pe
&& !s
->vm86
) {
2179 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
2180 gen_helper_load_seg(cpu_env
, tcg_const_i32(seg_reg
), cpu_tmp2_i32
);
2181 /* abort translation because the addseg value may change or
2182 because ss32 may change. For R_SS, translation must always
2183 stop as a special handling must be done to disable hardware
2184 interrupts for the next instruction */
2185 if (seg_reg
== R_SS
|| (s
->code32
&& seg_reg
< R_FS
))
2186 s
->is_jmp
= DISAS_TB_JUMP
;
2188 gen_op_movl_seg_T0_vm(seg_reg
);
2189 if (seg_reg
== R_SS
)
2190 s
->is_jmp
= DISAS_TB_JUMP
;
2194 static inline int svm_is_rep(int prefixes
)
2196 return ((prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) ? 8 : 0);
2200 gen_svm_check_intercept_param(DisasContext
*s
, target_ulong pc_start
,
2201 uint32_t type
, uint64_t param
)
2203 /* no SVM activated; fast case */
2204 if (likely(!(s
->flags
& HF_SVMI_MASK
)))
2206 gen_update_cc_op(s
);
2207 gen_jmp_im(pc_start
- s
->cs_base
);
2208 gen_helper_svm_check_intercept_param(cpu_env
, tcg_const_i32(type
),
2209 tcg_const_i64(param
));
2213 gen_svm_check_intercept(DisasContext
*s
, target_ulong pc_start
, uint64_t type
)
2215 gen_svm_check_intercept_param(s
, pc_start
, type
, 0);
2218 static inline void gen_stack_update(DisasContext
*s
, int addend
)
2220 gen_op_add_reg_im(mo_stacksize(s
), R_ESP
, addend
);
2223 /* Generate a push. It depends on ss32, addseg and dflag. */
2224 static void gen_push_v(DisasContext
*s
, TCGv val
)
2226 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2227 TCGMemOp a_ot
= mo_stacksize(s
);
2228 int size
= 1 << d_ot
;
2229 TCGv new_esp
= cpu_A0
;
2231 tcg_gen_subi_tl(cpu_A0
, cpu_regs
[R_ESP
], size
);
2236 tcg_gen_mov_tl(new_esp
, cpu_A0
);
2238 gen_lea_v_seg(s
, a_ot
, cpu_A0
, R_SS
, -1);
2241 gen_op_st_v(s
, d_ot
, val
, cpu_A0
);
2242 gen_op_mov_reg_v(a_ot
, R_ESP
, new_esp
);
2245 /* two step pop is necessary for precise exceptions */
2246 static TCGMemOp
gen_pop_T0(DisasContext
*s
)
2248 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2250 gen_lea_v_seg(s
, mo_stacksize(s
), cpu_regs
[R_ESP
], R_SS
, -1);
2251 gen_op_ld_v(s
, d_ot
, cpu_T0
, cpu_A0
);
2256 static inline void gen_pop_update(DisasContext
*s
, TCGMemOp ot
)
2258 gen_stack_update(s
, 1 << ot
);
2261 static inline void gen_stack_A0(DisasContext
*s
)
2263 gen_lea_v_seg(s
, s
->ss32
? MO_32
: MO_16
, cpu_regs
[R_ESP
], R_SS
, -1);
2266 static void gen_pusha(DisasContext
*s
)
2268 TCGMemOp s_ot
= s
->ss32
? MO_32
: MO_16
;
2269 TCGMemOp d_ot
= s
->dflag
;
2270 int size
= 1 << d_ot
;
2273 for (i
= 0; i
< 8; i
++) {
2274 tcg_gen_addi_tl(cpu_A0
, cpu_regs
[R_ESP
], (i
- 8) * size
);
2275 gen_lea_v_seg(s
, s_ot
, cpu_A0
, R_SS
, -1);
2276 gen_op_st_v(s
, d_ot
, cpu_regs
[7 - i
], cpu_A0
);
2279 gen_stack_update(s
, -8 * size
);
2282 static void gen_popa(DisasContext
*s
)
2284 TCGMemOp s_ot
= s
->ss32
? MO_32
: MO_16
;
2285 TCGMemOp d_ot
= s
->dflag
;
2286 int size
= 1 << d_ot
;
2289 for (i
= 0; i
< 8; i
++) {
2290 /* ESP is not reloaded */
2291 if (7 - i
== R_ESP
) {
2294 tcg_gen_addi_tl(cpu_A0
, cpu_regs
[R_ESP
], i
* size
);
2295 gen_lea_v_seg(s
, s_ot
, cpu_A0
, R_SS
, -1);
2296 gen_op_ld_v(s
, d_ot
, cpu_T0
, cpu_A0
);
2297 gen_op_mov_reg_v(d_ot
, 7 - i
, cpu_T0
);
2300 gen_stack_update(s
, 8 * size
);
2303 static void gen_enter(DisasContext
*s
, int esp_addend
, int level
)
2305 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2306 TCGMemOp a_ot
= CODE64(s
) ? MO_64
: s
->ss32
? MO_32
: MO_16
;
2307 int size
= 1 << d_ot
;
2309 /* Push BP; compute FrameTemp into T1. */
2310 tcg_gen_subi_tl(cpu_T1
, cpu_regs
[R_ESP
], size
);
2311 gen_lea_v_seg(s
, a_ot
, cpu_T1
, R_SS
, -1);
2312 gen_op_st_v(s
, d_ot
, cpu_regs
[R_EBP
], cpu_A0
);
2318 /* Copy level-1 pointers from the previous frame. */
2319 for (i
= 1; i
< level
; ++i
) {
2320 tcg_gen_subi_tl(cpu_A0
, cpu_regs
[R_EBP
], size
* i
);
2321 gen_lea_v_seg(s
, a_ot
, cpu_A0
, R_SS
, -1);
2322 gen_op_ld_v(s
, d_ot
, cpu_tmp0
, cpu_A0
);
2324 tcg_gen_subi_tl(cpu_A0
, cpu_T1
, size
* i
);
2325 gen_lea_v_seg(s
, a_ot
, cpu_A0
, R_SS
, -1);
2326 gen_op_st_v(s
, d_ot
, cpu_tmp0
, cpu_A0
);
2329 /* Push the current FrameTemp as the last level. */
2330 tcg_gen_subi_tl(cpu_A0
, cpu_T1
, size
* level
);
2331 gen_lea_v_seg(s
, a_ot
, cpu_A0
, R_SS
, -1);
2332 gen_op_st_v(s
, d_ot
, cpu_T1
, cpu_A0
);
2335 /* Copy the FrameTemp value to EBP. */
2336 gen_op_mov_reg_v(a_ot
, R_EBP
, cpu_T1
);
2338 /* Compute the final value of ESP. */
2339 tcg_gen_subi_tl(cpu_T1
, cpu_T1
, esp_addend
+ size
* level
);
2340 gen_op_mov_reg_v(a_ot
, R_ESP
, cpu_T1
);
2343 static void gen_leave(DisasContext
*s
)
2345 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2346 TCGMemOp a_ot
= mo_stacksize(s
);
2348 gen_lea_v_seg(s
, a_ot
, cpu_regs
[R_EBP
], R_SS
, -1);
2349 gen_op_ld_v(s
, d_ot
, cpu_T0
, cpu_A0
);
2351 tcg_gen_addi_tl(cpu_T1
, cpu_regs
[R_EBP
], 1 << d_ot
);
2353 gen_op_mov_reg_v(d_ot
, R_EBP
, cpu_T0
);
2354 gen_op_mov_reg_v(a_ot
, R_ESP
, cpu_T1
);
2357 static void gen_exception(DisasContext
*s
, int trapno
, target_ulong cur_eip
)
2359 gen_update_cc_op(s
);
2360 gen_jmp_im(cur_eip
);
2361 gen_helper_raise_exception(cpu_env
, tcg_const_i32(trapno
));
2362 s
->is_jmp
= DISAS_TB_JUMP
;
2365 /* an interrupt is different from an exception because of the
2367 static void gen_interrupt(DisasContext
*s
, int intno
,
2368 target_ulong cur_eip
, target_ulong next_eip
)
2370 gen_update_cc_op(s
);
2371 gen_jmp_im(cur_eip
);
2372 gen_helper_raise_interrupt(cpu_env
, tcg_const_i32(intno
),
2373 tcg_const_i32(next_eip
- cur_eip
));
2374 s
->is_jmp
= DISAS_TB_JUMP
;
2377 static void gen_debug(DisasContext
*s
, target_ulong cur_eip
)
2379 gen_update_cc_op(s
);
2380 gen_jmp_im(cur_eip
);
2381 gen_helper_debug(cpu_env
);
2382 s
->is_jmp
= DISAS_TB_JUMP
;
2385 static void gen_set_hflag(DisasContext
*s
, uint32_t mask
)
2387 if ((s
->flags
& mask
) == 0) {
2388 TCGv_i32 t
= tcg_temp_new_i32();
2389 tcg_gen_ld_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2390 tcg_gen_ori_i32(t
, t
, mask
);
2391 tcg_gen_st_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2392 tcg_temp_free_i32(t
);
2397 static void gen_reset_hflag(DisasContext
*s
, uint32_t mask
)
2399 if (s
->flags
& mask
) {
2400 TCGv_i32 t
= tcg_temp_new_i32();
2401 tcg_gen_ld_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2402 tcg_gen_andi_i32(t
, t
, ~mask
);
2403 tcg_gen_st_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2404 tcg_temp_free_i32(t
);
2409 /* Clear BND registers during legacy branches. */
2410 static void gen_bnd_jmp(DisasContext
*s
)
2412 /* Do nothing if BND prefix present, MPX is disabled, or if the
2413 BNDREGs are known to be in INIT state already. The helper
2414 itself will check BNDPRESERVE at runtime. */
2415 if ((s
->prefix
& PREFIX_REPNZ
) == 0
2416 && (s
->flags
& HF_MPX_EN_MASK
) == 0
2417 && (s
->flags
& HF_MPX_IU_MASK
) == 0) {
2418 gen_helper_bnd_jmp(cpu_env
);
2422 /* generate a generic end of block. Trace exception is also generated
2424 static void gen_eob(DisasContext
*s
)
2426 gen_update_cc_op(s
);
2427 gen_reset_hflag(s
, HF_INHIBIT_IRQ_MASK
);
2428 if (s
->tb
->flags
& HF_RF_MASK
) {
2429 gen_helper_reset_rf(cpu_env
);
2431 if (s
->singlestep_enabled
) {
2432 gen_helper_debug(cpu_env
);
2434 gen_helper_single_step(cpu_env
);
2438 s
->is_jmp
= DISAS_TB_JUMP
;
2441 /* generate a jump to eip. No segment change must happen before as a
2442 direct call to the next block may occur */
2443 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
)
2445 gen_update_cc_op(s
);
2446 set_cc_op(s
, CC_OP_DYNAMIC
);
2448 gen_goto_tb(s
, tb_num
, eip
);
2449 s
->is_jmp
= DISAS_TB_JUMP
;
2456 static void gen_jmp(DisasContext
*s
, target_ulong eip
)
2458 gen_jmp_tb(s
, eip
, 0);
2461 static inline void gen_ldq_env_A0(DisasContext
*s
, int offset
)
2463 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
2464 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2467 static inline void gen_stq_env_A0(DisasContext
*s
, int offset
)
2469 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2470 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
2473 static inline void gen_ldo_env_A0(DisasContext
*s
, int offset
)
2475 int mem_index
= s
->mem_index
;
2476 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, mem_index
, MO_LEQ
);
2477 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2478 tcg_gen_addi_tl(cpu_tmp0
, cpu_A0
, 8);
2479 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
, MO_LEQ
);
2480 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2483 static inline void gen_sto_env_A0(DisasContext
*s
, int offset
)
2485 int mem_index
= s
->mem_index
;
2486 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2487 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, mem_index
, MO_LEQ
);
2488 tcg_gen_addi_tl(cpu_tmp0
, cpu_A0
, 8);
2489 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2490 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
, MO_LEQ
);
2493 static inline void gen_op_movo(int d_offset
, int s_offset
)
2495 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2496 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2497 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2498 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2501 static inline void gen_op_movq(int d_offset
, int s_offset
)
2503 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
);
2504 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2507 static inline void gen_op_movl(int d_offset
, int s_offset
)
2509 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
, s_offset
);
2510 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, d_offset
);
2513 static inline void gen_op_movq_env_0(int d_offset
)
2515 tcg_gen_movi_i64(cpu_tmp1_i64
, 0);
2516 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2519 typedef void (*SSEFunc_i_ep
)(TCGv_i32 val
, TCGv_ptr env
, TCGv_ptr reg
);
2520 typedef void (*SSEFunc_l_ep
)(TCGv_i64 val
, TCGv_ptr env
, TCGv_ptr reg
);
2521 typedef void (*SSEFunc_0_epi
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i32 val
);
2522 typedef void (*SSEFunc_0_epl
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i64 val
);
2523 typedef void (*SSEFunc_0_epp
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
);
2524 typedef void (*SSEFunc_0_eppi
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2526 typedef void (*SSEFunc_0_ppi
)(TCGv_ptr reg_a
, TCGv_ptr reg_b
, TCGv_i32 val
);
2527 typedef void (*SSEFunc_0_eppt
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2530 #define SSE_SPECIAL ((void *)1)
2531 #define SSE_DUMMY ((void *)2)
2533 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2534 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2535 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2537 static const SSEFunc_0_epp sse_op_table1
[256][4] = {
2538 /* 3DNow! extensions */
2539 [0x0e] = { SSE_DUMMY
}, /* femms */
2540 [0x0f] = { SSE_DUMMY
}, /* pf... */
2541 /* pure SSE operations */
2542 [0x10] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2543 [0x11] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2544 [0x12] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd, movsldup, movddup */
2545 [0x13] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd */
2546 [0x14] = { gen_helper_punpckldq_xmm
, gen_helper_punpcklqdq_xmm
},
2547 [0x15] = { gen_helper_punpckhdq_xmm
, gen_helper_punpckhqdq_xmm
},
2548 [0x16] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd, movshdup */
2549 [0x17] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd */
2551 [0x28] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2552 [0x29] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2553 [0x2a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2554 [0x2b] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movntps, movntpd, movntss, movntsd */
2555 [0x2c] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2556 [0x2d] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2557 [0x2e] = { gen_helper_ucomiss
, gen_helper_ucomisd
},
2558 [0x2f] = { gen_helper_comiss
, gen_helper_comisd
},
2559 [0x50] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movmskps, movmskpd */
2560 [0x51] = SSE_FOP(sqrt
),
2561 [0x52] = { gen_helper_rsqrtps
, NULL
, gen_helper_rsqrtss
, NULL
},
2562 [0x53] = { gen_helper_rcpps
, NULL
, gen_helper_rcpss
, NULL
},
2563 [0x54] = { gen_helper_pand_xmm
, gen_helper_pand_xmm
}, /* andps, andpd */
2564 [0x55] = { gen_helper_pandn_xmm
, gen_helper_pandn_xmm
}, /* andnps, andnpd */
2565 [0x56] = { gen_helper_por_xmm
, gen_helper_por_xmm
}, /* orps, orpd */
2566 [0x57] = { gen_helper_pxor_xmm
, gen_helper_pxor_xmm
}, /* xorps, xorpd */
2567 [0x58] = SSE_FOP(add
),
2568 [0x59] = SSE_FOP(mul
),
2569 [0x5a] = { gen_helper_cvtps2pd
, gen_helper_cvtpd2ps
,
2570 gen_helper_cvtss2sd
, gen_helper_cvtsd2ss
},
2571 [0x5b] = { gen_helper_cvtdq2ps
, gen_helper_cvtps2dq
, gen_helper_cvttps2dq
},
2572 [0x5c] = SSE_FOP(sub
),
2573 [0x5d] = SSE_FOP(min
),
2574 [0x5e] = SSE_FOP(div
),
2575 [0x5f] = SSE_FOP(max
),
2577 [0xc2] = SSE_FOP(cmpeq
),
2578 [0xc6] = { (SSEFunc_0_epp
)gen_helper_shufps
,
2579 (SSEFunc_0_epp
)gen_helper_shufpd
}, /* XXX: casts */
2581 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */
2582 [0x38] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2583 [0x3a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2585 /* MMX ops and their SSE extensions */
2586 [0x60] = MMX_OP2(punpcklbw
),
2587 [0x61] = MMX_OP2(punpcklwd
),
2588 [0x62] = MMX_OP2(punpckldq
),
2589 [0x63] = MMX_OP2(packsswb
),
2590 [0x64] = MMX_OP2(pcmpgtb
),
2591 [0x65] = MMX_OP2(pcmpgtw
),
2592 [0x66] = MMX_OP2(pcmpgtl
),
2593 [0x67] = MMX_OP2(packuswb
),
2594 [0x68] = MMX_OP2(punpckhbw
),
2595 [0x69] = MMX_OP2(punpckhwd
),
2596 [0x6a] = MMX_OP2(punpckhdq
),
2597 [0x6b] = MMX_OP2(packssdw
),
2598 [0x6c] = { NULL
, gen_helper_punpcklqdq_xmm
},
2599 [0x6d] = { NULL
, gen_helper_punpckhqdq_xmm
},
2600 [0x6e] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movd mm, ea */
2601 [0x6f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, , movqdu */
2602 [0x70] = { (SSEFunc_0_epp
)gen_helper_pshufw_mmx
,
2603 (SSEFunc_0_epp
)gen_helper_pshufd_xmm
,
2604 (SSEFunc_0_epp
)gen_helper_pshufhw_xmm
,
2605 (SSEFunc_0_epp
)gen_helper_pshuflw_xmm
}, /* XXX: casts */
2606 [0x71] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftw */
2607 [0x72] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftd */
2608 [0x73] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftq */
2609 [0x74] = MMX_OP2(pcmpeqb
),
2610 [0x75] = MMX_OP2(pcmpeqw
),
2611 [0x76] = MMX_OP2(pcmpeql
),
2612 [0x77] = { SSE_DUMMY
}, /* emms */
2613 [0x78] = { NULL
, SSE_SPECIAL
, NULL
, SSE_SPECIAL
}, /* extrq_i, insertq_i */
2614 [0x79] = { NULL
, gen_helper_extrq_r
, NULL
, gen_helper_insertq_r
},
2615 [0x7c] = { NULL
, gen_helper_haddpd
, NULL
, gen_helper_haddps
},
2616 [0x7d] = { NULL
, gen_helper_hsubpd
, NULL
, gen_helper_hsubps
},
2617 [0x7e] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movd, movd, , movq */
2618 [0x7f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, movdqu */
2619 [0xc4] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pinsrw */
2620 [0xc5] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pextrw */
2621 [0xd0] = { NULL
, gen_helper_addsubpd
, NULL
, gen_helper_addsubps
},
2622 [0xd1] = MMX_OP2(psrlw
),
2623 [0xd2] = MMX_OP2(psrld
),
2624 [0xd3] = MMX_OP2(psrlq
),
2625 [0xd4] = MMX_OP2(paddq
),
2626 [0xd5] = MMX_OP2(pmullw
),
2627 [0xd6] = { NULL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2628 [0xd7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pmovmskb */
2629 [0xd8] = MMX_OP2(psubusb
),
2630 [0xd9] = MMX_OP2(psubusw
),
2631 [0xda] = MMX_OP2(pminub
),
2632 [0xdb] = MMX_OP2(pand
),
2633 [0xdc] = MMX_OP2(paddusb
),
2634 [0xdd] = MMX_OP2(paddusw
),
2635 [0xde] = MMX_OP2(pmaxub
),
2636 [0xdf] = MMX_OP2(pandn
),
2637 [0xe0] = MMX_OP2(pavgb
),
2638 [0xe1] = MMX_OP2(psraw
),
2639 [0xe2] = MMX_OP2(psrad
),
2640 [0xe3] = MMX_OP2(pavgw
),
2641 [0xe4] = MMX_OP2(pmulhuw
),
2642 [0xe5] = MMX_OP2(pmulhw
),
2643 [0xe6] = { NULL
, gen_helper_cvttpd2dq
, gen_helper_cvtdq2pd
, gen_helper_cvtpd2dq
},
2644 [0xe7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movntq, movntq */
2645 [0xe8] = MMX_OP2(psubsb
),
2646 [0xe9] = MMX_OP2(psubsw
),
2647 [0xea] = MMX_OP2(pminsw
),
2648 [0xeb] = MMX_OP2(por
),
2649 [0xec] = MMX_OP2(paddsb
),
2650 [0xed] = MMX_OP2(paddsw
),
2651 [0xee] = MMX_OP2(pmaxsw
),
2652 [0xef] = MMX_OP2(pxor
),
2653 [0xf0] = { NULL
, NULL
, NULL
, SSE_SPECIAL
}, /* lddqu */
2654 [0xf1] = MMX_OP2(psllw
),
2655 [0xf2] = MMX_OP2(pslld
),
2656 [0xf3] = MMX_OP2(psllq
),
2657 [0xf4] = MMX_OP2(pmuludq
),
2658 [0xf5] = MMX_OP2(pmaddwd
),
2659 [0xf6] = MMX_OP2(psadbw
),
2660 [0xf7] = { (SSEFunc_0_epp
)gen_helper_maskmov_mmx
,
2661 (SSEFunc_0_epp
)gen_helper_maskmov_xmm
}, /* XXX: casts */
2662 [0xf8] = MMX_OP2(psubb
),
2663 [0xf9] = MMX_OP2(psubw
),
2664 [0xfa] = MMX_OP2(psubl
),
2665 [0xfb] = MMX_OP2(psubq
),
2666 [0xfc] = MMX_OP2(paddb
),
2667 [0xfd] = MMX_OP2(paddw
),
2668 [0xfe] = MMX_OP2(paddl
),
2671 static const SSEFunc_0_epp sse_op_table2
[3 * 8][2] = {
2672 [0 + 2] = MMX_OP2(psrlw
),
2673 [0 + 4] = MMX_OP2(psraw
),
2674 [0 + 6] = MMX_OP2(psllw
),
2675 [8 + 2] = MMX_OP2(psrld
),
2676 [8 + 4] = MMX_OP2(psrad
),
2677 [8 + 6] = MMX_OP2(pslld
),
2678 [16 + 2] = MMX_OP2(psrlq
),
2679 [16 + 3] = { NULL
, gen_helper_psrldq_xmm
},
2680 [16 + 6] = MMX_OP2(psllq
),
2681 [16 + 7] = { NULL
, gen_helper_pslldq_xmm
},
2684 static const SSEFunc_0_epi sse_op_table3ai
[] = {
2685 gen_helper_cvtsi2ss
,
2689 #ifdef TARGET_X86_64
2690 static const SSEFunc_0_epl sse_op_table3aq
[] = {
2691 gen_helper_cvtsq2ss
,
2696 static const SSEFunc_i_ep sse_op_table3bi
[] = {
2697 gen_helper_cvttss2si
,
2698 gen_helper_cvtss2si
,
2699 gen_helper_cvttsd2si
,
2703 #ifdef TARGET_X86_64
2704 static const SSEFunc_l_ep sse_op_table3bq
[] = {
2705 gen_helper_cvttss2sq
,
2706 gen_helper_cvtss2sq
,
2707 gen_helper_cvttsd2sq
,
2712 static const SSEFunc_0_epp sse_op_table4
[8][4] = {
2723 static const SSEFunc_0_epp sse_op_table5
[256] = {
2724 [0x0c] = gen_helper_pi2fw
,
2725 [0x0d] = gen_helper_pi2fd
,
2726 [0x1c] = gen_helper_pf2iw
,
2727 [0x1d] = gen_helper_pf2id
,
2728 [0x8a] = gen_helper_pfnacc
,
2729 [0x8e] = gen_helper_pfpnacc
,
2730 [0x90] = gen_helper_pfcmpge
,
2731 [0x94] = gen_helper_pfmin
,
2732 [0x96] = gen_helper_pfrcp
,
2733 [0x97] = gen_helper_pfrsqrt
,
2734 [0x9a] = gen_helper_pfsub
,
2735 [0x9e] = gen_helper_pfadd
,
2736 [0xa0] = gen_helper_pfcmpgt
,
2737 [0xa4] = gen_helper_pfmax
,
2738 [0xa6] = gen_helper_movq
, /* pfrcpit1; no need to actually increase precision */
2739 [0xa7] = gen_helper_movq
, /* pfrsqit1 */
2740 [0xaa] = gen_helper_pfsubr
,
2741 [0xae] = gen_helper_pfacc
,
2742 [0xb0] = gen_helper_pfcmpeq
,
2743 [0xb4] = gen_helper_pfmul
,
2744 [0xb6] = gen_helper_movq
, /* pfrcpit2 */
2745 [0xb7] = gen_helper_pmulhrw_mmx
,
2746 [0xbb] = gen_helper_pswapd
,
2747 [0xbf] = gen_helper_pavgb_mmx
/* pavgusb */
2750 struct SSEOpHelper_epp
{
2751 SSEFunc_0_epp op
[2];
2755 struct SSEOpHelper_eppi
{
2756 SSEFunc_0_eppi op
[2];
2760 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
2761 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
2762 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
2763 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
2764 #define PCLMULQDQ_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, \
2765 CPUID_EXT_PCLMULQDQ }
2766 #define AESNI_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_AES }
2768 static const struct SSEOpHelper_epp sse_op_table6
[256] = {
2769 [0x00] = SSSE3_OP(pshufb
),
2770 [0x01] = SSSE3_OP(phaddw
),
2771 [0x02] = SSSE3_OP(phaddd
),
2772 [0x03] = SSSE3_OP(phaddsw
),
2773 [0x04] = SSSE3_OP(pmaddubsw
),
2774 [0x05] = SSSE3_OP(phsubw
),
2775 [0x06] = SSSE3_OP(phsubd
),
2776 [0x07] = SSSE3_OP(phsubsw
),
2777 [0x08] = SSSE3_OP(psignb
),
2778 [0x09] = SSSE3_OP(psignw
),
2779 [0x0a] = SSSE3_OP(psignd
),
2780 [0x0b] = SSSE3_OP(pmulhrsw
),
2781 [0x10] = SSE41_OP(pblendvb
),
2782 [0x14] = SSE41_OP(blendvps
),
2783 [0x15] = SSE41_OP(blendvpd
),
2784 [0x17] = SSE41_OP(ptest
),
2785 [0x1c] = SSSE3_OP(pabsb
),
2786 [0x1d] = SSSE3_OP(pabsw
),
2787 [0x1e] = SSSE3_OP(pabsd
),
2788 [0x20] = SSE41_OP(pmovsxbw
),
2789 [0x21] = SSE41_OP(pmovsxbd
),
2790 [0x22] = SSE41_OP(pmovsxbq
),
2791 [0x23] = SSE41_OP(pmovsxwd
),
2792 [0x24] = SSE41_OP(pmovsxwq
),
2793 [0x25] = SSE41_OP(pmovsxdq
),
2794 [0x28] = SSE41_OP(pmuldq
),
2795 [0x29] = SSE41_OP(pcmpeqq
),
2796 [0x2a] = SSE41_SPECIAL
, /* movntqda */
2797 [0x2b] = SSE41_OP(packusdw
),
2798 [0x30] = SSE41_OP(pmovzxbw
),
2799 [0x31] = SSE41_OP(pmovzxbd
),
2800 [0x32] = SSE41_OP(pmovzxbq
),
2801 [0x33] = SSE41_OP(pmovzxwd
),
2802 [0x34] = SSE41_OP(pmovzxwq
),
2803 [0x35] = SSE41_OP(pmovzxdq
),
2804 [0x37] = SSE42_OP(pcmpgtq
),
2805 [0x38] = SSE41_OP(pminsb
),
2806 [0x39] = SSE41_OP(pminsd
),
2807 [0x3a] = SSE41_OP(pminuw
),
2808 [0x3b] = SSE41_OP(pminud
),
2809 [0x3c] = SSE41_OP(pmaxsb
),
2810 [0x3d] = SSE41_OP(pmaxsd
),
2811 [0x3e] = SSE41_OP(pmaxuw
),
2812 [0x3f] = SSE41_OP(pmaxud
),
2813 [0x40] = SSE41_OP(pmulld
),
2814 [0x41] = SSE41_OP(phminposuw
),
2815 [0xdb] = AESNI_OP(aesimc
),
2816 [0xdc] = AESNI_OP(aesenc
),
2817 [0xdd] = AESNI_OP(aesenclast
),
2818 [0xde] = AESNI_OP(aesdec
),
2819 [0xdf] = AESNI_OP(aesdeclast
),
2822 static const struct SSEOpHelper_eppi sse_op_table7
[256] = {
2823 [0x08] = SSE41_OP(roundps
),
2824 [0x09] = SSE41_OP(roundpd
),
2825 [0x0a] = SSE41_OP(roundss
),
2826 [0x0b] = SSE41_OP(roundsd
),
2827 [0x0c] = SSE41_OP(blendps
),
2828 [0x0d] = SSE41_OP(blendpd
),
2829 [0x0e] = SSE41_OP(pblendw
),
2830 [0x0f] = SSSE3_OP(palignr
),
2831 [0x14] = SSE41_SPECIAL
, /* pextrb */
2832 [0x15] = SSE41_SPECIAL
, /* pextrw */
2833 [0x16] = SSE41_SPECIAL
, /* pextrd/pextrq */
2834 [0x17] = SSE41_SPECIAL
, /* extractps */
2835 [0x20] = SSE41_SPECIAL
, /* pinsrb */
2836 [0x21] = SSE41_SPECIAL
, /* insertps */
2837 [0x22] = SSE41_SPECIAL
, /* pinsrd/pinsrq */
2838 [0x40] = SSE41_OP(dpps
),
2839 [0x41] = SSE41_OP(dppd
),
2840 [0x42] = SSE41_OP(mpsadbw
),
2841 [0x44] = PCLMULQDQ_OP(pclmulqdq
),
2842 [0x60] = SSE42_OP(pcmpestrm
),
2843 [0x61] = SSE42_OP(pcmpestri
),
2844 [0x62] = SSE42_OP(pcmpistrm
),
2845 [0x63] = SSE42_OP(pcmpistri
),
2846 [0xdf] = AESNI_OP(aeskeygenassist
),
2849 static void gen_sse(CPUX86State
*env
, DisasContext
*s
, int b
,
2850 target_ulong pc_start
, int rex_r
)
2852 int b1
, op1_offset
, op2_offset
, is_xmm
, val
;
2853 int modrm
, mod
, rm
, reg
;
2854 SSEFunc_0_epp sse_fn_epp
;
2855 SSEFunc_0_eppi sse_fn_eppi
;
2856 SSEFunc_0_ppi sse_fn_ppi
;
2857 SSEFunc_0_eppt sse_fn_eppt
;
2861 if (s
->prefix
& PREFIX_DATA
)
2863 else if (s
->prefix
& PREFIX_REPZ
)
2865 else if (s
->prefix
& PREFIX_REPNZ
)
2869 sse_fn_epp
= sse_op_table1
[b
][b1
];
2873 if ((b
<= 0x5f && b
>= 0x10) || b
== 0xc6 || b
== 0xc2) {
2883 /* simple MMX/SSE operation */
2884 if (s
->flags
& HF_TS_MASK
) {
2885 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
2888 if (s
->flags
& HF_EM_MASK
) {
2890 gen_exception(s
, EXCP06_ILLOP
, pc_start
- s
->cs_base
);
2893 if (is_xmm
&& !(s
->flags
& HF_OSFXSR_MASK
))
2894 if ((b
!= 0x38 && b
!= 0x3a) || (s
->prefix
& PREFIX_DATA
))
2897 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
))
2900 gen_helper_emms(cpu_env
);
2905 gen_helper_emms(cpu_env
);
2908 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
2909 the static cpu state) */
2911 gen_helper_enter_mmx(cpu_env
);
2914 modrm
= cpu_ldub_code(env
, s
->pc
++);
2915 reg
= ((modrm
>> 3) & 7);
2918 mod
= (modrm
>> 6) & 3;
2919 if (sse_fn_epp
== SSE_SPECIAL
) {
2922 case 0x0e7: /* movntq */
2925 gen_lea_modrm(env
, s
, modrm
);
2926 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
2928 case 0x1e7: /* movntdq */
2929 case 0x02b: /* movntps */
2930 case 0x12b: /* movntps */
2933 gen_lea_modrm(env
, s
, modrm
);
2934 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
2936 case 0x3f0: /* lddqu */
2939 gen_lea_modrm(env
, s
, modrm
);
2940 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
2942 case 0x22b: /* movntss */
2943 case 0x32b: /* movntsd */
2946 gen_lea_modrm(env
, s
, modrm
);
2948 gen_stq_env_A0(s
, offsetof(CPUX86State
,
2949 xmm_regs
[reg
].ZMM_Q(0)));
2951 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,
2952 xmm_regs
[reg
].ZMM_L(0)));
2953 gen_op_st_v(s
, MO_32
, cpu_T0
, cpu_A0
);
2956 case 0x6e: /* movd mm, ea */
2957 #ifdef TARGET_X86_64
2958 if (s
->dflag
== MO_64
) {
2959 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
2960 tcg_gen_st_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,fpregs
[reg
].mmx
));
2964 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
2965 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
2966 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
2967 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
2968 gen_helper_movl_mm_T0_mmx(cpu_ptr0
, cpu_tmp2_i32
);
2971 case 0x16e: /* movd xmm, ea */
2972 #ifdef TARGET_X86_64
2973 if (s
->dflag
== MO_64
) {
2974 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
2975 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
2976 offsetof(CPUX86State
,xmm_regs
[reg
]));
2977 gen_helper_movq_mm_T0_xmm(cpu_ptr0
, cpu_T0
);
2981 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
2982 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
2983 offsetof(CPUX86State
,xmm_regs
[reg
]));
2984 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
2985 gen_helper_movl_mm_T0_xmm(cpu_ptr0
, cpu_tmp2_i32
);
2988 case 0x6f: /* movq mm, ea */
2990 gen_lea_modrm(env
, s
, modrm
);
2991 gen_ldq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
2994 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
2995 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
2996 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
2997 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3000 case 0x010: /* movups */
3001 case 0x110: /* movupd */
3002 case 0x028: /* movaps */
3003 case 0x128: /* movapd */
3004 case 0x16f: /* movdqa xmm, ea */
3005 case 0x26f: /* movdqu xmm, ea */
3007 gen_lea_modrm(env
, s
, modrm
);
3008 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3010 rm
= (modrm
& 7) | REX_B(s
);
3011 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[reg
]),
3012 offsetof(CPUX86State
,xmm_regs
[rm
]));
3015 case 0x210: /* movss xmm, ea */
3017 gen_lea_modrm(env
, s
, modrm
);
3018 gen_op_ld_v(s
, MO_32
, cpu_T0
, cpu_A0
);
3019 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3020 tcg_gen_movi_tl(cpu_T0
, 0);
3021 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)));
3022 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)));
3023 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)));
3025 rm
= (modrm
& 7) | REX_B(s
);
3026 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)),
3027 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)));
3030 case 0x310: /* movsd xmm, ea */
3032 gen_lea_modrm(env
, s
, modrm
);
3033 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3034 xmm_regs
[reg
].ZMM_Q(0)));
3035 tcg_gen_movi_tl(cpu_T0
, 0);
3036 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)));
3037 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)));
3039 rm
= (modrm
& 7) | REX_B(s
);
3040 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3041 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3044 case 0x012: /* movlps */
3045 case 0x112: /* movlpd */
3047 gen_lea_modrm(env
, s
, modrm
);
3048 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3049 xmm_regs
[reg
].ZMM_Q(0)));
3052 rm
= (modrm
& 7) | REX_B(s
);
3053 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3054 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(1)));
3057 case 0x212: /* movsldup */
3059 gen_lea_modrm(env
, s
, modrm
);
3060 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3062 rm
= (modrm
& 7) | REX_B(s
);
3063 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)),
3064 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)));
3065 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)),
3066 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(2)));
3068 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)),
3069 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3070 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)),
3071 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)));
3073 case 0x312: /* movddup */
3075 gen_lea_modrm(env
, s
, modrm
);
3076 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3077 xmm_regs
[reg
].ZMM_Q(0)));
3079 rm
= (modrm
& 7) | REX_B(s
);
3080 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3081 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3083 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)),
3084 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3086 case 0x016: /* movhps */
3087 case 0x116: /* movhpd */
3089 gen_lea_modrm(env
, s
, modrm
);
3090 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3091 xmm_regs
[reg
].ZMM_Q(1)));
3094 rm
= (modrm
& 7) | REX_B(s
);
3095 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)),
3096 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3099 case 0x216: /* movshdup */
3101 gen_lea_modrm(env
, s
, modrm
);
3102 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3104 rm
= (modrm
& 7) | REX_B(s
);
3105 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)),
3106 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(1)));
3107 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)),
3108 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(3)));
3110 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)),
3111 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)));
3112 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)),
3113 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)));
3118 int bit_index
, field_length
;
3120 if (b1
== 1 && reg
!= 0)
3122 field_length
= cpu_ldub_code(env
, s
->pc
++) & 0x3F;
3123 bit_index
= cpu_ldub_code(env
, s
->pc
++) & 0x3F;
3124 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3125 offsetof(CPUX86State
,xmm_regs
[reg
]));
3127 gen_helper_extrq_i(cpu_env
, cpu_ptr0
,
3128 tcg_const_i32(bit_index
),
3129 tcg_const_i32(field_length
));
3131 gen_helper_insertq_i(cpu_env
, cpu_ptr0
,
3132 tcg_const_i32(bit_index
),
3133 tcg_const_i32(field_length
));
3136 case 0x7e: /* movd ea, mm */
3137 #ifdef TARGET_X86_64
3138 if (s
->dflag
== MO_64
) {
3139 tcg_gen_ld_i64(cpu_T0
, cpu_env
,
3140 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3141 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3145 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
,
3146 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_L(0)));
3147 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3150 case 0x17e: /* movd ea, xmm */
3151 #ifdef TARGET_X86_64
3152 if (s
->dflag
== MO_64
) {
3153 tcg_gen_ld_i64(cpu_T0
, cpu_env
,
3154 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3155 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3159 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
,
3160 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3161 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3164 case 0x27e: /* movq xmm, ea */
3166 gen_lea_modrm(env
, s
, modrm
);
3167 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3168 xmm_regs
[reg
].ZMM_Q(0)));
3170 rm
= (modrm
& 7) | REX_B(s
);
3171 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3172 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3174 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)));
3176 case 0x7f: /* movq ea, mm */
3178 gen_lea_modrm(env
, s
, modrm
);
3179 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3182 gen_op_movq(offsetof(CPUX86State
,fpregs
[rm
].mmx
),
3183 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3186 case 0x011: /* movups */
3187 case 0x111: /* movupd */
3188 case 0x029: /* movaps */
3189 case 0x129: /* movapd */
3190 case 0x17f: /* movdqa ea, xmm */
3191 case 0x27f: /* movdqu ea, xmm */
3193 gen_lea_modrm(env
, s
, modrm
);
3194 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3196 rm
= (modrm
& 7) | REX_B(s
);
3197 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[rm
]),
3198 offsetof(CPUX86State
,xmm_regs
[reg
]));
3201 case 0x211: /* movss ea, xmm */
3203 gen_lea_modrm(env
, s
, modrm
);
3204 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3205 gen_op_st_v(s
, MO_32
, cpu_T0
, cpu_A0
);
3207 rm
= (modrm
& 7) | REX_B(s
);
3208 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)),
3209 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3212 case 0x311: /* movsd ea, xmm */
3214 gen_lea_modrm(env
, s
, modrm
);
3215 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3216 xmm_regs
[reg
].ZMM_Q(0)));
3218 rm
= (modrm
& 7) | REX_B(s
);
3219 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)),
3220 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3223 case 0x013: /* movlps */
3224 case 0x113: /* movlpd */
3226 gen_lea_modrm(env
, s
, modrm
);
3227 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3228 xmm_regs
[reg
].ZMM_Q(0)));
3233 case 0x017: /* movhps */
3234 case 0x117: /* movhpd */
3236 gen_lea_modrm(env
, s
, modrm
);
3237 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3238 xmm_regs
[reg
].ZMM_Q(1)));
3243 case 0x71: /* shift mm, im */
3246 case 0x171: /* shift xmm, im */
3252 val
= cpu_ldub_code(env
, s
->pc
++);
3254 tcg_gen_movi_tl(cpu_T0
, val
);
3255 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_t0
.ZMM_L(0)));
3256 tcg_gen_movi_tl(cpu_T0
, 0);
3257 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_t0
.ZMM_L(1)));
3258 op1_offset
= offsetof(CPUX86State
,xmm_t0
);
3260 tcg_gen_movi_tl(cpu_T0
, val
);
3261 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,mmx_t0
.MMX_L(0)));
3262 tcg_gen_movi_tl(cpu_T0
, 0);
3263 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,mmx_t0
.MMX_L(1)));
3264 op1_offset
= offsetof(CPUX86State
,mmx_t0
);
3266 sse_fn_epp
= sse_op_table2
[((b
- 1) & 3) * 8 +
3267 (((modrm
>> 3)) & 7)][b1
];
3272 rm
= (modrm
& 7) | REX_B(s
);
3273 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3276 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3278 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3279 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op1_offset
);
3280 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3282 case 0x050: /* movmskps */
3283 rm
= (modrm
& 7) | REX_B(s
);
3284 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3285 offsetof(CPUX86State
,xmm_regs
[rm
]));
3286 gen_helper_movmskps(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3287 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3289 case 0x150: /* movmskpd */
3290 rm
= (modrm
& 7) | REX_B(s
);
3291 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3292 offsetof(CPUX86State
,xmm_regs
[rm
]));
3293 gen_helper_movmskpd(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3294 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3296 case 0x02a: /* cvtpi2ps */
3297 case 0x12a: /* cvtpi2pd */
3298 gen_helper_enter_mmx(cpu_env
);
3300 gen_lea_modrm(env
, s
, modrm
);
3301 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3302 gen_ldq_env_A0(s
, op2_offset
);
3305 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3307 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3308 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3309 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3312 gen_helper_cvtpi2ps(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3316 gen_helper_cvtpi2pd(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3320 case 0x22a: /* cvtsi2ss */
3321 case 0x32a: /* cvtsi2sd */
3322 ot
= mo_64_32(s
->dflag
);
3323 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3324 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3325 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3327 SSEFunc_0_epi sse_fn_epi
= sse_op_table3ai
[(b
>> 8) & 1];
3328 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
3329 sse_fn_epi(cpu_env
, cpu_ptr0
, cpu_tmp2_i32
);
3331 #ifdef TARGET_X86_64
3332 SSEFunc_0_epl sse_fn_epl
= sse_op_table3aq
[(b
>> 8) & 1];
3333 sse_fn_epl(cpu_env
, cpu_ptr0
, cpu_T0
);
3339 case 0x02c: /* cvttps2pi */
3340 case 0x12c: /* cvttpd2pi */
3341 case 0x02d: /* cvtps2pi */
3342 case 0x12d: /* cvtpd2pi */
3343 gen_helper_enter_mmx(cpu_env
);
3345 gen_lea_modrm(env
, s
, modrm
);
3346 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3347 gen_ldo_env_A0(s
, op2_offset
);
3349 rm
= (modrm
& 7) | REX_B(s
);
3350 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3352 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
);
3353 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3354 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3357 gen_helper_cvttps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3360 gen_helper_cvttpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3363 gen_helper_cvtps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3366 gen_helper_cvtpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3370 case 0x22c: /* cvttss2si */
3371 case 0x32c: /* cvttsd2si */
3372 case 0x22d: /* cvtss2si */
3373 case 0x32d: /* cvtsd2si */
3374 ot
= mo_64_32(s
->dflag
);
3376 gen_lea_modrm(env
, s
, modrm
);
3378 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.ZMM_Q(0)));
3380 gen_op_ld_v(s
, MO_32
, cpu_T0
, cpu_A0
);
3381 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_t0
.ZMM_L(0)));
3383 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3385 rm
= (modrm
& 7) | REX_B(s
);
3386 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3388 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3390 SSEFunc_i_ep sse_fn_i_ep
=
3391 sse_op_table3bi
[((b
>> 7) & 2) | (b
& 1)];
3392 sse_fn_i_ep(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3393 tcg_gen_extu_i32_tl(cpu_T0
, cpu_tmp2_i32
);
3395 #ifdef TARGET_X86_64
3396 SSEFunc_l_ep sse_fn_l_ep
=
3397 sse_op_table3bq
[((b
>> 7) & 2) | (b
& 1)];
3398 sse_fn_l_ep(cpu_T0
, cpu_env
, cpu_ptr0
);
3403 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3405 case 0xc4: /* pinsrw */
3408 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
3409 val
= cpu_ldub_code(env
, s
->pc
++);
3412 tcg_gen_st16_tl(cpu_T0
, cpu_env
,
3413 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_W(val
)));
3416 tcg_gen_st16_tl(cpu_T0
, cpu_env
,
3417 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_W(val
)));
3420 case 0xc5: /* pextrw */
3424 ot
= mo_64_32(s
->dflag
);
3425 val
= cpu_ldub_code(env
, s
->pc
++);
3428 rm
= (modrm
& 7) | REX_B(s
);
3429 tcg_gen_ld16u_tl(cpu_T0
, cpu_env
,
3430 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_W(val
)));
3434 tcg_gen_ld16u_tl(cpu_T0
, cpu_env
,
3435 offsetof(CPUX86State
,fpregs
[rm
].mmx
.MMX_W(val
)));
3437 reg
= ((modrm
>> 3) & 7) | rex_r
;
3438 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3440 case 0x1d6: /* movq ea, xmm */
3442 gen_lea_modrm(env
, s
, modrm
);
3443 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3444 xmm_regs
[reg
].ZMM_Q(0)));
3446 rm
= (modrm
& 7) | REX_B(s
);
3447 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)),
3448 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3449 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(1)));
3452 case 0x2d6: /* movq2dq */
3453 gen_helper_enter_mmx(cpu_env
);
3455 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3456 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3457 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)));
3459 case 0x3d6: /* movdq2q */
3460 gen_helper_enter_mmx(cpu_env
);
3461 rm
= (modrm
& 7) | REX_B(s
);
3462 gen_op_movq(offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
),
3463 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3465 case 0xd7: /* pmovmskb */
3470 rm
= (modrm
& 7) | REX_B(s
);
3471 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[rm
]));
3472 gen_helper_pmovmskb_xmm(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3475 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3476 gen_helper_pmovmskb_mmx(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3478 reg
= ((modrm
>> 3) & 7) | rex_r
;
3479 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3485 if ((b
& 0xf0) == 0xf0) {
3488 modrm
= cpu_ldub_code(env
, s
->pc
++);
3490 reg
= ((modrm
>> 3) & 7) | rex_r
;
3491 mod
= (modrm
>> 6) & 3;
3496 sse_fn_epp
= sse_op_table6
[b
].op
[b1
];
3500 if (!(s
->cpuid_ext_features
& sse_op_table6
[b
].ext_mask
))
3504 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3506 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
3508 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3509 gen_lea_modrm(env
, s
, modrm
);
3511 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3512 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3513 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3514 gen_ldq_env_A0(s
, op2_offset
+
3515 offsetof(ZMMReg
, ZMM_Q(0)));
3517 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3518 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3519 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
3520 s
->mem_index
, MO_LEUL
);
3521 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, op2_offset
+
3522 offsetof(ZMMReg
, ZMM_L(0)));
3524 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3525 tcg_gen_qemu_ld_tl(cpu_tmp0
, cpu_A0
,
3526 s
->mem_index
, MO_LEUW
);
3527 tcg_gen_st16_tl(cpu_tmp0
, cpu_env
, op2_offset
+
3528 offsetof(ZMMReg
, ZMM_W(0)));
3530 case 0x2a: /* movntqda */
3531 gen_ldo_env_A0(s
, op1_offset
);
3534 gen_ldo_env_A0(s
, op2_offset
);
3538 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
3540 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3542 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3543 gen_lea_modrm(env
, s
, modrm
);
3544 gen_ldq_env_A0(s
, op2_offset
);
3547 if (sse_fn_epp
== SSE_SPECIAL
) {
3551 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3552 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3553 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3556 set_cc_op(s
, CC_OP_EFLAGS
);
3563 /* Various integer extensions at 0f 38 f[0-f]. */
3564 b
= modrm
| (b1
<< 8);
3565 modrm
= cpu_ldub_code(env
, s
->pc
++);
3566 reg
= ((modrm
>> 3) & 7) | rex_r
;
3569 case 0x3f0: /* crc32 Gd,Eb */
3570 case 0x3f1: /* crc32 Gd,Ey */
3572 if (!(s
->cpuid_ext_features
& CPUID_EXT_SSE42
)) {
3575 if ((b
& 0xff) == 0xf0) {
3577 } else if (s
->dflag
!= MO_64
) {
3578 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3583 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[reg
]);
3584 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3585 gen_helper_crc32(cpu_T0
, cpu_tmp2_i32
,
3586 cpu_T0
, tcg_const_i32(8 << ot
));
3588 ot
= mo_64_32(s
->dflag
);
3589 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3592 case 0x1f0: /* crc32 or movbe */
3594 /* For these insns, the f3 prefix is supposed to have priority
3595 over the 66 prefix, but that's not what we implement above
3597 if (s
->prefix
& PREFIX_REPNZ
) {
3601 case 0x0f0: /* movbe Gy,My */
3602 case 0x0f1: /* movbe My,Gy */
3603 if (!(s
->cpuid_ext_features
& CPUID_EXT_MOVBE
)) {
3606 if (s
->dflag
!= MO_64
) {
3607 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3612 gen_lea_modrm(env
, s
, modrm
);
3614 tcg_gen_qemu_ld_tl(cpu_T0
, cpu_A0
,
3615 s
->mem_index
, ot
| MO_BE
);
3616 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3618 tcg_gen_qemu_st_tl(cpu_regs
[reg
], cpu_A0
,
3619 s
->mem_index
, ot
| MO_BE
);
3623 case 0x0f2: /* andn Gy, By, Ey */
3624 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3625 || !(s
->prefix
& PREFIX_VEX
)
3629 ot
= mo_64_32(s
->dflag
);
3630 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3631 tcg_gen_andc_tl(cpu_T0
, cpu_regs
[s
->vex_v
], cpu_T0
);
3632 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3633 gen_op_update1_cc();
3634 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3637 case 0x0f7: /* bextr Gy, Ey, By */
3638 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3639 || !(s
->prefix
& PREFIX_VEX
)
3643 ot
= mo_64_32(s
->dflag
);
3647 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3648 /* Extract START, and shift the operand.
3649 Shifts larger than operand size get zeros. */
3650 tcg_gen_ext8u_tl(cpu_A0
, cpu_regs
[s
->vex_v
]);
3651 tcg_gen_shr_tl(cpu_T0
, cpu_T0
, cpu_A0
);
3653 bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3654 zero
= tcg_const_tl(0);
3655 tcg_gen_movcond_tl(TCG_COND_LEU
, cpu_T0
, cpu_A0
, bound
,
3657 tcg_temp_free(zero
);
3659 /* Extract the LEN into a mask. Lengths larger than
3660 operand size get all ones. */
3661 tcg_gen_shri_tl(cpu_A0
, cpu_regs
[s
->vex_v
], 8);
3662 tcg_gen_ext8u_tl(cpu_A0
, cpu_A0
);
3663 tcg_gen_movcond_tl(TCG_COND_LEU
, cpu_A0
, cpu_A0
, bound
,
3665 tcg_temp_free(bound
);
3666 tcg_gen_movi_tl(cpu_T1
, 1);
3667 tcg_gen_shl_tl(cpu_T1
, cpu_T1
, cpu_A0
);
3668 tcg_gen_subi_tl(cpu_T1
, cpu_T1
, 1);
3669 tcg_gen_and_tl(cpu_T0
, cpu_T0
, cpu_T1
);
3671 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3672 gen_op_update1_cc();
3673 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3677 case 0x0f5: /* bzhi Gy, Ey, By */
3678 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3679 || !(s
->prefix
& PREFIX_VEX
)
3683 ot
= mo_64_32(s
->dflag
);
3684 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3685 tcg_gen_ext8u_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3687 TCGv bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3688 /* Note that since we're using BMILG (in order to get O
3689 cleared) we need to store the inverse into C. */
3690 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_cc_src
,
3692 tcg_gen_movcond_tl(TCG_COND_GT
, cpu_T1
, cpu_T1
,
3693 bound
, bound
, cpu_T1
);
3694 tcg_temp_free(bound
);
3696 tcg_gen_movi_tl(cpu_A0
, -1);
3697 tcg_gen_shl_tl(cpu_A0
, cpu_A0
, cpu_T1
);
3698 tcg_gen_andc_tl(cpu_T0
, cpu_T0
, cpu_A0
);
3699 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3700 gen_op_update1_cc();
3701 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
3704 case 0x3f6: /* mulx By, Gy, rdx, Ey */
3705 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3706 || !(s
->prefix
& PREFIX_VEX
)
3710 ot
= mo_64_32(s
->dflag
);
3711 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3714 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
3715 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EDX
]);
3716 tcg_gen_mulu2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
3717 cpu_tmp2_i32
, cpu_tmp3_i32
);
3718 tcg_gen_extu_i32_tl(cpu_regs
[s
->vex_v
], cpu_tmp2_i32
);
3719 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp3_i32
);
3721 #ifdef TARGET_X86_64
3723 tcg_gen_mulu2_i64(cpu_T0
, cpu_T1
,
3724 cpu_T0
, cpu_regs
[R_EDX
]);
3725 tcg_gen_mov_i64(cpu_regs
[s
->vex_v
], cpu_T0
);
3726 tcg_gen_mov_i64(cpu_regs
[reg
], cpu_T1
);
3732 case 0x3f5: /* pdep Gy, By, Ey */
3733 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3734 || !(s
->prefix
& PREFIX_VEX
)
3738 ot
= mo_64_32(s
->dflag
);
3739 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3740 /* Note that by zero-extending the mask operand, we
3741 automatically handle zero-extending the result. */
3743 tcg_gen_mov_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3745 tcg_gen_ext32u_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3747 gen_helper_pdep(cpu_regs
[reg
], cpu_T0
, cpu_T1
);
3750 case 0x2f5: /* pext Gy, By, Ey */
3751 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3752 || !(s
->prefix
& PREFIX_VEX
)
3756 ot
= mo_64_32(s
->dflag
);
3757 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3758 /* Note that by zero-extending the mask operand, we
3759 automatically handle zero-extending the result. */
3761 tcg_gen_mov_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3763 tcg_gen_ext32u_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3765 gen_helper_pext(cpu_regs
[reg
], cpu_T0
, cpu_T1
);
3768 case 0x1f6: /* adcx Gy, Ey */
3769 case 0x2f6: /* adox Gy, Ey */
3770 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_ADX
)) {
3773 TCGv carry_in
, carry_out
, zero
;
3776 ot
= mo_64_32(s
->dflag
);
3777 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3779 /* Re-use the carry-out from a previous round. */
3780 TCGV_UNUSED(carry_in
);
3781 carry_out
= (b
== 0x1f6 ? cpu_cc_dst
: cpu_cc_src2
);
3785 carry_in
= cpu_cc_dst
;
3786 end_op
= CC_OP_ADCX
;
3788 end_op
= CC_OP_ADCOX
;
3793 end_op
= CC_OP_ADCOX
;
3795 carry_in
= cpu_cc_src2
;
3796 end_op
= CC_OP_ADOX
;
3800 end_op
= CC_OP_ADCOX
;
3801 carry_in
= carry_out
;
3804 end_op
= (b
== 0x1f6 ? CC_OP_ADCX
: CC_OP_ADOX
);
3807 /* If we can't reuse carry-out, get it out of EFLAGS. */
3808 if (TCGV_IS_UNUSED(carry_in
)) {
3809 if (s
->cc_op
!= CC_OP_ADCX
&& s
->cc_op
!= CC_OP_ADOX
) {
3810 gen_compute_eflags(s
);
3812 carry_in
= cpu_tmp0
;
3813 tcg_gen_shri_tl(carry_in
, cpu_cc_src
,
3814 ctz32(b
== 0x1f6 ? CC_C
: CC_O
));
3815 tcg_gen_andi_tl(carry_in
, carry_in
, 1);
3819 #ifdef TARGET_X86_64
3821 /* If we know TL is 64-bit, and we want a 32-bit
3822 result, just do everything in 64-bit arithmetic. */
3823 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_regs
[reg
]);
3824 tcg_gen_ext32u_i64(cpu_T0
, cpu_T0
);
3825 tcg_gen_add_i64(cpu_T0
, cpu_T0
, cpu_regs
[reg
]);
3826 tcg_gen_add_i64(cpu_T0
, cpu_T0
, carry_in
);
3827 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_T0
);
3828 tcg_gen_shri_i64(carry_out
, cpu_T0
, 32);
3832 /* Otherwise compute the carry-out in two steps. */
3833 zero
= tcg_const_tl(0);
3834 tcg_gen_add2_tl(cpu_T0
, carry_out
,
3837 tcg_gen_add2_tl(cpu_regs
[reg
], carry_out
,
3838 cpu_regs
[reg
], carry_out
,
3840 tcg_temp_free(zero
);
3843 set_cc_op(s
, end_op
);
3847 case 0x1f7: /* shlx Gy, Ey, By */
3848 case 0x2f7: /* sarx Gy, Ey, By */
3849 case 0x3f7: /* shrx Gy, Ey, By */
3850 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3851 || !(s
->prefix
& PREFIX_VEX
)
3855 ot
= mo_64_32(s
->dflag
);
3856 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3858 tcg_gen_andi_tl(cpu_T1
, cpu_regs
[s
->vex_v
], 63);
3860 tcg_gen_andi_tl(cpu_T1
, cpu_regs
[s
->vex_v
], 31);
3863 tcg_gen_shl_tl(cpu_T0
, cpu_T0
, cpu_T1
);
3864 } else if (b
== 0x2f7) {
3866 tcg_gen_ext32s_tl(cpu_T0
, cpu_T0
);
3868 tcg_gen_sar_tl(cpu_T0
, cpu_T0
, cpu_T1
);
3871 tcg_gen_ext32u_tl(cpu_T0
, cpu_T0
);
3873 tcg_gen_shr_tl(cpu_T0
, cpu_T0
, cpu_T1
);
3875 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3881 case 0x3f3: /* Group 17 */
3882 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3883 || !(s
->prefix
& PREFIX_VEX
)
3887 ot
= mo_64_32(s
->dflag
);
3888 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3891 case 1: /* blsr By,Ey */
3892 tcg_gen_neg_tl(cpu_T1
, cpu_T0
);
3893 tcg_gen_and_tl(cpu_T0
, cpu_T0
, cpu_T1
);
3894 gen_op_mov_reg_v(ot
, s
->vex_v
, cpu_T0
);
3895 gen_op_update2_cc();
3896 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
3899 case 2: /* blsmsk By,Ey */
3900 tcg_gen_mov_tl(cpu_cc_src
, cpu_T0
);
3901 tcg_gen_subi_tl(cpu_T0
, cpu_T0
, 1);
3902 tcg_gen_xor_tl(cpu_T0
, cpu_T0
, cpu_cc_src
);
3903 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
3904 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
3907 case 3: /* blsi By, Ey */
3908 tcg_gen_mov_tl(cpu_cc_src
, cpu_T0
);
3909 tcg_gen_subi_tl(cpu_T0
, cpu_T0
, 1);
3910 tcg_gen_and_tl(cpu_T0
, cpu_T0
, cpu_cc_src
);
3911 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
3912 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
3928 modrm
= cpu_ldub_code(env
, s
->pc
++);
3930 reg
= ((modrm
>> 3) & 7) | rex_r
;
3931 mod
= (modrm
>> 6) & 3;
3936 sse_fn_eppi
= sse_op_table7
[b
].op
[b1
];
3940 if (!(s
->cpuid_ext_features
& sse_op_table7
[b
].ext_mask
))
3943 if (sse_fn_eppi
== SSE_SPECIAL
) {
3944 ot
= mo_64_32(s
->dflag
);
3945 rm
= (modrm
& 7) | REX_B(s
);
3947 gen_lea_modrm(env
, s
, modrm
);
3948 reg
= ((modrm
>> 3) & 7) | rex_r
;
3949 val
= cpu_ldub_code(env
, s
->pc
++);
3951 case 0x14: /* pextrb */
3952 tcg_gen_ld8u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,
3953 xmm_regs
[reg
].ZMM_B(val
& 15)));
3955 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
3957 tcg_gen_qemu_st_tl(cpu_T0
, cpu_A0
,
3958 s
->mem_index
, MO_UB
);
3961 case 0x15: /* pextrw */
3962 tcg_gen_ld16u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,
3963 xmm_regs
[reg
].ZMM_W(val
& 7)));
3965 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
3967 tcg_gen_qemu_st_tl(cpu_T0
, cpu_A0
,
3968 s
->mem_index
, MO_LEUW
);
3972 if (ot
== MO_32
) { /* pextrd */
3973 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
3974 offsetof(CPUX86State
,
3975 xmm_regs
[reg
].ZMM_L(val
& 3)));
3977 tcg_gen_extu_i32_tl(cpu_regs
[rm
], cpu_tmp2_i32
);
3979 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
3980 s
->mem_index
, MO_LEUL
);
3982 } else { /* pextrq */
3983 #ifdef TARGET_X86_64
3984 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
3985 offsetof(CPUX86State
,
3986 xmm_regs
[reg
].ZMM_Q(val
& 1)));
3988 tcg_gen_mov_i64(cpu_regs
[rm
], cpu_tmp1_i64
);
3990 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
3991 s
->mem_index
, MO_LEQ
);
3998 case 0x17: /* extractps */
3999 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,
4000 xmm_regs
[reg
].ZMM_L(val
& 3)));
4002 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
4004 tcg_gen_qemu_st_tl(cpu_T0
, cpu_A0
,
4005 s
->mem_index
, MO_LEUL
);
4008 case 0x20: /* pinsrb */
4010 gen_op_mov_v_reg(MO_32
, cpu_T0
, rm
);
4012 tcg_gen_qemu_ld_tl(cpu_T0
, cpu_A0
,
4013 s
->mem_index
, MO_UB
);
4015 tcg_gen_st8_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,
4016 xmm_regs
[reg
].ZMM_B(val
& 15)));
4018 case 0x21: /* insertps */
4020 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4021 offsetof(CPUX86State
,xmm_regs
[rm
]
4022 .ZMM_L((val
>> 6) & 3)));
4024 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
4025 s
->mem_index
, MO_LEUL
);
4027 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4028 offsetof(CPUX86State
,xmm_regs
[reg
]
4029 .ZMM_L((val
>> 4) & 3)));
4031 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4032 cpu_env
, offsetof(CPUX86State
,
4033 xmm_regs
[reg
].ZMM_L(0)));
4035 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4036 cpu_env
, offsetof(CPUX86State
,
4037 xmm_regs
[reg
].ZMM_L(1)));
4039 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4040 cpu_env
, offsetof(CPUX86State
,
4041 xmm_regs
[reg
].ZMM_L(2)));
4043 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4044 cpu_env
, offsetof(CPUX86State
,
4045 xmm_regs
[reg
].ZMM_L(3)));
4048 if (ot
== MO_32
) { /* pinsrd */
4050 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[rm
]);
4052 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
4053 s
->mem_index
, MO_LEUL
);
4055 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4056 offsetof(CPUX86State
,
4057 xmm_regs
[reg
].ZMM_L(val
& 3)));
4058 } else { /* pinsrq */
4059 #ifdef TARGET_X86_64
4061 gen_op_mov_v_reg(ot
, cpu_tmp1_i64
, rm
);
4063 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
4064 s
->mem_index
, MO_LEQ
);
4066 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
4067 offsetof(CPUX86State
,
4068 xmm_regs
[reg
].ZMM_Q(val
& 1)));
4079 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4081 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
4083 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4084 gen_lea_modrm(env
, s
, modrm
);
4085 gen_ldo_env_A0(s
, op2_offset
);
4088 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4090 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4092 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4093 gen_lea_modrm(env
, s
, modrm
);
4094 gen_ldq_env_A0(s
, op2_offset
);
4097 val
= cpu_ldub_code(env
, s
->pc
++);
4099 if ((b
& 0xfc) == 0x60) { /* pcmpXstrX */
4100 set_cc_op(s
, CC_OP_EFLAGS
);
4102 if (s
->dflag
== MO_64
) {
4103 /* The helper must use entire 64-bit gp registers */
4108 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4109 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4110 sse_fn_eppi(cpu_env
, cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4114 /* Various integer extensions at 0f 3a f[0-f]. */
4115 b
= modrm
| (b1
<< 8);
4116 modrm
= cpu_ldub_code(env
, s
->pc
++);
4117 reg
= ((modrm
>> 3) & 7) | rex_r
;
4120 case 0x3f0: /* rorx Gy,Ey, Ib */
4121 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4122 || !(s
->prefix
& PREFIX_VEX
)
4126 ot
= mo_64_32(s
->dflag
);
4127 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4128 b
= cpu_ldub_code(env
, s
->pc
++);
4130 tcg_gen_rotri_tl(cpu_T0
, cpu_T0
, b
& 63);
4132 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
4133 tcg_gen_rotri_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, b
& 31);
4134 tcg_gen_extu_i32_tl(cpu_T0
, cpu_tmp2_i32
);
4136 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
4148 /* generic MMX or SSE operation */
4150 case 0x70: /* pshufx insn */
4151 case 0xc6: /* pshufx insn */
4152 case 0xc2: /* compare insns */
4159 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4163 gen_lea_modrm(env
, s
, modrm
);
4164 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4170 /* Most sse scalar operations. */
4173 } else if (b1
== 3) {
4178 case 0x2e: /* ucomis[sd] */
4179 case 0x2f: /* comis[sd] */
4191 gen_op_ld_v(s
, MO_32
, cpu_T0
, cpu_A0
);
4192 tcg_gen_st32_tl(cpu_T0
, cpu_env
,
4193 offsetof(CPUX86State
,xmm_t0
.ZMM_L(0)));
4197 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.ZMM_D(0)));
4200 /* 128 bit access */
4201 gen_ldo_env_A0(s
, op2_offset
);
4205 rm
= (modrm
& 7) | REX_B(s
);
4206 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
4209 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4211 gen_lea_modrm(env
, s
, modrm
);
4212 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4213 gen_ldq_env_A0(s
, op2_offset
);
4216 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4220 case 0x0f: /* 3DNow! data insns */
4221 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
))
4223 val
= cpu_ldub_code(env
, s
->pc
++);
4224 sse_fn_epp
= sse_op_table5
[val
];
4228 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4229 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4230 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4232 case 0x70: /* pshufx insn */
4233 case 0xc6: /* pshufx insn */
4234 val
= cpu_ldub_code(env
, s
->pc
++);
4235 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4236 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4237 /* XXX: introduce a new table? */
4238 sse_fn_ppi
= (SSEFunc_0_ppi
)sse_fn_epp
;
4239 sse_fn_ppi(cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4243 val
= cpu_ldub_code(env
, s
->pc
++);
4246 sse_fn_epp
= sse_op_table4
[val
][b1
];
4248 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4249 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4250 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4253 /* maskmov : we must prepare A0 */
4256 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EDI
]);
4257 gen_extu(s
->aflag
, cpu_A0
);
4258 gen_add_A0_ds_seg(s
);
4260 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4261 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4262 /* XXX: introduce a new table? */
4263 sse_fn_eppt
= (SSEFunc_0_eppt
)sse_fn_epp
;
4264 sse_fn_eppt(cpu_env
, cpu_ptr0
, cpu_ptr1
, cpu_A0
);
4267 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4268 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4269 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4272 if (b
== 0x2e || b
== 0x2f) {
4273 set_cc_op(s
, CC_OP_EFLAGS
);
4278 /* convert one instruction. s->is_jmp is set if the translation must
4279 be stopped. Return the next pc value */
4280 static target_ulong
disas_insn(CPUX86State
*env
, DisasContext
*s
,
4281 target_ulong pc_start
)
4285 TCGMemOp ot
, aflag
, dflag
;
4286 int modrm
, reg
, rm
, mod
, op
, opreg
, val
;
4287 target_ulong next_eip
, tval
;
4295 #ifdef TARGET_X86_64
4300 s
->rip_offset
= 0; /* for relative ip address */
4304 b
= cpu_ldub_code(env
, s
->pc
);
4306 /* Collect prefixes. */
4309 prefixes
|= PREFIX_REPZ
;
4312 prefixes
|= PREFIX_REPNZ
;
4315 prefixes
|= PREFIX_LOCK
;
4336 prefixes
|= PREFIX_DATA
;
4339 prefixes
|= PREFIX_ADR
;
4341 #ifdef TARGET_X86_64
4345 rex_w
= (b
>> 3) & 1;
4346 rex_r
= (b
& 0x4) << 1;
4347 s
->rex_x
= (b
& 0x2) << 2;
4348 REX_B(s
) = (b
& 0x1) << 3;
4349 x86_64_hregs
= 1; /* select uniform byte register addressing */
4354 case 0xc5: /* 2-byte VEX */
4355 case 0xc4: /* 3-byte VEX */
4356 /* VEX prefixes cannot be used except in 32-bit mode.
4357 Otherwise the instruction is LES or LDS. */
4358 if (s
->code32
&& !s
->vm86
) {
4359 static const int pp_prefix
[4] = {
4360 0, PREFIX_DATA
, PREFIX_REPZ
, PREFIX_REPNZ
4362 int vex3
, vex2
= cpu_ldub_code(env
, s
->pc
);
4364 if (!CODE64(s
) && (vex2
& 0xc0) != 0xc0) {
4365 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4366 otherwise the instruction is LES or LDS. */
4371 /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
4372 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
4373 | PREFIX_LOCK
| PREFIX_DATA
)) {
4376 #ifdef TARGET_X86_64
4381 rex_r
= (~vex2
>> 4) & 8;
4384 b
= cpu_ldub_code(env
, s
->pc
++);
4386 #ifdef TARGET_X86_64
4387 s
->rex_x
= (~vex2
>> 3) & 8;
4388 s
->rex_b
= (~vex2
>> 2) & 8;
4390 vex3
= cpu_ldub_code(env
, s
->pc
++);
4391 rex_w
= (vex3
>> 7) & 1;
4392 switch (vex2
& 0x1f) {
4393 case 0x01: /* Implied 0f leading opcode bytes. */
4394 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4396 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4399 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4402 default: /* Reserved for future use. */
4406 s
->vex_v
= (~vex3
>> 3) & 0xf;
4407 s
->vex_l
= (vex3
>> 2) & 1;
4408 prefixes
|= pp_prefix
[vex3
& 3] | PREFIX_VEX
;
4413 /* Post-process prefixes. */
4415 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit
4416 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4417 over 0x66 if both are present. */
4418 dflag
= (rex_w
> 0 ? MO_64
: prefixes
& PREFIX_DATA
? MO_16
: MO_32
);
4419 /* In 64-bit mode, 0x67 selects 32-bit addressing. */
4420 aflag
= (prefixes
& PREFIX_ADR
? MO_32
: MO_64
);
4422 /* In 16/32-bit mode, 0x66 selects the opposite data size. */
4423 if (s
->code32
^ ((prefixes
& PREFIX_DATA
) != 0)) {
4428 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */
4429 if (s
->code32
^ ((prefixes
& PREFIX_ADR
) != 0)) {
4436 s
->prefix
= prefixes
;
4440 /* lock generation */
4441 if (prefixes
& PREFIX_LOCK
)
4444 /* now check op code */
4448 /**************************/
4449 /* extended op code */
4450 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4453 /**************************/
4468 ot
= mo_b_d(b
, dflag
);
4471 case 0: /* OP Ev, Gv */
4472 modrm
= cpu_ldub_code(env
, s
->pc
++);
4473 reg
= ((modrm
>> 3) & 7) | rex_r
;
4474 mod
= (modrm
>> 6) & 3;
4475 rm
= (modrm
& 7) | REX_B(s
);
4477 gen_lea_modrm(env
, s
, modrm
);
4479 } else if (op
== OP_XORL
&& rm
== reg
) {
4481 /* xor reg, reg optimisation */
4482 set_cc_op(s
, CC_OP_CLR
);
4483 tcg_gen_movi_tl(cpu_T0
, 0);
4484 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
4489 gen_op_mov_v_reg(ot
, cpu_T1
, reg
);
4490 gen_op(s
, op
, ot
, opreg
);
4492 case 1: /* OP Gv, Ev */
4493 modrm
= cpu_ldub_code(env
, s
->pc
++);
4494 mod
= (modrm
>> 6) & 3;
4495 reg
= ((modrm
>> 3) & 7) | rex_r
;
4496 rm
= (modrm
& 7) | REX_B(s
);
4498 gen_lea_modrm(env
, s
, modrm
);
4499 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
4500 } else if (op
== OP_XORL
&& rm
== reg
) {
4503 gen_op_mov_v_reg(ot
, cpu_T1
, rm
);
4505 gen_op(s
, op
, ot
, reg
);
4507 case 2: /* OP A, Iv */
4508 val
= insn_get(env
, s
, ot
);
4509 tcg_gen_movi_tl(cpu_T1
, val
);
4510 gen_op(s
, op
, ot
, OR_EAX
);
4519 case 0x80: /* GRP1 */
4525 ot
= mo_b_d(b
, dflag
);
4527 modrm
= cpu_ldub_code(env
, s
->pc
++);
4528 mod
= (modrm
>> 6) & 3;
4529 rm
= (modrm
& 7) | REX_B(s
);
4530 op
= (modrm
>> 3) & 7;
4536 s
->rip_offset
= insn_const_size(ot
);
4537 gen_lea_modrm(env
, s
, modrm
);
4548 val
= insn_get(env
, s
, ot
);
4551 val
= (int8_t)insn_get(env
, s
, MO_8
);
4554 tcg_gen_movi_tl(cpu_T1
, val
);
4555 gen_op(s
, op
, ot
, opreg
);
4559 /**************************/
4560 /* inc, dec, and other misc arith */
4561 case 0x40 ... 0x47: /* inc Gv */
4563 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), 1);
4565 case 0x48 ... 0x4f: /* dec Gv */
4567 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), -1);
4569 case 0xf6: /* GRP3 */
4571 ot
= mo_b_d(b
, dflag
);
4573 modrm
= cpu_ldub_code(env
, s
->pc
++);
4574 mod
= (modrm
>> 6) & 3;
4575 rm
= (modrm
& 7) | REX_B(s
);
4576 op
= (modrm
>> 3) & 7;
4579 s
->rip_offset
= insn_const_size(ot
);
4580 gen_lea_modrm(env
, s
, modrm
);
4581 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
4583 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
4588 val
= insn_get(env
, s
, ot
);
4589 tcg_gen_movi_tl(cpu_T1
, val
);
4590 gen_op_testl_T0_T1_cc();
4591 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4594 tcg_gen_not_tl(cpu_T0
, cpu_T0
);
4596 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
4598 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
4602 tcg_gen_neg_tl(cpu_T0
, cpu_T0
);
4604 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
4606 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
4608 gen_op_update_neg_cc();
4609 set_cc_op(s
, CC_OP_SUBB
+ ot
);
4614 gen_op_mov_v_reg(MO_8
, cpu_T1
, R_EAX
);
4615 tcg_gen_ext8u_tl(cpu_T0
, cpu_T0
);
4616 tcg_gen_ext8u_tl(cpu_T1
, cpu_T1
);
4617 /* XXX: use 32 bit mul which could be faster */
4618 tcg_gen_mul_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4619 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
4620 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
4621 tcg_gen_andi_tl(cpu_cc_src
, cpu_T0
, 0xff00);
4622 set_cc_op(s
, CC_OP_MULB
);
4625 gen_op_mov_v_reg(MO_16
, cpu_T1
, R_EAX
);
4626 tcg_gen_ext16u_tl(cpu_T0
, cpu_T0
);
4627 tcg_gen_ext16u_tl(cpu_T1
, cpu_T1
);
4628 /* XXX: use 32 bit mul which could be faster */
4629 tcg_gen_mul_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4630 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
4631 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
4632 tcg_gen_shri_tl(cpu_T0
, cpu_T0
, 16);
4633 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T0
);
4634 tcg_gen_mov_tl(cpu_cc_src
, cpu_T0
);
4635 set_cc_op(s
, CC_OP_MULW
);
4639 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
4640 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
4641 tcg_gen_mulu2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4642 cpu_tmp2_i32
, cpu_tmp3_i32
);
4643 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
4644 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
4645 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4646 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4647 set_cc_op(s
, CC_OP_MULL
);
4649 #ifdef TARGET_X86_64
4651 tcg_gen_mulu2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4652 cpu_T0
, cpu_regs
[R_EAX
]);
4653 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4654 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4655 set_cc_op(s
, CC_OP_MULQ
);
4663 gen_op_mov_v_reg(MO_8
, cpu_T1
, R_EAX
);
4664 tcg_gen_ext8s_tl(cpu_T0
, cpu_T0
);
4665 tcg_gen_ext8s_tl(cpu_T1
, cpu_T1
);
4666 /* XXX: use 32 bit mul which could be faster */
4667 tcg_gen_mul_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4668 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
4669 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
4670 tcg_gen_ext8s_tl(cpu_tmp0
, cpu_T0
);
4671 tcg_gen_sub_tl(cpu_cc_src
, cpu_T0
, cpu_tmp0
);
4672 set_cc_op(s
, CC_OP_MULB
);
4675 gen_op_mov_v_reg(MO_16
, cpu_T1
, R_EAX
);
4676 tcg_gen_ext16s_tl(cpu_T0
, cpu_T0
);
4677 tcg_gen_ext16s_tl(cpu_T1
, cpu_T1
);
4678 /* XXX: use 32 bit mul which could be faster */
4679 tcg_gen_mul_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4680 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
4681 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
4682 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T0
);
4683 tcg_gen_sub_tl(cpu_cc_src
, cpu_T0
, cpu_tmp0
);
4684 tcg_gen_shri_tl(cpu_T0
, cpu_T0
, 16);
4685 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T0
);
4686 set_cc_op(s
, CC_OP_MULW
);
4690 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
4691 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
4692 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4693 cpu_tmp2_i32
, cpu_tmp3_i32
);
4694 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
4695 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
4696 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
4697 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4698 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
4699 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
4700 set_cc_op(s
, CC_OP_MULL
);
4702 #ifdef TARGET_X86_64
4704 tcg_gen_muls2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4705 cpu_T0
, cpu_regs
[R_EAX
]);
4706 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4707 tcg_gen_sari_tl(cpu_cc_src
, cpu_regs
[R_EAX
], 63);
4708 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_regs
[R_EDX
]);
4709 set_cc_op(s
, CC_OP_MULQ
);
4717 gen_helper_divb_AL(cpu_env
, cpu_T0
);
4720 gen_helper_divw_AX(cpu_env
, cpu_T0
);
4724 gen_helper_divl_EAX(cpu_env
, cpu_T0
);
4726 #ifdef TARGET_X86_64
4728 gen_helper_divq_EAX(cpu_env
, cpu_T0
);
4736 gen_helper_idivb_AL(cpu_env
, cpu_T0
);
4739 gen_helper_idivw_AX(cpu_env
, cpu_T0
);
4743 gen_helper_idivl_EAX(cpu_env
, cpu_T0
);
4745 #ifdef TARGET_X86_64
4747 gen_helper_idivq_EAX(cpu_env
, cpu_T0
);
4757 case 0xfe: /* GRP4 */
4758 case 0xff: /* GRP5 */
4759 ot
= mo_b_d(b
, dflag
);
4761 modrm
= cpu_ldub_code(env
, s
->pc
++);
4762 mod
= (modrm
>> 6) & 3;
4763 rm
= (modrm
& 7) | REX_B(s
);
4764 op
= (modrm
>> 3) & 7;
4765 if (op
>= 2 && b
== 0xfe) {
4769 if (op
== 2 || op
== 4) {
4770 /* operand size for jumps is 64 bit */
4772 } else if (op
== 3 || op
== 5) {
4773 ot
= dflag
!= MO_16
? MO_32
+ (rex_w
== 1) : MO_16
;
4774 } else if (op
== 6) {
4775 /* default push size is 64 bit */
4776 ot
= mo_pushpop(s
, dflag
);
4780 gen_lea_modrm(env
, s
, modrm
);
4781 if (op
>= 2 && op
!= 3 && op
!= 5)
4782 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
4784 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
4788 case 0: /* inc Ev */
4793 gen_inc(s
, ot
, opreg
, 1);
4795 case 1: /* dec Ev */
4800 gen_inc(s
, ot
, opreg
, -1);
4802 case 2: /* call Ev */
4803 /* XXX: optimize if memory (no 'and' is necessary) */
4804 if (dflag
== MO_16
) {
4805 tcg_gen_ext16u_tl(cpu_T0
, cpu_T0
);
4807 next_eip
= s
->pc
- s
->cs_base
;
4808 tcg_gen_movi_tl(cpu_T1
, next_eip
);
4809 gen_push_v(s
, cpu_T1
);
4810 gen_op_jmp_v(cpu_T0
);
4814 case 3: /* lcall Ev */
4815 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
4816 gen_add_A0_im(s
, 1 << ot
);
4817 gen_op_ld_v(s
, MO_16
, cpu_T0
, cpu_A0
);
4819 if (s
->pe
&& !s
->vm86
) {
4820 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
4821 gen_helper_lcall_protected(cpu_env
, cpu_tmp2_i32
, cpu_T1
,
4822 tcg_const_i32(dflag
- 1),
4823 tcg_const_tl(s
->pc
- s
->cs_base
));
4825 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
4826 gen_helper_lcall_real(cpu_env
, cpu_tmp2_i32
, cpu_T1
,
4827 tcg_const_i32(dflag
- 1),
4828 tcg_const_i32(s
->pc
- s
->cs_base
));
4832 case 4: /* jmp Ev */
4833 if (dflag
== MO_16
) {
4834 tcg_gen_ext16u_tl(cpu_T0
, cpu_T0
);
4836 gen_op_jmp_v(cpu_T0
);
4840 case 5: /* ljmp Ev */
4841 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
4842 gen_add_A0_im(s
, 1 << ot
);
4843 gen_op_ld_v(s
, MO_16
, cpu_T0
, cpu_A0
);
4845 if (s
->pe
&& !s
->vm86
) {
4846 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
4847 gen_helper_ljmp_protected(cpu_env
, cpu_tmp2_i32
, cpu_T1
,
4848 tcg_const_tl(s
->pc
- s
->cs_base
));
4850 gen_op_movl_seg_T0_vm(R_CS
);
4851 gen_op_jmp_v(cpu_T1
);
4855 case 6: /* push Ev */
4856 gen_push_v(s
, cpu_T0
);
4863 case 0x84: /* test Ev, Gv */
4865 ot
= mo_b_d(b
, dflag
);
4867 modrm
= cpu_ldub_code(env
, s
->pc
++);
4868 reg
= ((modrm
>> 3) & 7) | rex_r
;
4870 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4871 gen_op_mov_v_reg(ot
, cpu_T1
, reg
);
4872 gen_op_testl_T0_T1_cc();
4873 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4876 case 0xa8: /* test eAX, Iv */
4878 ot
= mo_b_d(b
, dflag
);
4879 val
= insn_get(env
, s
, ot
);
4881 gen_op_mov_v_reg(ot
, cpu_T0
, OR_EAX
);
4882 tcg_gen_movi_tl(cpu_T1
, val
);
4883 gen_op_testl_T0_T1_cc();
4884 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4887 case 0x98: /* CWDE/CBW */
4889 #ifdef TARGET_X86_64
4891 gen_op_mov_v_reg(MO_32
, cpu_T0
, R_EAX
);
4892 tcg_gen_ext32s_tl(cpu_T0
, cpu_T0
);
4893 gen_op_mov_reg_v(MO_64
, R_EAX
, cpu_T0
);
4897 gen_op_mov_v_reg(MO_16
, cpu_T0
, R_EAX
);
4898 tcg_gen_ext16s_tl(cpu_T0
, cpu_T0
);
4899 gen_op_mov_reg_v(MO_32
, R_EAX
, cpu_T0
);
4902 gen_op_mov_v_reg(MO_8
, cpu_T0
, R_EAX
);
4903 tcg_gen_ext8s_tl(cpu_T0
, cpu_T0
);
4904 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
4910 case 0x99: /* CDQ/CWD */
4912 #ifdef TARGET_X86_64
4914 gen_op_mov_v_reg(MO_64
, cpu_T0
, R_EAX
);
4915 tcg_gen_sari_tl(cpu_T0
, cpu_T0
, 63);
4916 gen_op_mov_reg_v(MO_64
, R_EDX
, cpu_T0
);
4920 gen_op_mov_v_reg(MO_32
, cpu_T0
, R_EAX
);
4921 tcg_gen_ext32s_tl(cpu_T0
, cpu_T0
);
4922 tcg_gen_sari_tl(cpu_T0
, cpu_T0
, 31);
4923 gen_op_mov_reg_v(MO_32
, R_EDX
, cpu_T0
);
4926 gen_op_mov_v_reg(MO_16
, cpu_T0
, R_EAX
);
4927 tcg_gen_ext16s_tl(cpu_T0
, cpu_T0
);
4928 tcg_gen_sari_tl(cpu_T0
, cpu_T0
, 15);
4929 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T0
);
4935 case 0x1af: /* imul Gv, Ev */
4936 case 0x69: /* imul Gv, Ev, I */
4939 modrm
= cpu_ldub_code(env
, s
->pc
++);
4940 reg
= ((modrm
>> 3) & 7) | rex_r
;
4942 s
->rip_offset
= insn_const_size(ot
);
4945 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4947 val
= insn_get(env
, s
, ot
);
4948 tcg_gen_movi_tl(cpu_T1
, val
);
4949 } else if (b
== 0x6b) {
4950 val
= (int8_t)insn_get(env
, s
, MO_8
);
4951 tcg_gen_movi_tl(cpu_T1
, val
);
4953 gen_op_mov_v_reg(ot
, cpu_T1
, reg
);
4956 #ifdef TARGET_X86_64
4958 tcg_gen_muls2_i64(cpu_regs
[reg
], cpu_T1
, cpu_T0
, cpu_T1
);
4959 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
4960 tcg_gen_sari_tl(cpu_cc_src
, cpu_cc_dst
, 63);
4961 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_T1
);
4965 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
4966 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T1
);
4967 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4968 cpu_tmp2_i32
, cpu_tmp3_i32
);
4969 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
4970 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
4971 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
4972 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
4973 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
4976 tcg_gen_ext16s_tl(cpu_T0
, cpu_T0
);
4977 tcg_gen_ext16s_tl(cpu_T1
, cpu_T1
);
4978 /* XXX: use 32 bit mul which could be faster */
4979 tcg_gen_mul_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4980 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
4981 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T0
);
4982 tcg_gen_sub_tl(cpu_cc_src
, cpu_T0
, cpu_tmp0
);
4983 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
4986 set_cc_op(s
, CC_OP_MULB
+ ot
);
4989 case 0x1c1: /* xadd Ev, Gv */
4990 ot
= mo_b_d(b
, dflag
);
4991 modrm
= cpu_ldub_code(env
, s
->pc
++);
4992 reg
= ((modrm
>> 3) & 7) | rex_r
;
4993 mod
= (modrm
>> 6) & 3;
4995 rm
= (modrm
& 7) | REX_B(s
);
4996 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
4997 gen_op_mov_v_reg(ot
, cpu_T1
, rm
);
4998 tcg_gen_add_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4999 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
5000 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
5002 gen_lea_modrm(env
, s
, modrm
);
5003 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
5004 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
5005 tcg_gen_add_tl(cpu_T0
, cpu_T0
, cpu_T1
);
5006 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
5007 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
5009 gen_op_update2_cc();
5010 set_cc_op(s
, CC_OP_ADDB
+ ot
);
5013 case 0x1b1: /* cmpxchg Ev, Gv */
5015 TCGLabel
*label1
, *label2
;
5016 TCGv t0
, t1
, t2
, a0
;
5018 ot
= mo_b_d(b
, dflag
);
5019 modrm
= cpu_ldub_code(env
, s
->pc
++);
5020 reg
= ((modrm
>> 3) & 7) | rex_r
;
5021 mod
= (modrm
>> 6) & 3;
5022 t0
= tcg_temp_local_new();
5023 t1
= tcg_temp_local_new();
5024 t2
= tcg_temp_local_new();
5025 a0
= tcg_temp_local_new();
5026 gen_op_mov_v_reg(ot
, t1
, reg
);
5028 rm
= (modrm
& 7) | REX_B(s
);
5029 gen_op_mov_v_reg(ot
, t0
, rm
);
5031 gen_lea_modrm(env
, s
, modrm
);
5032 tcg_gen_mov_tl(a0
, cpu_A0
);
5033 gen_op_ld_v(s
, ot
, t0
, a0
);
5034 rm
= 0; /* avoid warning */
5036 label1
= gen_new_label();
5037 tcg_gen_mov_tl(t2
, cpu_regs
[R_EAX
]);
5040 tcg_gen_brcond_tl(TCG_COND_EQ
, t2
, t0
, label1
);
5041 label2
= gen_new_label();
5043 gen_op_mov_reg_v(ot
, R_EAX
, t0
);
5045 gen_set_label(label1
);
5046 gen_op_mov_reg_v(ot
, rm
, t1
);
5048 /* perform no-op store cycle like physical cpu; must be
5049 before changing accumulator to ensure idempotency if
5050 the store faults and the instruction is restarted */
5051 gen_op_st_v(s
, ot
, t0
, a0
);
5052 gen_op_mov_reg_v(ot
, R_EAX
, t0
);
5054 gen_set_label(label1
);
5055 gen_op_st_v(s
, ot
, t1
, a0
);
5057 gen_set_label(label2
);
5058 tcg_gen_mov_tl(cpu_cc_src
, t0
);
5059 tcg_gen_mov_tl(cpu_cc_srcT
, t2
);
5060 tcg_gen_sub_tl(cpu_cc_dst
, t2
, t0
);
5061 set_cc_op(s
, CC_OP_SUBB
+ ot
);
5068 case 0x1c7: /* cmpxchg8b */
5069 modrm
= cpu_ldub_code(env
, s
->pc
++);
5070 mod
= (modrm
>> 6) & 3;
5071 if ((mod
== 3) || ((modrm
& 0x38) != 0x8))
5073 #ifdef TARGET_X86_64
5074 if (dflag
== MO_64
) {
5075 if (!(s
->cpuid_ext_features
& CPUID_EXT_CX16
))
5077 gen_lea_modrm(env
, s
, modrm
);
5078 gen_helper_cmpxchg16b(cpu_env
, cpu_A0
);
5082 if (!(s
->cpuid_features
& CPUID_CX8
))
5084 gen_lea_modrm(env
, s
, modrm
);
5085 gen_helper_cmpxchg8b(cpu_env
, cpu_A0
);
5087 set_cc_op(s
, CC_OP_EFLAGS
);
5090 /**************************/
5092 case 0x50 ... 0x57: /* push */
5093 gen_op_mov_v_reg(MO_32
, cpu_T0
, (b
& 7) | REX_B(s
));
5094 gen_push_v(s
, cpu_T0
);
5096 case 0x58 ... 0x5f: /* pop */
5098 /* NOTE: order is important for pop %sp */
5099 gen_pop_update(s
, ot
);
5100 gen_op_mov_reg_v(ot
, (b
& 7) | REX_B(s
), cpu_T0
);
5102 case 0x60: /* pusha */
5107 case 0x61: /* popa */
5112 case 0x68: /* push Iv */
5114 ot
= mo_pushpop(s
, dflag
);
5116 val
= insn_get(env
, s
, ot
);
5118 val
= (int8_t)insn_get(env
, s
, MO_8
);
5119 tcg_gen_movi_tl(cpu_T0
, val
);
5120 gen_push_v(s
, cpu_T0
);
5122 case 0x8f: /* pop Ev */
5123 modrm
= cpu_ldub_code(env
, s
->pc
++);
5124 mod
= (modrm
>> 6) & 3;
5127 /* NOTE: order is important for pop %sp */
5128 gen_pop_update(s
, ot
);
5129 rm
= (modrm
& 7) | REX_B(s
);
5130 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
5132 /* NOTE: order is important too for MMU exceptions */
5133 s
->popl_esp_hack
= 1 << ot
;
5134 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5135 s
->popl_esp_hack
= 0;
5136 gen_pop_update(s
, ot
);
5139 case 0xc8: /* enter */
5142 val
= cpu_lduw_code(env
, s
->pc
);
5144 level
= cpu_ldub_code(env
, s
->pc
++);
5145 gen_enter(s
, val
, level
);
5148 case 0xc9: /* leave */
5151 case 0x06: /* push es */
5152 case 0x0e: /* push cs */
5153 case 0x16: /* push ss */
5154 case 0x1e: /* push ds */
5157 gen_op_movl_T0_seg(b
>> 3);
5158 gen_push_v(s
, cpu_T0
);
5160 case 0x1a0: /* push fs */
5161 case 0x1a8: /* push gs */
5162 gen_op_movl_T0_seg((b
>> 3) & 7);
5163 gen_push_v(s
, cpu_T0
);
5165 case 0x07: /* pop es */
5166 case 0x17: /* pop ss */
5167 case 0x1f: /* pop ds */
5172 gen_movl_seg_T0(s
, reg
);
5173 gen_pop_update(s
, ot
);
5175 /* if reg == SS, inhibit interrupts/trace. */
5176 /* If several instructions disable interrupts, only the
5178 gen_set_hflag(s
, HF_INHIBIT_IRQ_MASK
);
5182 gen_jmp_im(s
->pc
- s
->cs_base
);
5186 case 0x1a1: /* pop fs */
5187 case 0x1a9: /* pop gs */
5189 gen_movl_seg_T0(s
, (b
>> 3) & 7);
5190 gen_pop_update(s
, ot
);
5192 gen_jmp_im(s
->pc
- s
->cs_base
);
5197 /**************************/
5200 case 0x89: /* mov Gv, Ev */
5201 ot
= mo_b_d(b
, dflag
);
5202 modrm
= cpu_ldub_code(env
, s
->pc
++);
5203 reg
= ((modrm
>> 3) & 7) | rex_r
;
5205 /* generate a generic store */
5206 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
5209 case 0xc7: /* mov Ev, Iv */
5210 ot
= mo_b_d(b
, dflag
);
5211 modrm
= cpu_ldub_code(env
, s
->pc
++);
5212 mod
= (modrm
>> 6) & 3;
5214 s
->rip_offset
= insn_const_size(ot
);
5215 gen_lea_modrm(env
, s
, modrm
);
5217 val
= insn_get(env
, s
, ot
);
5218 tcg_gen_movi_tl(cpu_T0
, val
);
5220 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
5222 gen_op_mov_reg_v(ot
, (modrm
& 7) | REX_B(s
), cpu_T0
);
5226 case 0x8b: /* mov Ev, Gv */
5227 ot
= mo_b_d(b
, dflag
);
5228 modrm
= cpu_ldub_code(env
, s
->pc
++);
5229 reg
= ((modrm
>> 3) & 7) | rex_r
;
5231 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5232 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
5234 case 0x8e: /* mov seg, Gv */
5235 modrm
= cpu_ldub_code(env
, s
->pc
++);
5236 reg
= (modrm
>> 3) & 7;
5237 if (reg
>= 6 || reg
== R_CS
)
5239 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
5240 gen_movl_seg_T0(s
, reg
);
5242 /* if reg == SS, inhibit interrupts/trace */
5243 /* If several instructions disable interrupts, only the
5245 gen_set_hflag(s
, HF_INHIBIT_IRQ_MASK
);
5249 gen_jmp_im(s
->pc
- s
->cs_base
);
5253 case 0x8c: /* mov Gv, seg */
5254 modrm
= cpu_ldub_code(env
, s
->pc
++);
5255 reg
= (modrm
>> 3) & 7;
5256 mod
= (modrm
>> 6) & 3;
5259 gen_op_movl_T0_seg(reg
);
5260 ot
= mod
== 3 ? dflag
: MO_16
;
5261 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5264 case 0x1b6: /* movzbS Gv, Eb */
5265 case 0x1b7: /* movzwS Gv, Eb */
5266 case 0x1be: /* movsbS Gv, Eb */
5267 case 0x1bf: /* movswS Gv, Eb */
5272 /* d_ot is the size of destination */
5274 /* ot is the size of source */
5275 ot
= (b
& 1) + MO_8
;
5276 /* s_ot is the sign+size of source */
5277 s_ot
= b
& 8 ? MO_SIGN
| ot
: ot
;
5279 modrm
= cpu_ldub_code(env
, s
->pc
++);
5280 reg
= ((modrm
>> 3) & 7) | rex_r
;
5281 mod
= (modrm
>> 6) & 3;
5282 rm
= (modrm
& 7) | REX_B(s
);
5285 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
5288 tcg_gen_ext8u_tl(cpu_T0
, cpu_T0
);
5291 tcg_gen_ext8s_tl(cpu_T0
, cpu_T0
);
5294 tcg_gen_ext16u_tl(cpu_T0
, cpu_T0
);
5298 tcg_gen_ext16s_tl(cpu_T0
, cpu_T0
);
5301 gen_op_mov_reg_v(d_ot
, reg
, cpu_T0
);
5303 gen_lea_modrm(env
, s
, modrm
);
5304 gen_op_ld_v(s
, s_ot
, cpu_T0
, cpu_A0
);
5305 gen_op_mov_reg_v(d_ot
, reg
, cpu_T0
);
5310 case 0x8d: /* lea */
5311 modrm
= cpu_ldub_code(env
, s
->pc
++);
5312 mod
= (modrm
>> 6) & 3;
5315 reg
= ((modrm
>> 3) & 7) | rex_r
;
5317 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
5318 TCGv ea
= gen_lea_modrm_1(a
);
5319 gen_op_mov_reg_v(dflag
, reg
, ea
);
5323 case 0xa0: /* mov EAX, Ov */
5325 case 0xa2: /* mov Ov, EAX */
5328 target_ulong offset_addr
;
5330 ot
= mo_b_d(b
, dflag
);
5332 #ifdef TARGET_X86_64
5334 offset_addr
= cpu_ldq_code(env
, s
->pc
);
5339 offset_addr
= insn_get(env
, s
, s
->aflag
);
5342 tcg_gen_movi_tl(cpu_A0
, offset_addr
);
5343 gen_add_A0_ds_seg(s
);
5345 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
5346 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T0
);
5348 gen_op_mov_v_reg(ot
, cpu_T0
, R_EAX
);
5349 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
5353 case 0xd7: /* xlat */
5354 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EBX
]);
5355 tcg_gen_ext8u_tl(cpu_T0
, cpu_regs
[R_EAX
]);
5356 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_T0
);
5357 gen_extu(s
->aflag
, cpu_A0
);
5358 gen_add_A0_ds_seg(s
);
5359 gen_op_ld_v(s
, MO_8
, cpu_T0
, cpu_A0
);
5360 gen_op_mov_reg_v(MO_8
, R_EAX
, cpu_T0
);
5362 case 0xb0 ... 0xb7: /* mov R, Ib */
5363 val
= insn_get(env
, s
, MO_8
);
5364 tcg_gen_movi_tl(cpu_T0
, val
);
5365 gen_op_mov_reg_v(MO_8
, (b
& 7) | REX_B(s
), cpu_T0
);
5367 case 0xb8 ... 0xbf: /* mov R, Iv */
5368 #ifdef TARGET_X86_64
5369 if (dflag
== MO_64
) {
5372 tmp
= cpu_ldq_code(env
, s
->pc
);
5374 reg
= (b
& 7) | REX_B(s
);
5375 tcg_gen_movi_tl(cpu_T0
, tmp
);
5376 gen_op_mov_reg_v(MO_64
, reg
, cpu_T0
);
5381 val
= insn_get(env
, s
, ot
);
5382 reg
= (b
& 7) | REX_B(s
);
5383 tcg_gen_movi_tl(cpu_T0
, val
);
5384 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
5388 case 0x91 ... 0x97: /* xchg R, EAX */
5391 reg
= (b
& 7) | REX_B(s
);
5395 case 0x87: /* xchg Ev, Gv */
5396 ot
= mo_b_d(b
, dflag
);
5397 modrm
= cpu_ldub_code(env
, s
->pc
++);
5398 reg
= ((modrm
>> 3) & 7) | rex_r
;
5399 mod
= (modrm
>> 6) & 3;
5401 rm
= (modrm
& 7) | REX_B(s
);
5403 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
5404 gen_op_mov_v_reg(ot
, cpu_T1
, rm
);
5405 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
5406 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
5408 gen_lea_modrm(env
, s
, modrm
);
5409 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
5410 /* for xchg, lock is implicit */
5411 if (!(prefixes
& PREFIX_LOCK
))
5413 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
5414 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
5415 if (!(prefixes
& PREFIX_LOCK
))
5416 gen_helper_unlock();
5417 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
5420 case 0xc4: /* les Gv */
5421 /* In CODE64 this is VEX3; see above. */
5424 case 0xc5: /* lds Gv */
5425 /* In CODE64 this is VEX2; see above. */
5428 case 0x1b2: /* lss Gv */
5431 case 0x1b4: /* lfs Gv */
5434 case 0x1b5: /* lgs Gv */
5437 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
5438 modrm
= cpu_ldub_code(env
, s
->pc
++);
5439 reg
= ((modrm
>> 3) & 7) | rex_r
;
5440 mod
= (modrm
>> 6) & 3;
5443 gen_lea_modrm(env
, s
, modrm
);
5444 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
5445 gen_add_A0_im(s
, 1 << ot
);
5446 /* load the segment first to handle exceptions properly */
5447 gen_op_ld_v(s
, MO_16
, cpu_T0
, cpu_A0
);
5448 gen_movl_seg_T0(s
, op
);
5449 /* then put the data */
5450 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
5452 gen_jmp_im(s
->pc
- s
->cs_base
);
5457 /************************/
5465 ot
= mo_b_d(b
, dflag
);
5466 modrm
= cpu_ldub_code(env
, s
->pc
++);
5467 mod
= (modrm
>> 6) & 3;
5468 op
= (modrm
>> 3) & 7;
5474 gen_lea_modrm(env
, s
, modrm
);
5477 opreg
= (modrm
& 7) | REX_B(s
);
5482 gen_shift(s
, op
, ot
, opreg
, OR_ECX
);
5485 shift
= cpu_ldub_code(env
, s
->pc
++);
5487 gen_shifti(s
, op
, ot
, opreg
, shift
);
5502 case 0x1a4: /* shld imm */
5506 case 0x1a5: /* shld cl */
5510 case 0x1ac: /* shrd imm */
5514 case 0x1ad: /* shrd cl */
5519 modrm
= cpu_ldub_code(env
, s
->pc
++);
5520 mod
= (modrm
>> 6) & 3;
5521 rm
= (modrm
& 7) | REX_B(s
);
5522 reg
= ((modrm
>> 3) & 7) | rex_r
;
5524 gen_lea_modrm(env
, s
, modrm
);
5529 gen_op_mov_v_reg(ot
, cpu_T1
, reg
);
5532 TCGv imm
= tcg_const_tl(cpu_ldub_code(env
, s
->pc
++));
5533 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, imm
);
5536 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, cpu_regs
[R_ECX
]);
5540 /************************/
5543 if (s
->flags
& (HF_EM_MASK
| HF_TS_MASK
)) {
5544 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5545 /* XXX: what to do if illegal op ? */
5546 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
5549 modrm
= cpu_ldub_code(env
, s
->pc
++);
5550 mod
= (modrm
>> 6) & 3;
5552 op
= ((b
& 7) << 3) | ((modrm
>> 3) & 7);
5555 gen_lea_modrm(env
, s
, modrm
);
5557 case 0x00 ... 0x07: /* fxxxs */
5558 case 0x10 ... 0x17: /* fixxxl */
5559 case 0x20 ... 0x27: /* fxxxl */
5560 case 0x30 ... 0x37: /* fixxx */
5567 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5568 s
->mem_index
, MO_LEUL
);
5569 gen_helper_flds_FT0(cpu_env
, cpu_tmp2_i32
);
5572 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5573 s
->mem_index
, MO_LEUL
);
5574 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
5577 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
5578 s
->mem_index
, MO_LEQ
);
5579 gen_helper_fldl_FT0(cpu_env
, cpu_tmp1_i64
);
5583 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5584 s
->mem_index
, MO_LESW
);
5585 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
5589 gen_helper_fp_arith_ST0_FT0(op1
);
5591 /* fcomp needs pop */
5592 gen_helper_fpop(cpu_env
);
5596 case 0x08: /* flds */
5597 case 0x0a: /* fsts */
5598 case 0x0b: /* fstps */
5599 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5600 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5601 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5606 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5607 s
->mem_index
, MO_LEUL
);
5608 gen_helper_flds_ST0(cpu_env
, cpu_tmp2_i32
);
5611 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5612 s
->mem_index
, MO_LEUL
);
5613 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
5616 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
5617 s
->mem_index
, MO_LEQ
);
5618 gen_helper_fldl_ST0(cpu_env
, cpu_tmp1_i64
);
5622 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5623 s
->mem_index
, MO_LESW
);
5624 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
5629 /* XXX: the corresponding CPUID bit must be tested ! */
5632 gen_helper_fisttl_ST0(cpu_tmp2_i32
, cpu_env
);
5633 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5634 s
->mem_index
, MO_LEUL
);
5637 gen_helper_fisttll_ST0(cpu_tmp1_i64
, cpu_env
);
5638 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
5639 s
->mem_index
, MO_LEQ
);
5643 gen_helper_fistt_ST0(cpu_tmp2_i32
, cpu_env
);
5644 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5645 s
->mem_index
, MO_LEUW
);
5648 gen_helper_fpop(cpu_env
);
5653 gen_helper_fsts_ST0(cpu_tmp2_i32
, cpu_env
);
5654 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5655 s
->mem_index
, MO_LEUL
);
5658 gen_helper_fistl_ST0(cpu_tmp2_i32
, cpu_env
);
5659 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5660 s
->mem_index
, MO_LEUL
);
5663 gen_helper_fstl_ST0(cpu_tmp1_i64
, cpu_env
);
5664 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
5665 s
->mem_index
, MO_LEQ
);
5669 gen_helper_fist_ST0(cpu_tmp2_i32
, cpu_env
);
5670 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5671 s
->mem_index
, MO_LEUW
);
5675 gen_helper_fpop(cpu_env
);
5679 case 0x0c: /* fldenv mem */
5680 gen_helper_fldenv(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5682 case 0x0d: /* fldcw mem */
5683 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5684 s
->mem_index
, MO_LEUW
);
5685 gen_helper_fldcw(cpu_env
, cpu_tmp2_i32
);
5687 case 0x0e: /* fnstenv mem */
5688 gen_helper_fstenv(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5690 case 0x0f: /* fnstcw mem */
5691 gen_helper_fnstcw(cpu_tmp2_i32
, cpu_env
);
5692 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5693 s
->mem_index
, MO_LEUW
);
5695 case 0x1d: /* fldt mem */
5696 gen_helper_fldt_ST0(cpu_env
, cpu_A0
);
5698 case 0x1f: /* fstpt mem */
5699 gen_helper_fstt_ST0(cpu_env
, cpu_A0
);
5700 gen_helper_fpop(cpu_env
);
5702 case 0x2c: /* frstor mem */
5703 gen_helper_frstor(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5705 case 0x2e: /* fnsave mem */
5706 gen_helper_fsave(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5708 case 0x2f: /* fnstsw mem */
5709 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
5710 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5711 s
->mem_index
, MO_LEUW
);
5713 case 0x3c: /* fbld */
5714 gen_helper_fbld_ST0(cpu_env
, cpu_A0
);
5716 case 0x3e: /* fbstp */
5717 gen_helper_fbst_ST0(cpu_env
, cpu_A0
);
5718 gen_helper_fpop(cpu_env
);
5720 case 0x3d: /* fildll */
5721 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
5722 gen_helper_fildll_ST0(cpu_env
, cpu_tmp1_i64
);
5724 case 0x3f: /* fistpll */
5725 gen_helper_fistll_ST0(cpu_tmp1_i64
, cpu_env
);
5726 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
5727 gen_helper_fpop(cpu_env
);
5733 /* register float ops */
5737 case 0x08: /* fld sti */
5738 gen_helper_fpush(cpu_env
);
5739 gen_helper_fmov_ST0_STN(cpu_env
,
5740 tcg_const_i32((opreg
+ 1) & 7));
5742 case 0x09: /* fxchg sti */
5743 case 0x29: /* fxchg4 sti, undocumented op */
5744 case 0x39: /* fxchg7 sti, undocumented op */
5745 gen_helper_fxchg_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
5747 case 0x0a: /* grp d9/2 */
5750 /* check exceptions (FreeBSD FPU probe) */
5751 gen_helper_fwait(cpu_env
);
5757 case 0x0c: /* grp d9/4 */
5760 gen_helper_fchs_ST0(cpu_env
);
5763 gen_helper_fabs_ST0(cpu_env
);
5766 gen_helper_fldz_FT0(cpu_env
);
5767 gen_helper_fcom_ST0_FT0(cpu_env
);
5770 gen_helper_fxam_ST0(cpu_env
);
5776 case 0x0d: /* grp d9/5 */
5780 gen_helper_fpush(cpu_env
);
5781 gen_helper_fld1_ST0(cpu_env
);
5784 gen_helper_fpush(cpu_env
);
5785 gen_helper_fldl2t_ST0(cpu_env
);
5788 gen_helper_fpush(cpu_env
);
5789 gen_helper_fldl2e_ST0(cpu_env
);
5792 gen_helper_fpush(cpu_env
);
5793 gen_helper_fldpi_ST0(cpu_env
);
5796 gen_helper_fpush(cpu_env
);
5797 gen_helper_fldlg2_ST0(cpu_env
);
5800 gen_helper_fpush(cpu_env
);
5801 gen_helper_fldln2_ST0(cpu_env
);
5804 gen_helper_fpush(cpu_env
);
5805 gen_helper_fldz_ST0(cpu_env
);
5812 case 0x0e: /* grp d9/6 */
5815 gen_helper_f2xm1(cpu_env
);
5818 gen_helper_fyl2x(cpu_env
);
5821 gen_helper_fptan(cpu_env
);
5823 case 3: /* fpatan */
5824 gen_helper_fpatan(cpu_env
);
5826 case 4: /* fxtract */
5827 gen_helper_fxtract(cpu_env
);
5829 case 5: /* fprem1 */
5830 gen_helper_fprem1(cpu_env
);
5832 case 6: /* fdecstp */
5833 gen_helper_fdecstp(cpu_env
);
5836 case 7: /* fincstp */
5837 gen_helper_fincstp(cpu_env
);
5841 case 0x0f: /* grp d9/7 */
5844 gen_helper_fprem(cpu_env
);
5846 case 1: /* fyl2xp1 */
5847 gen_helper_fyl2xp1(cpu_env
);
5850 gen_helper_fsqrt(cpu_env
);
5852 case 3: /* fsincos */
5853 gen_helper_fsincos(cpu_env
);
5855 case 5: /* fscale */
5856 gen_helper_fscale(cpu_env
);
5858 case 4: /* frndint */
5859 gen_helper_frndint(cpu_env
);
5862 gen_helper_fsin(cpu_env
);
5866 gen_helper_fcos(cpu_env
);
5870 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
5871 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
5872 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
5878 gen_helper_fp_arith_STN_ST0(op1
, opreg
);
5880 gen_helper_fpop(cpu_env
);
5882 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
5883 gen_helper_fp_arith_ST0_FT0(op1
);
5887 case 0x02: /* fcom */
5888 case 0x22: /* fcom2, undocumented op */
5889 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
5890 gen_helper_fcom_ST0_FT0(cpu_env
);
5892 case 0x03: /* fcomp */
5893 case 0x23: /* fcomp3, undocumented op */
5894 case 0x32: /* fcomp5, undocumented op */
5895 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
5896 gen_helper_fcom_ST0_FT0(cpu_env
);
5897 gen_helper_fpop(cpu_env
);
5899 case 0x15: /* da/5 */
5901 case 1: /* fucompp */
5902 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
5903 gen_helper_fucom_ST0_FT0(cpu_env
);
5904 gen_helper_fpop(cpu_env
);
5905 gen_helper_fpop(cpu_env
);
5913 case 0: /* feni (287 only, just do nop here) */
5915 case 1: /* fdisi (287 only, just do nop here) */
5918 gen_helper_fclex(cpu_env
);
5920 case 3: /* fninit */
5921 gen_helper_fninit(cpu_env
);
5923 case 4: /* fsetpm (287 only, just do nop here) */
5929 case 0x1d: /* fucomi */
5930 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
5933 gen_update_cc_op(s
);
5934 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
5935 gen_helper_fucomi_ST0_FT0(cpu_env
);
5936 set_cc_op(s
, CC_OP_EFLAGS
);
5938 case 0x1e: /* fcomi */
5939 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
5942 gen_update_cc_op(s
);
5943 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
5944 gen_helper_fcomi_ST0_FT0(cpu_env
);
5945 set_cc_op(s
, CC_OP_EFLAGS
);
5947 case 0x28: /* ffree sti */
5948 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
5950 case 0x2a: /* fst sti */
5951 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
5953 case 0x2b: /* fstp sti */
5954 case 0x0b: /* fstp1 sti, undocumented op */
5955 case 0x3a: /* fstp8 sti, undocumented op */
5956 case 0x3b: /* fstp9 sti, undocumented op */
5957 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
5958 gen_helper_fpop(cpu_env
);
5960 case 0x2c: /* fucom st(i) */
5961 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
5962 gen_helper_fucom_ST0_FT0(cpu_env
);
5964 case 0x2d: /* fucomp st(i) */
5965 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
5966 gen_helper_fucom_ST0_FT0(cpu_env
);
5967 gen_helper_fpop(cpu_env
);
5969 case 0x33: /* de/3 */
5971 case 1: /* fcompp */
5972 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
5973 gen_helper_fcom_ST0_FT0(cpu_env
);
5974 gen_helper_fpop(cpu_env
);
5975 gen_helper_fpop(cpu_env
);
5981 case 0x38: /* ffreep sti, undocumented op */
5982 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
5983 gen_helper_fpop(cpu_env
);
5985 case 0x3c: /* df/4 */
5988 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
5989 tcg_gen_extu_i32_tl(cpu_T0
, cpu_tmp2_i32
);
5990 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
5996 case 0x3d: /* fucomip */
5997 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6000 gen_update_cc_op(s
);
6001 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6002 gen_helper_fucomi_ST0_FT0(cpu_env
);
6003 gen_helper_fpop(cpu_env
);
6004 set_cc_op(s
, CC_OP_EFLAGS
);
6006 case 0x3e: /* fcomip */
6007 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6010 gen_update_cc_op(s
);
6011 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6012 gen_helper_fcomi_ST0_FT0(cpu_env
);
6013 gen_helper_fpop(cpu_env
);
6014 set_cc_op(s
, CC_OP_EFLAGS
);
6016 case 0x10 ... 0x13: /* fcmovxx */
6021 static const uint8_t fcmov_cc
[8] = {
6028 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6031 op1
= fcmov_cc
[op
& 3] | (((op
>> 3) & 1) ^ 1);
6032 l1
= gen_new_label();
6033 gen_jcc1_noeob(s
, op1
, l1
);
6034 gen_helper_fmov_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6043 /************************/
6046 case 0xa4: /* movsS */
6048 ot
= mo_b_d(b
, dflag
);
6049 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6050 gen_repz_movs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6056 case 0xaa: /* stosS */
6058 ot
= mo_b_d(b
, dflag
);
6059 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6060 gen_repz_stos(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6065 case 0xac: /* lodsS */
6067 ot
= mo_b_d(b
, dflag
);
6068 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6069 gen_repz_lods(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6074 case 0xae: /* scasS */
6076 ot
= mo_b_d(b
, dflag
);
6077 if (prefixes
& PREFIX_REPNZ
) {
6078 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6079 } else if (prefixes
& PREFIX_REPZ
) {
6080 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6086 case 0xa6: /* cmpsS */
6088 ot
= mo_b_d(b
, dflag
);
6089 if (prefixes
& PREFIX_REPNZ
) {
6090 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6091 } else if (prefixes
& PREFIX_REPZ
) {
6092 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6097 case 0x6c: /* insS */
6099 ot
= mo_b_d32(b
, dflag
);
6100 tcg_gen_ext16u_tl(cpu_T0
, cpu_regs
[R_EDX
]);
6101 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6102 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
) | 4);
6103 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6104 gen_repz_ins(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6107 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6108 gen_jmp(s
, s
->pc
- s
->cs_base
);
6112 case 0x6e: /* outsS */
6114 ot
= mo_b_d32(b
, dflag
);
6115 tcg_gen_ext16u_tl(cpu_T0
, cpu_regs
[R_EDX
]);
6116 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6117 svm_is_rep(prefixes
) | 4);
6118 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6119 gen_repz_outs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6122 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6123 gen_jmp(s
, s
->pc
- s
->cs_base
);
6128 /************************/
6133 ot
= mo_b_d32(b
, dflag
);
6134 val
= cpu_ldub_code(env
, s
->pc
++);
6135 tcg_gen_movi_tl(cpu_T0
, val
);
6136 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6137 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6138 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6141 tcg_gen_movi_i32(cpu_tmp2_i32
, val
);
6142 gen_helper_in_func(ot
, cpu_T1
, cpu_tmp2_i32
);
6143 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T1
);
6144 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6145 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6147 gen_jmp(s
, s
->pc
- s
->cs_base
);
6152 ot
= mo_b_d32(b
, dflag
);
6153 val
= cpu_ldub_code(env
, s
->pc
++);
6154 tcg_gen_movi_tl(cpu_T0
, val
);
6155 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6156 svm_is_rep(prefixes
));
6157 gen_op_mov_v_reg(ot
, cpu_T1
, R_EAX
);
6159 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6162 tcg_gen_movi_i32(cpu_tmp2_i32
, val
);
6163 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T1
);
6164 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6165 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6166 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6168 gen_jmp(s
, s
->pc
- s
->cs_base
);
6173 ot
= mo_b_d32(b
, dflag
);
6174 tcg_gen_ext16u_tl(cpu_T0
, cpu_regs
[R_EDX
]);
6175 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6176 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6177 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6180 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
6181 gen_helper_in_func(ot
, cpu_T1
, cpu_tmp2_i32
);
6182 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T1
);
6183 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6184 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6186 gen_jmp(s
, s
->pc
- s
->cs_base
);
6191 ot
= mo_b_d32(b
, dflag
);
6192 tcg_gen_ext16u_tl(cpu_T0
, cpu_regs
[R_EDX
]);
6193 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6194 svm_is_rep(prefixes
));
6195 gen_op_mov_v_reg(ot
, cpu_T1
, R_EAX
);
6197 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6200 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
6201 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T1
);
6202 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6203 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6204 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6206 gen_jmp(s
, s
->pc
- s
->cs_base
);
6210 /************************/
6212 case 0xc2: /* ret im */
6213 val
= cpu_ldsw_code(env
, s
->pc
);
6216 gen_stack_update(s
, val
+ (1 << ot
));
6217 /* Note that gen_pop_T0 uses a zero-extending load. */
6218 gen_op_jmp_v(cpu_T0
);
6222 case 0xc3: /* ret */
6224 gen_pop_update(s
, ot
);
6225 /* Note that gen_pop_T0 uses a zero-extending load. */
6226 gen_op_jmp_v(cpu_T0
);
6230 case 0xca: /* lret im */
6231 val
= cpu_ldsw_code(env
, s
->pc
);
6234 if (s
->pe
&& !s
->vm86
) {
6235 gen_update_cc_op(s
);
6236 gen_jmp_im(pc_start
- s
->cs_base
);
6237 gen_helper_lret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6238 tcg_const_i32(val
));
6242 gen_op_ld_v(s
, dflag
, cpu_T0
, cpu_A0
);
6243 /* NOTE: keeping EIP updated is not a problem in case of
6245 gen_op_jmp_v(cpu_T0
);
6247 gen_add_A0_im(s
, 1 << dflag
);
6248 gen_op_ld_v(s
, dflag
, cpu_T0
, cpu_A0
);
6249 gen_op_movl_seg_T0_vm(R_CS
);
6250 /* add stack offset */
6251 gen_stack_update(s
, val
+ (2 << dflag
));
6255 case 0xcb: /* lret */
6258 case 0xcf: /* iret */
6259 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IRET
);
6262 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6263 set_cc_op(s
, CC_OP_EFLAGS
);
6264 } else if (s
->vm86
) {
6266 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6268 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6269 set_cc_op(s
, CC_OP_EFLAGS
);
6272 gen_helper_iret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6273 tcg_const_i32(s
->pc
- s
->cs_base
));
6274 set_cc_op(s
, CC_OP_EFLAGS
);
6278 case 0xe8: /* call im */
6280 if (dflag
!= MO_16
) {
6281 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6283 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6285 next_eip
= s
->pc
- s
->cs_base
;
6287 if (dflag
== MO_16
) {
6289 } else if (!CODE64(s
)) {
6292 tcg_gen_movi_tl(cpu_T0
, next_eip
);
6293 gen_push_v(s
, cpu_T0
);
6298 case 0x9a: /* lcall im */
6300 unsigned int selector
, offset
;
6305 offset
= insn_get(env
, s
, ot
);
6306 selector
= insn_get(env
, s
, MO_16
);
6308 tcg_gen_movi_tl(cpu_T0
, selector
);
6309 tcg_gen_movi_tl(cpu_T1
, offset
);
6312 case 0xe9: /* jmp im */
6313 if (dflag
!= MO_16
) {
6314 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6316 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6318 tval
+= s
->pc
- s
->cs_base
;
6319 if (dflag
== MO_16
) {
6321 } else if (!CODE64(s
)) {
6327 case 0xea: /* ljmp im */
6329 unsigned int selector
, offset
;
6334 offset
= insn_get(env
, s
, ot
);
6335 selector
= insn_get(env
, s
, MO_16
);
6337 tcg_gen_movi_tl(cpu_T0
, selector
);
6338 tcg_gen_movi_tl(cpu_T1
, offset
);
6341 case 0xeb: /* jmp Jb */
6342 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6343 tval
+= s
->pc
- s
->cs_base
;
6344 if (dflag
== MO_16
) {
6349 case 0x70 ... 0x7f: /* jcc Jb */
6350 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6352 case 0x180 ... 0x18f: /* jcc Jv */
6353 if (dflag
!= MO_16
) {
6354 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6356 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6359 next_eip
= s
->pc
- s
->cs_base
;
6361 if (dflag
== MO_16
) {
6365 gen_jcc(s
, b
, tval
, next_eip
);
6368 case 0x190 ... 0x19f: /* setcc Gv */
6369 modrm
= cpu_ldub_code(env
, s
->pc
++);
6370 gen_setcc1(s
, b
, cpu_T0
);
6371 gen_ldst_modrm(env
, s
, modrm
, MO_8
, OR_TMP0
, 1);
6373 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6374 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6378 modrm
= cpu_ldub_code(env
, s
->pc
++);
6379 reg
= ((modrm
>> 3) & 7) | rex_r
;
6380 gen_cmovcc1(env
, s
, ot
, b
, modrm
, reg
);
6383 /************************/
6385 case 0x9c: /* pushf */
6386 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_PUSHF
);
6387 if (s
->vm86
&& s
->iopl
!= 3) {
6388 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6390 gen_update_cc_op(s
);
6391 gen_helper_read_eflags(cpu_T0
, cpu_env
);
6392 gen_push_v(s
, cpu_T0
);
6395 case 0x9d: /* popf */
6396 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_POPF
);
6397 if (s
->vm86
&& s
->iopl
!= 3) {
6398 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6402 if (dflag
!= MO_16
) {
6403 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6404 tcg_const_i32((TF_MASK
| AC_MASK
|
6409 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6410 tcg_const_i32((TF_MASK
| AC_MASK
|
6412 IF_MASK
| IOPL_MASK
)
6416 if (s
->cpl
<= s
->iopl
) {
6417 if (dflag
!= MO_16
) {
6418 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6419 tcg_const_i32((TF_MASK
|
6425 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6426 tcg_const_i32((TF_MASK
|
6434 if (dflag
!= MO_16
) {
6435 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6436 tcg_const_i32((TF_MASK
| AC_MASK
|
6437 ID_MASK
| NT_MASK
)));
6439 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6440 tcg_const_i32((TF_MASK
| AC_MASK
|
6446 gen_pop_update(s
, ot
);
6447 set_cc_op(s
, CC_OP_EFLAGS
);
6448 /* abort translation because TF/AC flag may change */
6449 gen_jmp_im(s
->pc
- s
->cs_base
);
6453 case 0x9e: /* sahf */
6454 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6456 gen_op_mov_v_reg(MO_8
, cpu_T0
, R_AH
);
6457 gen_compute_eflags(s
);
6458 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, CC_O
);
6459 tcg_gen_andi_tl(cpu_T0
, cpu_T0
, CC_S
| CC_Z
| CC_A
| CC_P
| CC_C
);
6460 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, cpu_T0
);
6462 case 0x9f: /* lahf */
6463 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6465 gen_compute_eflags(s
);
6466 /* Note: gen_compute_eflags() only gives the condition codes */
6467 tcg_gen_ori_tl(cpu_T0
, cpu_cc_src
, 0x02);
6468 gen_op_mov_reg_v(MO_8
, R_AH
, cpu_T0
);
6470 case 0xf5: /* cmc */
6471 gen_compute_eflags(s
);
6472 tcg_gen_xori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6474 case 0xf8: /* clc */
6475 gen_compute_eflags(s
);
6476 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_C
);
6478 case 0xf9: /* stc */
6479 gen_compute_eflags(s
);
6480 tcg_gen_ori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6482 case 0xfc: /* cld */
6483 tcg_gen_movi_i32(cpu_tmp2_i32
, 1);
6484 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6486 case 0xfd: /* std */
6487 tcg_gen_movi_i32(cpu_tmp2_i32
, -1);
6488 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6491 /************************/
6492 /* bit operations */
6493 case 0x1ba: /* bt/bts/btr/btc Gv, im */
6495 modrm
= cpu_ldub_code(env
, s
->pc
++);
6496 op
= (modrm
>> 3) & 7;
6497 mod
= (modrm
>> 6) & 3;
6498 rm
= (modrm
& 7) | REX_B(s
);
6501 gen_lea_modrm(env
, s
, modrm
);
6502 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
6504 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
6507 val
= cpu_ldub_code(env
, s
->pc
++);
6508 tcg_gen_movi_tl(cpu_T1
, val
);
6513 case 0x1a3: /* bt Gv, Ev */
6516 case 0x1ab: /* bts */
6519 case 0x1b3: /* btr */
6522 case 0x1bb: /* btc */
6526 modrm
= cpu_ldub_code(env
, s
->pc
++);
6527 reg
= ((modrm
>> 3) & 7) | rex_r
;
6528 mod
= (modrm
>> 6) & 3;
6529 rm
= (modrm
& 7) | REX_B(s
);
6530 gen_op_mov_v_reg(MO_32
, cpu_T1
, reg
);
6532 gen_lea_modrm(env
, s
, modrm
);
6533 /* specific case: we need to add a displacement */
6534 gen_exts(ot
, cpu_T1
);
6535 tcg_gen_sari_tl(cpu_tmp0
, cpu_T1
, 3 + ot
);
6536 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, ot
);
6537 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
6538 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
6540 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
6543 tcg_gen_andi_tl(cpu_T1
, cpu_T1
, (1 << (3 + ot
)) - 1);
6544 tcg_gen_shr_tl(cpu_tmp4
, cpu_T0
, cpu_T1
);
6549 tcg_gen_movi_tl(cpu_tmp0
, 1);
6550 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T1
);
6551 tcg_gen_or_tl(cpu_T0
, cpu_T0
, cpu_tmp0
);
6554 tcg_gen_movi_tl(cpu_tmp0
, 1);
6555 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T1
);
6556 tcg_gen_andc_tl(cpu_T0
, cpu_T0
, cpu_tmp0
);
6560 tcg_gen_movi_tl(cpu_tmp0
, 1);
6561 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T1
);
6562 tcg_gen_xor_tl(cpu_T0
, cpu_T0
, cpu_tmp0
);
6567 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
6569 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
6573 /* Delay all CC updates until after the store above. Note that
6574 C is the result of the test, Z is unchanged, and the others
6575 are all undefined. */
6577 case CC_OP_MULB
... CC_OP_MULQ
:
6578 case CC_OP_ADDB
... CC_OP_ADDQ
:
6579 case CC_OP_ADCB
... CC_OP_ADCQ
:
6580 case CC_OP_SUBB
... CC_OP_SUBQ
:
6581 case CC_OP_SBBB
... CC_OP_SBBQ
:
6582 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
6583 case CC_OP_INCB
... CC_OP_INCQ
:
6584 case CC_OP_DECB
... CC_OP_DECQ
:
6585 case CC_OP_SHLB
... CC_OP_SHLQ
:
6586 case CC_OP_SARB
... CC_OP_SARQ
:
6587 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
6588 /* Z was going to be computed from the non-zero status of CC_DST.
6589 We can get that same Z value (and the new C value) by leaving
6590 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
6592 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
6593 set_cc_op(s
, ((s
->cc_op
- CC_OP_MULB
) & 3) + CC_OP_SARB
);
6596 /* Otherwise, generate EFLAGS and replace the C bit. */
6597 gen_compute_eflags(s
);
6598 tcg_gen_deposit_tl(cpu_cc_src
, cpu_cc_src
, cpu_tmp4
,
6603 case 0x1bc: /* bsf / tzcnt */
6604 case 0x1bd: /* bsr / lzcnt */
6606 modrm
= cpu_ldub_code(env
, s
->pc
++);
6607 reg
= ((modrm
>> 3) & 7) | rex_r
;
6608 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
6609 gen_extu(ot
, cpu_T0
);
6611 /* Note that lzcnt and tzcnt are in different extensions. */
6612 if ((prefixes
& PREFIX_REPZ
)
6614 ? s
->cpuid_ext3_features
& CPUID_EXT3_ABM
6615 : s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)) {
6617 tcg_gen_mov_tl(cpu_cc_src
, cpu_T0
);
6619 /* For lzcnt, reduce the target_ulong result by the
6620 number of zeros that we expect to find at the top. */
6621 gen_helper_clz(cpu_T0
, cpu_T0
);
6622 tcg_gen_subi_tl(cpu_T0
, cpu_T0
, TARGET_LONG_BITS
- size
);
6624 /* For tzcnt, a zero input must return the operand size:
6625 force all bits outside the operand size to 1. */
6626 target_ulong mask
= (target_ulong
)-2 << (size
- 1);
6627 tcg_gen_ori_tl(cpu_T0
, cpu_T0
, mask
);
6628 gen_helper_ctz(cpu_T0
, cpu_T0
);
6630 /* For lzcnt/tzcnt, C and Z bits are defined and are
6631 related to the result. */
6632 gen_op_update1_cc();
6633 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
6635 /* For bsr/bsf, only the Z bit is defined and it is related
6636 to the input and not the result. */
6637 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
6638 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
6640 /* For bsr, return the bit index of the first 1 bit,
6641 not the count of leading zeros. */
6642 gen_helper_clz(cpu_T0
, cpu_T0
);
6643 tcg_gen_xori_tl(cpu_T0
, cpu_T0
, TARGET_LONG_BITS
- 1);
6645 gen_helper_ctz(cpu_T0
, cpu_T0
);
6647 /* ??? The manual says that the output is undefined when the
6648 input is zero, but real hardware leaves it unchanged, and
6649 real programs appear to depend on that. */
6650 tcg_gen_movi_tl(cpu_tmp0
, 0);
6651 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_T0
, cpu_cc_dst
, cpu_tmp0
,
6652 cpu_regs
[reg
], cpu_T0
);
6654 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
6656 /************************/
6658 case 0x27: /* daa */
6661 gen_update_cc_op(s
);
6662 gen_helper_daa(cpu_env
);
6663 set_cc_op(s
, CC_OP_EFLAGS
);
6665 case 0x2f: /* das */
6668 gen_update_cc_op(s
);
6669 gen_helper_das(cpu_env
);
6670 set_cc_op(s
, CC_OP_EFLAGS
);
6672 case 0x37: /* aaa */
6675 gen_update_cc_op(s
);
6676 gen_helper_aaa(cpu_env
);
6677 set_cc_op(s
, CC_OP_EFLAGS
);
6679 case 0x3f: /* aas */
6682 gen_update_cc_op(s
);
6683 gen_helper_aas(cpu_env
);
6684 set_cc_op(s
, CC_OP_EFLAGS
);
6686 case 0xd4: /* aam */
6689 val
= cpu_ldub_code(env
, s
->pc
++);
6691 gen_exception(s
, EXCP00_DIVZ
, pc_start
- s
->cs_base
);
6693 gen_helper_aam(cpu_env
, tcg_const_i32(val
));
6694 set_cc_op(s
, CC_OP_LOGICB
);
6697 case 0xd5: /* aad */
6700 val
= cpu_ldub_code(env
, s
->pc
++);
6701 gen_helper_aad(cpu_env
, tcg_const_i32(val
));
6702 set_cc_op(s
, CC_OP_LOGICB
);
6704 /************************/
6706 case 0x90: /* nop */
6707 /* XXX: correct lock test for all insn */
6708 if (prefixes
& PREFIX_LOCK
) {
6711 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
6713 goto do_xchg_reg_eax
;
6715 if (prefixes
& PREFIX_REPZ
) {
6716 gen_update_cc_op(s
);
6717 gen_jmp_im(pc_start
- s
->cs_base
);
6718 gen_helper_pause(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
6719 s
->is_jmp
= DISAS_TB_JUMP
;
6722 case 0x9b: /* fwait */
6723 if ((s
->flags
& (HF_MP_MASK
| HF_TS_MASK
)) ==
6724 (HF_MP_MASK
| HF_TS_MASK
)) {
6725 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
6727 gen_helper_fwait(cpu_env
);
6730 case 0xcc: /* int3 */
6731 gen_interrupt(s
, EXCP03_INT3
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6733 case 0xcd: /* int N */
6734 val
= cpu_ldub_code(env
, s
->pc
++);
6735 if (s
->vm86
&& s
->iopl
!= 3) {
6736 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6738 gen_interrupt(s
, val
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6741 case 0xce: /* into */
6744 gen_update_cc_op(s
);
6745 gen_jmp_im(pc_start
- s
->cs_base
);
6746 gen_helper_into(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
6749 case 0xf1: /* icebp (undocumented, exits to external debugger) */
6750 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_ICEBP
);
6752 gen_debug(s
, pc_start
- s
->cs_base
);
6755 tb_flush(CPU(x86_env_get_cpu(env
)));
6756 qemu_set_log(CPU_LOG_INT
| CPU_LOG_TB_IN_ASM
);
6760 case 0xfa: /* cli */
6762 if (s
->cpl
<= s
->iopl
) {
6763 gen_helper_cli(cpu_env
);
6765 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6769 gen_helper_cli(cpu_env
);
6771 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6775 case 0xfb: /* sti */
6777 if (s
->cpl
<= s
->iopl
) {
6779 gen_helper_sti(cpu_env
);
6780 /* interruptions are enabled only the first insn after sti */
6781 /* If several instructions disable interrupts, only the
6783 gen_set_hflag(s
, HF_INHIBIT_IRQ_MASK
);
6784 /* give a chance to handle pending irqs */
6785 gen_jmp_im(s
->pc
- s
->cs_base
);
6788 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6794 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6798 case 0x62: /* bound */
6802 modrm
= cpu_ldub_code(env
, s
->pc
++);
6803 reg
= (modrm
>> 3) & 7;
6804 mod
= (modrm
>> 6) & 3;
6807 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
6808 gen_lea_modrm(env
, s
, modrm
);
6809 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
6811 gen_helper_boundw(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
6813 gen_helper_boundl(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
6816 case 0x1c8 ... 0x1cf: /* bswap reg */
6817 reg
= (b
& 7) | REX_B(s
);
6818 #ifdef TARGET_X86_64
6819 if (dflag
== MO_64
) {
6820 gen_op_mov_v_reg(MO_64
, cpu_T0
, reg
);
6821 tcg_gen_bswap64_i64(cpu_T0
, cpu_T0
);
6822 gen_op_mov_reg_v(MO_64
, reg
, cpu_T0
);
6826 gen_op_mov_v_reg(MO_32
, cpu_T0
, reg
);
6827 tcg_gen_ext32u_tl(cpu_T0
, cpu_T0
);
6828 tcg_gen_bswap32_tl(cpu_T0
, cpu_T0
);
6829 gen_op_mov_reg_v(MO_32
, reg
, cpu_T0
);
6832 case 0xd6: /* salc */
6835 gen_compute_eflags_c(s
, cpu_T0
);
6836 tcg_gen_neg_tl(cpu_T0
, cpu_T0
);
6837 gen_op_mov_reg_v(MO_8
, R_EAX
, cpu_T0
);
6839 case 0xe0: /* loopnz */
6840 case 0xe1: /* loopz */
6841 case 0xe2: /* loop */
6842 case 0xe3: /* jecxz */
6844 TCGLabel
*l1
, *l2
, *l3
;
6846 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6847 next_eip
= s
->pc
- s
->cs_base
;
6849 if (dflag
== MO_16
) {
6853 l1
= gen_new_label();
6854 l2
= gen_new_label();
6855 l3
= gen_new_label();
6858 case 0: /* loopnz */
6860 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
6861 gen_op_jz_ecx(s
->aflag
, l3
);
6862 gen_jcc1(s
, (JCC_Z
<< 1) | (b
^ 1), l1
);
6865 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
6866 gen_op_jnz_ecx(s
->aflag
, l1
);
6870 gen_op_jz_ecx(s
->aflag
, l1
);
6875 gen_jmp_im(next_eip
);
6884 case 0x130: /* wrmsr */
6885 case 0x132: /* rdmsr */
6887 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6889 gen_update_cc_op(s
);
6890 gen_jmp_im(pc_start
- s
->cs_base
);
6892 gen_helper_rdmsr(cpu_env
);
6894 gen_helper_wrmsr(cpu_env
);
6898 case 0x131: /* rdtsc */
6899 gen_update_cc_op(s
);
6900 gen_jmp_im(pc_start
- s
->cs_base
);
6901 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6904 gen_helper_rdtsc(cpu_env
);
6905 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6907 gen_jmp(s
, s
->pc
- s
->cs_base
);
6910 case 0x133: /* rdpmc */
6911 gen_update_cc_op(s
);
6912 gen_jmp_im(pc_start
- s
->cs_base
);
6913 gen_helper_rdpmc(cpu_env
);
6915 case 0x134: /* sysenter */
6916 /* For Intel SYSENTER is valid on 64-bit */
6917 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
6920 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6922 gen_helper_sysenter(cpu_env
);
6926 case 0x135: /* sysexit */
6927 /* For Intel SYSEXIT is valid on 64-bit */
6928 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
6931 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6933 gen_helper_sysexit(cpu_env
, tcg_const_i32(dflag
- 1));
6937 #ifdef TARGET_X86_64
6938 case 0x105: /* syscall */
6939 /* XXX: is it usable in real mode ? */
6940 gen_update_cc_op(s
);
6941 gen_jmp_im(pc_start
- s
->cs_base
);
6942 gen_helper_syscall(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
6945 case 0x107: /* sysret */
6947 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6949 gen_helper_sysret(cpu_env
, tcg_const_i32(dflag
- 1));
6950 /* condition codes are modified only in long mode */
6952 set_cc_op(s
, CC_OP_EFLAGS
);
6958 case 0x1a2: /* cpuid */
6959 gen_update_cc_op(s
);
6960 gen_jmp_im(pc_start
- s
->cs_base
);
6961 gen_helper_cpuid(cpu_env
);
6963 case 0xf4: /* hlt */
6965 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6967 gen_update_cc_op(s
);
6968 gen_jmp_im(pc_start
- s
->cs_base
);
6969 gen_helper_hlt(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
6970 s
->is_jmp
= DISAS_TB_JUMP
;
6974 modrm
= cpu_ldub_code(env
, s
->pc
++);
6975 mod
= (modrm
>> 6) & 3;
6976 op
= (modrm
>> 3) & 7;
6979 if (!s
->pe
|| s
->vm86
)
6981 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_READ
);
6982 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
,
6983 offsetof(CPUX86State
, ldt
.selector
));
6984 ot
= mod
== 3 ? dflag
: MO_16
;
6985 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
6988 if (!s
->pe
|| s
->vm86
)
6991 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6993 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_WRITE
);
6994 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
6995 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
6996 gen_helper_lldt(cpu_env
, cpu_tmp2_i32
);
7000 if (!s
->pe
|| s
->vm86
)
7002 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_READ
);
7003 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
,
7004 offsetof(CPUX86State
, tr
.selector
));
7005 ot
= mod
== 3 ? dflag
: MO_16
;
7006 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7009 if (!s
->pe
|| s
->vm86
)
7012 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7014 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_WRITE
);
7015 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7016 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
7017 gen_helper_ltr(cpu_env
, cpu_tmp2_i32
);
7022 if (!s
->pe
|| s
->vm86
)
7024 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7025 gen_update_cc_op(s
);
7027 gen_helper_verr(cpu_env
, cpu_T0
);
7029 gen_helper_verw(cpu_env
, cpu_T0
);
7031 set_cc_op(s
, CC_OP_EFLAGS
);
7039 modrm
= cpu_ldub_code(env
, s
->pc
++);
7041 CASE_MEM_OP(0): /* sgdt */
7042 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_READ
);
7043 gen_lea_modrm(env
, s
, modrm
);
7044 tcg_gen_ld32u_tl(cpu_T0
,
7045 cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7046 gen_op_st_v(s
, MO_16
, cpu_T0
, cpu_A0
);
7047 gen_add_A0_im(s
, 2);
7048 tcg_gen_ld_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7049 if (dflag
== MO_16
) {
7050 tcg_gen_andi_tl(cpu_T0
, cpu_T0
, 0xffffff);
7052 gen_op_st_v(s
, CODE64(s
) + MO_32
, cpu_T0
, cpu_A0
);
7055 case 0xc8: /* monitor */
7056 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) || s
->cpl
!= 0) {
7059 gen_update_cc_op(s
);
7060 gen_jmp_im(pc_start
- s
->cs_base
);
7061 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EAX
]);
7062 gen_extu(s
->aflag
, cpu_A0
);
7063 gen_add_A0_ds_seg(s
);
7064 gen_helper_monitor(cpu_env
, cpu_A0
);
7067 case 0xc9: /* mwait */
7068 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) || s
->cpl
!= 0) {
7071 gen_update_cc_op(s
);
7072 gen_jmp_im(pc_start
- s
->cs_base
);
7073 gen_helper_mwait(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7077 case 0xca: /* clac */
7078 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
)
7082 gen_helper_clac(cpu_env
);
7083 gen_jmp_im(s
->pc
- s
->cs_base
);
7087 case 0xcb: /* stac */
7088 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
)
7092 gen_helper_stac(cpu_env
);
7093 gen_jmp_im(s
->pc
- s
->cs_base
);
7097 CASE_MEM_OP(1): /* sidt */
7098 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_READ
);
7099 gen_lea_modrm(env
, s
, modrm
);
7100 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7101 gen_op_st_v(s
, MO_16
, cpu_T0
, cpu_A0
);
7102 gen_add_A0_im(s
, 2);
7103 tcg_gen_ld_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, idt
.base
));
7104 if (dflag
== MO_16
) {
7105 tcg_gen_andi_tl(cpu_T0
, cpu_T0
, 0xffffff);
7107 gen_op_st_v(s
, CODE64(s
) + MO_32
, cpu_T0
, cpu_A0
);
7110 case 0xd0: /* xgetbv */
7111 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
7112 || (s
->prefix
& (PREFIX_LOCK
| PREFIX_DATA
7113 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
7116 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_ECX
]);
7117 gen_helper_xgetbv(cpu_tmp1_i64
, cpu_env
, cpu_tmp2_i32
);
7118 tcg_gen_extr_i64_tl(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
], cpu_tmp1_i64
);
7121 case 0xd1: /* xsetbv */
7122 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
7123 || (s
->prefix
& (PREFIX_LOCK
| PREFIX_DATA
7124 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
7128 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7131 tcg_gen_concat_tl_i64(cpu_tmp1_i64
, cpu_regs
[R_EAX
],
7133 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_ECX
]);
7134 gen_helper_xsetbv(cpu_env
, cpu_tmp2_i32
, cpu_tmp1_i64
);
7135 /* End TB because translation flags may change. */
7136 gen_jmp_im(s
->pc
- pc_start
);
7140 case 0xd8: /* VMRUN */
7141 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7145 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7148 gen_update_cc_op(s
);
7149 gen_jmp_im(pc_start
- s
->cs_base
);
7150 gen_helper_vmrun(cpu_env
, tcg_const_i32(s
->aflag
- 1),
7151 tcg_const_i32(s
->pc
- pc_start
));
7153 s
->is_jmp
= DISAS_TB_JUMP
;
7156 case 0xd9: /* VMMCALL */
7157 if (!(s
->flags
& HF_SVME_MASK
)) {
7160 gen_update_cc_op(s
);
7161 gen_jmp_im(pc_start
- s
->cs_base
);
7162 gen_helper_vmmcall(cpu_env
);
7165 case 0xda: /* VMLOAD */
7166 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7170 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7173 gen_update_cc_op(s
);
7174 gen_jmp_im(pc_start
- s
->cs_base
);
7175 gen_helper_vmload(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7178 case 0xdb: /* VMSAVE */
7179 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7183 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7186 gen_update_cc_op(s
);
7187 gen_jmp_im(pc_start
- s
->cs_base
);
7188 gen_helper_vmsave(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7191 case 0xdc: /* STGI */
7192 if ((!(s
->flags
& HF_SVME_MASK
)
7193 && !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
))
7198 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7201 gen_update_cc_op(s
);
7202 gen_jmp_im(pc_start
- s
->cs_base
);
7203 gen_helper_stgi(cpu_env
);
7206 case 0xdd: /* CLGI */
7207 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7211 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7214 gen_update_cc_op(s
);
7215 gen_jmp_im(pc_start
- s
->cs_base
);
7216 gen_helper_clgi(cpu_env
);
7219 case 0xde: /* SKINIT */
7220 if ((!(s
->flags
& HF_SVME_MASK
)
7221 && !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
))
7225 gen_update_cc_op(s
);
7226 gen_jmp_im(pc_start
- s
->cs_base
);
7227 gen_helper_skinit(cpu_env
);
7230 case 0xdf: /* INVLPGA */
7231 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7235 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7238 gen_update_cc_op(s
);
7239 gen_jmp_im(pc_start
- s
->cs_base
);
7240 gen_helper_invlpga(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7243 CASE_MEM_OP(2): /* lgdt */
7245 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7248 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_WRITE
);
7249 gen_lea_modrm(env
, s
, modrm
);
7250 gen_op_ld_v(s
, MO_16
, cpu_T1
, cpu_A0
);
7251 gen_add_A0_im(s
, 2);
7252 gen_op_ld_v(s
, CODE64(s
) + MO_32
, cpu_T0
, cpu_A0
);
7253 if (dflag
== MO_16
) {
7254 tcg_gen_andi_tl(cpu_T0
, cpu_T0
, 0xffffff);
7256 tcg_gen_st_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7257 tcg_gen_st32_tl(cpu_T1
, cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7260 CASE_MEM_OP(3): /* lidt */
7262 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7265 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_WRITE
);
7266 gen_lea_modrm(env
, s
, modrm
);
7267 gen_op_ld_v(s
, MO_16
, cpu_T1
, cpu_A0
);
7268 gen_add_A0_im(s
, 2);
7269 gen_op_ld_v(s
, CODE64(s
) + MO_32
, cpu_T0
, cpu_A0
);
7270 if (dflag
== MO_16
) {
7271 tcg_gen_andi_tl(cpu_T0
, cpu_T0
, 0xffffff);
7273 tcg_gen_st_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, idt
.base
));
7274 tcg_gen_st32_tl(cpu_T1
, cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7277 CASE_MEM_OP(4): /* smsw */
7278 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_CR0
);
7279 #if defined TARGET_X86_64 && defined HOST_WORDS_BIGENDIAN
7280 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, cr
[0]) + 4);
7282 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, cr
[0]));
7284 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 1);
7287 CASE_MEM_OP(6): /* lmsw */
7289 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7292 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7293 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7294 gen_helper_lmsw(cpu_env
, cpu_T0
);
7295 gen_jmp_im(s
->pc
- s
->cs_base
);
7299 CASE_MEM_OP(7): /* invlpg */
7301 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7304 gen_update_cc_op(s
);
7305 gen_jmp_im(pc_start
- s
->cs_base
);
7306 gen_lea_modrm(env
, s
, modrm
);
7307 gen_helper_invlpg(cpu_env
, cpu_A0
);
7308 gen_jmp_im(s
->pc
- s
->cs_base
);
7312 case 0xf8: /* swapgs */
7313 #ifdef TARGET_X86_64
7316 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7318 tcg_gen_mov_tl(cpu_T0
, cpu_seg_base
[R_GS
]);
7319 tcg_gen_ld_tl(cpu_seg_base
[R_GS
], cpu_env
,
7320 offsetof(CPUX86State
, kernelgsbase
));
7321 tcg_gen_st_tl(cpu_T0
, cpu_env
,
7322 offsetof(CPUX86State
, kernelgsbase
));
7329 case 0xf9: /* rdtscp */
7330 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_RDTSCP
)) {
7333 gen_update_cc_op(s
);
7334 gen_jmp_im(pc_start
- s
->cs_base
);
7335 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7338 gen_helper_rdtscp(cpu_env
);
7339 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7341 gen_jmp(s
, s
->pc
- s
->cs_base
);
7350 case 0x108: /* invd */
7351 case 0x109: /* wbinvd */
7353 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7355 gen_svm_check_intercept(s
, pc_start
, (b
& 2) ? SVM_EXIT_INVD
: SVM_EXIT_WBINVD
);
7359 case 0x63: /* arpl or movslS (x86_64) */
7360 #ifdef TARGET_X86_64
7363 /* d_ot is the size of destination */
7366 modrm
= cpu_ldub_code(env
, s
->pc
++);
7367 reg
= ((modrm
>> 3) & 7) | rex_r
;
7368 mod
= (modrm
>> 6) & 3;
7369 rm
= (modrm
& 7) | REX_B(s
);
7372 gen_op_mov_v_reg(MO_32
, cpu_T0
, rm
);
7374 if (d_ot
== MO_64
) {
7375 tcg_gen_ext32s_tl(cpu_T0
, cpu_T0
);
7377 gen_op_mov_reg_v(d_ot
, reg
, cpu_T0
);
7379 gen_lea_modrm(env
, s
, modrm
);
7380 gen_op_ld_v(s
, MO_32
| MO_SIGN
, cpu_T0
, cpu_A0
);
7381 gen_op_mov_reg_v(d_ot
, reg
, cpu_T0
);
7387 TCGv t0
, t1
, t2
, a0
;
7389 if (!s
->pe
|| s
->vm86
)
7391 t0
= tcg_temp_local_new();
7392 t1
= tcg_temp_local_new();
7393 t2
= tcg_temp_local_new();
7395 modrm
= cpu_ldub_code(env
, s
->pc
++);
7396 reg
= (modrm
>> 3) & 7;
7397 mod
= (modrm
>> 6) & 3;
7400 gen_lea_modrm(env
, s
, modrm
);
7401 gen_op_ld_v(s
, ot
, t0
, cpu_A0
);
7402 a0
= tcg_temp_local_new();
7403 tcg_gen_mov_tl(a0
, cpu_A0
);
7405 gen_op_mov_v_reg(ot
, t0
, rm
);
7408 gen_op_mov_v_reg(ot
, t1
, reg
);
7409 tcg_gen_andi_tl(cpu_tmp0
, t0
, 3);
7410 tcg_gen_andi_tl(t1
, t1
, 3);
7411 tcg_gen_movi_tl(t2
, 0);
7412 label1
= gen_new_label();
7413 tcg_gen_brcond_tl(TCG_COND_GE
, cpu_tmp0
, t1
, label1
);
7414 tcg_gen_andi_tl(t0
, t0
, ~3);
7415 tcg_gen_or_tl(t0
, t0
, t1
);
7416 tcg_gen_movi_tl(t2
, CC_Z
);
7417 gen_set_label(label1
);
7419 gen_op_st_v(s
, ot
, t0
, a0
);
7422 gen_op_mov_reg_v(ot
, rm
, t0
);
7424 gen_compute_eflags(s
);
7425 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_Z
);
7426 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, t2
);
7432 case 0x102: /* lar */
7433 case 0x103: /* lsl */
7437 if (!s
->pe
|| s
->vm86
)
7439 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
7440 modrm
= cpu_ldub_code(env
, s
->pc
++);
7441 reg
= ((modrm
>> 3) & 7) | rex_r
;
7442 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7443 t0
= tcg_temp_local_new();
7444 gen_update_cc_op(s
);
7446 gen_helper_lar(t0
, cpu_env
, cpu_T0
);
7448 gen_helper_lsl(t0
, cpu_env
, cpu_T0
);
7450 tcg_gen_andi_tl(cpu_tmp0
, cpu_cc_src
, CC_Z
);
7451 label1
= gen_new_label();
7452 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
7453 gen_op_mov_reg_v(ot
, reg
, t0
);
7454 gen_set_label(label1
);
7455 set_cc_op(s
, CC_OP_EFLAGS
);
7460 modrm
= cpu_ldub_code(env
, s
->pc
++);
7461 mod
= (modrm
>> 6) & 3;
7462 op
= (modrm
>> 3) & 7;
7464 case 0: /* prefetchnta */
7465 case 1: /* prefetchnt0 */
7466 case 2: /* prefetchnt0 */
7467 case 3: /* prefetchnt0 */
7470 gen_lea_modrm(env
, s
, modrm
);
7471 /* nothing more to do */
7473 default: /* nop (multi byte) */
7474 gen_nop_modrm(env
, s
, modrm
);
7479 modrm
= cpu_ldub_code(env
, s
->pc
++);
7480 if (s
->flags
& HF_MPX_EN_MASK
) {
7481 mod
= (modrm
>> 6) & 3;
7482 reg
= ((modrm
>> 3) & 7) | rex_r
;
7483 if (prefixes
& PREFIX_REPZ
) {
7486 || (prefixes
& PREFIX_LOCK
)
7487 || s
->aflag
== MO_16
) {
7490 gen_bndck(env
, s
, modrm
, TCG_COND_LTU
, cpu_bndl
[reg
]);
7491 } else if (prefixes
& PREFIX_REPNZ
) {
7494 || (prefixes
& PREFIX_LOCK
)
7495 || s
->aflag
== MO_16
) {
7498 TCGv_i64 notu
= tcg_temp_new_i64();
7499 tcg_gen_not_i64(notu
, cpu_bndu
[reg
]);
7500 gen_bndck(env
, s
, modrm
, TCG_COND_GTU
, notu
);
7501 tcg_temp_free_i64(notu
);
7502 } else if (prefixes
& PREFIX_DATA
) {
7503 /* bndmov -- from reg/mem */
7504 if (reg
>= 4 || s
->aflag
== MO_16
) {
7508 int reg2
= (modrm
& 7) | REX_B(s
);
7509 if (reg2
>= 4 || (prefixes
& PREFIX_LOCK
)) {
7512 if (s
->flags
& HF_MPX_IU_MASK
) {
7513 tcg_gen_mov_i64(cpu_bndl
[reg
], cpu_bndl
[reg2
]);
7514 tcg_gen_mov_i64(cpu_bndu
[reg
], cpu_bndu
[reg2
]);
7517 gen_lea_modrm(env
, s
, modrm
);
7519 tcg_gen_qemu_ld_i64(cpu_bndl
[reg
], cpu_A0
,
7520 s
->mem_index
, MO_LEQ
);
7521 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, 8);
7522 tcg_gen_qemu_ld_i64(cpu_bndu
[reg
], cpu_A0
,
7523 s
->mem_index
, MO_LEQ
);
7525 tcg_gen_qemu_ld_i64(cpu_bndl
[reg
], cpu_A0
,
7526 s
->mem_index
, MO_LEUL
);
7527 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, 4);
7528 tcg_gen_qemu_ld_i64(cpu_bndu
[reg
], cpu_A0
,
7529 s
->mem_index
, MO_LEUL
);
7531 /* bnd registers are now in-use */
7532 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7534 } else if (mod
!= 3) {
7536 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7538 || (prefixes
& PREFIX_LOCK
)
7539 || s
->aflag
== MO_16
7544 tcg_gen_addi_tl(cpu_A0
, cpu_regs
[a
.base
], a
.disp
);
7546 tcg_gen_movi_tl(cpu_A0
, 0);
7548 gen_lea_v_seg(s
, s
->aflag
, cpu_A0
, a
.def_seg
, s
->override
);
7550 tcg_gen_mov_tl(cpu_T0
, cpu_regs
[a
.index
]);
7552 tcg_gen_movi_tl(cpu_T0
, 0);
7555 gen_helper_bndldx64(cpu_bndl
[reg
], cpu_env
, cpu_A0
, cpu_T0
);
7556 tcg_gen_ld_i64(cpu_bndu
[reg
], cpu_env
,
7557 offsetof(CPUX86State
, mmx_t0
.MMX_Q(0)));
7559 gen_helper_bndldx32(cpu_bndu
[reg
], cpu_env
, cpu_A0
, cpu_T0
);
7560 tcg_gen_ext32u_i64(cpu_bndl
[reg
], cpu_bndu
[reg
]);
7561 tcg_gen_shri_i64(cpu_bndu
[reg
], cpu_bndu
[reg
], 32);
7563 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7566 gen_nop_modrm(env
, s
, modrm
);
7569 modrm
= cpu_ldub_code(env
, s
->pc
++);
7570 if (s
->flags
& HF_MPX_EN_MASK
) {
7571 mod
= (modrm
>> 6) & 3;
7572 reg
= ((modrm
>> 3) & 7) | rex_r
;
7573 if (mod
!= 3 && (prefixes
& PREFIX_REPZ
)) {
7576 || (prefixes
& PREFIX_LOCK
)
7577 || s
->aflag
== MO_16
) {
7580 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7582 tcg_gen_extu_tl_i64(cpu_bndl
[reg
], cpu_regs
[a
.base
]);
7584 tcg_gen_ext32u_i64(cpu_bndl
[reg
], cpu_bndl
[reg
]);
7586 } else if (a
.base
== -1) {
7587 /* no base register has lower bound of 0 */
7588 tcg_gen_movi_i64(cpu_bndl
[reg
], 0);
7590 /* rip-relative generates #ud */
7593 tcg_gen_not_tl(cpu_A0
, gen_lea_modrm_1(a
));
7595 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
7597 tcg_gen_extu_tl_i64(cpu_bndu
[reg
], cpu_A0
);
7598 /* bnd registers are now in-use */
7599 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7601 } else if (prefixes
& PREFIX_REPNZ
) {
7604 || (prefixes
& PREFIX_LOCK
)
7605 || s
->aflag
== MO_16
) {
7608 gen_bndck(env
, s
, modrm
, TCG_COND_GTU
, cpu_bndu
[reg
]);
7609 } else if (prefixes
& PREFIX_DATA
) {
7610 /* bndmov -- to reg/mem */
7611 if (reg
>= 4 || s
->aflag
== MO_16
) {
7615 int reg2
= (modrm
& 7) | REX_B(s
);
7616 if (reg2
>= 4 || (prefixes
& PREFIX_LOCK
)) {
7619 if (s
->flags
& HF_MPX_IU_MASK
) {
7620 tcg_gen_mov_i64(cpu_bndl
[reg2
], cpu_bndl
[reg
]);
7621 tcg_gen_mov_i64(cpu_bndu
[reg2
], cpu_bndu
[reg
]);
7624 gen_lea_modrm(env
, s
, modrm
);
7626 tcg_gen_qemu_st_i64(cpu_bndl
[reg
], cpu_A0
,
7627 s
->mem_index
, MO_LEQ
);
7628 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, 8);
7629 tcg_gen_qemu_st_i64(cpu_bndu
[reg
], cpu_A0
,
7630 s
->mem_index
, MO_LEQ
);
7632 tcg_gen_qemu_st_i64(cpu_bndl
[reg
], cpu_A0
,
7633 s
->mem_index
, MO_LEUL
);
7634 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, 4);
7635 tcg_gen_qemu_st_i64(cpu_bndu
[reg
], cpu_A0
,
7636 s
->mem_index
, MO_LEUL
);
7639 } else if (mod
!= 3) {
7641 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7643 || (prefixes
& PREFIX_LOCK
)
7644 || s
->aflag
== MO_16
7649 tcg_gen_addi_tl(cpu_A0
, cpu_regs
[a
.base
], a
.disp
);
7651 tcg_gen_movi_tl(cpu_A0
, 0);
7653 gen_lea_v_seg(s
, s
->aflag
, cpu_A0
, a
.def_seg
, s
->override
);
7655 tcg_gen_mov_tl(cpu_T0
, cpu_regs
[a
.index
]);
7657 tcg_gen_movi_tl(cpu_T0
, 0);
7660 gen_helper_bndstx64(cpu_env
, cpu_A0
, cpu_T0
,
7661 cpu_bndl
[reg
], cpu_bndu
[reg
]);
7663 gen_helper_bndstx32(cpu_env
, cpu_A0
, cpu_T0
,
7664 cpu_bndl
[reg
], cpu_bndu
[reg
]);
7668 gen_nop_modrm(env
, s
, modrm
);
7670 case 0x119: case 0x11c ... 0x11f: /* nop (multi byte) */
7671 modrm
= cpu_ldub_code(env
, s
->pc
++);
7672 gen_nop_modrm(env
, s
, modrm
);
7674 case 0x120: /* mov reg, crN */
7675 case 0x122: /* mov crN, reg */
7677 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7679 modrm
= cpu_ldub_code(env
, s
->pc
++);
7680 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7681 * AMD documentation (24594.pdf) and testing of
7682 * intel 386 and 486 processors all show that the mod bits
7683 * are assumed to be 1's, regardless of actual values.
7685 rm
= (modrm
& 7) | REX_B(s
);
7686 reg
= ((modrm
>> 3) & 7) | rex_r
;
7691 if ((prefixes
& PREFIX_LOCK
) && (reg
== 0) &&
7692 (s
->cpuid_ext3_features
& CPUID_EXT3_CR8LEG
)) {
7701 gen_update_cc_op(s
);
7702 gen_jmp_im(pc_start
- s
->cs_base
);
7704 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
7705 gen_helper_write_crN(cpu_env
, tcg_const_i32(reg
),
7707 gen_jmp_im(s
->pc
- s
->cs_base
);
7710 gen_helper_read_crN(cpu_T0
, cpu_env
, tcg_const_i32(reg
));
7711 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
7719 case 0x121: /* mov reg, drN */
7720 case 0x123: /* mov drN, reg */
7722 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7724 modrm
= cpu_ldub_code(env
, s
->pc
++);
7725 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7726 * AMD documentation (24594.pdf) and testing of
7727 * intel 386 and 486 processors all show that the mod bits
7728 * are assumed to be 1's, regardless of actual values.
7730 rm
= (modrm
& 7) | REX_B(s
);
7731 reg
= ((modrm
>> 3) & 7) | rex_r
;
7740 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_DR0
+ reg
);
7741 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
7742 tcg_gen_movi_i32(cpu_tmp2_i32
, reg
);
7743 gen_helper_set_dr(cpu_env
, cpu_tmp2_i32
, cpu_T0
);
7744 gen_jmp_im(s
->pc
- s
->cs_base
);
7747 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_DR0
+ reg
);
7748 tcg_gen_movi_i32(cpu_tmp2_i32
, reg
);
7749 gen_helper_get_dr(cpu_T0
, cpu_env
, cpu_tmp2_i32
);
7750 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
7754 case 0x106: /* clts */
7756 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7758 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7759 gen_helper_clts(cpu_env
);
7760 /* abort block because static cpu state changed */
7761 gen_jmp_im(s
->pc
- s
->cs_base
);
7765 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
7766 case 0x1c3: /* MOVNTI reg, mem */
7767 if (!(s
->cpuid_features
& CPUID_SSE2
))
7769 ot
= mo_64_32(dflag
);
7770 modrm
= cpu_ldub_code(env
, s
->pc
++);
7771 mod
= (modrm
>> 6) & 3;
7774 reg
= ((modrm
>> 3) & 7) | rex_r
;
7775 /* generate a generic store */
7776 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
7779 modrm
= cpu_ldub_code(env
, s
->pc
++);
7781 CASE_MEM_OP(0): /* fxsave */
7782 if (!(s
->cpuid_features
& CPUID_FXSR
)
7783 || (prefixes
& PREFIX_LOCK
)) {
7786 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
7787 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7790 gen_lea_modrm(env
, s
, modrm
);
7791 gen_helper_fxsave(cpu_env
, cpu_A0
);
7794 CASE_MEM_OP(1): /* fxrstor */
7795 if (!(s
->cpuid_features
& CPUID_FXSR
)
7796 || (prefixes
& PREFIX_LOCK
)) {
7799 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
7800 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7803 gen_lea_modrm(env
, s
, modrm
);
7804 gen_helper_fxrstor(cpu_env
, cpu_A0
);
7807 CASE_MEM_OP(2): /* ldmxcsr */
7808 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
)) {
7811 if (s
->flags
& HF_TS_MASK
) {
7812 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7815 gen_lea_modrm(env
, s
, modrm
);
7816 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
, s
->mem_index
, MO_LEUL
);
7817 gen_helper_ldmxcsr(cpu_env
, cpu_tmp2_i32
);
7820 CASE_MEM_OP(3): /* stmxcsr */
7821 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
)) {
7824 if (s
->flags
& HF_TS_MASK
) {
7825 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7828 gen_lea_modrm(env
, s
, modrm
);
7829 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, mxcsr
));
7830 gen_op_st_v(s
, MO_32
, cpu_T0
, cpu_A0
);
7833 CASE_MEM_OP(4): /* xsave */
7834 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
7835 || (prefixes
& (PREFIX_LOCK
| PREFIX_DATA
7836 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
7839 gen_lea_modrm(env
, s
, modrm
);
7840 tcg_gen_concat_tl_i64(cpu_tmp1_i64
, cpu_regs
[R_EAX
],
7842 gen_helper_xsave(cpu_env
, cpu_A0
, cpu_tmp1_i64
);
7845 CASE_MEM_OP(5): /* xrstor */
7846 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
7847 || (prefixes
& (PREFIX_LOCK
| PREFIX_DATA
7848 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
7851 gen_lea_modrm(env
, s
, modrm
);
7852 tcg_gen_concat_tl_i64(cpu_tmp1_i64
, cpu_regs
[R_EAX
],
7854 gen_helper_xrstor(cpu_env
, cpu_A0
, cpu_tmp1_i64
);
7855 /* XRSTOR is how MPX is enabled, which changes how
7856 we translate. Thus we need to end the TB. */
7857 gen_update_cc_op(s
);
7858 gen_jmp_im(s
->pc
- s
->cs_base
);
7862 CASE_MEM_OP(6): /* xsaveopt / clwb */
7863 if (prefixes
& PREFIX_LOCK
) {
7866 if (prefixes
& PREFIX_DATA
) {
7868 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLWB
)) {
7871 gen_nop_modrm(env
, s
, modrm
);
7874 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
7875 || (s
->cpuid_xsave_features
& CPUID_XSAVE_XSAVEOPT
) == 0
7876 || (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
))) {
7879 gen_lea_modrm(env
, s
, modrm
);
7880 tcg_gen_concat_tl_i64(cpu_tmp1_i64
, cpu_regs
[R_EAX
],
7882 gen_helper_xsaveopt(cpu_env
, cpu_A0
, cpu_tmp1_i64
);
7886 CASE_MEM_OP(7): /* clflush / clflushopt */
7887 if (prefixes
& PREFIX_LOCK
) {
7890 if (prefixes
& PREFIX_DATA
) {
7892 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLFLUSHOPT
)) {
7897 if ((s
->prefix
& (PREFIX_REPZ
| PREFIX_REPNZ
))
7898 || !(s
->cpuid_features
& CPUID_CLFLUSH
)) {
7902 gen_nop_modrm(env
, s
, modrm
);
7905 case 0xc0 ... 0xc7: /* rdfsbase (f3 0f ae /0) */
7906 case 0xc8 ... 0xc8: /* rdgsbase (f3 0f ae /1) */
7907 case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */
7908 case 0xd8 ... 0xd8: /* wrgsbase (f3 0f ae /3) */
7910 && (prefixes
& PREFIX_REPZ
)
7911 && !(prefixes
& PREFIX_LOCK
)
7912 && (s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_FSGSBASE
)) {
7913 TCGv base
, treg
, src
, dst
;
7915 /* Preserve hflags bits by testing CR4 at runtime. */
7916 tcg_gen_movi_i32(cpu_tmp2_i32
, CR4_FSGSBASE_MASK
);
7917 gen_helper_cr4_testbit(cpu_env
, cpu_tmp2_i32
);
7919 base
= cpu_seg_base
[modrm
& 8 ? R_GS
: R_FS
];
7920 treg
= cpu_regs
[(modrm
& 7) | REX_B(s
)];
7924 dst
= base
, src
= treg
;
7927 dst
= treg
, src
= base
;
7930 if (s
->dflag
== MO_32
) {
7931 tcg_gen_ext32u_tl(dst
, src
);
7933 tcg_gen_mov_tl(dst
, src
);
7939 case 0xf8: /* sfence / pcommit */
7940 if (prefixes
& PREFIX_DATA
) {
7942 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_PCOMMIT
)
7943 || (prefixes
& PREFIX_LOCK
)) {
7949 case 0xf9 ... 0xff: /* sfence */
7950 case 0xe8 ... 0xef: /* lfence */
7951 case 0xf0 ... 0xf7: /* mfence */
7952 if (!(s
->cpuid_features
& CPUID_SSE2
)
7953 || (prefixes
& PREFIX_LOCK
)) {
7963 case 0x10d: /* 3DNow! prefetch(w) */
7964 modrm
= cpu_ldub_code(env
, s
->pc
++);
7965 mod
= (modrm
>> 6) & 3;
7968 gen_lea_modrm(env
, s
, modrm
);
7969 /* ignore for now */
7971 case 0x1aa: /* rsm */
7972 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_RSM
);
7973 if (!(s
->flags
& HF_SMM_MASK
))
7975 gen_update_cc_op(s
);
7976 gen_jmp_im(s
->pc
- s
->cs_base
);
7977 gen_helper_rsm(cpu_env
);
7980 case 0x1b8: /* SSE4.2 popcnt */
7981 if ((prefixes
& (PREFIX_REPZ
| PREFIX_LOCK
| PREFIX_REPNZ
)) !=
7984 if (!(s
->cpuid_ext_features
& CPUID_EXT_POPCNT
))
7987 modrm
= cpu_ldub_code(env
, s
->pc
++);
7988 reg
= ((modrm
>> 3) & 7) | rex_r
;
7990 if (s
->prefix
& PREFIX_DATA
) {
7993 ot
= mo_64_32(dflag
);
7996 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
7997 gen_helper_popcnt(cpu_T0
, cpu_env
, cpu_T0
, tcg_const_i32(ot
));
7998 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
8000 set_cc_op(s
, CC_OP_EFLAGS
);
8002 case 0x10e ... 0x10f:
8003 /* 3DNow! instructions, ignore prefixes */
8004 s
->prefix
&= ~(PREFIX_REPZ
| PREFIX_REPNZ
| PREFIX_DATA
);
8005 case 0x110 ... 0x117:
8006 case 0x128 ... 0x12f:
8007 case 0x138 ... 0x13a:
8008 case 0x150 ... 0x179:
8009 case 0x17c ... 0x17f:
8011 case 0x1c4 ... 0x1c6:
8012 case 0x1d0 ... 0x1fe:
8013 gen_sse(env
, s
, b
, pc_start
, rex_r
);
8018 /* lock generation */
8019 if (s
->prefix
& PREFIX_LOCK
)
8020 gen_helper_unlock();
8023 if (s
->prefix
& PREFIX_LOCK
)
8024 gen_helper_unlock();
8025 /* XXX: ensure that no lock was generated */
8026 gen_exception(s
, EXCP06_ILLOP
, pc_start
- s
->cs_base
);
8030 void tcg_x86_init(void)
8032 static const char reg_names
[CPU_NB_REGS
][4] = {
8033 #ifdef TARGET_X86_64
8061 static const char seg_base_names
[6][8] = {
8069 static const char bnd_regl_names
[4][8] = {
8070 "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb"
8072 static const char bnd_regu_names
[4][8] = {
8073 "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub"
8077 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
8078 cpu_cc_op
= tcg_global_mem_new_i32(cpu_env
,
8079 offsetof(CPUX86State
, cc_op
), "cc_op");
8080 cpu_cc_dst
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_dst
),
8082 cpu_cc_src
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_src
),
8084 cpu_cc_src2
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_src2
),
8087 for (i
= 0; i
< CPU_NB_REGS
; ++i
) {
8088 cpu_regs
[i
] = tcg_global_mem_new(cpu_env
,
8089 offsetof(CPUX86State
, regs
[i
]),
8093 for (i
= 0; i
< 6; ++i
) {
8095 = tcg_global_mem_new(cpu_env
,
8096 offsetof(CPUX86State
, segs
[i
].base
),
8100 for (i
= 0; i
< 4; ++i
) {
8102 = tcg_global_mem_new_i64(cpu_env
,
8103 offsetof(CPUX86State
, bnd_regs
[i
].lb
),
8106 = tcg_global_mem_new_i64(cpu_env
,
8107 offsetof(CPUX86State
, bnd_regs
[i
].ub
),
8114 /* generate intermediate code for basic block 'tb'. */
8115 void gen_intermediate_code(CPUX86State
*env
, TranslationBlock
*tb
)
8117 X86CPU
*cpu
= x86_env_get_cpu(env
);
8118 CPUState
*cs
= CPU(cpu
);
8119 DisasContext dc1
, *dc
= &dc1
;
8120 target_ulong pc_ptr
;
8122 target_ulong pc_start
;
8123 target_ulong cs_base
;
8127 /* generate intermediate code */
8129 cs_base
= tb
->cs_base
;
8132 dc
->pe
= (flags
>> HF_PE_SHIFT
) & 1;
8133 dc
->code32
= (flags
>> HF_CS32_SHIFT
) & 1;
8134 dc
->ss32
= (flags
>> HF_SS32_SHIFT
) & 1;
8135 dc
->addseg
= (flags
>> HF_ADDSEG_SHIFT
) & 1;
8137 dc
->vm86
= (flags
>> VM_SHIFT
) & 1;
8138 dc
->cpl
= (flags
>> HF_CPL_SHIFT
) & 3;
8139 dc
->iopl
= (flags
>> IOPL_SHIFT
) & 3;
8140 dc
->tf
= (flags
>> TF_SHIFT
) & 1;
8141 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
8142 dc
->cc_op
= CC_OP_DYNAMIC
;
8143 dc
->cc_op_dirty
= false;
8144 dc
->cs_base
= cs_base
;
8146 dc
->popl_esp_hack
= 0;
8147 /* select memory access functions */
8149 if (flags
& HF_SOFTMMU_MASK
) {
8150 dc
->mem_index
= cpu_mmu_index(env
, false);
8152 dc
->cpuid_features
= env
->features
[FEAT_1_EDX
];
8153 dc
->cpuid_ext_features
= env
->features
[FEAT_1_ECX
];
8154 dc
->cpuid_ext2_features
= env
->features
[FEAT_8000_0001_EDX
];
8155 dc
->cpuid_ext3_features
= env
->features
[FEAT_8000_0001_ECX
];
8156 dc
->cpuid_7_0_ebx_features
= env
->features
[FEAT_7_0_EBX
];
8157 dc
->cpuid_xsave_features
= env
->features
[FEAT_XSAVE
];
8158 #ifdef TARGET_X86_64
8159 dc
->lma
= (flags
>> HF_LMA_SHIFT
) & 1;
8160 dc
->code64
= (flags
>> HF_CS64_SHIFT
) & 1;
8163 dc
->jmp_opt
= !(dc
->tf
|| cs
->singlestep_enabled
||
8164 (flags
& HF_INHIBIT_IRQ_MASK
)
8165 #ifndef CONFIG_SOFTMMU
8166 || (flags
& HF_SOFTMMU_MASK
)
8169 /* Do not optimize repz jumps at all in icount mode, because
8170 rep movsS instructions are execured with different paths
8171 in !repz_opt and repz_opt modes. The first one was used
8172 always except single step mode. And this setting
8173 disables jumps optimization and control paths become
8174 equivalent in run and single step modes.
8175 Now there will be no jump optimization for repz in
8176 record/replay modes and there will always be an
8177 additional step for ecx=0 when icount is enabled.
8179 dc
->repz_opt
= !dc
->jmp_opt
&& !(tb
->cflags
& CF_USE_ICOUNT
);
8181 /* check addseg logic */
8182 if (!dc
->addseg
&& (dc
->vm86
|| !dc
->pe
|| !dc
->code32
))
8183 printf("ERROR addseg\n");
8186 cpu_T0
= tcg_temp_new();
8187 cpu_T1
= tcg_temp_new();
8188 cpu_A0
= tcg_temp_new();
8190 cpu_tmp0
= tcg_temp_new();
8191 cpu_tmp1_i64
= tcg_temp_new_i64();
8192 cpu_tmp2_i32
= tcg_temp_new_i32();
8193 cpu_tmp3_i32
= tcg_temp_new_i32();
8194 cpu_tmp4
= tcg_temp_new();
8195 cpu_ptr0
= tcg_temp_new_ptr();
8196 cpu_ptr1
= tcg_temp_new_ptr();
8197 cpu_cc_srcT
= tcg_temp_local_new();
8199 dc
->is_jmp
= DISAS_NEXT
;
8202 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
8203 if (max_insns
== 0) {
8204 max_insns
= CF_COUNT_MASK
;
8206 if (max_insns
> TCG_MAX_INSNS
) {
8207 max_insns
= TCG_MAX_INSNS
;
8212 tcg_gen_insn_start(pc_ptr
, dc
->cc_op
);
8215 /* If RF is set, suppress an internally generated breakpoint. */
8216 if (unlikely(cpu_breakpoint_test(cs
, pc_ptr
,
8217 tb
->flags
& HF_RF_MASK
8218 ? BP_GDB
: BP_ANY
))) {
8219 gen_debug(dc
, pc_ptr
- dc
->cs_base
);
8220 /* The address covered by the breakpoint must be included in
8221 [tb->pc, tb->pc + tb->size) in order to for it to be
8222 properly cleared -- thus we increment the PC here so that
8223 the logic setting tb->size below does the right thing. */
8225 goto done_generating
;
8227 if (num_insns
== max_insns
&& (tb
->cflags
& CF_LAST_IO
)) {
8231 pc_ptr
= disas_insn(env
, dc
, pc_ptr
);
8232 /* stop translation if indicated */
8235 /* if single step mode, we generate only one instruction and
8236 generate an exception */
8237 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
8238 the flag and abort the translation to give the irqs a
8239 change to be happen */
8240 if (dc
->tf
|| dc
->singlestep_enabled
||
8241 (flags
& HF_INHIBIT_IRQ_MASK
)) {
8242 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8246 /* Do not cross the boundary of the pages in icount mode,
8247 it can cause an exception. Do it only when boundary is
8248 crossed by the first instruction in the block.
8249 If current instruction already crossed the bound - it's ok,
8250 because an exception hasn't stopped this code.
8252 if ((tb
->cflags
& CF_USE_ICOUNT
)
8253 && ((pc_ptr
& TARGET_PAGE_MASK
)
8254 != ((pc_ptr
+ TARGET_MAX_INSN_SIZE
- 1) & TARGET_PAGE_MASK
)
8255 || (pc_ptr
& ~TARGET_PAGE_MASK
) == 0)) {
8256 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8260 /* if too long translation, stop generation too */
8261 if (tcg_op_buf_full() ||
8262 (pc_ptr
- pc_start
) >= (TARGET_PAGE_SIZE
- 32) ||
8263 num_insns
>= max_insns
) {
8264 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8269 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8274 if (tb
->cflags
& CF_LAST_IO
)
8277 gen_tb_end(tb
, num_insns
);
8280 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
8282 qemu_log("----------------\n");
8283 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
8284 #ifdef TARGET_X86_64
8289 disas_flags
= !dc
->code32
;
8290 log_target_disas(cs
, pc_start
, pc_ptr
- pc_start
, disas_flags
);
8295 tb
->size
= pc_ptr
- pc_start
;
8296 tb
->icount
= num_insns
;
8299 void restore_state_to_opc(CPUX86State
*env
, TranslationBlock
*tb
,
8302 int cc_op
= data
[1];
8303 env
->eip
= data
[0] - tb
->cs_base
;
8304 if (cc_op
!= CC_OP_DYNAMIC
) {