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"
33 #define PREFIX_REPZ 0x01
34 #define PREFIX_REPNZ 0x02
35 #define PREFIX_LOCK 0x04
36 #define PREFIX_DATA 0x08
37 #define PREFIX_ADR 0x10
38 #define PREFIX_VEX 0x20
41 #define CODE64(s) ((s)->code64)
42 #define REX_X(s) ((s)->rex_x)
43 #define REX_B(s) ((s)->rex_b)
58 //#define MACRO_TEST 1
60 /* global register indexes */
61 static TCGv_ptr cpu_env
;
63 static TCGv cpu_cc_dst
, cpu_cc_src
, cpu_cc_src2
, cpu_cc_srcT
;
64 static TCGv_i32 cpu_cc_op
;
65 static TCGv cpu_regs
[CPU_NB_REGS
];
68 /* local register indexes (only used inside old micro ops) */
69 static TCGv cpu_tmp0
, cpu_tmp4
;
70 static TCGv_ptr cpu_ptr0
, cpu_ptr1
;
71 static TCGv_i32 cpu_tmp2_i32
, cpu_tmp3_i32
;
72 static TCGv_i64 cpu_tmp1_i64
;
74 #include "exec/gen-icount.h"
77 static int x86_64_hregs
;
80 typedef struct DisasContext
{
81 /* current insn context */
82 int override
; /* -1 if no override */
86 target_ulong pc
; /* pc = eip + cs_base */
87 int is_jmp
; /* 1 = means jump (stop translation), 2 means CPU
88 static state change (stop translation) */
89 /* current block context */
90 target_ulong cs_base
; /* base of CS segment */
91 int pe
; /* protected mode */
92 int code32
; /* 32 bit code segment */
94 int lma
; /* long mode active */
95 int code64
; /* 64 bit code segment */
98 int vex_l
; /* vex vector length */
99 int vex_v
; /* vex vvvv register, without 1's compliment. */
100 int ss32
; /* 32 bit stack segment */
101 CCOp cc_op
; /* current CC operation */
103 int addseg
; /* non zero if either DS/ES/SS have a non zero base */
104 int f_st
; /* currently unused */
105 int vm86
; /* vm86 mode */
108 int tf
; /* TF cpu flag */
109 int singlestep_enabled
; /* "hardware" single step enabled */
110 int jmp_opt
; /* use direct block chaining for direct jumps */
111 int repz_opt
; /* optimize jumps within repz instructions */
112 int mem_index
; /* select memory access functions */
113 uint64_t flags
; /* all execution flags */
114 struct TranslationBlock
*tb
;
115 int popl_esp_hack
; /* for correct popl with esp base handling */
116 int rip_offset
; /* only used in x86_64, but left for simplicity */
118 int cpuid_ext_features
;
119 int cpuid_ext2_features
;
120 int cpuid_ext3_features
;
121 int cpuid_7_0_ebx_features
;
124 static void gen_eob(DisasContext
*s
);
125 static void gen_jmp(DisasContext
*s
, target_ulong eip
);
126 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
);
127 static void gen_op(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
);
129 /* i386 arith/logic operations */
149 OP_SHL1
, /* undocumented */
165 /* I386 int registers */
166 OR_EAX
, /* MUST be even numbered */
175 OR_TMP0
= 16, /* temporary operand register */
177 OR_A0
, /* temporary register used when doing address evaluation */
187 /* Bit set if the global variable is live after setting CC_OP to X. */
188 static const uint8_t cc_op_live
[CC_OP_NB
] = {
189 [CC_OP_DYNAMIC
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
190 [CC_OP_EFLAGS
] = USES_CC_SRC
,
191 [CC_OP_MULB
... CC_OP_MULQ
] = USES_CC_DST
| USES_CC_SRC
,
192 [CC_OP_ADDB
... CC_OP_ADDQ
] = USES_CC_DST
| USES_CC_SRC
,
193 [CC_OP_ADCB
... CC_OP_ADCQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
194 [CC_OP_SUBB
... CC_OP_SUBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRCT
,
195 [CC_OP_SBBB
... CC_OP_SBBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
196 [CC_OP_LOGICB
... CC_OP_LOGICQ
] = USES_CC_DST
,
197 [CC_OP_INCB
... CC_OP_INCQ
] = USES_CC_DST
| USES_CC_SRC
,
198 [CC_OP_DECB
... CC_OP_DECQ
] = USES_CC_DST
| USES_CC_SRC
,
199 [CC_OP_SHLB
... CC_OP_SHLQ
] = USES_CC_DST
| USES_CC_SRC
,
200 [CC_OP_SARB
... CC_OP_SARQ
] = USES_CC_DST
| USES_CC_SRC
,
201 [CC_OP_BMILGB
... CC_OP_BMILGQ
] = USES_CC_DST
| USES_CC_SRC
,
202 [CC_OP_ADCX
] = USES_CC_DST
| USES_CC_SRC
,
203 [CC_OP_ADOX
] = USES_CC_SRC
| USES_CC_SRC2
,
204 [CC_OP_ADCOX
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
208 static void set_cc_op(DisasContext
*s
, CCOp op
)
212 if (s
->cc_op
== op
) {
216 /* Discard CC computation that will no longer be used. */
217 dead
= cc_op_live
[s
->cc_op
] & ~cc_op_live
[op
];
218 if (dead
& USES_CC_DST
) {
219 tcg_gen_discard_tl(cpu_cc_dst
);
221 if (dead
& USES_CC_SRC
) {
222 tcg_gen_discard_tl(cpu_cc_src
);
224 if (dead
& USES_CC_SRC2
) {
225 tcg_gen_discard_tl(cpu_cc_src2
);
227 if (dead
& USES_CC_SRCT
) {
228 tcg_gen_discard_tl(cpu_cc_srcT
);
231 if (op
== CC_OP_DYNAMIC
) {
232 /* The DYNAMIC setting is translator only, and should never be
233 stored. Thus we always consider it clean. */
234 s
->cc_op_dirty
= false;
236 /* Discard any computed CC_OP value (see shifts). */
237 if (s
->cc_op
== CC_OP_DYNAMIC
) {
238 tcg_gen_discard_i32(cpu_cc_op
);
240 s
->cc_op_dirty
= true;
245 static void gen_update_cc_op(DisasContext
*s
)
247 if (s
->cc_op_dirty
) {
248 tcg_gen_movi_i32(cpu_cc_op
, s
->cc_op
);
249 s
->cc_op_dirty
= false;
255 #define NB_OP_SIZES 4
257 #else /* !TARGET_X86_64 */
259 #define NB_OP_SIZES 3
261 #endif /* !TARGET_X86_64 */
263 #if defined(HOST_WORDS_BIGENDIAN)
264 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
265 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
266 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
267 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
268 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
270 #define REG_B_OFFSET 0
271 #define REG_H_OFFSET 1
272 #define REG_W_OFFSET 0
273 #define REG_L_OFFSET 0
274 #define REG_LH_OFFSET 4
277 /* In instruction encodings for byte register accesses the
278 * register number usually indicates "low 8 bits of register N";
279 * however there are some special cases where N 4..7 indicates
280 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
281 * true for this special case, false otherwise.
283 static inline bool byte_reg_is_xH(int reg
)
289 if (reg
>= 8 || x86_64_hregs
) {
296 /* Select the size of a push/pop operation. */
297 static inline TCGMemOp
mo_pushpop(DisasContext
*s
, TCGMemOp ot
)
300 return ot
== MO_16
? MO_16
: MO_64
;
306 /* Select only size 64 else 32. Used for SSE operand sizes. */
307 static inline TCGMemOp
mo_64_32(TCGMemOp ot
)
310 return ot
== MO_64
? MO_64
: MO_32
;
316 /* Select size 8 if lsb of B is clear, else OT. Used for decoding
317 byte vs word opcodes. */
318 static inline TCGMemOp
mo_b_d(int b
, TCGMemOp ot
)
320 return b
& 1 ? ot
: MO_8
;
323 /* Select size 8 if lsb of B is clear, else OT capped at 32.
324 Used for decoding operand size of port opcodes. */
325 static inline TCGMemOp
mo_b_d32(int b
, TCGMemOp ot
)
327 return b
& 1 ? (ot
== MO_16
? MO_16
: MO_32
) : MO_8
;
330 static void gen_op_mov_reg_v(TCGMemOp ot
, int reg
, TCGv t0
)
334 if (!byte_reg_is_xH(reg
)) {
335 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 8);
337 tcg_gen_deposit_tl(cpu_regs
[reg
- 4], cpu_regs
[reg
- 4], t0
, 8, 8);
341 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 16);
344 /* For x86_64, this sets the higher half of register to zero.
345 For i386, this is equivalent to a mov. */
346 tcg_gen_ext32u_tl(cpu_regs
[reg
], t0
);
350 tcg_gen_mov_tl(cpu_regs
[reg
], t0
);
358 static inline void gen_op_mov_v_reg(TCGMemOp ot
, TCGv t0
, int reg
)
360 if (ot
== MO_8
&& byte_reg_is_xH(reg
)) {
361 tcg_gen_shri_tl(t0
, cpu_regs
[reg
- 4], 8);
362 tcg_gen_ext8u_tl(t0
, t0
);
364 tcg_gen_mov_tl(t0
, cpu_regs
[reg
]);
368 static inline void gen_op_movl_A0_reg(int reg
)
370 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[reg
]);
373 static inline void gen_op_addl_A0_im(int32_t val
)
375 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, val
);
377 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffffffff);
382 static inline void gen_op_addq_A0_im(int64_t val
)
384 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, val
);
388 static void gen_add_A0_im(DisasContext
*s
, int val
)
392 gen_op_addq_A0_im(val
);
395 gen_op_addl_A0_im(val
);
398 static inline void gen_op_jmp_v(TCGv dest
)
400 tcg_gen_st_tl(dest
, cpu_env
, offsetof(CPUX86State
, eip
));
403 static inline void gen_op_add_reg_im(TCGMemOp size
, int reg
, int32_t val
)
405 tcg_gen_addi_tl(cpu_tmp0
, cpu_regs
[reg
], val
);
406 gen_op_mov_reg_v(size
, reg
, cpu_tmp0
);
409 static inline void gen_op_add_reg_T0(TCGMemOp size
, int reg
)
411 tcg_gen_add_tl(cpu_tmp0
, cpu_regs
[reg
], cpu_T
[0]);
412 gen_op_mov_reg_v(size
, reg
, cpu_tmp0
);
415 static inline void gen_op_addl_A0_reg_sN(int shift
, int reg
)
417 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[reg
]);
419 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, shift
);
420 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
421 /* For x86_64, this sets the higher half of register to zero.
422 For i386, this is equivalent to a nop. */
423 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
426 static inline void gen_op_movl_A0_seg(int reg
)
428 tcg_gen_ld32u_tl(cpu_A0
, cpu_env
, offsetof(CPUX86State
, segs
[reg
].base
) + REG_L_OFFSET
);
431 static inline void gen_op_addl_A0_seg(DisasContext
*s
, int reg
)
433 tcg_gen_ld_tl(cpu_tmp0
, cpu_env
, offsetof(CPUX86State
, segs
[reg
].base
));
436 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffffffff);
437 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
439 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
440 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffffffff);
443 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
448 static inline void gen_op_movq_A0_seg(int reg
)
450 tcg_gen_ld_tl(cpu_A0
, cpu_env
, offsetof(CPUX86State
, segs
[reg
].base
));
453 static inline void gen_op_addq_A0_seg(int reg
)
455 tcg_gen_ld_tl(cpu_tmp0
, cpu_env
, offsetof(CPUX86State
, segs
[reg
].base
));
456 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
459 static inline void gen_op_movq_A0_reg(int reg
)
461 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[reg
]);
464 static inline void gen_op_addq_A0_reg_sN(int shift
, int reg
)
466 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[reg
]);
468 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, shift
);
469 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
473 static inline void gen_op_ld_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
475 tcg_gen_qemu_ld_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
478 static inline void gen_op_st_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
480 tcg_gen_qemu_st_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
483 static inline void gen_op_st_rm_T0_A0(DisasContext
*s
, int idx
, int d
)
486 gen_op_st_v(s
, idx
, cpu_T
[0], cpu_A0
);
488 gen_op_mov_reg_v(idx
, d
, cpu_T
[0]);
492 static inline void gen_jmp_im(target_ulong pc
)
494 tcg_gen_movi_tl(cpu_tmp0
, pc
);
495 gen_op_jmp_v(cpu_tmp0
);
498 static inline void gen_string_movl_A0_ESI(DisasContext
*s
)
502 override
= s
->override
;
507 gen_op_movq_A0_seg(override
);
508 gen_op_addq_A0_reg_sN(0, R_ESI
);
510 gen_op_movq_A0_reg(R_ESI
);
516 if (s
->addseg
&& override
< 0)
519 gen_op_movl_A0_seg(override
);
520 gen_op_addl_A0_reg_sN(0, R_ESI
);
522 gen_op_movl_A0_reg(R_ESI
);
526 /* 16 address, always override */
529 tcg_gen_ext16u_tl(cpu_A0
, cpu_regs
[R_ESI
]);
530 gen_op_addl_A0_seg(s
, override
);
537 static inline void gen_string_movl_A0_EDI(DisasContext
*s
)
542 gen_op_movq_A0_reg(R_EDI
);
547 gen_op_movl_A0_seg(R_ES
);
548 gen_op_addl_A0_reg_sN(0, R_EDI
);
550 gen_op_movl_A0_reg(R_EDI
);
554 tcg_gen_ext16u_tl(cpu_A0
, cpu_regs
[R_EDI
]);
555 gen_op_addl_A0_seg(s
, R_ES
);
562 static inline void gen_op_movl_T0_Dshift(TCGMemOp ot
)
564 tcg_gen_ld32s_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, df
));
565 tcg_gen_shli_tl(cpu_T
[0], cpu_T
[0], ot
);
568 static TCGv
gen_ext_tl(TCGv dst
, TCGv src
, TCGMemOp size
, bool sign
)
573 tcg_gen_ext8s_tl(dst
, src
);
575 tcg_gen_ext8u_tl(dst
, src
);
580 tcg_gen_ext16s_tl(dst
, src
);
582 tcg_gen_ext16u_tl(dst
, src
);
588 tcg_gen_ext32s_tl(dst
, src
);
590 tcg_gen_ext32u_tl(dst
, src
);
599 static void gen_extu(TCGMemOp ot
, TCGv reg
)
601 gen_ext_tl(reg
, reg
, ot
, false);
604 static void gen_exts(TCGMemOp ot
, TCGv reg
)
606 gen_ext_tl(reg
, reg
, ot
, true);
609 static inline void gen_op_jnz_ecx(TCGMemOp size
, TCGLabel
*label1
)
611 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[R_ECX
]);
612 gen_extu(size
, cpu_tmp0
);
613 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_tmp0
, 0, label1
);
616 static inline void gen_op_jz_ecx(TCGMemOp size
, TCGLabel
*label1
)
618 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[R_ECX
]);
619 gen_extu(size
, cpu_tmp0
);
620 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
623 static void gen_helper_in_func(TCGMemOp ot
, TCGv v
, TCGv_i32 n
)
627 gen_helper_inb(v
, cpu_env
, n
);
630 gen_helper_inw(v
, cpu_env
, n
);
633 gen_helper_inl(v
, cpu_env
, n
);
640 static void gen_helper_out_func(TCGMemOp ot
, TCGv_i32 v
, TCGv_i32 n
)
644 gen_helper_outb(cpu_env
, v
, n
);
647 gen_helper_outw(cpu_env
, v
, n
);
650 gen_helper_outl(cpu_env
, v
, n
);
657 static void gen_check_io(DisasContext
*s
, TCGMemOp ot
, target_ulong cur_eip
,
660 target_ulong next_eip
;
662 if (s
->pe
&& (s
->cpl
> s
->iopl
|| s
->vm86
)) {
663 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
666 gen_helper_check_iob(cpu_env
, cpu_tmp2_i32
);
669 gen_helper_check_iow(cpu_env
, cpu_tmp2_i32
);
672 gen_helper_check_iol(cpu_env
, cpu_tmp2_i32
);
678 if(s
->flags
& HF_SVMI_MASK
) {
681 svm_flags
|= (1 << (4 + ot
));
682 next_eip
= s
->pc
- s
->cs_base
;
683 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
684 gen_helper_svm_check_io(cpu_env
, cpu_tmp2_i32
,
685 tcg_const_i32(svm_flags
),
686 tcg_const_i32(next_eip
- cur_eip
));
690 static inline void gen_movs(DisasContext
*s
, TCGMemOp ot
)
692 gen_string_movl_A0_ESI(s
);
693 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
694 gen_string_movl_A0_EDI(s
);
695 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
696 gen_op_movl_T0_Dshift(ot
);
697 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
698 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
701 static void gen_op_update1_cc(void)
703 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
706 static void gen_op_update2_cc(void)
708 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
709 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
712 static void gen_op_update3_cc(TCGv reg
)
714 tcg_gen_mov_tl(cpu_cc_src2
, reg
);
715 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
716 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
719 static inline void gen_op_testl_T0_T1_cc(void)
721 tcg_gen_and_tl(cpu_cc_dst
, cpu_T
[0], cpu_T
[1]);
724 static void gen_op_update_neg_cc(void)
726 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
727 tcg_gen_neg_tl(cpu_cc_src
, cpu_T
[0]);
728 tcg_gen_movi_tl(cpu_cc_srcT
, 0);
731 /* compute all eflags to cc_src */
732 static void gen_compute_eflags(DisasContext
*s
)
734 TCGv zero
, dst
, src1
, src2
;
737 if (s
->cc_op
== CC_OP_EFLAGS
) {
740 if (s
->cc_op
== CC_OP_CLR
) {
741 tcg_gen_movi_tl(cpu_cc_src
, CC_Z
| CC_P
);
742 set_cc_op(s
, CC_OP_EFLAGS
);
751 /* Take care to not read values that are not live. */
752 live
= cc_op_live
[s
->cc_op
] & ~USES_CC_SRCT
;
753 dead
= live
^ (USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
);
755 zero
= tcg_const_tl(0);
756 if (dead
& USES_CC_DST
) {
759 if (dead
& USES_CC_SRC
) {
762 if (dead
& USES_CC_SRC2
) {
768 gen_helper_cc_compute_all(cpu_cc_src
, dst
, src1
, src2
, cpu_cc_op
);
769 set_cc_op(s
, CC_OP_EFLAGS
);
776 typedef struct CCPrepare
{
786 /* compute eflags.C to reg */
787 static CCPrepare
gen_prepare_eflags_c(DisasContext
*s
, TCGv reg
)
793 case CC_OP_SUBB
... CC_OP_SUBQ
:
794 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
795 size
= s
->cc_op
- CC_OP_SUBB
;
796 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
797 /* If no temporary was used, be careful not to alias t1 and t0. */
798 t0
= TCGV_EQUAL(t1
, cpu_cc_src
) ? cpu_tmp0
: reg
;
799 tcg_gen_mov_tl(t0
, cpu_cc_srcT
);
803 case CC_OP_ADDB
... CC_OP_ADDQ
:
804 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
805 size
= s
->cc_op
- CC_OP_ADDB
;
806 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
807 t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
809 return (CCPrepare
) { .cond
= TCG_COND_LTU
, .reg
= t0
,
810 .reg2
= t1
, .mask
= -1, .use_reg2
= true };
812 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
814 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
816 case CC_OP_INCB
... CC_OP_INCQ
:
817 case CC_OP_DECB
... CC_OP_DECQ
:
818 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
819 .mask
= -1, .no_setcond
= true };
821 case CC_OP_SHLB
... CC_OP_SHLQ
:
822 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
823 size
= s
->cc_op
- CC_OP_SHLB
;
824 shift
= (8 << size
) - 1;
825 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
826 .mask
= (target_ulong
)1 << shift
};
828 case CC_OP_MULB
... CC_OP_MULQ
:
829 return (CCPrepare
) { .cond
= TCG_COND_NE
,
830 .reg
= cpu_cc_src
, .mask
= -1 };
832 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
833 size
= s
->cc_op
- CC_OP_BMILGB
;
834 t0
= gen_ext_tl(reg
, cpu_cc_src
, size
, false);
835 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
839 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_dst
,
840 .mask
= -1, .no_setcond
= true };
843 case CC_OP_SARB
... CC_OP_SARQ
:
845 return (CCPrepare
) { .cond
= TCG_COND_NE
,
846 .reg
= cpu_cc_src
, .mask
= CC_C
};
849 /* The need to compute only C from CC_OP_DYNAMIC is important
850 in efficiently implementing e.g. INC at the start of a TB. */
852 gen_helper_cc_compute_c(reg
, cpu_cc_dst
, cpu_cc_src
,
853 cpu_cc_src2
, cpu_cc_op
);
854 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
855 .mask
= -1, .no_setcond
= true };
859 /* compute eflags.P to reg */
860 static CCPrepare
gen_prepare_eflags_p(DisasContext
*s
, TCGv reg
)
862 gen_compute_eflags(s
);
863 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
867 /* compute eflags.S to reg */
868 static CCPrepare
gen_prepare_eflags_s(DisasContext
*s
, TCGv reg
)
872 gen_compute_eflags(s
);
878 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
881 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
884 TCGMemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
885 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, true);
886 return (CCPrepare
) { .cond
= TCG_COND_LT
, .reg
= t0
, .mask
= -1 };
891 /* compute eflags.O to reg */
892 static CCPrepare
gen_prepare_eflags_o(DisasContext
*s
, TCGv reg
)
897 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src2
,
898 .mask
= -1, .no_setcond
= true };
900 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
902 gen_compute_eflags(s
);
903 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
908 /* compute eflags.Z to reg */
909 static CCPrepare
gen_prepare_eflags_z(DisasContext
*s
, TCGv reg
)
913 gen_compute_eflags(s
);
919 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
922 return (CCPrepare
) { .cond
= TCG_COND_ALWAYS
, .mask
= -1 };
925 TCGMemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
926 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
927 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
932 /* perform a conditional store into register 'reg' according to jump opcode
933 value 'b'. In the fast case, T0 is guaranted not to be used. */
934 static CCPrepare
gen_prepare_cc(DisasContext
*s
, int b
, TCGv reg
)
936 int inv
, jcc_op
, cond
;
942 jcc_op
= (b
>> 1) & 7;
945 case CC_OP_SUBB
... CC_OP_SUBQ
:
946 /* We optimize relational operators for the cmp/jcc case. */
947 size
= s
->cc_op
- CC_OP_SUBB
;
950 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
951 gen_extu(size
, cpu_tmp4
);
952 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
953 cc
= (CCPrepare
) { .cond
= TCG_COND_LEU
, .reg
= cpu_tmp4
,
954 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
963 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
964 gen_exts(size
, cpu_tmp4
);
965 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, true);
966 cc
= (CCPrepare
) { .cond
= cond
, .reg
= cpu_tmp4
,
967 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
977 /* This actually generates good code for JC, JZ and JS. */
980 cc
= gen_prepare_eflags_o(s
, reg
);
983 cc
= gen_prepare_eflags_c(s
, reg
);
986 cc
= gen_prepare_eflags_z(s
, reg
);
989 gen_compute_eflags(s
);
990 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
991 .mask
= CC_Z
| CC_C
};
994 cc
= gen_prepare_eflags_s(s
, reg
);
997 cc
= gen_prepare_eflags_p(s
, reg
);
1000 gen_compute_eflags(s
);
1001 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
1004 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
1005 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
1006 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
1011 gen_compute_eflags(s
);
1012 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
1015 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
1016 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
1017 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
1018 .mask
= CC_S
| CC_Z
};
1025 cc
.cond
= tcg_invert_cond(cc
.cond
);
1030 static void gen_setcc1(DisasContext
*s
, int b
, TCGv reg
)
1032 CCPrepare cc
= gen_prepare_cc(s
, b
, reg
);
1034 if (cc
.no_setcond
) {
1035 if (cc
.cond
== TCG_COND_EQ
) {
1036 tcg_gen_xori_tl(reg
, cc
.reg
, 1);
1038 tcg_gen_mov_tl(reg
, cc
.reg
);
1043 if (cc
.cond
== TCG_COND_NE
&& !cc
.use_reg2
&& cc
.imm
== 0 &&
1044 cc
.mask
!= 0 && (cc
.mask
& (cc
.mask
- 1)) == 0) {
1045 tcg_gen_shri_tl(reg
, cc
.reg
, ctztl(cc
.mask
));
1046 tcg_gen_andi_tl(reg
, reg
, 1);
1049 if (cc
.mask
!= -1) {
1050 tcg_gen_andi_tl(reg
, cc
.reg
, cc
.mask
);
1054 tcg_gen_setcond_tl(cc
.cond
, reg
, cc
.reg
, cc
.reg2
);
1056 tcg_gen_setcondi_tl(cc
.cond
, reg
, cc
.reg
, cc
.imm
);
1060 static inline void gen_compute_eflags_c(DisasContext
*s
, TCGv reg
)
1062 gen_setcc1(s
, JCC_B
<< 1, reg
);
1065 /* generate a conditional jump to label 'l1' according to jump opcode
1066 value 'b'. In the fast case, T0 is guaranted not to be used. */
1067 static inline void gen_jcc1_noeob(DisasContext
*s
, int b
, TCGLabel
*l1
)
1069 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T
[0]);
1071 if (cc
.mask
!= -1) {
1072 tcg_gen_andi_tl(cpu_T
[0], cc
.reg
, cc
.mask
);
1076 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1078 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1082 /* Generate a conditional jump to label 'l1' according to jump opcode
1083 value 'b'. In the fast case, T0 is guaranted not to be used.
1084 A translation block must end soon. */
1085 static inline void gen_jcc1(DisasContext
*s
, int b
, TCGLabel
*l1
)
1087 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T
[0]);
1089 gen_update_cc_op(s
);
1090 if (cc
.mask
!= -1) {
1091 tcg_gen_andi_tl(cpu_T
[0], cc
.reg
, cc
.mask
);
1094 set_cc_op(s
, CC_OP_DYNAMIC
);
1096 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1098 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1102 /* XXX: does not work with gdbstub "ice" single step - not a
1104 static TCGLabel
*gen_jz_ecx_string(DisasContext
*s
, target_ulong next_eip
)
1106 TCGLabel
*l1
= gen_new_label();
1107 TCGLabel
*l2
= gen_new_label();
1108 gen_op_jnz_ecx(s
->aflag
, l1
);
1110 gen_jmp_tb(s
, next_eip
, 1);
1115 static inline void gen_stos(DisasContext
*s
, TCGMemOp ot
)
1117 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EAX
);
1118 gen_string_movl_A0_EDI(s
);
1119 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
1120 gen_op_movl_T0_Dshift(ot
);
1121 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1124 static inline void gen_lods(DisasContext
*s
, TCGMemOp ot
)
1126 gen_string_movl_A0_ESI(s
);
1127 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1128 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T
[0]);
1129 gen_op_movl_T0_Dshift(ot
);
1130 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1133 static inline void gen_scas(DisasContext
*s
, TCGMemOp ot
)
1135 gen_string_movl_A0_EDI(s
);
1136 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
1137 gen_op(s
, OP_CMPL
, ot
, R_EAX
);
1138 gen_op_movl_T0_Dshift(ot
);
1139 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1142 static inline void gen_cmps(DisasContext
*s
, TCGMemOp ot
)
1144 gen_string_movl_A0_EDI(s
);
1145 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
1146 gen_string_movl_A0_ESI(s
);
1147 gen_op(s
, OP_CMPL
, ot
, OR_TMP0
);
1148 gen_op_movl_T0_Dshift(ot
);
1149 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1150 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1153 static void gen_bpt_io(DisasContext
*s
, TCGv_i32 t_port
, int ot
)
1155 if (s
->flags
& HF_IOBPT_MASK
) {
1156 TCGv_i32 t_size
= tcg_const_i32(1 << ot
);
1157 TCGv t_next
= tcg_const_tl(s
->pc
- s
->cs_base
);
1159 gen_helper_bpt_io(cpu_env
, t_port
, t_size
, t_next
);
1160 tcg_temp_free_i32(t_size
);
1161 tcg_temp_free(t_next
);
1166 static inline void gen_ins(DisasContext
*s
, TCGMemOp ot
)
1168 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1171 gen_string_movl_A0_EDI(s
);
1172 /* Note: we must do this dummy write first to be restartable in
1173 case of page fault. */
1174 tcg_gen_movi_tl(cpu_T
[0], 0);
1175 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
1176 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_EDX
]);
1177 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1178 gen_helper_in_func(ot
, cpu_T
[0], cpu_tmp2_i32
);
1179 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
1180 gen_op_movl_T0_Dshift(ot
);
1181 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1182 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
1183 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1188 static inline void gen_outs(DisasContext
*s
, TCGMemOp ot
)
1190 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1193 gen_string_movl_A0_ESI(s
);
1194 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1196 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_EDX
]);
1197 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1198 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[0]);
1199 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1200 gen_op_movl_T0_Dshift(ot
);
1201 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1202 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
1203 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1208 /* same method as Valgrind : we generate jumps to current or next
1210 #define GEN_REPZ(op) \
1211 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1212 target_ulong cur_eip, target_ulong next_eip) \
1215 gen_update_cc_op(s); \
1216 l2 = gen_jz_ecx_string(s, next_eip); \
1217 gen_ ## op(s, ot); \
1218 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1219 /* a loop would cause two single step exceptions if ECX = 1 \
1220 before rep string_insn */ \
1222 gen_op_jz_ecx(s->aflag, l2); \
1223 gen_jmp(s, cur_eip); \
1226 #define GEN_REPZ2(op) \
1227 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1228 target_ulong cur_eip, \
1229 target_ulong next_eip, \
1233 gen_update_cc_op(s); \
1234 l2 = gen_jz_ecx_string(s, next_eip); \
1235 gen_ ## op(s, ot); \
1236 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1237 gen_update_cc_op(s); \
1238 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
1240 gen_op_jz_ecx(s->aflag, l2); \
1241 gen_jmp(s, cur_eip); \
1252 static void gen_helper_fp_arith_ST0_FT0(int op
)
1256 gen_helper_fadd_ST0_FT0(cpu_env
);
1259 gen_helper_fmul_ST0_FT0(cpu_env
);
1262 gen_helper_fcom_ST0_FT0(cpu_env
);
1265 gen_helper_fcom_ST0_FT0(cpu_env
);
1268 gen_helper_fsub_ST0_FT0(cpu_env
);
1271 gen_helper_fsubr_ST0_FT0(cpu_env
);
1274 gen_helper_fdiv_ST0_FT0(cpu_env
);
1277 gen_helper_fdivr_ST0_FT0(cpu_env
);
1282 /* NOTE the exception in "r" op ordering */
1283 static void gen_helper_fp_arith_STN_ST0(int op
, int opreg
)
1285 TCGv_i32 tmp
= tcg_const_i32(opreg
);
1288 gen_helper_fadd_STN_ST0(cpu_env
, tmp
);
1291 gen_helper_fmul_STN_ST0(cpu_env
, tmp
);
1294 gen_helper_fsubr_STN_ST0(cpu_env
, tmp
);
1297 gen_helper_fsub_STN_ST0(cpu_env
, tmp
);
1300 gen_helper_fdivr_STN_ST0(cpu_env
, tmp
);
1303 gen_helper_fdiv_STN_ST0(cpu_env
, tmp
);
1308 /* if d == OR_TMP0, it means memory operand (address in A0) */
1309 static void gen_op(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
)
1312 gen_op_mov_v_reg(ot
, cpu_T
[0], d
);
1314 gen_op_ld_v(s1
, ot
, cpu_T
[0], cpu_A0
);
1318 gen_compute_eflags_c(s1
, cpu_tmp4
);
1319 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1320 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_tmp4
);
1321 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1322 gen_op_update3_cc(cpu_tmp4
);
1323 set_cc_op(s1
, CC_OP_ADCB
+ ot
);
1326 gen_compute_eflags_c(s1
, cpu_tmp4
);
1327 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1328 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_tmp4
);
1329 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1330 gen_op_update3_cc(cpu_tmp4
);
1331 set_cc_op(s1
, CC_OP_SBBB
+ ot
);
1334 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1335 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1336 gen_op_update2_cc();
1337 set_cc_op(s1
, CC_OP_ADDB
+ ot
);
1340 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T
[0]);
1341 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1342 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1343 gen_op_update2_cc();
1344 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1348 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1349 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1350 gen_op_update1_cc();
1351 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1354 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1355 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1356 gen_op_update1_cc();
1357 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1360 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1361 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1362 gen_op_update1_cc();
1363 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1366 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
1367 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T
[0]);
1368 tcg_gen_sub_tl(cpu_cc_dst
, cpu_T
[0], cpu_T
[1]);
1369 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1374 /* if d == OR_TMP0, it means memory operand (address in A0) */
1375 static void gen_inc(DisasContext
*s1
, TCGMemOp ot
, int d
, int c
)
1378 gen_op_mov_v_reg(ot
, cpu_T
[0], d
);
1380 gen_op_ld_v(s1
, ot
, cpu_T
[0], cpu_A0
);
1382 gen_compute_eflags_c(s1
, cpu_cc_src
);
1384 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], 1);
1385 set_cc_op(s1
, CC_OP_INCB
+ ot
);
1387 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], -1);
1388 set_cc_op(s1
, CC_OP_DECB
+ ot
);
1390 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1391 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
1394 static void gen_shift_flags(DisasContext
*s
, TCGMemOp ot
, TCGv result
,
1395 TCGv shm1
, TCGv count
, bool is_right
)
1397 TCGv_i32 z32
, s32
, oldop
;
1400 /* Store the results into the CC variables. If we know that the
1401 variable must be dead, store unconditionally. Otherwise we'll
1402 need to not disrupt the current contents. */
1403 z_tl
= tcg_const_tl(0);
1404 if (cc_op_live
[s
->cc_op
] & USES_CC_DST
) {
1405 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_dst
, count
, z_tl
,
1406 result
, cpu_cc_dst
);
1408 tcg_gen_mov_tl(cpu_cc_dst
, result
);
1410 if (cc_op_live
[s
->cc_op
] & USES_CC_SRC
) {
1411 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_src
, count
, z_tl
,
1414 tcg_gen_mov_tl(cpu_cc_src
, shm1
);
1416 tcg_temp_free(z_tl
);
1418 /* Get the two potential CC_OP values into temporaries. */
1419 tcg_gen_movi_i32(cpu_tmp2_i32
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1420 if (s
->cc_op
== CC_OP_DYNAMIC
) {
1423 tcg_gen_movi_i32(cpu_tmp3_i32
, s
->cc_op
);
1424 oldop
= cpu_tmp3_i32
;
1427 /* Conditionally store the CC_OP value. */
1428 z32
= tcg_const_i32(0);
1429 s32
= tcg_temp_new_i32();
1430 tcg_gen_trunc_tl_i32(s32
, count
);
1431 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, s32
, z32
, cpu_tmp2_i32
, oldop
);
1432 tcg_temp_free_i32(z32
);
1433 tcg_temp_free_i32(s32
);
1435 /* The CC_OP value is no longer predictable. */
1436 set_cc_op(s
, CC_OP_DYNAMIC
);
1439 static void gen_shift_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1440 int is_right
, int is_arith
)
1442 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1445 if (op1
== OR_TMP0
) {
1446 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1448 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1451 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], mask
);
1452 tcg_gen_subi_tl(cpu_tmp0
, cpu_T
[1], 1);
1456 gen_exts(ot
, cpu_T
[0]);
1457 tcg_gen_sar_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1458 tcg_gen_sar_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1460 gen_extu(ot
, cpu_T
[0]);
1461 tcg_gen_shr_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1462 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1465 tcg_gen_shl_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1466 tcg_gen_shl_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1470 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1472 gen_shift_flags(s
, ot
, cpu_T
[0], cpu_tmp0
, cpu_T
[1], is_right
);
1475 static void gen_shift_rm_im(DisasContext
*s
, TCGMemOp ot
, int op1
, int op2
,
1476 int is_right
, int is_arith
)
1478 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1482 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1484 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1490 gen_exts(ot
, cpu_T
[0]);
1491 tcg_gen_sari_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1492 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], op2
);
1494 gen_extu(ot
, cpu_T
[0]);
1495 tcg_gen_shri_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1496 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], op2
);
1499 tcg_gen_shli_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1500 tcg_gen_shli_tl(cpu_T
[0], cpu_T
[0], op2
);
1505 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1507 /* update eflags if non zero shift */
1509 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
1510 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
1511 set_cc_op(s
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1515 static void gen_rot_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
, int is_right
)
1517 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1521 if (op1
== OR_TMP0
) {
1522 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1524 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1527 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], mask
);
1531 /* Replicate the 8-bit input so that a 32-bit rotate works. */
1532 tcg_gen_ext8u_tl(cpu_T
[0], cpu_T
[0]);
1533 tcg_gen_muli_tl(cpu_T
[0], cpu_T
[0], 0x01010101);
1536 /* Replicate the 16-bit input so that a 32-bit rotate works. */
1537 tcg_gen_deposit_tl(cpu_T
[0], cpu_T
[0], cpu_T
[0], 16, 16);
1540 #ifdef TARGET_X86_64
1542 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
1543 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
1545 tcg_gen_rotr_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1547 tcg_gen_rotl_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1549 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
1554 tcg_gen_rotr_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1556 tcg_gen_rotl_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1562 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1564 /* We'll need the flags computed into CC_SRC. */
1565 gen_compute_eflags(s
);
1567 /* The value that was "rotated out" is now present at the other end
1568 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1569 since we've computed the flags into CC_SRC, these variables are
1572 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T
[0], mask
- 1);
1573 tcg_gen_shri_tl(cpu_cc_dst
, cpu_T
[0], mask
);
1574 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1576 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T
[0], mask
);
1577 tcg_gen_andi_tl(cpu_cc_dst
, cpu_T
[0], 1);
1579 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1580 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1582 /* Now conditionally store the new CC_OP value. If the shift count
1583 is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1584 Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1585 exactly as we computed above. */
1586 t0
= tcg_const_i32(0);
1587 t1
= tcg_temp_new_i32();
1588 tcg_gen_trunc_tl_i32(t1
, cpu_T
[1]);
1589 tcg_gen_movi_i32(cpu_tmp2_i32
, CC_OP_ADCOX
);
1590 tcg_gen_movi_i32(cpu_tmp3_i32
, CC_OP_EFLAGS
);
1591 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, t1
, t0
,
1592 cpu_tmp2_i32
, cpu_tmp3_i32
);
1593 tcg_temp_free_i32(t0
);
1594 tcg_temp_free_i32(t1
);
1596 /* The CC_OP value is no longer predictable. */
1597 set_cc_op(s
, CC_OP_DYNAMIC
);
1600 static void gen_rot_rm_im(DisasContext
*s
, TCGMemOp ot
, int op1
, int op2
,
1603 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1607 if (op1
== OR_TMP0
) {
1608 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1610 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1616 #ifdef TARGET_X86_64
1618 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
1620 tcg_gen_rotri_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, op2
);
1622 tcg_gen_rotli_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, op2
);
1624 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
1629 tcg_gen_rotri_tl(cpu_T
[0], cpu_T
[0], op2
);
1631 tcg_gen_rotli_tl(cpu_T
[0], cpu_T
[0], op2
);
1642 shift
= mask
+ 1 - shift
;
1644 gen_extu(ot
, cpu_T
[0]);
1645 tcg_gen_shli_tl(cpu_tmp0
, cpu_T
[0], shift
);
1646 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], mask
+ 1 - shift
);
1647 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
1653 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1656 /* Compute the flags into CC_SRC. */
1657 gen_compute_eflags(s
);
1659 /* The value that was "rotated out" is now present at the other end
1660 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1661 since we've computed the flags into CC_SRC, these variables are
1664 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T
[0], mask
- 1);
1665 tcg_gen_shri_tl(cpu_cc_dst
, cpu_T
[0], mask
);
1666 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1668 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T
[0], mask
);
1669 tcg_gen_andi_tl(cpu_cc_dst
, cpu_T
[0], 1);
1671 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1672 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1673 set_cc_op(s
, CC_OP_ADCOX
);
1677 /* XXX: add faster immediate = 1 case */
1678 static void gen_rotc_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1681 gen_compute_eflags(s
);
1682 assert(s
->cc_op
== CC_OP_EFLAGS
);
1686 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1688 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1693 gen_helper_rcrb(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1696 gen_helper_rcrw(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1699 gen_helper_rcrl(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1701 #ifdef TARGET_X86_64
1703 gen_helper_rcrq(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1712 gen_helper_rclb(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1715 gen_helper_rclw(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1718 gen_helper_rcll(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1720 #ifdef TARGET_X86_64
1722 gen_helper_rclq(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1730 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1733 /* XXX: add faster immediate case */
1734 static void gen_shiftd_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1735 bool is_right
, TCGv count_in
)
1737 target_ulong mask
= (ot
== MO_64
? 63 : 31);
1741 if (op1
== OR_TMP0
) {
1742 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1744 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1747 count
= tcg_temp_new();
1748 tcg_gen_andi_tl(count
, count_in
, mask
);
1752 /* Note: we implement the Intel behaviour for shift count > 16.
1753 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A
1754 portion by constructing it as a 32-bit value. */
1756 tcg_gen_deposit_tl(cpu_tmp0
, cpu_T
[0], cpu_T
[1], 16, 16);
1757 tcg_gen_mov_tl(cpu_T
[1], cpu_T
[0]);
1758 tcg_gen_mov_tl(cpu_T
[0], cpu_tmp0
);
1760 tcg_gen_deposit_tl(cpu_T
[1], cpu_T
[0], cpu_T
[1], 16, 16);
1763 #ifdef TARGET_X86_64
1765 /* Concatenate the two 32-bit values and use a 64-bit shift. */
1766 tcg_gen_subi_tl(cpu_tmp0
, count
, 1);
1768 tcg_gen_concat_tl_i64(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1769 tcg_gen_shr_i64(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1770 tcg_gen_shr_i64(cpu_T
[0], cpu_T
[0], count
);
1772 tcg_gen_concat_tl_i64(cpu_T
[0], cpu_T
[1], cpu_T
[0]);
1773 tcg_gen_shl_i64(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1774 tcg_gen_shl_i64(cpu_T
[0], cpu_T
[0], count
);
1775 tcg_gen_shri_i64(cpu_tmp0
, cpu_tmp0
, 32);
1776 tcg_gen_shri_i64(cpu_T
[0], cpu_T
[0], 32);
1781 tcg_gen_subi_tl(cpu_tmp0
, count
, 1);
1783 tcg_gen_shr_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1785 tcg_gen_subfi_tl(cpu_tmp4
, mask
+ 1, count
);
1786 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], count
);
1787 tcg_gen_shl_tl(cpu_T
[1], cpu_T
[1], cpu_tmp4
);
1789 tcg_gen_shl_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1791 /* Only needed if count > 16, for Intel behaviour. */
1792 tcg_gen_subfi_tl(cpu_tmp4
, 33, count
);
1793 tcg_gen_shr_tl(cpu_tmp4
, cpu_T
[1], cpu_tmp4
);
1794 tcg_gen_or_tl(cpu_tmp0
, cpu_tmp0
, cpu_tmp4
);
1797 tcg_gen_subfi_tl(cpu_tmp4
, mask
+ 1, count
);
1798 tcg_gen_shl_tl(cpu_T
[0], cpu_T
[0], count
);
1799 tcg_gen_shr_tl(cpu_T
[1], cpu_T
[1], cpu_tmp4
);
1801 tcg_gen_movi_tl(cpu_tmp4
, 0);
1802 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_T
[1], count
, cpu_tmp4
,
1803 cpu_tmp4
, cpu_T
[1]);
1804 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1809 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1811 gen_shift_flags(s
, ot
, cpu_T
[0], cpu_tmp0
, count
, is_right
);
1812 tcg_temp_free(count
);
1815 static void gen_shift(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
, int s
)
1818 gen_op_mov_v_reg(ot
, cpu_T
[1], s
);
1821 gen_rot_rm_T1(s1
, ot
, d
, 0);
1824 gen_rot_rm_T1(s1
, ot
, d
, 1);
1828 gen_shift_rm_T1(s1
, ot
, d
, 0, 0);
1831 gen_shift_rm_T1(s1
, ot
, d
, 1, 0);
1834 gen_shift_rm_T1(s1
, ot
, d
, 1, 1);
1837 gen_rotc_rm_T1(s1
, ot
, d
, 0);
1840 gen_rotc_rm_T1(s1
, ot
, d
, 1);
1845 static void gen_shifti(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
, int c
)
1849 gen_rot_rm_im(s1
, ot
, d
, c
, 0);
1852 gen_rot_rm_im(s1
, ot
, d
, c
, 1);
1856 gen_shift_rm_im(s1
, ot
, d
, c
, 0, 0);
1859 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 0);
1862 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 1);
1865 /* currently not optimized */
1866 tcg_gen_movi_tl(cpu_T
[1], c
);
1867 gen_shift(s1
, op
, ot
, d
, OR_TMP1
);
1872 static void gen_lea_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
1879 int mod
, rm
, code
, override
, must_add_seg
;
1882 override
= s
->override
;
1883 must_add_seg
= s
->addseg
;
1886 mod
= (modrm
>> 6) & 3;
1899 code
= cpu_ldub_code(env
, s
->pc
++);
1900 scale
= (code
>> 6) & 3;
1901 index
= ((code
>> 3) & 7) | REX_X(s
);
1903 index
= -1; /* no index */
1911 if ((base
& 7) == 5) {
1913 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
1915 if (CODE64(s
) && !havesib
) {
1916 disp
+= s
->pc
+ s
->rip_offset
;
1923 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
1927 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
1932 /* For correct popl handling with esp. */
1933 if (base
== R_ESP
&& s
->popl_esp_hack
) {
1934 disp
+= s
->popl_esp_hack
;
1937 /* Compute the address, with a minimum number of TCG ops. */
1941 sum
= cpu_regs
[index
];
1943 tcg_gen_shli_tl(cpu_A0
, cpu_regs
[index
], scale
);
1947 tcg_gen_add_tl(cpu_A0
, sum
, cpu_regs
[base
]);
1950 } else if (base
>= 0) {
1951 sum
= cpu_regs
[base
];
1953 if (TCGV_IS_UNUSED(sum
)) {
1954 tcg_gen_movi_tl(cpu_A0
, disp
);
1956 tcg_gen_addi_tl(cpu_A0
, sum
, disp
);
1961 if (base
== R_EBP
|| base
== R_ESP
) {
1968 tcg_gen_ld_tl(cpu_tmp0
, cpu_env
,
1969 offsetof(CPUX86State
, segs
[override
].base
));
1971 if (s
->aflag
== MO_32
) {
1972 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
1974 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
1978 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
1981 if (s
->aflag
== MO_32
) {
1982 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
1990 disp
= cpu_lduw_code(env
, s
->pc
);
1992 tcg_gen_movi_tl(cpu_A0
, disp
);
1993 rm
= 0; /* avoid SS override */
2000 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
2004 disp
= (int16_t)cpu_lduw_code(env
, s
->pc
);
2012 tcg_gen_add_tl(cpu_A0
, cpu_regs
[R_EBX
], cpu_regs
[R_ESI
]);
2015 tcg_gen_add_tl(cpu_A0
, cpu_regs
[R_EBX
], cpu_regs
[R_EDI
]);
2018 tcg_gen_add_tl(cpu_A0
, cpu_regs
[R_EBP
], cpu_regs
[R_ESI
]);
2021 tcg_gen_add_tl(cpu_A0
, cpu_regs
[R_EBP
], cpu_regs
[R_EDI
]);
2024 sum
= cpu_regs
[R_ESI
];
2027 sum
= cpu_regs
[R_EDI
];
2030 sum
= cpu_regs
[R_EBP
];
2034 sum
= cpu_regs
[R_EBX
];
2037 tcg_gen_addi_tl(cpu_A0
, sum
, disp
);
2038 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2042 if (rm
== 2 || rm
== 3 || rm
== 6) {
2048 gen_op_addl_A0_seg(s
, override
);
2057 static void gen_nop_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2059 int mod
, rm
, base
, code
;
2061 mod
= (modrm
>> 6) & 3;
2072 code
= cpu_ldub_code(env
, s
->pc
++);
2114 /* used for LEA and MOV AX, mem */
2115 static void gen_add_A0_ds_seg(DisasContext
*s
)
2117 int override
, must_add_seg
;
2118 must_add_seg
= s
->addseg
;
2120 if (s
->override
>= 0) {
2121 override
= s
->override
;
2125 #ifdef TARGET_X86_64
2127 gen_op_addq_A0_seg(override
);
2131 gen_op_addl_A0_seg(s
, override
);
2136 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2138 static void gen_ldst_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2139 TCGMemOp ot
, int reg
, int is_store
)
2143 mod
= (modrm
>> 6) & 3;
2144 rm
= (modrm
& 7) | REX_B(s
);
2148 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
2149 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
2151 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
2153 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
2156 gen_lea_modrm(env
, s
, modrm
);
2159 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
2160 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
2162 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
2164 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
2169 static inline uint32_t insn_get(CPUX86State
*env
, DisasContext
*s
, TCGMemOp ot
)
2175 ret
= cpu_ldub_code(env
, s
->pc
);
2179 ret
= cpu_lduw_code(env
, s
->pc
);
2183 #ifdef TARGET_X86_64
2186 ret
= cpu_ldl_code(env
, s
->pc
);
2195 static inline int insn_const_size(TCGMemOp ot
)
2204 static inline void gen_goto_tb(DisasContext
*s
, int tb_num
, target_ulong eip
)
2206 TranslationBlock
*tb
;
2209 pc
= s
->cs_base
+ eip
;
2211 /* NOTE: we handle the case where the TB spans two pages here */
2212 if ((pc
& TARGET_PAGE_MASK
) == (tb
->pc
& TARGET_PAGE_MASK
) ||
2213 (pc
& TARGET_PAGE_MASK
) == ((s
->pc
- 1) & TARGET_PAGE_MASK
)) {
2214 /* jump to same page: we can use a direct jump */
2215 tcg_gen_goto_tb(tb_num
);
2217 tcg_gen_exit_tb((uintptr_t)tb
+ tb_num
);
2219 /* jump to another page: currently not optimized */
2225 static inline void gen_jcc(DisasContext
*s
, int b
,
2226 target_ulong val
, target_ulong next_eip
)
2231 l1
= gen_new_label();
2234 gen_goto_tb(s
, 0, next_eip
);
2237 gen_goto_tb(s
, 1, val
);
2238 s
->is_jmp
= DISAS_TB_JUMP
;
2240 l1
= gen_new_label();
2241 l2
= gen_new_label();
2244 gen_jmp_im(next_eip
);
2254 static void gen_cmovcc1(CPUX86State
*env
, DisasContext
*s
, TCGMemOp ot
, int b
,
2259 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
2261 cc
= gen_prepare_cc(s
, b
, cpu_T
[1]);
2262 if (cc
.mask
!= -1) {
2263 TCGv t0
= tcg_temp_new();
2264 tcg_gen_andi_tl(t0
, cc
.reg
, cc
.mask
);
2268 cc
.reg2
= tcg_const_tl(cc
.imm
);
2271 tcg_gen_movcond_tl(cc
.cond
, cpu_T
[0], cc
.reg
, cc
.reg2
,
2272 cpu_T
[0], cpu_regs
[reg
]);
2273 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
2275 if (cc
.mask
!= -1) {
2276 tcg_temp_free(cc
.reg
);
2279 tcg_temp_free(cc
.reg2
);
2283 static inline void gen_op_movl_T0_seg(int seg_reg
)
2285 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
,
2286 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2289 static inline void gen_op_movl_seg_T0_vm(int seg_reg
)
2291 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffff);
2292 tcg_gen_st32_tl(cpu_T
[0], cpu_env
,
2293 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2294 tcg_gen_shli_tl(cpu_T
[0], cpu_T
[0], 4);
2295 tcg_gen_st_tl(cpu_T
[0], cpu_env
,
2296 offsetof(CPUX86State
,segs
[seg_reg
].base
));
2299 /* move T0 to seg_reg and compute if the CPU state may change. Never
2300 call this function with seg_reg == R_CS */
2301 static void gen_movl_seg_T0(DisasContext
*s
, int seg_reg
)
2303 if (s
->pe
&& !s
->vm86
) {
2304 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
2305 gen_helper_load_seg(cpu_env
, tcg_const_i32(seg_reg
), cpu_tmp2_i32
);
2306 /* abort translation because the addseg value may change or
2307 because ss32 may change. For R_SS, translation must always
2308 stop as a special handling must be done to disable hardware
2309 interrupts for the next instruction */
2310 if (seg_reg
== R_SS
|| (s
->code32
&& seg_reg
< R_FS
))
2311 s
->is_jmp
= DISAS_TB_JUMP
;
2313 gen_op_movl_seg_T0_vm(seg_reg
);
2314 if (seg_reg
== R_SS
)
2315 s
->is_jmp
= DISAS_TB_JUMP
;
2319 static inline int svm_is_rep(int prefixes
)
2321 return ((prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) ? 8 : 0);
2325 gen_svm_check_intercept_param(DisasContext
*s
, target_ulong pc_start
,
2326 uint32_t type
, uint64_t param
)
2328 /* no SVM activated; fast case */
2329 if (likely(!(s
->flags
& HF_SVMI_MASK
)))
2331 gen_update_cc_op(s
);
2332 gen_jmp_im(pc_start
- s
->cs_base
);
2333 gen_helper_svm_check_intercept_param(cpu_env
, tcg_const_i32(type
),
2334 tcg_const_i64(param
));
2338 gen_svm_check_intercept(DisasContext
*s
, target_ulong pc_start
, uint64_t type
)
2340 gen_svm_check_intercept_param(s
, pc_start
, type
, 0);
2343 static inline void gen_stack_update(DisasContext
*s
, int addend
)
2345 #ifdef TARGET_X86_64
2347 gen_op_add_reg_im(MO_64
, R_ESP
, addend
);
2351 gen_op_add_reg_im(MO_32
, R_ESP
, addend
);
2353 gen_op_add_reg_im(MO_16
, R_ESP
, addend
);
2357 /* Generate a push. It depends on ss32, addseg and dflag. */
2358 static void gen_push_v(DisasContext
*s
, TCGv val
)
2360 TCGMemOp a_ot
, d_ot
= mo_pushpop(s
, s
->dflag
);
2361 int size
= 1 << d_ot
;
2362 TCGv new_esp
= cpu_A0
;
2364 tcg_gen_subi_tl(cpu_A0
, cpu_regs
[R_ESP
], size
);
2368 } else if (s
->ss32
) {
2372 tcg_gen_mov_tl(new_esp
, cpu_A0
);
2373 gen_op_addl_A0_seg(s
, R_SS
);
2375 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
2380 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2381 tcg_gen_mov_tl(new_esp
, cpu_A0
);
2382 gen_op_addl_A0_seg(s
, R_SS
);
2385 gen_op_st_v(s
, d_ot
, val
, cpu_A0
);
2386 gen_op_mov_reg_v(a_ot
, R_ESP
, new_esp
);
2389 /* two step pop is necessary for precise exceptions */
2390 static TCGMemOp
gen_pop_T0(DisasContext
*s
)
2392 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2396 addr
= cpu_regs
[R_ESP
];
2397 } else if (!s
->ss32
) {
2398 tcg_gen_ext16u_tl(cpu_A0
, cpu_regs
[R_ESP
]);
2399 gen_op_addl_A0_seg(s
, R_SS
);
2400 } else if (s
->addseg
) {
2401 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_ESP
]);
2402 gen_op_addl_A0_seg(s
, R_SS
);
2404 tcg_gen_ext32u_tl(cpu_A0
, cpu_regs
[R_ESP
]);
2407 gen_op_ld_v(s
, d_ot
, cpu_T
[0], addr
);
2411 static void gen_pop_update(DisasContext
*s
, TCGMemOp ot
)
2413 gen_stack_update(s
, 1 << ot
);
2416 static void gen_stack_A0(DisasContext
*s
)
2418 gen_op_movl_A0_reg(R_ESP
);
2420 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2421 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2423 gen_op_addl_A0_seg(s
, R_SS
);
2426 /* NOTE: wrap around in 16 bit not fully handled */
2427 static void gen_pusha(DisasContext
*s
)
2430 gen_op_movl_A0_reg(R_ESP
);
2431 gen_op_addl_A0_im(-(8 << s
->dflag
));
2433 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2434 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2436 gen_op_addl_A0_seg(s
, R_SS
);
2437 for(i
= 0;i
< 8; i
++) {
2438 gen_op_mov_v_reg(MO_32
, cpu_T
[0], 7 - i
);
2439 gen_op_st_v(s
, s
->dflag
, cpu_T
[0], cpu_A0
);
2440 gen_op_addl_A0_im(1 << s
->dflag
);
2442 gen_op_mov_reg_v(MO_16
+ s
->ss32
, R_ESP
, cpu_T
[1]);
2445 /* NOTE: wrap around in 16 bit not fully handled */
2446 static void gen_popa(DisasContext
*s
)
2449 gen_op_movl_A0_reg(R_ESP
);
2451 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2452 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2453 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], 8 << s
->dflag
);
2455 gen_op_addl_A0_seg(s
, R_SS
);
2456 for(i
= 0;i
< 8; i
++) {
2457 /* ESP is not reloaded */
2459 gen_op_ld_v(s
, s
->dflag
, cpu_T
[0], cpu_A0
);
2460 gen_op_mov_reg_v(s
->dflag
, 7 - i
, cpu_T
[0]);
2462 gen_op_addl_A0_im(1 << s
->dflag
);
2464 gen_op_mov_reg_v(MO_16
+ s
->ss32
, R_ESP
, cpu_T
[1]);
2467 static void gen_enter(DisasContext
*s
, int esp_addend
, int level
)
2469 TCGMemOp ot
= mo_pushpop(s
, s
->dflag
);
2470 int opsize
= 1 << ot
;
2473 #ifdef TARGET_X86_64
2475 gen_op_movl_A0_reg(R_ESP
);
2476 gen_op_addq_A0_im(-opsize
);
2477 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2480 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EBP
);
2481 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
2483 /* XXX: must save state */
2484 gen_helper_enter64_level(cpu_env
, tcg_const_i32(level
),
2485 tcg_const_i32((ot
== MO_64
)),
2488 gen_op_mov_reg_v(ot
, R_EBP
, cpu_T
[1]);
2489 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], -esp_addend
+ (-opsize
* level
));
2490 gen_op_mov_reg_v(MO_64
, R_ESP
, cpu_T
[1]);
2494 gen_op_movl_A0_reg(R_ESP
);
2495 gen_op_addl_A0_im(-opsize
);
2497 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2498 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2500 gen_op_addl_A0_seg(s
, R_SS
);
2502 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EBP
);
2503 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
2505 /* XXX: must save state */
2506 gen_helper_enter_level(cpu_env
, tcg_const_i32(level
),
2507 tcg_const_i32(s
->dflag
- 1),
2510 gen_op_mov_reg_v(ot
, R_EBP
, cpu_T
[1]);
2511 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], -esp_addend
+ (-opsize
* level
));
2512 gen_op_mov_reg_v(MO_16
+ s
->ss32
, R_ESP
, cpu_T
[1]);
2516 static void gen_exception(DisasContext
*s
, int trapno
, target_ulong cur_eip
)
2518 gen_update_cc_op(s
);
2519 gen_jmp_im(cur_eip
);
2520 gen_helper_raise_exception(cpu_env
, tcg_const_i32(trapno
));
2521 s
->is_jmp
= DISAS_TB_JUMP
;
2524 /* an interrupt is different from an exception because of the
2526 static void gen_interrupt(DisasContext
*s
, int intno
,
2527 target_ulong cur_eip
, target_ulong next_eip
)
2529 gen_update_cc_op(s
);
2530 gen_jmp_im(cur_eip
);
2531 gen_helper_raise_interrupt(cpu_env
, tcg_const_i32(intno
),
2532 tcg_const_i32(next_eip
- cur_eip
));
2533 s
->is_jmp
= DISAS_TB_JUMP
;
2536 static void gen_debug(DisasContext
*s
, target_ulong cur_eip
)
2538 gen_update_cc_op(s
);
2539 gen_jmp_im(cur_eip
);
2540 gen_helper_debug(cpu_env
);
2541 s
->is_jmp
= DISAS_TB_JUMP
;
2544 /* generate a generic end of block. Trace exception is also generated
2546 static void gen_eob(DisasContext
*s
)
2548 gen_update_cc_op(s
);
2549 if (s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
) {
2550 gen_helper_reset_inhibit_irq(cpu_env
);
2552 if (s
->tb
->flags
& HF_RF_MASK
) {
2553 gen_helper_reset_rf(cpu_env
);
2555 if (s
->singlestep_enabled
) {
2556 gen_helper_debug(cpu_env
);
2558 gen_helper_single_step(cpu_env
);
2562 s
->is_jmp
= DISAS_TB_JUMP
;
2565 /* generate a jump to eip. No segment change must happen before as a
2566 direct call to the next block may occur */
2567 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
)
2569 gen_update_cc_op(s
);
2570 set_cc_op(s
, CC_OP_DYNAMIC
);
2572 gen_goto_tb(s
, tb_num
, eip
);
2573 s
->is_jmp
= DISAS_TB_JUMP
;
2580 static void gen_jmp(DisasContext
*s
, target_ulong eip
)
2582 gen_jmp_tb(s
, eip
, 0);
2585 static inline void gen_ldq_env_A0(DisasContext
*s
, int offset
)
2587 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
2588 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2591 static inline void gen_stq_env_A0(DisasContext
*s
, int offset
)
2593 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2594 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
2597 static inline void gen_ldo_env_A0(DisasContext
*s
, int offset
)
2599 int mem_index
= s
->mem_index
;
2600 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, mem_index
, MO_LEQ
);
2601 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2602 tcg_gen_addi_tl(cpu_tmp0
, cpu_A0
, 8);
2603 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
, MO_LEQ
);
2604 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2607 static inline void gen_sto_env_A0(DisasContext
*s
, int offset
)
2609 int mem_index
= s
->mem_index
;
2610 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2611 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, mem_index
, MO_LEQ
);
2612 tcg_gen_addi_tl(cpu_tmp0
, cpu_A0
, 8);
2613 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2614 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
, MO_LEQ
);
2617 static inline void gen_op_movo(int d_offset
, int s_offset
)
2619 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2620 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2621 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2622 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2625 static inline void gen_op_movq(int d_offset
, int s_offset
)
2627 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
);
2628 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2631 static inline void gen_op_movl(int d_offset
, int s_offset
)
2633 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
, s_offset
);
2634 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, d_offset
);
2637 static inline void gen_op_movq_env_0(int d_offset
)
2639 tcg_gen_movi_i64(cpu_tmp1_i64
, 0);
2640 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2643 typedef void (*SSEFunc_i_ep
)(TCGv_i32 val
, TCGv_ptr env
, TCGv_ptr reg
);
2644 typedef void (*SSEFunc_l_ep
)(TCGv_i64 val
, TCGv_ptr env
, TCGv_ptr reg
);
2645 typedef void (*SSEFunc_0_epi
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i32 val
);
2646 typedef void (*SSEFunc_0_epl
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i64 val
);
2647 typedef void (*SSEFunc_0_epp
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
);
2648 typedef void (*SSEFunc_0_eppi
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2650 typedef void (*SSEFunc_0_ppi
)(TCGv_ptr reg_a
, TCGv_ptr reg_b
, TCGv_i32 val
);
2651 typedef void (*SSEFunc_0_eppt
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2654 #define SSE_SPECIAL ((void *)1)
2655 #define SSE_DUMMY ((void *)2)
2657 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2658 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2659 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2661 static const SSEFunc_0_epp sse_op_table1
[256][4] = {
2662 /* 3DNow! extensions */
2663 [0x0e] = { SSE_DUMMY
}, /* femms */
2664 [0x0f] = { SSE_DUMMY
}, /* pf... */
2665 /* pure SSE operations */
2666 [0x10] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2667 [0x11] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2668 [0x12] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd, movsldup, movddup */
2669 [0x13] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd */
2670 [0x14] = { gen_helper_punpckldq_xmm
, gen_helper_punpcklqdq_xmm
},
2671 [0x15] = { gen_helper_punpckhdq_xmm
, gen_helper_punpckhqdq_xmm
},
2672 [0x16] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd, movshdup */
2673 [0x17] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd */
2675 [0x28] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2676 [0x29] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2677 [0x2a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2678 [0x2b] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movntps, movntpd, movntss, movntsd */
2679 [0x2c] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2680 [0x2d] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2681 [0x2e] = { gen_helper_ucomiss
, gen_helper_ucomisd
},
2682 [0x2f] = { gen_helper_comiss
, gen_helper_comisd
},
2683 [0x50] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movmskps, movmskpd */
2684 [0x51] = SSE_FOP(sqrt
),
2685 [0x52] = { gen_helper_rsqrtps
, NULL
, gen_helper_rsqrtss
, NULL
},
2686 [0x53] = { gen_helper_rcpps
, NULL
, gen_helper_rcpss
, NULL
},
2687 [0x54] = { gen_helper_pand_xmm
, gen_helper_pand_xmm
}, /* andps, andpd */
2688 [0x55] = { gen_helper_pandn_xmm
, gen_helper_pandn_xmm
}, /* andnps, andnpd */
2689 [0x56] = { gen_helper_por_xmm
, gen_helper_por_xmm
}, /* orps, orpd */
2690 [0x57] = { gen_helper_pxor_xmm
, gen_helper_pxor_xmm
}, /* xorps, xorpd */
2691 [0x58] = SSE_FOP(add
),
2692 [0x59] = SSE_FOP(mul
),
2693 [0x5a] = { gen_helper_cvtps2pd
, gen_helper_cvtpd2ps
,
2694 gen_helper_cvtss2sd
, gen_helper_cvtsd2ss
},
2695 [0x5b] = { gen_helper_cvtdq2ps
, gen_helper_cvtps2dq
, gen_helper_cvttps2dq
},
2696 [0x5c] = SSE_FOP(sub
),
2697 [0x5d] = SSE_FOP(min
),
2698 [0x5e] = SSE_FOP(div
),
2699 [0x5f] = SSE_FOP(max
),
2701 [0xc2] = SSE_FOP(cmpeq
),
2702 [0xc6] = { (SSEFunc_0_epp
)gen_helper_shufps
,
2703 (SSEFunc_0_epp
)gen_helper_shufpd
}, /* XXX: casts */
2705 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */
2706 [0x38] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2707 [0x3a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2709 /* MMX ops and their SSE extensions */
2710 [0x60] = MMX_OP2(punpcklbw
),
2711 [0x61] = MMX_OP2(punpcklwd
),
2712 [0x62] = MMX_OP2(punpckldq
),
2713 [0x63] = MMX_OP2(packsswb
),
2714 [0x64] = MMX_OP2(pcmpgtb
),
2715 [0x65] = MMX_OP2(pcmpgtw
),
2716 [0x66] = MMX_OP2(pcmpgtl
),
2717 [0x67] = MMX_OP2(packuswb
),
2718 [0x68] = MMX_OP2(punpckhbw
),
2719 [0x69] = MMX_OP2(punpckhwd
),
2720 [0x6a] = MMX_OP2(punpckhdq
),
2721 [0x6b] = MMX_OP2(packssdw
),
2722 [0x6c] = { NULL
, gen_helper_punpcklqdq_xmm
},
2723 [0x6d] = { NULL
, gen_helper_punpckhqdq_xmm
},
2724 [0x6e] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movd mm, ea */
2725 [0x6f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, , movqdu */
2726 [0x70] = { (SSEFunc_0_epp
)gen_helper_pshufw_mmx
,
2727 (SSEFunc_0_epp
)gen_helper_pshufd_xmm
,
2728 (SSEFunc_0_epp
)gen_helper_pshufhw_xmm
,
2729 (SSEFunc_0_epp
)gen_helper_pshuflw_xmm
}, /* XXX: casts */
2730 [0x71] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftw */
2731 [0x72] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftd */
2732 [0x73] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftq */
2733 [0x74] = MMX_OP2(pcmpeqb
),
2734 [0x75] = MMX_OP2(pcmpeqw
),
2735 [0x76] = MMX_OP2(pcmpeql
),
2736 [0x77] = { SSE_DUMMY
}, /* emms */
2737 [0x78] = { NULL
, SSE_SPECIAL
, NULL
, SSE_SPECIAL
}, /* extrq_i, insertq_i */
2738 [0x79] = { NULL
, gen_helper_extrq_r
, NULL
, gen_helper_insertq_r
},
2739 [0x7c] = { NULL
, gen_helper_haddpd
, NULL
, gen_helper_haddps
},
2740 [0x7d] = { NULL
, gen_helper_hsubpd
, NULL
, gen_helper_hsubps
},
2741 [0x7e] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movd, movd, , movq */
2742 [0x7f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, movdqu */
2743 [0xc4] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pinsrw */
2744 [0xc5] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pextrw */
2745 [0xd0] = { NULL
, gen_helper_addsubpd
, NULL
, gen_helper_addsubps
},
2746 [0xd1] = MMX_OP2(psrlw
),
2747 [0xd2] = MMX_OP2(psrld
),
2748 [0xd3] = MMX_OP2(psrlq
),
2749 [0xd4] = MMX_OP2(paddq
),
2750 [0xd5] = MMX_OP2(pmullw
),
2751 [0xd6] = { NULL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2752 [0xd7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pmovmskb */
2753 [0xd8] = MMX_OP2(psubusb
),
2754 [0xd9] = MMX_OP2(psubusw
),
2755 [0xda] = MMX_OP2(pminub
),
2756 [0xdb] = MMX_OP2(pand
),
2757 [0xdc] = MMX_OP2(paddusb
),
2758 [0xdd] = MMX_OP2(paddusw
),
2759 [0xde] = MMX_OP2(pmaxub
),
2760 [0xdf] = MMX_OP2(pandn
),
2761 [0xe0] = MMX_OP2(pavgb
),
2762 [0xe1] = MMX_OP2(psraw
),
2763 [0xe2] = MMX_OP2(psrad
),
2764 [0xe3] = MMX_OP2(pavgw
),
2765 [0xe4] = MMX_OP2(pmulhuw
),
2766 [0xe5] = MMX_OP2(pmulhw
),
2767 [0xe6] = { NULL
, gen_helper_cvttpd2dq
, gen_helper_cvtdq2pd
, gen_helper_cvtpd2dq
},
2768 [0xe7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movntq, movntq */
2769 [0xe8] = MMX_OP2(psubsb
),
2770 [0xe9] = MMX_OP2(psubsw
),
2771 [0xea] = MMX_OP2(pminsw
),
2772 [0xeb] = MMX_OP2(por
),
2773 [0xec] = MMX_OP2(paddsb
),
2774 [0xed] = MMX_OP2(paddsw
),
2775 [0xee] = MMX_OP2(pmaxsw
),
2776 [0xef] = MMX_OP2(pxor
),
2777 [0xf0] = { NULL
, NULL
, NULL
, SSE_SPECIAL
}, /* lddqu */
2778 [0xf1] = MMX_OP2(psllw
),
2779 [0xf2] = MMX_OP2(pslld
),
2780 [0xf3] = MMX_OP2(psllq
),
2781 [0xf4] = MMX_OP2(pmuludq
),
2782 [0xf5] = MMX_OP2(pmaddwd
),
2783 [0xf6] = MMX_OP2(psadbw
),
2784 [0xf7] = { (SSEFunc_0_epp
)gen_helper_maskmov_mmx
,
2785 (SSEFunc_0_epp
)gen_helper_maskmov_xmm
}, /* XXX: casts */
2786 [0xf8] = MMX_OP2(psubb
),
2787 [0xf9] = MMX_OP2(psubw
),
2788 [0xfa] = MMX_OP2(psubl
),
2789 [0xfb] = MMX_OP2(psubq
),
2790 [0xfc] = MMX_OP2(paddb
),
2791 [0xfd] = MMX_OP2(paddw
),
2792 [0xfe] = MMX_OP2(paddl
),
2795 static const SSEFunc_0_epp sse_op_table2
[3 * 8][2] = {
2796 [0 + 2] = MMX_OP2(psrlw
),
2797 [0 + 4] = MMX_OP2(psraw
),
2798 [0 + 6] = MMX_OP2(psllw
),
2799 [8 + 2] = MMX_OP2(psrld
),
2800 [8 + 4] = MMX_OP2(psrad
),
2801 [8 + 6] = MMX_OP2(pslld
),
2802 [16 + 2] = MMX_OP2(psrlq
),
2803 [16 + 3] = { NULL
, gen_helper_psrldq_xmm
},
2804 [16 + 6] = MMX_OP2(psllq
),
2805 [16 + 7] = { NULL
, gen_helper_pslldq_xmm
},
2808 static const SSEFunc_0_epi sse_op_table3ai
[] = {
2809 gen_helper_cvtsi2ss
,
2813 #ifdef TARGET_X86_64
2814 static const SSEFunc_0_epl sse_op_table3aq
[] = {
2815 gen_helper_cvtsq2ss
,
2820 static const SSEFunc_i_ep sse_op_table3bi
[] = {
2821 gen_helper_cvttss2si
,
2822 gen_helper_cvtss2si
,
2823 gen_helper_cvttsd2si
,
2827 #ifdef TARGET_X86_64
2828 static const SSEFunc_l_ep sse_op_table3bq
[] = {
2829 gen_helper_cvttss2sq
,
2830 gen_helper_cvtss2sq
,
2831 gen_helper_cvttsd2sq
,
2836 static const SSEFunc_0_epp sse_op_table4
[8][4] = {
2847 static const SSEFunc_0_epp sse_op_table5
[256] = {
2848 [0x0c] = gen_helper_pi2fw
,
2849 [0x0d] = gen_helper_pi2fd
,
2850 [0x1c] = gen_helper_pf2iw
,
2851 [0x1d] = gen_helper_pf2id
,
2852 [0x8a] = gen_helper_pfnacc
,
2853 [0x8e] = gen_helper_pfpnacc
,
2854 [0x90] = gen_helper_pfcmpge
,
2855 [0x94] = gen_helper_pfmin
,
2856 [0x96] = gen_helper_pfrcp
,
2857 [0x97] = gen_helper_pfrsqrt
,
2858 [0x9a] = gen_helper_pfsub
,
2859 [0x9e] = gen_helper_pfadd
,
2860 [0xa0] = gen_helper_pfcmpgt
,
2861 [0xa4] = gen_helper_pfmax
,
2862 [0xa6] = gen_helper_movq
, /* pfrcpit1; no need to actually increase precision */
2863 [0xa7] = gen_helper_movq
, /* pfrsqit1 */
2864 [0xaa] = gen_helper_pfsubr
,
2865 [0xae] = gen_helper_pfacc
,
2866 [0xb0] = gen_helper_pfcmpeq
,
2867 [0xb4] = gen_helper_pfmul
,
2868 [0xb6] = gen_helper_movq
, /* pfrcpit2 */
2869 [0xb7] = gen_helper_pmulhrw_mmx
,
2870 [0xbb] = gen_helper_pswapd
,
2871 [0xbf] = gen_helper_pavgb_mmx
/* pavgusb */
2874 struct SSEOpHelper_epp
{
2875 SSEFunc_0_epp op
[2];
2879 struct SSEOpHelper_eppi
{
2880 SSEFunc_0_eppi op
[2];
2884 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
2885 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
2886 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
2887 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
2888 #define PCLMULQDQ_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, \
2889 CPUID_EXT_PCLMULQDQ }
2890 #define AESNI_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_AES }
2892 static const struct SSEOpHelper_epp sse_op_table6
[256] = {
2893 [0x00] = SSSE3_OP(pshufb
),
2894 [0x01] = SSSE3_OP(phaddw
),
2895 [0x02] = SSSE3_OP(phaddd
),
2896 [0x03] = SSSE3_OP(phaddsw
),
2897 [0x04] = SSSE3_OP(pmaddubsw
),
2898 [0x05] = SSSE3_OP(phsubw
),
2899 [0x06] = SSSE3_OP(phsubd
),
2900 [0x07] = SSSE3_OP(phsubsw
),
2901 [0x08] = SSSE3_OP(psignb
),
2902 [0x09] = SSSE3_OP(psignw
),
2903 [0x0a] = SSSE3_OP(psignd
),
2904 [0x0b] = SSSE3_OP(pmulhrsw
),
2905 [0x10] = SSE41_OP(pblendvb
),
2906 [0x14] = SSE41_OP(blendvps
),
2907 [0x15] = SSE41_OP(blendvpd
),
2908 [0x17] = SSE41_OP(ptest
),
2909 [0x1c] = SSSE3_OP(pabsb
),
2910 [0x1d] = SSSE3_OP(pabsw
),
2911 [0x1e] = SSSE3_OP(pabsd
),
2912 [0x20] = SSE41_OP(pmovsxbw
),
2913 [0x21] = SSE41_OP(pmovsxbd
),
2914 [0x22] = SSE41_OP(pmovsxbq
),
2915 [0x23] = SSE41_OP(pmovsxwd
),
2916 [0x24] = SSE41_OP(pmovsxwq
),
2917 [0x25] = SSE41_OP(pmovsxdq
),
2918 [0x28] = SSE41_OP(pmuldq
),
2919 [0x29] = SSE41_OP(pcmpeqq
),
2920 [0x2a] = SSE41_SPECIAL
, /* movntqda */
2921 [0x2b] = SSE41_OP(packusdw
),
2922 [0x30] = SSE41_OP(pmovzxbw
),
2923 [0x31] = SSE41_OP(pmovzxbd
),
2924 [0x32] = SSE41_OP(pmovzxbq
),
2925 [0x33] = SSE41_OP(pmovzxwd
),
2926 [0x34] = SSE41_OP(pmovzxwq
),
2927 [0x35] = SSE41_OP(pmovzxdq
),
2928 [0x37] = SSE42_OP(pcmpgtq
),
2929 [0x38] = SSE41_OP(pminsb
),
2930 [0x39] = SSE41_OP(pminsd
),
2931 [0x3a] = SSE41_OP(pminuw
),
2932 [0x3b] = SSE41_OP(pminud
),
2933 [0x3c] = SSE41_OP(pmaxsb
),
2934 [0x3d] = SSE41_OP(pmaxsd
),
2935 [0x3e] = SSE41_OP(pmaxuw
),
2936 [0x3f] = SSE41_OP(pmaxud
),
2937 [0x40] = SSE41_OP(pmulld
),
2938 [0x41] = SSE41_OP(phminposuw
),
2939 [0xdb] = AESNI_OP(aesimc
),
2940 [0xdc] = AESNI_OP(aesenc
),
2941 [0xdd] = AESNI_OP(aesenclast
),
2942 [0xde] = AESNI_OP(aesdec
),
2943 [0xdf] = AESNI_OP(aesdeclast
),
2946 static const struct SSEOpHelper_eppi sse_op_table7
[256] = {
2947 [0x08] = SSE41_OP(roundps
),
2948 [0x09] = SSE41_OP(roundpd
),
2949 [0x0a] = SSE41_OP(roundss
),
2950 [0x0b] = SSE41_OP(roundsd
),
2951 [0x0c] = SSE41_OP(blendps
),
2952 [0x0d] = SSE41_OP(blendpd
),
2953 [0x0e] = SSE41_OP(pblendw
),
2954 [0x0f] = SSSE3_OP(palignr
),
2955 [0x14] = SSE41_SPECIAL
, /* pextrb */
2956 [0x15] = SSE41_SPECIAL
, /* pextrw */
2957 [0x16] = SSE41_SPECIAL
, /* pextrd/pextrq */
2958 [0x17] = SSE41_SPECIAL
, /* extractps */
2959 [0x20] = SSE41_SPECIAL
, /* pinsrb */
2960 [0x21] = SSE41_SPECIAL
, /* insertps */
2961 [0x22] = SSE41_SPECIAL
, /* pinsrd/pinsrq */
2962 [0x40] = SSE41_OP(dpps
),
2963 [0x41] = SSE41_OP(dppd
),
2964 [0x42] = SSE41_OP(mpsadbw
),
2965 [0x44] = PCLMULQDQ_OP(pclmulqdq
),
2966 [0x60] = SSE42_OP(pcmpestrm
),
2967 [0x61] = SSE42_OP(pcmpestri
),
2968 [0x62] = SSE42_OP(pcmpistrm
),
2969 [0x63] = SSE42_OP(pcmpistri
),
2970 [0xdf] = AESNI_OP(aeskeygenassist
),
2973 static void gen_sse(CPUX86State
*env
, DisasContext
*s
, int b
,
2974 target_ulong pc_start
, int rex_r
)
2976 int b1
, op1_offset
, op2_offset
, is_xmm
, val
;
2977 int modrm
, mod
, rm
, reg
;
2978 SSEFunc_0_epp sse_fn_epp
;
2979 SSEFunc_0_eppi sse_fn_eppi
;
2980 SSEFunc_0_ppi sse_fn_ppi
;
2981 SSEFunc_0_eppt sse_fn_eppt
;
2985 if (s
->prefix
& PREFIX_DATA
)
2987 else if (s
->prefix
& PREFIX_REPZ
)
2989 else if (s
->prefix
& PREFIX_REPNZ
)
2993 sse_fn_epp
= sse_op_table1
[b
][b1
];
2997 if ((b
<= 0x5f && b
>= 0x10) || b
== 0xc6 || b
== 0xc2) {
3007 /* simple MMX/SSE operation */
3008 if (s
->flags
& HF_TS_MASK
) {
3009 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
3012 if (s
->flags
& HF_EM_MASK
) {
3014 gen_exception(s
, EXCP06_ILLOP
, pc_start
- s
->cs_base
);
3017 if (is_xmm
&& !(s
->flags
& HF_OSFXSR_MASK
))
3018 if ((b
!= 0x38 && b
!= 0x3a) || (s
->prefix
& PREFIX_DATA
))
3021 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
))
3024 gen_helper_emms(cpu_env
);
3029 gen_helper_emms(cpu_env
);
3032 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3033 the static cpu state) */
3035 gen_helper_enter_mmx(cpu_env
);
3038 modrm
= cpu_ldub_code(env
, s
->pc
++);
3039 reg
= ((modrm
>> 3) & 7);
3042 mod
= (modrm
>> 6) & 3;
3043 if (sse_fn_epp
== SSE_SPECIAL
) {
3046 case 0x0e7: /* movntq */
3049 gen_lea_modrm(env
, s
, modrm
);
3050 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3052 case 0x1e7: /* movntdq */
3053 case 0x02b: /* movntps */
3054 case 0x12b: /* movntps */
3057 gen_lea_modrm(env
, s
, modrm
);
3058 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3060 case 0x3f0: /* lddqu */
3063 gen_lea_modrm(env
, s
, modrm
);
3064 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3066 case 0x22b: /* movntss */
3067 case 0x32b: /* movntsd */
3070 gen_lea_modrm(env
, s
, modrm
);
3072 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3073 xmm_regs
[reg
].ZMM_Q(0)));
3075 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
3076 xmm_regs
[reg
].ZMM_L(0)));
3077 gen_op_st_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
3080 case 0x6e: /* movd mm, ea */
3081 #ifdef TARGET_X86_64
3082 if (s
->dflag
== MO_64
) {
3083 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3084 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3088 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3089 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3090 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3091 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3092 gen_helper_movl_mm_T0_mmx(cpu_ptr0
, cpu_tmp2_i32
);
3095 case 0x16e: /* movd xmm, ea */
3096 #ifdef TARGET_X86_64
3097 if (s
->dflag
== MO_64
) {
3098 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3099 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3100 offsetof(CPUX86State
,xmm_regs
[reg
]));
3101 gen_helper_movq_mm_T0_xmm(cpu_ptr0
, cpu_T
[0]);
3105 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3106 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3107 offsetof(CPUX86State
,xmm_regs
[reg
]));
3108 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3109 gen_helper_movl_mm_T0_xmm(cpu_ptr0
, cpu_tmp2_i32
);
3112 case 0x6f: /* movq mm, ea */
3114 gen_lea_modrm(env
, s
, modrm
);
3115 gen_ldq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3118 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
3119 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3120 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
3121 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3124 case 0x010: /* movups */
3125 case 0x110: /* movupd */
3126 case 0x028: /* movaps */
3127 case 0x128: /* movapd */
3128 case 0x16f: /* movdqa xmm, ea */
3129 case 0x26f: /* movdqu xmm, ea */
3131 gen_lea_modrm(env
, s
, modrm
);
3132 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3134 rm
= (modrm
& 7) | REX_B(s
);
3135 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[reg
]),
3136 offsetof(CPUX86State
,xmm_regs
[rm
]));
3139 case 0x210: /* movss xmm, ea */
3141 gen_lea_modrm(env
, s
, modrm
);
3142 gen_op_ld_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
3143 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3144 tcg_gen_movi_tl(cpu_T
[0], 0);
3145 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)));
3146 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)));
3147 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)));
3149 rm
= (modrm
& 7) | REX_B(s
);
3150 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)),
3151 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)));
3154 case 0x310: /* movsd xmm, ea */
3156 gen_lea_modrm(env
, s
, modrm
);
3157 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3158 xmm_regs
[reg
].ZMM_Q(0)));
3159 tcg_gen_movi_tl(cpu_T
[0], 0);
3160 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)));
3161 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)));
3163 rm
= (modrm
& 7) | REX_B(s
);
3164 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3165 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3168 case 0x012: /* movlps */
3169 case 0x112: /* movlpd */
3171 gen_lea_modrm(env
, s
, modrm
);
3172 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3173 xmm_regs
[reg
].ZMM_Q(0)));
3176 rm
= (modrm
& 7) | REX_B(s
);
3177 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3178 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(1)));
3181 case 0x212: /* movsldup */
3183 gen_lea_modrm(env
, s
, modrm
);
3184 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3186 rm
= (modrm
& 7) | REX_B(s
);
3187 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)),
3188 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)));
3189 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)),
3190 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(2)));
3192 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)),
3193 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3194 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)),
3195 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)));
3197 case 0x312: /* movddup */
3199 gen_lea_modrm(env
, s
, modrm
);
3200 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3201 xmm_regs
[reg
].ZMM_Q(0)));
3203 rm
= (modrm
& 7) | REX_B(s
);
3204 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3205 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3207 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)),
3208 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3210 case 0x016: /* movhps */
3211 case 0x116: /* movhpd */
3213 gen_lea_modrm(env
, s
, modrm
);
3214 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3215 xmm_regs
[reg
].ZMM_Q(1)));
3218 rm
= (modrm
& 7) | REX_B(s
);
3219 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)),
3220 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3223 case 0x216: /* movshdup */
3225 gen_lea_modrm(env
, s
, modrm
);
3226 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3228 rm
= (modrm
& 7) | REX_B(s
);
3229 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)),
3230 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(1)));
3231 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)),
3232 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(3)));
3234 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)),
3235 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)));
3236 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)),
3237 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)));
3242 int bit_index
, field_length
;
3244 if (b1
== 1 && reg
!= 0)
3246 field_length
= cpu_ldub_code(env
, s
->pc
++) & 0x3F;
3247 bit_index
= cpu_ldub_code(env
, s
->pc
++) & 0x3F;
3248 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3249 offsetof(CPUX86State
,xmm_regs
[reg
]));
3251 gen_helper_extrq_i(cpu_env
, cpu_ptr0
,
3252 tcg_const_i32(bit_index
),
3253 tcg_const_i32(field_length
));
3255 gen_helper_insertq_i(cpu_env
, cpu_ptr0
,
3256 tcg_const_i32(bit_index
),
3257 tcg_const_i32(field_length
));
3260 case 0x7e: /* movd ea, mm */
3261 #ifdef TARGET_X86_64
3262 if (s
->dflag
== MO_64
) {
3263 tcg_gen_ld_i64(cpu_T
[0], cpu_env
,
3264 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3265 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3269 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
,
3270 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_L(0)));
3271 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3274 case 0x17e: /* movd ea, xmm */
3275 #ifdef TARGET_X86_64
3276 if (s
->dflag
== MO_64
) {
3277 tcg_gen_ld_i64(cpu_T
[0], cpu_env
,
3278 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3279 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3283 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
,
3284 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3285 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3288 case 0x27e: /* movq xmm, ea */
3290 gen_lea_modrm(env
, s
, modrm
);
3291 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3292 xmm_regs
[reg
].ZMM_Q(0)));
3294 rm
= (modrm
& 7) | REX_B(s
);
3295 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3296 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3298 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)));
3300 case 0x7f: /* movq ea, mm */
3302 gen_lea_modrm(env
, s
, modrm
);
3303 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3306 gen_op_movq(offsetof(CPUX86State
,fpregs
[rm
].mmx
),
3307 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3310 case 0x011: /* movups */
3311 case 0x111: /* movupd */
3312 case 0x029: /* movaps */
3313 case 0x129: /* movapd */
3314 case 0x17f: /* movdqa ea, xmm */
3315 case 0x27f: /* movdqu ea, xmm */
3317 gen_lea_modrm(env
, s
, modrm
);
3318 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3320 rm
= (modrm
& 7) | REX_B(s
);
3321 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[rm
]),
3322 offsetof(CPUX86State
,xmm_regs
[reg
]));
3325 case 0x211: /* movss ea, xmm */
3327 gen_lea_modrm(env
, s
, modrm
);
3328 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3329 gen_op_st_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
3331 rm
= (modrm
& 7) | REX_B(s
);
3332 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)),
3333 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3336 case 0x311: /* movsd ea, xmm */
3338 gen_lea_modrm(env
, s
, modrm
);
3339 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3340 xmm_regs
[reg
].ZMM_Q(0)));
3342 rm
= (modrm
& 7) | REX_B(s
);
3343 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)),
3344 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3347 case 0x013: /* movlps */
3348 case 0x113: /* movlpd */
3350 gen_lea_modrm(env
, s
, modrm
);
3351 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3352 xmm_regs
[reg
].ZMM_Q(0)));
3357 case 0x017: /* movhps */
3358 case 0x117: /* movhpd */
3360 gen_lea_modrm(env
, s
, modrm
);
3361 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3362 xmm_regs
[reg
].ZMM_Q(1)));
3367 case 0x71: /* shift mm, im */
3370 case 0x171: /* shift xmm, im */
3376 val
= cpu_ldub_code(env
, s
->pc
++);
3378 tcg_gen_movi_tl(cpu_T
[0], val
);
3379 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.ZMM_L(0)));
3380 tcg_gen_movi_tl(cpu_T
[0], 0);
3381 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.ZMM_L(1)));
3382 op1_offset
= offsetof(CPUX86State
,xmm_t0
);
3384 tcg_gen_movi_tl(cpu_T
[0], val
);
3385 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,mmx_t0
.MMX_L(0)));
3386 tcg_gen_movi_tl(cpu_T
[0], 0);
3387 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,mmx_t0
.MMX_L(1)));
3388 op1_offset
= offsetof(CPUX86State
,mmx_t0
);
3390 sse_fn_epp
= sse_op_table2
[((b
- 1) & 3) * 8 +
3391 (((modrm
>> 3)) & 7)][b1
];
3396 rm
= (modrm
& 7) | REX_B(s
);
3397 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3400 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3402 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3403 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op1_offset
);
3404 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3406 case 0x050: /* movmskps */
3407 rm
= (modrm
& 7) | REX_B(s
);
3408 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3409 offsetof(CPUX86State
,xmm_regs
[rm
]));
3410 gen_helper_movmskps(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3411 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3413 case 0x150: /* movmskpd */
3414 rm
= (modrm
& 7) | REX_B(s
);
3415 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3416 offsetof(CPUX86State
,xmm_regs
[rm
]));
3417 gen_helper_movmskpd(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3418 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3420 case 0x02a: /* cvtpi2ps */
3421 case 0x12a: /* cvtpi2pd */
3422 gen_helper_enter_mmx(cpu_env
);
3424 gen_lea_modrm(env
, s
, modrm
);
3425 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3426 gen_ldq_env_A0(s
, op2_offset
);
3429 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3431 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3432 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3433 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3436 gen_helper_cvtpi2ps(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3440 gen_helper_cvtpi2pd(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3444 case 0x22a: /* cvtsi2ss */
3445 case 0x32a: /* cvtsi2sd */
3446 ot
= mo_64_32(s
->dflag
);
3447 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3448 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3449 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3451 SSEFunc_0_epi sse_fn_epi
= sse_op_table3ai
[(b
>> 8) & 1];
3452 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3453 sse_fn_epi(cpu_env
, cpu_ptr0
, cpu_tmp2_i32
);
3455 #ifdef TARGET_X86_64
3456 SSEFunc_0_epl sse_fn_epl
= sse_op_table3aq
[(b
>> 8) & 1];
3457 sse_fn_epl(cpu_env
, cpu_ptr0
, cpu_T
[0]);
3463 case 0x02c: /* cvttps2pi */
3464 case 0x12c: /* cvttpd2pi */
3465 case 0x02d: /* cvtps2pi */
3466 case 0x12d: /* cvtpd2pi */
3467 gen_helper_enter_mmx(cpu_env
);
3469 gen_lea_modrm(env
, s
, modrm
);
3470 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3471 gen_ldo_env_A0(s
, op2_offset
);
3473 rm
= (modrm
& 7) | REX_B(s
);
3474 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3476 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
);
3477 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3478 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3481 gen_helper_cvttps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3484 gen_helper_cvttpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3487 gen_helper_cvtps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3490 gen_helper_cvtpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3494 case 0x22c: /* cvttss2si */
3495 case 0x32c: /* cvttsd2si */
3496 case 0x22d: /* cvtss2si */
3497 case 0x32d: /* cvtsd2si */
3498 ot
= mo_64_32(s
->dflag
);
3500 gen_lea_modrm(env
, s
, modrm
);
3502 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.ZMM_Q(0)));
3504 gen_op_ld_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
3505 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.ZMM_L(0)));
3507 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3509 rm
= (modrm
& 7) | REX_B(s
);
3510 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3512 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3514 SSEFunc_i_ep sse_fn_i_ep
=
3515 sse_op_table3bi
[((b
>> 7) & 2) | (b
& 1)];
3516 sse_fn_i_ep(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3517 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
3519 #ifdef TARGET_X86_64
3520 SSEFunc_l_ep sse_fn_l_ep
=
3521 sse_op_table3bq
[((b
>> 7) & 2) | (b
& 1)];
3522 sse_fn_l_ep(cpu_T
[0], cpu_env
, cpu_ptr0
);
3527 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3529 case 0xc4: /* pinsrw */
3532 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
3533 val
= cpu_ldub_code(env
, s
->pc
++);
3536 tcg_gen_st16_tl(cpu_T
[0], cpu_env
,
3537 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_W(val
)));
3540 tcg_gen_st16_tl(cpu_T
[0], cpu_env
,
3541 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_W(val
)));
3544 case 0xc5: /* pextrw */
3548 ot
= mo_64_32(s
->dflag
);
3549 val
= cpu_ldub_code(env
, s
->pc
++);
3552 rm
= (modrm
& 7) | REX_B(s
);
3553 tcg_gen_ld16u_tl(cpu_T
[0], cpu_env
,
3554 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_W(val
)));
3558 tcg_gen_ld16u_tl(cpu_T
[0], cpu_env
,
3559 offsetof(CPUX86State
,fpregs
[rm
].mmx
.MMX_W(val
)));
3561 reg
= ((modrm
>> 3) & 7) | rex_r
;
3562 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3564 case 0x1d6: /* movq ea, xmm */
3566 gen_lea_modrm(env
, s
, modrm
);
3567 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3568 xmm_regs
[reg
].ZMM_Q(0)));
3570 rm
= (modrm
& 7) | REX_B(s
);
3571 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)),
3572 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3573 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(1)));
3576 case 0x2d6: /* movq2dq */
3577 gen_helper_enter_mmx(cpu_env
);
3579 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3580 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3581 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)));
3583 case 0x3d6: /* movdq2q */
3584 gen_helper_enter_mmx(cpu_env
);
3585 rm
= (modrm
& 7) | REX_B(s
);
3586 gen_op_movq(offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
),
3587 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3589 case 0xd7: /* pmovmskb */
3594 rm
= (modrm
& 7) | REX_B(s
);
3595 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[rm
]));
3596 gen_helper_pmovmskb_xmm(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3599 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3600 gen_helper_pmovmskb_mmx(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3602 reg
= ((modrm
>> 3) & 7) | rex_r
;
3603 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3609 if ((b
& 0xf0) == 0xf0) {
3612 modrm
= cpu_ldub_code(env
, s
->pc
++);
3614 reg
= ((modrm
>> 3) & 7) | rex_r
;
3615 mod
= (modrm
>> 6) & 3;
3620 sse_fn_epp
= sse_op_table6
[b
].op
[b1
];
3624 if (!(s
->cpuid_ext_features
& sse_op_table6
[b
].ext_mask
))
3628 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3630 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
3632 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3633 gen_lea_modrm(env
, s
, modrm
);
3635 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3636 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3637 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3638 gen_ldq_env_A0(s
, op2_offset
+
3639 offsetof(ZMMReg
, ZMM_Q(0)));
3641 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3642 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3643 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
3644 s
->mem_index
, MO_LEUL
);
3645 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, op2_offset
+
3646 offsetof(ZMMReg
, ZMM_L(0)));
3648 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3649 tcg_gen_qemu_ld_tl(cpu_tmp0
, cpu_A0
,
3650 s
->mem_index
, MO_LEUW
);
3651 tcg_gen_st16_tl(cpu_tmp0
, cpu_env
, op2_offset
+
3652 offsetof(ZMMReg
, ZMM_W(0)));
3654 case 0x2a: /* movntqda */
3655 gen_ldo_env_A0(s
, op1_offset
);
3658 gen_ldo_env_A0(s
, op2_offset
);
3662 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
3664 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3666 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3667 gen_lea_modrm(env
, s
, modrm
);
3668 gen_ldq_env_A0(s
, op2_offset
);
3671 if (sse_fn_epp
== SSE_SPECIAL
) {
3675 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3676 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3677 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3680 set_cc_op(s
, CC_OP_EFLAGS
);
3687 /* Various integer extensions at 0f 38 f[0-f]. */
3688 b
= modrm
| (b1
<< 8);
3689 modrm
= cpu_ldub_code(env
, s
->pc
++);
3690 reg
= ((modrm
>> 3) & 7) | rex_r
;
3693 case 0x3f0: /* crc32 Gd,Eb */
3694 case 0x3f1: /* crc32 Gd,Ey */
3696 if (!(s
->cpuid_ext_features
& CPUID_EXT_SSE42
)) {
3699 if ((b
& 0xff) == 0xf0) {
3701 } else if (s
->dflag
!= MO_64
) {
3702 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3707 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[reg
]);
3708 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3709 gen_helper_crc32(cpu_T
[0], cpu_tmp2_i32
,
3710 cpu_T
[0], tcg_const_i32(8 << ot
));
3712 ot
= mo_64_32(s
->dflag
);
3713 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3716 case 0x1f0: /* crc32 or movbe */
3718 /* For these insns, the f3 prefix is supposed to have priority
3719 over the 66 prefix, but that's not what we implement above
3721 if (s
->prefix
& PREFIX_REPNZ
) {
3725 case 0x0f0: /* movbe Gy,My */
3726 case 0x0f1: /* movbe My,Gy */
3727 if (!(s
->cpuid_ext_features
& CPUID_EXT_MOVBE
)) {
3730 if (s
->dflag
!= MO_64
) {
3731 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3736 gen_lea_modrm(env
, s
, modrm
);
3738 tcg_gen_qemu_ld_tl(cpu_T
[0], cpu_A0
,
3739 s
->mem_index
, ot
| MO_BE
);
3740 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3742 tcg_gen_qemu_st_tl(cpu_regs
[reg
], cpu_A0
,
3743 s
->mem_index
, ot
| MO_BE
);
3747 case 0x0f2: /* andn Gy, By, Ey */
3748 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3749 || !(s
->prefix
& PREFIX_VEX
)
3753 ot
= mo_64_32(s
->dflag
);
3754 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3755 tcg_gen_andc_tl(cpu_T
[0], cpu_regs
[s
->vex_v
], cpu_T
[0]);
3756 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3757 gen_op_update1_cc();
3758 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3761 case 0x0f7: /* bextr Gy, Ey, By */
3762 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3763 || !(s
->prefix
& PREFIX_VEX
)
3767 ot
= mo_64_32(s
->dflag
);
3771 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3772 /* Extract START, and shift the operand.
3773 Shifts larger than operand size get zeros. */
3774 tcg_gen_ext8u_tl(cpu_A0
, cpu_regs
[s
->vex_v
]);
3775 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], cpu_A0
);
3777 bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3778 zero
= tcg_const_tl(0);
3779 tcg_gen_movcond_tl(TCG_COND_LEU
, cpu_T
[0], cpu_A0
, bound
,
3781 tcg_temp_free(zero
);
3783 /* Extract the LEN into a mask. Lengths larger than
3784 operand size get all ones. */
3785 tcg_gen_shri_tl(cpu_A0
, cpu_regs
[s
->vex_v
], 8);
3786 tcg_gen_ext8u_tl(cpu_A0
, cpu_A0
);
3787 tcg_gen_movcond_tl(TCG_COND_LEU
, cpu_A0
, cpu_A0
, bound
,
3789 tcg_temp_free(bound
);
3790 tcg_gen_movi_tl(cpu_T
[1], 1);
3791 tcg_gen_shl_tl(cpu_T
[1], cpu_T
[1], cpu_A0
);
3792 tcg_gen_subi_tl(cpu_T
[1], cpu_T
[1], 1);
3793 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
3795 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3796 gen_op_update1_cc();
3797 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3801 case 0x0f5: /* bzhi Gy, Ey, By */
3802 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3803 || !(s
->prefix
& PREFIX_VEX
)
3807 ot
= mo_64_32(s
->dflag
);
3808 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3809 tcg_gen_ext8u_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
3811 TCGv bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3812 /* Note that since we're using BMILG (in order to get O
3813 cleared) we need to store the inverse into C. */
3814 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_cc_src
,
3816 tcg_gen_movcond_tl(TCG_COND_GT
, cpu_T
[1], cpu_T
[1],
3817 bound
, bound
, cpu_T
[1]);
3818 tcg_temp_free(bound
);
3820 tcg_gen_movi_tl(cpu_A0
, -1);
3821 tcg_gen_shl_tl(cpu_A0
, cpu_A0
, cpu_T
[1]);
3822 tcg_gen_andc_tl(cpu_T
[0], cpu_T
[0], cpu_A0
);
3823 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3824 gen_op_update1_cc();
3825 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
3828 case 0x3f6: /* mulx By, Gy, rdx, Ey */
3829 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3830 || !(s
->prefix
& PREFIX_VEX
)
3834 ot
= mo_64_32(s
->dflag
);
3835 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3838 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3839 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EDX
]);
3840 tcg_gen_mulu2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
3841 cpu_tmp2_i32
, cpu_tmp3_i32
);
3842 tcg_gen_extu_i32_tl(cpu_regs
[s
->vex_v
], cpu_tmp2_i32
);
3843 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp3_i32
);
3845 #ifdef TARGET_X86_64
3847 tcg_gen_mulu2_i64(cpu_T
[0], cpu_T
[1],
3848 cpu_T
[0], cpu_regs
[R_EDX
]);
3849 tcg_gen_mov_i64(cpu_regs
[s
->vex_v
], cpu_T
[0]);
3850 tcg_gen_mov_i64(cpu_regs
[reg
], cpu_T
[1]);
3856 case 0x3f5: /* pdep Gy, By, Ey */
3857 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3858 || !(s
->prefix
& PREFIX_VEX
)
3862 ot
= mo_64_32(s
->dflag
);
3863 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3864 /* Note that by zero-extending the mask operand, we
3865 automatically handle zero-extending the result. */
3867 tcg_gen_mov_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
3869 tcg_gen_ext32u_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
3871 gen_helper_pdep(cpu_regs
[reg
], cpu_T
[0], cpu_T
[1]);
3874 case 0x2f5: /* pext Gy, By, Ey */
3875 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3876 || !(s
->prefix
& PREFIX_VEX
)
3880 ot
= mo_64_32(s
->dflag
);
3881 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3882 /* Note that by zero-extending the mask operand, we
3883 automatically handle zero-extending the result. */
3885 tcg_gen_mov_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
3887 tcg_gen_ext32u_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
3889 gen_helper_pext(cpu_regs
[reg
], cpu_T
[0], cpu_T
[1]);
3892 case 0x1f6: /* adcx Gy, Ey */
3893 case 0x2f6: /* adox Gy, Ey */
3894 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_ADX
)) {
3897 TCGv carry_in
, carry_out
, zero
;
3900 ot
= mo_64_32(s
->dflag
);
3901 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3903 /* Re-use the carry-out from a previous round. */
3904 TCGV_UNUSED(carry_in
);
3905 carry_out
= (b
== 0x1f6 ? cpu_cc_dst
: cpu_cc_src2
);
3909 carry_in
= cpu_cc_dst
;
3910 end_op
= CC_OP_ADCX
;
3912 end_op
= CC_OP_ADCOX
;
3917 end_op
= CC_OP_ADCOX
;
3919 carry_in
= cpu_cc_src2
;
3920 end_op
= CC_OP_ADOX
;
3924 end_op
= CC_OP_ADCOX
;
3925 carry_in
= carry_out
;
3928 end_op
= (b
== 0x1f6 ? CC_OP_ADCX
: CC_OP_ADOX
);
3931 /* If we can't reuse carry-out, get it out of EFLAGS. */
3932 if (TCGV_IS_UNUSED(carry_in
)) {
3933 if (s
->cc_op
!= CC_OP_ADCX
&& s
->cc_op
!= CC_OP_ADOX
) {
3934 gen_compute_eflags(s
);
3936 carry_in
= cpu_tmp0
;
3937 tcg_gen_shri_tl(carry_in
, cpu_cc_src
,
3938 ctz32(b
== 0x1f6 ? CC_C
: CC_O
));
3939 tcg_gen_andi_tl(carry_in
, carry_in
, 1);
3943 #ifdef TARGET_X86_64
3945 /* If we know TL is 64-bit, and we want a 32-bit
3946 result, just do everything in 64-bit arithmetic. */
3947 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_regs
[reg
]);
3948 tcg_gen_ext32u_i64(cpu_T
[0], cpu_T
[0]);
3949 tcg_gen_add_i64(cpu_T
[0], cpu_T
[0], cpu_regs
[reg
]);
3950 tcg_gen_add_i64(cpu_T
[0], cpu_T
[0], carry_in
);
3951 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_T
[0]);
3952 tcg_gen_shri_i64(carry_out
, cpu_T
[0], 32);
3956 /* Otherwise compute the carry-out in two steps. */
3957 zero
= tcg_const_tl(0);
3958 tcg_gen_add2_tl(cpu_T
[0], carry_out
,
3961 tcg_gen_add2_tl(cpu_regs
[reg
], carry_out
,
3962 cpu_regs
[reg
], carry_out
,
3964 tcg_temp_free(zero
);
3967 set_cc_op(s
, end_op
);
3971 case 0x1f7: /* shlx Gy, Ey, By */
3972 case 0x2f7: /* sarx Gy, Ey, By */
3973 case 0x3f7: /* shrx Gy, Ey, By */
3974 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3975 || !(s
->prefix
& PREFIX_VEX
)
3979 ot
= mo_64_32(s
->dflag
);
3980 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3982 tcg_gen_andi_tl(cpu_T
[1], cpu_regs
[s
->vex_v
], 63);
3984 tcg_gen_andi_tl(cpu_T
[1], cpu_regs
[s
->vex_v
], 31);
3987 tcg_gen_shl_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
3988 } else if (b
== 0x2f7) {
3990 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
3992 tcg_gen_sar_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
3995 tcg_gen_ext32u_tl(cpu_T
[0], cpu_T
[0]);
3997 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
3999 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
4005 case 0x3f3: /* Group 17 */
4006 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
4007 || !(s
->prefix
& PREFIX_VEX
)
4011 ot
= mo_64_32(s
->dflag
);
4012 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4015 case 1: /* blsr By,Ey */
4016 tcg_gen_neg_tl(cpu_T
[1], cpu_T
[0]);
4017 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4018 gen_op_mov_reg_v(ot
, s
->vex_v
, cpu_T
[0]);
4019 gen_op_update2_cc();
4020 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4023 case 2: /* blsmsk By,Ey */
4024 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
4025 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], 1);
4026 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_cc_src
);
4027 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4028 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4031 case 3: /* blsi By, Ey */
4032 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
4033 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], 1);
4034 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_cc_src
);
4035 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4036 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4052 modrm
= cpu_ldub_code(env
, s
->pc
++);
4054 reg
= ((modrm
>> 3) & 7) | rex_r
;
4055 mod
= (modrm
>> 6) & 3;
4060 sse_fn_eppi
= sse_op_table7
[b
].op
[b1
];
4064 if (!(s
->cpuid_ext_features
& sse_op_table7
[b
].ext_mask
))
4067 if (sse_fn_eppi
== SSE_SPECIAL
) {
4068 ot
= mo_64_32(s
->dflag
);
4069 rm
= (modrm
& 7) | REX_B(s
);
4071 gen_lea_modrm(env
, s
, modrm
);
4072 reg
= ((modrm
>> 3) & 7) | rex_r
;
4073 val
= cpu_ldub_code(env
, s
->pc
++);
4075 case 0x14: /* pextrb */
4076 tcg_gen_ld8u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4077 xmm_regs
[reg
].ZMM_B(val
& 15)));
4079 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4081 tcg_gen_qemu_st_tl(cpu_T
[0], cpu_A0
,
4082 s
->mem_index
, MO_UB
);
4085 case 0x15: /* pextrw */
4086 tcg_gen_ld16u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4087 xmm_regs
[reg
].ZMM_W(val
& 7)));
4089 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4091 tcg_gen_qemu_st_tl(cpu_T
[0], cpu_A0
,
4092 s
->mem_index
, MO_LEUW
);
4096 if (ot
== MO_32
) { /* pextrd */
4097 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4098 offsetof(CPUX86State
,
4099 xmm_regs
[reg
].ZMM_L(val
& 3)));
4101 tcg_gen_extu_i32_tl(cpu_regs
[rm
], cpu_tmp2_i32
);
4103 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
4104 s
->mem_index
, MO_LEUL
);
4106 } else { /* pextrq */
4107 #ifdef TARGET_X86_64
4108 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
4109 offsetof(CPUX86State
,
4110 xmm_regs
[reg
].ZMM_Q(val
& 1)));
4112 tcg_gen_mov_i64(cpu_regs
[rm
], cpu_tmp1_i64
);
4114 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
4115 s
->mem_index
, MO_LEQ
);
4122 case 0x17: /* extractps */
4123 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4124 xmm_regs
[reg
].ZMM_L(val
& 3)));
4126 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4128 tcg_gen_qemu_st_tl(cpu_T
[0], cpu_A0
,
4129 s
->mem_index
, MO_LEUL
);
4132 case 0x20: /* pinsrb */
4134 gen_op_mov_v_reg(MO_32
, cpu_T
[0], rm
);
4136 tcg_gen_qemu_ld_tl(cpu_T
[0], cpu_A0
,
4137 s
->mem_index
, MO_UB
);
4139 tcg_gen_st8_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4140 xmm_regs
[reg
].ZMM_B(val
& 15)));
4142 case 0x21: /* insertps */
4144 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4145 offsetof(CPUX86State
,xmm_regs
[rm
]
4146 .ZMM_L((val
>> 6) & 3)));
4148 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
4149 s
->mem_index
, MO_LEUL
);
4151 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4152 offsetof(CPUX86State
,xmm_regs
[reg
]
4153 .ZMM_L((val
>> 4) & 3)));
4155 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4156 cpu_env
, offsetof(CPUX86State
,
4157 xmm_regs
[reg
].ZMM_L(0)));
4159 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4160 cpu_env
, offsetof(CPUX86State
,
4161 xmm_regs
[reg
].ZMM_L(1)));
4163 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4164 cpu_env
, offsetof(CPUX86State
,
4165 xmm_regs
[reg
].ZMM_L(2)));
4167 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4168 cpu_env
, offsetof(CPUX86State
,
4169 xmm_regs
[reg
].ZMM_L(3)));
4172 if (ot
== MO_32
) { /* pinsrd */
4174 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[rm
]);
4176 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
4177 s
->mem_index
, MO_LEUL
);
4179 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4180 offsetof(CPUX86State
,
4181 xmm_regs
[reg
].ZMM_L(val
& 3)));
4182 } else { /* pinsrq */
4183 #ifdef TARGET_X86_64
4185 gen_op_mov_v_reg(ot
, cpu_tmp1_i64
, rm
);
4187 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
4188 s
->mem_index
, MO_LEQ
);
4190 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
4191 offsetof(CPUX86State
,
4192 xmm_regs
[reg
].ZMM_Q(val
& 1)));
4203 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4205 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
4207 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4208 gen_lea_modrm(env
, s
, modrm
);
4209 gen_ldo_env_A0(s
, op2_offset
);
4212 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4214 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4216 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4217 gen_lea_modrm(env
, s
, modrm
);
4218 gen_ldq_env_A0(s
, op2_offset
);
4221 val
= cpu_ldub_code(env
, s
->pc
++);
4223 if ((b
& 0xfc) == 0x60) { /* pcmpXstrX */
4224 set_cc_op(s
, CC_OP_EFLAGS
);
4226 if (s
->dflag
== MO_64
) {
4227 /* The helper must use entire 64-bit gp registers */
4232 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4233 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4234 sse_fn_eppi(cpu_env
, cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4238 /* Various integer extensions at 0f 3a f[0-f]. */
4239 b
= modrm
| (b1
<< 8);
4240 modrm
= cpu_ldub_code(env
, s
->pc
++);
4241 reg
= ((modrm
>> 3) & 7) | rex_r
;
4244 case 0x3f0: /* rorx Gy,Ey, Ib */
4245 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4246 || !(s
->prefix
& PREFIX_VEX
)
4250 ot
= mo_64_32(s
->dflag
);
4251 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4252 b
= cpu_ldub_code(env
, s
->pc
++);
4254 tcg_gen_rotri_tl(cpu_T
[0], cpu_T
[0], b
& 63);
4256 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4257 tcg_gen_rotri_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, b
& 31);
4258 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
4260 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
4272 /* generic MMX or SSE operation */
4274 case 0x70: /* pshufx insn */
4275 case 0xc6: /* pshufx insn */
4276 case 0xc2: /* compare insns */
4283 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4287 gen_lea_modrm(env
, s
, modrm
);
4288 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4294 /* Most sse scalar operations. */
4297 } else if (b1
== 3) {
4302 case 0x2e: /* ucomis[sd] */
4303 case 0x2f: /* comis[sd] */
4315 gen_op_ld_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
4316 tcg_gen_st32_tl(cpu_T
[0], cpu_env
,
4317 offsetof(CPUX86State
,xmm_t0
.ZMM_L(0)));
4321 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.ZMM_D(0)));
4324 /* 128 bit access */
4325 gen_ldo_env_A0(s
, op2_offset
);
4329 rm
= (modrm
& 7) | REX_B(s
);
4330 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
4333 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4335 gen_lea_modrm(env
, s
, modrm
);
4336 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4337 gen_ldq_env_A0(s
, op2_offset
);
4340 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4344 case 0x0f: /* 3DNow! data insns */
4345 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
))
4347 val
= cpu_ldub_code(env
, s
->pc
++);
4348 sse_fn_epp
= sse_op_table5
[val
];
4352 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4353 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4354 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4356 case 0x70: /* pshufx insn */
4357 case 0xc6: /* pshufx insn */
4358 val
= cpu_ldub_code(env
, s
->pc
++);
4359 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4360 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4361 /* XXX: introduce a new table? */
4362 sse_fn_ppi
= (SSEFunc_0_ppi
)sse_fn_epp
;
4363 sse_fn_ppi(cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4367 val
= cpu_ldub_code(env
, s
->pc
++);
4370 sse_fn_epp
= sse_op_table4
[val
][b1
];
4372 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4373 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4374 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4377 /* maskmov : we must prepare A0 */
4380 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EDI
]);
4381 gen_extu(s
->aflag
, cpu_A0
);
4382 gen_add_A0_ds_seg(s
);
4384 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4385 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4386 /* XXX: introduce a new table? */
4387 sse_fn_eppt
= (SSEFunc_0_eppt
)sse_fn_epp
;
4388 sse_fn_eppt(cpu_env
, cpu_ptr0
, cpu_ptr1
, cpu_A0
);
4391 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4392 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4393 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4396 if (b
== 0x2e || b
== 0x2f) {
4397 set_cc_op(s
, CC_OP_EFLAGS
);
4402 /* convert one instruction. s->is_jmp is set if the translation must
4403 be stopped. Return the next pc value */
4404 static target_ulong
disas_insn(CPUX86State
*env
, DisasContext
*s
,
4405 target_ulong pc_start
)
4409 TCGMemOp ot
, aflag
, dflag
;
4410 int modrm
, reg
, rm
, mod
, op
, opreg
, val
;
4411 target_ulong next_eip
, tval
;
4419 #ifdef TARGET_X86_64
4424 s
->rip_offset
= 0; /* for relative ip address */
4428 b
= cpu_ldub_code(env
, s
->pc
);
4430 /* Collect prefixes. */
4433 prefixes
|= PREFIX_REPZ
;
4436 prefixes
|= PREFIX_REPNZ
;
4439 prefixes
|= PREFIX_LOCK
;
4460 prefixes
|= PREFIX_DATA
;
4463 prefixes
|= PREFIX_ADR
;
4465 #ifdef TARGET_X86_64
4469 rex_w
= (b
>> 3) & 1;
4470 rex_r
= (b
& 0x4) << 1;
4471 s
->rex_x
= (b
& 0x2) << 2;
4472 REX_B(s
) = (b
& 0x1) << 3;
4473 x86_64_hregs
= 1; /* select uniform byte register addressing */
4478 case 0xc5: /* 2-byte VEX */
4479 case 0xc4: /* 3-byte VEX */
4480 /* VEX prefixes cannot be used except in 32-bit mode.
4481 Otherwise the instruction is LES or LDS. */
4482 if (s
->code32
&& !s
->vm86
) {
4483 static const int pp_prefix
[4] = {
4484 0, PREFIX_DATA
, PREFIX_REPZ
, PREFIX_REPNZ
4486 int vex3
, vex2
= cpu_ldub_code(env
, s
->pc
);
4488 if (!CODE64(s
) && (vex2
& 0xc0) != 0xc0) {
4489 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4490 otherwise the instruction is LES or LDS. */
4495 /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
4496 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
4497 | PREFIX_LOCK
| PREFIX_DATA
)) {
4500 #ifdef TARGET_X86_64
4505 rex_r
= (~vex2
>> 4) & 8;
4508 b
= cpu_ldub_code(env
, s
->pc
++);
4510 #ifdef TARGET_X86_64
4511 s
->rex_x
= (~vex2
>> 3) & 8;
4512 s
->rex_b
= (~vex2
>> 2) & 8;
4514 vex3
= cpu_ldub_code(env
, s
->pc
++);
4515 rex_w
= (vex3
>> 7) & 1;
4516 switch (vex2
& 0x1f) {
4517 case 0x01: /* Implied 0f leading opcode bytes. */
4518 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4520 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4523 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4526 default: /* Reserved for future use. */
4530 s
->vex_v
= (~vex3
>> 3) & 0xf;
4531 s
->vex_l
= (vex3
>> 2) & 1;
4532 prefixes
|= pp_prefix
[vex3
& 3] | PREFIX_VEX
;
4537 /* Post-process prefixes. */
4539 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit
4540 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4541 over 0x66 if both are present. */
4542 dflag
= (rex_w
> 0 ? MO_64
: prefixes
& PREFIX_DATA
? MO_16
: MO_32
);
4543 /* In 64-bit mode, 0x67 selects 32-bit addressing. */
4544 aflag
= (prefixes
& PREFIX_ADR
? MO_32
: MO_64
);
4546 /* In 16/32-bit mode, 0x66 selects the opposite data size. */
4547 if (s
->code32
^ ((prefixes
& PREFIX_DATA
) != 0)) {
4552 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */
4553 if (s
->code32
^ ((prefixes
& PREFIX_ADR
) != 0)) {
4560 s
->prefix
= prefixes
;
4564 /* lock generation */
4565 if (prefixes
& PREFIX_LOCK
)
4568 /* now check op code */
4572 /**************************/
4573 /* extended op code */
4574 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4577 /**************************/
4592 ot
= mo_b_d(b
, dflag
);
4595 case 0: /* OP Ev, Gv */
4596 modrm
= cpu_ldub_code(env
, s
->pc
++);
4597 reg
= ((modrm
>> 3) & 7) | rex_r
;
4598 mod
= (modrm
>> 6) & 3;
4599 rm
= (modrm
& 7) | REX_B(s
);
4601 gen_lea_modrm(env
, s
, modrm
);
4603 } else if (op
== OP_XORL
&& rm
== reg
) {
4605 /* xor reg, reg optimisation */
4606 set_cc_op(s
, CC_OP_CLR
);
4607 tcg_gen_movi_tl(cpu_T
[0], 0);
4608 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
4613 gen_op_mov_v_reg(ot
, cpu_T
[1], reg
);
4614 gen_op(s
, op
, ot
, opreg
);
4616 case 1: /* OP Gv, Ev */
4617 modrm
= cpu_ldub_code(env
, s
->pc
++);
4618 mod
= (modrm
>> 6) & 3;
4619 reg
= ((modrm
>> 3) & 7) | rex_r
;
4620 rm
= (modrm
& 7) | REX_B(s
);
4622 gen_lea_modrm(env
, s
, modrm
);
4623 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
4624 } else if (op
== OP_XORL
&& rm
== reg
) {
4627 gen_op_mov_v_reg(ot
, cpu_T
[1], rm
);
4629 gen_op(s
, op
, ot
, reg
);
4631 case 2: /* OP A, Iv */
4632 val
= insn_get(env
, s
, ot
);
4633 tcg_gen_movi_tl(cpu_T
[1], val
);
4634 gen_op(s
, op
, ot
, OR_EAX
);
4643 case 0x80: /* GRP1 */
4649 ot
= mo_b_d(b
, dflag
);
4651 modrm
= cpu_ldub_code(env
, s
->pc
++);
4652 mod
= (modrm
>> 6) & 3;
4653 rm
= (modrm
& 7) | REX_B(s
);
4654 op
= (modrm
>> 3) & 7;
4660 s
->rip_offset
= insn_const_size(ot
);
4661 gen_lea_modrm(env
, s
, modrm
);
4672 val
= insn_get(env
, s
, ot
);
4675 val
= (int8_t)insn_get(env
, s
, MO_8
);
4678 tcg_gen_movi_tl(cpu_T
[1], val
);
4679 gen_op(s
, op
, ot
, opreg
);
4683 /**************************/
4684 /* inc, dec, and other misc arith */
4685 case 0x40 ... 0x47: /* inc Gv */
4687 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), 1);
4689 case 0x48 ... 0x4f: /* dec Gv */
4691 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), -1);
4693 case 0xf6: /* GRP3 */
4695 ot
= mo_b_d(b
, dflag
);
4697 modrm
= cpu_ldub_code(env
, s
->pc
++);
4698 mod
= (modrm
>> 6) & 3;
4699 rm
= (modrm
& 7) | REX_B(s
);
4700 op
= (modrm
>> 3) & 7;
4703 s
->rip_offset
= insn_const_size(ot
);
4704 gen_lea_modrm(env
, s
, modrm
);
4705 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
4707 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
4712 val
= insn_get(env
, s
, ot
);
4713 tcg_gen_movi_tl(cpu_T
[1], val
);
4714 gen_op_testl_T0_T1_cc();
4715 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4718 tcg_gen_not_tl(cpu_T
[0], cpu_T
[0]);
4720 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
4722 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4726 tcg_gen_neg_tl(cpu_T
[0], cpu_T
[0]);
4728 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
4730 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4732 gen_op_update_neg_cc();
4733 set_cc_op(s
, CC_OP_SUBB
+ ot
);
4738 gen_op_mov_v_reg(MO_8
, cpu_T
[1], R_EAX
);
4739 tcg_gen_ext8u_tl(cpu_T
[0], cpu_T
[0]);
4740 tcg_gen_ext8u_tl(cpu_T
[1], cpu_T
[1]);
4741 /* XXX: use 32 bit mul which could be faster */
4742 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4743 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
4744 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4745 tcg_gen_andi_tl(cpu_cc_src
, cpu_T
[0], 0xff00);
4746 set_cc_op(s
, CC_OP_MULB
);
4749 gen_op_mov_v_reg(MO_16
, cpu_T
[1], R_EAX
);
4750 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
4751 tcg_gen_ext16u_tl(cpu_T
[1], cpu_T
[1]);
4752 /* XXX: use 32 bit mul which could be faster */
4753 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4754 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
4755 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4756 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], 16);
4757 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T
[0]);
4758 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
4759 set_cc_op(s
, CC_OP_MULW
);
4763 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4764 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
4765 tcg_gen_mulu2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4766 cpu_tmp2_i32
, cpu_tmp3_i32
);
4767 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
4768 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
4769 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4770 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4771 set_cc_op(s
, CC_OP_MULL
);
4773 #ifdef TARGET_X86_64
4775 tcg_gen_mulu2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4776 cpu_T
[0], cpu_regs
[R_EAX
]);
4777 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4778 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4779 set_cc_op(s
, CC_OP_MULQ
);
4787 gen_op_mov_v_reg(MO_8
, cpu_T
[1], R_EAX
);
4788 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
4789 tcg_gen_ext8s_tl(cpu_T
[1], cpu_T
[1]);
4790 /* XXX: use 32 bit mul which could be faster */
4791 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4792 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
4793 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4794 tcg_gen_ext8s_tl(cpu_tmp0
, cpu_T
[0]);
4795 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
4796 set_cc_op(s
, CC_OP_MULB
);
4799 gen_op_mov_v_reg(MO_16
, cpu_T
[1], R_EAX
);
4800 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
4801 tcg_gen_ext16s_tl(cpu_T
[1], cpu_T
[1]);
4802 /* XXX: use 32 bit mul which could be faster */
4803 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4804 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
4805 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4806 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T
[0]);
4807 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
4808 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], 16);
4809 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T
[0]);
4810 set_cc_op(s
, CC_OP_MULW
);
4814 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4815 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
4816 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4817 cpu_tmp2_i32
, cpu_tmp3_i32
);
4818 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
4819 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
4820 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
4821 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4822 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
4823 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
4824 set_cc_op(s
, CC_OP_MULL
);
4826 #ifdef TARGET_X86_64
4828 tcg_gen_muls2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4829 cpu_T
[0], cpu_regs
[R_EAX
]);
4830 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4831 tcg_gen_sari_tl(cpu_cc_src
, cpu_regs
[R_EAX
], 63);
4832 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_regs
[R_EDX
]);
4833 set_cc_op(s
, CC_OP_MULQ
);
4841 gen_helper_divb_AL(cpu_env
, cpu_T
[0]);
4844 gen_helper_divw_AX(cpu_env
, cpu_T
[0]);
4848 gen_helper_divl_EAX(cpu_env
, cpu_T
[0]);
4850 #ifdef TARGET_X86_64
4852 gen_helper_divq_EAX(cpu_env
, cpu_T
[0]);
4860 gen_helper_idivb_AL(cpu_env
, cpu_T
[0]);
4863 gen_helper_idivw_AX(cpu_env
, cpu_T
[0]);
4867 gen_helper_idivl_EAX(cpu_env
, cpu_T
[0]);
4869 #ifdef TARGET_X86_64
4871 gen_helper_idivq_EAX(cpu_env
, cpu_T
[0]);
4881 case 0xfe: /* GRP4 */
4882 case 0xff: /* GRP5 */
4883 ot
= mo_b_d(b
, dflag
);
4885 modrm
= cpu_ldub_code(env
, s
->pc
++);
4886 mod
= (modrm
>> 6) & 3;
4887 rm
= (modrm
& 7) | REX_B(s
);
4888 op
= (modrm
>> 3) & 7;
4889 if (op
>= 2 && b
== 0xfe) {
4893 if (op
== 2 || op
== 4) {
4894 /* operand size for jumps is 64 bit */
4896 } else if (op
== 3 || op
== 5) {
4897 ot
= dflag
!= MO_16
? MO_32
+ (rex_w
== 1) : MO_16
;
4898 } else if (op
== 6) {
4899 /* default push size is 64 bit */
4900 ot
= mo_pushpop(s
, dflag
);
4904 gen_lea_modrm(env
, s
, modrm
);
4905 if (op
>= 2 && op
!= 3 && op
!= 5)
4906 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
4908 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
4912 case 0: /* inc Ev */
4917 gen_inc(s
, ot
, opreg
, 1);
4919 case 1: /* dec Ev */
4924 gen_inc(s
, ot
, opreg
, -1);
4926 case 2: /* call Ev */
4927 /* XXX: optimize if memory (no 'and' is necessary) */
4928 if (dflag
== MO_16
) {
4929 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
4931 next_eip
= s
->pc
- s
->cs_base
;
4932 tcg_gen_movi_tl(cpu_T
[1], next_eip
);
4933 gen_push_v(s
, cpu_T
[1]);
4934 gen_op_jmp_v(cpu_T
[0]);
4937 case 3: /* lcall Ev */
4938 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
4939 gen_add_A0_im(s
, 1 << ot
);
4940 gen_op_ld_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
4942 if (s
->pe
&& !s
->vm86
) {
4943 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4944 gen_helper_lcall_protected(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
4945 tcg_const_i32(dflag
- 1),
4946 tcg_const_tl(s
->pc
- s
->cs_base
));
4948 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4949 gen_helper_lcall_real(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
4950 tcg_const_i32(dflag
- 1),
4951 tcg_const_i32(s
->pc
- s
->cs_base
));
4955 case 4: /* jmp Ev */
4956 if (dflag
== MO_16
) {
4957 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
4959 gen_op_jmp_v(cpu_T
[0]);
4962 case 5: /* ljmp Ev */
4963 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
4964 gen_add_A0_im(s
, 1 << ot
);
4965 gen_op_ld_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
4967 if (s
->pe
&& !s
->vm86
) {
4968 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4969 gen_helper_ljmp_protected(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
4970 tcg_const_tl(s
->pc
- s
->cs_base
));
4972 gen_op_movl_seg_T0_vm(R_CS
);
4973 gen_op_jmp_v(cpu_T
[1]);
4977 case 6: /* push Ev */
4978 gen_push_v(s
, cpu_T
[0]);
4985 case 0x84: /* test Ev, Gv */
4987 ot
= mo_b_d(b
, dflag
);
4989 modrm
= cpu_ldub_code(env
, s
->pc
++);
4990 reg
= ((modrm
>> 3) & 7) | rex_r
;
4992 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4993 gen_op_mov_v_reg(ot
, cpu_T
[1], reg
);
4994 gen_op_testl_T0_T1_cc();
4995 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4998 case 0xa8: /* test eAX, Iv */
5000 ot
= mo_b_d(b
, dflag
);
5001 val
= insn_get(env
, s
, ot
);
5003 gen_op_mov_v_reg(ot
, cpu_T
[0], OR_EAX
);
5004 tcg_gen_movi_tl(cpu_T
[1], val
);
5005 gen_op_testl_T0_T1_cc();
5006 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5009 case 0x98: /* CWDE/CBW */
5011 #ifdef TARGET_X86_64
5013 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EAX
);
5014 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
5015 gen_op_mov_reg_v(MO_64
, R_EAX
, cpu_T
[0]);
5019 gen_op_mov_v_reg(MO_16
, cpu_T
[0], R_EAX
);
5020 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5021 gen_op_mov_reg_v(MO_32
, R_EAX
, cpu_T
[0]);
5024 gen_op_mov_v_reg(MO_8
, cpu_T
[0], R_EAX
);
5025 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
5026 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
5032 case 0x99: /* CDQ/CWD */
5034 #ifdef TARGET_X86_64
5036 gen_op_mov_v_reg(MO_64
, cpu_T
[0], R_EAX
);
5037 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 63);
5038 gen_op_mov_reg_v(MO_64
, R_EDX
, cpu_T
[0]);
5042 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EAX
);
5043 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
5044 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 31);
5045 gen_op_mov_reg_v(MO_32
, R_EDX
, cpu_T
[0]);
5048 gen_op_mov_v_reg(MO_16
, cpu_T
[0], R_EAX
);
5049 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5050 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 15);
5051 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T
[0]);
5057 case 0x1af: /* imul Gv, Ev */
5058 case 0x69: /* imul Gv, Ev, I */
5061 modrm
= cpu_ldub_code(env
, s
->pc
++);
5062 reg
= ((modrm
>> 3) & 7) | rex_r
;
5064 s
->rip_offset
= insn_const_size(ot
);
5067 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5069 val
= insn_get(env
, s
, ot
);
5070 tcg_gen_movi_tl(cpu_T
[1], val
);
5071 } else if (b
== 0x6b) {
5072 val
= (int8_t)insn_get(env
, s
, MO_8
);
5073 tcg_gen_movi_tl(cpu_T
[1], val
);
5075 gen_op_mov_v_reg(ot
, cpu_T
[1], reg
);
5078 #ifdef TARGET_X86_64
5080 tcg_gen_muls2_i64(cpu_regs
[reg
], cpu_T
[1], cpu_T
[0], cpu_T
[1]);
5081 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5082 tcg_gen_sari_tl(cpu_cc_src
, cpu_cc_dst
, 63);
5083 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_T
[1]);
5087 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5088 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
5089 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
5090 cpu_tmp2_i32
, cpu_tmp3_i32
);
5091 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
5092 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
5093 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5094 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
5095 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
5098 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5099 tcg_gen_ext16s_tl(cpu_T
[1], cpu_T
[1]);
5100 /* XXX: use 32 bit mul which could be faster */
5101 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5102 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5103 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T
[0]);
5104 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
5105 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
5108 set_cc_op(s
, CC_OP_MULB
+ ot
);
5111 case 0x1c1: /* xadd Ev, Gv */
5112 ot
= mo_b_d(b
, dflag
);
5113 modrm
= cpu_ldub_code(env
, s
->pc
++);
5114 reg
= ((modrm
>> 3) & 7) | rex_r
;
5115 mod
= (modrm
>> 6) & 3;
5117 rm
= (modrm
& 7) | REX_B(s
);
5118 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
5119 gen_op_mov_v_reg(ot
, cpu_T
[1], rm
);
5120 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5121 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5122 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
5124 gen_lea_modrm(env
, s
, modrm
);
5125 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
5126 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
5127 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5128 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
5129 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5131 gen_op_update2_cc();
5132 set_cc_op(s
, CC_OP_ADDB
+ ot
);
5135 case 0x1b1: /* cmpxchg Ev, Gv */
5137 TCGLabel
*label1
, *label2
;
5138 TCGv t0
, t1
, t2
, a0
;
5140 ot
= mo_b_d(b
, dflag
);
5141 modrm
= cpu_ldub_code(env
, s
->pc
++);
5142 reg
= ((modrm
>> 3) & 7) | rex_r
;
5143 mod
= (modrm
>> 6) & 3;
5144 t0
= tcg_temp_local_new();
5145 t1
= tcg_temp_local_new();
5146 t2
= tcg_temp_local_new();
5147 a0
= tcg_temp_local_new();
5148 gen_op_mov_v_reg(ot
, t1
, reg
);
5150 rm
= (modrm
& 7) | REX_B(s
);
5151 gen_op_mov_v_reg(ot
, t0
, rm
);
5153 gen_lea_modrm(env
, s
, modrm
);
5154 tcg_gen_mov_tl(a0
, cpu_A0
);
5155 gen_op_ld_v(s
, ot
, t0
, a0
);
5156 rm
= 0; /* avoid warning */
5158 label1
= gen_new_label();
5159 tcg_gen_mov_tl(t2
, cpu_regs
[R_EAX
]);
5162 tcg_gen_brcond_tl(TCG_COND_EQ
, t2
, t0
, label1
);
5163 label2
= gen_new_label();
5165 gen_op_mov_reg_v(ot
, R_EAX
, t0
);
5167 gen_set_label(label1
);
5168 gen_op_mov_reg_v(ot
, rm
, t1
);
5170 /* perform no-op store cycle like physical cpu; must be
5171 before changing accumulator to ensure idempotency if
5172 the store faults and the instruction is restarted */
5173 gen_op_st_v(s
, ot
, t0
, a0
);
5174 gen_op_mov_reg_v(ot
, R_EAX
, t0
);
5176 gen_set_label(label1
);
5177 gen_op_st_v(s
, ot
, t1
, a0
);
5179 gen_set_label(label2
);
5180 tcg_gen_mov_tl(cpu_cc_src
, t0
);
5181 tcg_gen_mov_tl(cpu_cc_srcT
, t2
);
5182 tcg_gen_sub_tl(cpu_cc_dst
, t2
, t0
);
5183 set_cc_op(s
, CC_OP_SUBB
+ ot
);
5190 case 0x1c7: /* cmpxchg8b */
5191 modrm
= cpu_ldub_code(env
, s
->pc
++);
5192 mod
= (modrm
>> 6) & 3;
5193 if ((mod
== 3) || ((modrm
& 0x38) != 0x8))
5195 #ifdef TARGET_X86_64
5196 if (dflag
== MO_64
) {
5197 if (!(s
->cpuid_ext_features
& CPUID_EXT_CX16
))
5199 gen_lea_modrm(env
, s
, modrm
);
5200 gen_helper_cmpxchg16b(cpu_env
, cpu_A0
);
5204 if (!(s
->cpuid_features
& CPUID_CX8
))
5206 gen_lea_modrm(env
, s
, modrm
);
5207 gen_helper_cmpxchg8b(cpu_env
, cpu_A0
);
5209 set_cc_op(s
, CC_OP_EFLAGS
);
5212 /**************************/
5214 case 0x50 ... 0x57: /* push */
5215 gen_op_mov_v_reg(MO_32
, cpu_T
[0], (b
& 7) | REX_B(s
));
5216 gen_push_v(s
, cpu_T
[0]);
5218 case 0x58 ... 0x5f: /* pop */
5220 /* NOTE: order is important for pop %sp */
5221 gen_pop_update(s
, ot
);
5222 gen_op_mov_reg_v(ot
, (b
& 7) | REX_B(s
), cpu_T
[0]);
5224 case 0x60: /* pusha */
5229 case 0x61: /* popa */
5234 case 0x68: /* push Iv */
5236 ot
= mo_pushpop(s
, dflag
);
5238 val
= insn_get(env
, s
, ot
);
5240 val
= (int8_t)insn_get(env
, s
, MO_8
);
5241 tcg_gen_movi_tl(cpu_T
[0], val
);
5242 gen_push_v(s
, cpu_T
[0]);
5244 case 0x8f: /* pop Ev */
5245 modrm
= cpu_ldub_code(env
, s
->pc
++);
5246 mod
= (modrm
>> 6) & 3;
5249 /* NOTE: order is important for pop %sp */
5250 gen_pop_update(s
, ot
);
5251 rm
= (modrm
& 7) | REX_B(s
);
5252 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
5254 /* NOTE: order is important too for MMU exceptions */
5255 s
->popl_esp_hack
= 1 << ot
;
5256 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5257 s
->popl_esp_hack
= 0;
5258 gen_pop_update(s
, ot
);
5261 case 0xc8: /* enter */
5264 val
= cpu_lduw_code(env
, s
->pc
);
5266 level
= cpu_ldub_code(env
, s
->pc
++);
5267 gen_enter(s
, val
, level
);
5270 case 0xc9: /* leave */
5271 /* XXX: exception not precise (ESP is updated before potential exception) */
5273 gen_op_mov_v_reg(MO_64
, cpu_T
[0], R_EBP
);
5274 gen_op_mov_reg_v(MO_64
, R_ESP
, cpu_T
[0]);
5275 } else if (s
->ss32
) {
5276 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EBP
);
5277 gen_op_mov_reg_v(MO_32
, R_ESP
, cpu_T
[0]);
5279 gen_op_mov_v_reg(MO_16
, cpu_T
[0], R_EBP
);
5280 gen_op_mov_reg_v(MO_16
, R_ESP
, cpu_T
[0]);
5283 gen_op_mov_reg_v(ot
, R_EBP
, cpu_T
[0]);
5284 gen_pop_update(s
, ot
);
5286 case 0x06: /* push es */
5287 case 0x0e: /* push cs */
5288 case 0x16: /* push ss */
5289 case 0x1e: /* push ds */
5292 gen_op_movl_T0_seg(b
>> 3);
5293 gen_push_v(s
, cpu_T
[0]);
5295 case 0x1a0: /* push fs */
5296 case 0x1a8: /* push gs */
5297 gen_op_movl_T0_seg((b
>> 3) & 7);
5298 gen_push_v(s
, cpu_T
[0]);
5300 case 0x07: /* pop es */
5301 case 0x17: /* pop ss */
5302 case 0x1f: /* pop ds */
5307 gen_movl_seg_T0(s
, reg
);
5308 gen_pop_update(s
, ot
);
5310 /* if reg == SS, inhibit interrupts/trace. */
5311 /* If several instructions disable interrupts, only the
5313 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
5314 gen_helper_set_inhibit_irq(cpu_env
);
5318 gen_jmp_im(s
->pc
- s
->cs_base
);
5322 case 0x1a1: /* pop fs */
5323 case 0x1a9: /* pop gs */
5325 gen_movl_seg_T0(s
, (b
>> 3) & 7);
5326 gen_pop_update(s
, ot
);
5328 gen_jmp_im(s
->pc
- s
->cs_base
);
5333 /**************************/
5336 case 0x89: /* mov Gv, Ev */
5337 ot
= mo_b_d(b
, dflag
);
5338 modrm
= cpu_ldub_code(env
, s
->pc
++);
5339 reg
= ((modrm
>> 3) & 7) | rex_r
;
5341 /* generate a generic store */
5342 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
5345 case 0xc7: /* mov Ev, Iv */
5346 ot
= mo_b_d(b
, dflag
);
5347 modrm
= cpu_ldub_code(env
, s
->pc
++);
5348 mod
= (modrm
>> 6) & 3;
5350 s
->rip_offset
= insn_const_size(ot
);
5351 gen_lea_modrm(env
, s
, modrm
);
5353 val
= insn_get(env
, s
, ot
);
5354 tcg_gen_movi_tl(cpu_T
[0], val
);
5356 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
5358 gen_op_mov_reg_v(ot
, (modrm
& 7) | REX_B(s
), cpu_T
[0]);
5362 case 0x8b: /* mov Ev, Gv */
5363 ot
= mo_b_d(b
, dflag
);
5364 modrm
= cpu_ldub_code(env
, s
->pc
++);
5365 reg
= ((modrm
>> 3) & 7) | rex_r
;
5367 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5368 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
5370 case 0x8e: /* mov seg, Gv */
5371 modrm
= cpu_ldub_code(env
, s
->pc
++);
5372 reg
= (modrm
>> 3) & 7;
5373 if (reg
>= 6 || reg
== R_CS
)
5375 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
5376 gen_movl_seg_T0(s
, reg
);
5378 /* if reg == SS, inhibit interrupts/trace */
5379 /* If several instructions disable interrupts, only the
5381 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
5382 gen_helper_set_inhibit_irq(cpu_env
);
5386 gen_jmp_im(s
->pc
- s
->cs_base
);
5390 case 0x8c: /* mov Gv, seg */
5391 modrm
= cpu_ldub_code(env
, s
->pc
++);
5392 reg
= (modrm
>> 3) & 7;
5393 mod
= (modrm
>> 6) & 3;
5396 gen_op_movl_T0_seg(reg
);
5397 ot
= mod
== 3 ? dflag
: MO_16
;
5398 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5401 case 0x1b6: /* movzbS Gv, Eb */
5402 case 0x1b7: /* movzwS Gv, Eb */
5403 case 0x1be: /* movsbS Gv, Eb */
5404 case 0x1bf: /* movswS Gv, Eb */
5409 /* d_ot is the size of destination */
5411 /* ot is the size of source */
5412 ot
= (b
& 1) + MO_8
;
5413 /* s_ot is the sign+size of source */
5414 s_ot
= b
& 8 ? MO_SIGN
| ot
: ot
;
5416 modrm
= cpu_ldub_code(env
, s
->pc
++);
5417 reg
= ((modrm
>> 3) & 7) | rex_r
;
5418 mod
= (modrm
>> 6) & 3;
5419 rm
= (modrm
& 7) | REX_B(s
);
5422 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
5425 tcg_gen_ext8u_tl(cpu_T
[0], cpu_T
[0]);
5428 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
5431 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
5435 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5438 gen_op_mov_reg_v(d_ot
, reg
, cpu_T
[0]);
5440 gen_lea_modrm(env
, s
, modrm
);
5441 gen_op_ld_v(s
, s_ot
, cpu_T
[0], cpu_A0
);
5442 gen_op_mov_reg_v(d_ot
, reg
, cpu_T
[0]);
5447 case 0x8d: /* lea */
5449 modrm
= cpu_ldub_code(env
, s
->pc
++);
5450 mod
= (modrm
>> 6) & 3;
5453 reg
= ((modrm
>> 3) & 7) | rex_r
;
5454 /* we must ensure that no segment is added */
5458 gen_lea_modrm(env
, s
, modrm
);
5460 gen_op_mov_reg_v(ot
, reg
, cpu_A0
);
5463 case 0xa0: /* mov EAX, Ov */
5465 case 0xa2: /* mov Ov, EAX */
5468 target_ulong offset_addr
;
5470 ot
= mo_b_d(b
, dflag
);
5472 #ifdef TARGET_X86_64
5474 offset_addr
= cpu_ldq_code(env
, s
->pc
);
5479 offset_addr
= insn_get(env
, s
, s
->aflag
);
5482 tcg_gen_movi_tl(cpu_A0
, offset_addr
);
5483 gen_add_A0_ds_seg(s
);
5485 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
5486 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T
[0]);
5488 gen_op_mov_v_reg(ot
, cpu_T
[0], R_EAX
);
5489 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
5493 case 0xd7: /* xlat */
5494 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EBX
]);
5495 tcg_gen_ext8u_tl(cpu_T
[0], cpu_regs
[R_EAX
]);
5496 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_T
[0]);
5497 gen_extu(s
->aflag
, cpu_A0
);
5498 gen_add_A0_ds_seg(s
);
5499 gen_op_ld_v(s
, MO_8
, cpu_T
[0], cpu_A0
);
5500 gen_op_mov_reg_v(MO_8
, R_EAX
, cpu_T
[0]);
5502 case 0xb0 ... 0xb7: /* mov R, Ib */
5503 val
= insn_get(env
, s
, MO_8
);
5504 tcg_gen_movi_tl(cpu_T
[0], val
);
5505 gen_op_mov_reg_v(MO_8
, (b
& 7) | REX_B(s
), cpu_T
[0]);
5507 case 0xb8 ... 0xbf: /* mov R, Iv */
5508 #ifdef TARGET_X86_64
5509 if (dflag
== MO_64
) {
5512 tmp
= cpu_ldq_code(env
, s
->pc
);
5514 reg
= (b
& 7) | REX_B(s
);
5515 tcg_gen_movi_tl(cpu_T
[0], tmp
);
5516 gen_op_mov_reg_v(MO_64
, reg
, cpu_T
[0]);
5521 val
= insn_get(env
, s
, ot
);
5522 reg
= (b
& 7) | REX_B(s
);
5523 tcg_gen_movi_tl(cpu_T
[0], val
);
5524 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
5528 case 0x91 ... 0x97: /* xchg R, EAX */
5531 reg
= (b
& 7) | REX_B(s
);
5535 case 0x87: /* xchg Ev, Gv */
5536 ot
= mo_b_d(b
, dflag
);
5537 modrm
= cpu_ldub_code(env
, s
->pc
++);
5538 reg
= ((modrm
>> 3) & 7) | rex_r
;
5539 mod
= (modrm
>> 6) & 3;
5541 rm
= (modrm
& 7) | REX_B(s
);
5543 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
5544 gen_op_mov_v_reg(ot
, cpu_T
[1], rm
);
5545 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
5546 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5548 gen_lea_modrm(env
, s
, modrm
);
5549 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
5550 /* for xchg, lock is implicit */
5551 if (!(prefixes
& PREFIX_LOCK
))
5553 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
5554 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
5555 if (!(prefixes
& PREFIX_LOCK
))
5556 gen_helper_unlock();
5557 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5560 case 0xc4: /* les Gv */
5561 /* In CODE64 this is VEX3; see above. */
5564 case 0xc5: /* lds Gv */
5565 /* In CODE64 this is VEX2; see above. */
5568 case 0x1b2: /* lss Gv */
5571 case 0x1b4: /* lfs Gv */
5574 case 0x1b5: /* lgs Gv */
5577 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
5578 modrm
= cpu_ldub_code(env
, s
->pc
++);
5579 reg
= ((modrm
>> 3) & 7) | rex_r
;
5580 mod
= (modrm
>> 6) & 3;
5583 gen_lea_modrm(env
, s
, modrm
);
5584 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
5585 gen_add_A0_im(s
, 1 << ot
);
5586 /* load the segment first to handle exceptions properly */
5587 gen_op_ld_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
5588 gen_movl_seg_T0(s
, op
);
5589 /* then put the data */
5590 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5592 gen_jmp_im(s
->pc
- s
->cs_base
);
5597 /************************/
5605 ot
= mo_b_d(b
, dflag
);
5606 modrm
= cpu_ldub_code(env
, s
->pc
++);
5607 mod
= (modrm
>> 6) & 3;
5608 op
= (modrm
>> 3) & 7;
5614 gen_lea_modrm(env
, s
, modrm
);
5617 opreg
= (modrm
& 7) | REX_B(s
);
5622 gen_shift(s
, op
, ot
, opreg
, OR_ECX
);
5625 shift
= cpu_ldub_code(env
, s
->pc
++);
5627 gen_shifti(s
, op
, ot
, opreg
, shift
);
5642 case 0x1a4: /* shld imm */
5646 case 0x1a5: /* shld cl */
5650 case 0x1ac: /* shrd imm */
5654 case 0x1ad: /* shrd cl */
5659 modrm
= cpu_ldub_code(env
, s
->pc
++);
5660 mod
= (modrm
>> 6) & 3;
5661 rm
= (modrm
& 7) | REX_B(s
);
5662 reg
= ((modrm
>> 3) & 7) | rex_r
;
5664 gen_lea_modrm(env
, s
, modrm
);
5669 gen_op_mov_v_reg(ot
, cpu_T
[1], reg
);
5672 TCGv imm
= tcg_const_tl(cpu_ldub_code(env
, s
->pc
++));
5673 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, imm
);
5676 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, cpu_regs
[R_ECX
]);
5680 /************************/
5683 if (s
->flags
& (HF_EM_MASK
| HF_TS_MASK
)) {
5684 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5685 /* XXX: what to do if illegal op ? */
5686 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
5689 modrm
= cpu_ldub_code(env
, s
->pc
++);
5690 mod
= (modrm
>> 6) & 3;
5692 op
= ((b
& 7) << 3) | ((modrm
>> 3) & 7);
5695 gen_lea_modrm(env
, s
, modrm
);
5697 case 0x00 ... 0x07: /* fxxxs */
5698 case 0x10 ... 0x17: /* fixxxl */
5699 case 0x20 ... 0x27: /* fxxxl */
5700 case 0x30 ... 0x37: /* fixxx */
5707 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5708 s
->mem_index
, MO_LEUL
);
5709 gen_helper_flds_FT0(cpu_env
, cpu_tmp2_i32
);
5712 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5713 s
->mem_index
, MO_LEUL
);
5714 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
5717 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
5718 s
->mem_index
, MO_LEQ
);
5719 gen_helper_fldl_FT0(cpu_env
, cpu_tmp1_i64
);
5723 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5724 s
->mem_index
, MO_LESW
);
5725 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
5729 gen_helper_fp_arith_ST0_FT0(op1
);
5731 /* fcomp needs pop */
5732 gen_helper_fpop(cpu_env
);
5736 case 0x08: /* flds */
5737 case 0x0a: /* fsts */
5738 case 0x0b: /* fstps */
5739 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5740 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5741 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5746 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5747 s
->mem_index
, MO_LEUL
);
5748 gen_helper_flds_ST0(cpu_env
, cpu_tmp2_i32
);
5751 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5752 s
->mem_index
, MO_LEUL
);
5753 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
5756 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
5757 s
->mem_index
, MO_LEQ
);
5758 gen_helper_fldl_ST0(cpu_env
, cpu_tmp1_i64
);
5762 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5763 s
->mem_index
, MO_LESW
);
5764 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
5769 /* XXX: the corresponding CPUID bit must be tested ! */
5772 gen_helper_fisttl_ST0(cpu_tmp2_i32
, cpu_env
);
5773 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5774 s
->mem_index
, MO_LEUL
);
5777 gen_helper_fisttll_ST0(cpu_tmp1_i64
, cpu_env
);
5778 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
5779 s
->mem_index
, MO_LEQ
);
5783 gen_helper_fistt_ST0(cpu_tmp2_i32
, cpu_env
);
5784 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5785 s
->mem_index
, MO_LEUW
);
5788 gen_helper_fpop(cpu_env
);
5793 gen_helper_fsts_ST0(cpu_tmp2_i32
, cpu_env
);
5794 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5795 s
->mem_index
, MO_LEUL
);
5798 gen_helper_fistl_ST0(cpu_tmp2_i32
, cpu_env
);
5799 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5800 s
->mem_index
, MO_LEUL
);
5803 gen_helper_fstl_ST0(cpu_tmp1_i64
, cpu_env
);
5804 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
5805 s
->mem_index
, MO_LEQ
);
5809 gen_helper_fist_ST0(cpu_tmp2_i32
, cpu_env
);
5810 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5811 s
->mem_index
, MO_LEUW
);
5815 gen_helper_fpop(cpu_env
);
5819 case 0x0c: /* fldenv mem */
5820 gen_helper_fldenv(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5822 case 0x0d: /* fldcw mem */
5823 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5824 s
->mem_index
, MO_LEUW
);
5825 gen_helper_fldcw(cpu_env
, cpu_tmp2_i32
);
5827 case 0x0e: /* fnstenv mem */
5828 gen_helper_fstenv(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5830 case 0x0f: /* fnstcw mem */
5831 gen_helper_fnstcw(cpu_tmp2_i32
, cpu_env
);
5832 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5833 s
->mem_index
, MO_LEUW
);
5835 case 0x1d: /* fldt mem */
5836 gen_helper_fldt_ST0(cpu_env
, cpu_A0
);
5838 case 0x1f: /* fstpt mem */
5839 gen_helper_fstt_ST0(cpu_env
, cpu_A0
);
5840 gen_helper_fpop(cpu_env
);
5842 case 0x2c: /* frstor mem */
5843 gen_helper_frstor(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5845 case 0x2e: /* fnsave mem */
5846 gen_helper_fsave(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5848 case 0x2f: /* fnstsw mem */
5849 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
5850 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5851 s
->mem_index
, MO_LEUW
);
5853 case 0x3c: /* fbld */
5854 gen_helper_fbld_ST0(cpu_env
, cpu_A0
);
5856 case 0x3e: /* fbstp */
5857 gen_helper_fbst_ST0(cpu_env
, cpu_A0
);
5858 gen_helper_fpop(cpu_env
);
5860 case 0x3d: /* fildll */
5861 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
5862 gen_helper_fildll_ST0(cpu_env
, cpu_tmp1_i64
);
5864 case 0x3f: /* fistpll */
5865 gen_helper_fistll_ST0(cpu_tmp1_i64
, cpu_env
);
5866 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
5867 gen_helper_fpop(cpu_env
);
5873 /* register float ops */
5877 case 0x08: /* fld sti */
5878 gen_helper_fpush(cpu_env
);
5879 gen_helper_fmov_ST0_STN(cpu_env
,
5880 tcg_const_i32((opreg
+ 1) & 7));
5882 case 0x09: /* fxchg sti */
5883 case 0x29: /* fxchg4 sti, undocumented op */
5884 case 0x39: /* fxchg7 sti, undocumented op */
5885 gen_helper_fxchg_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
5887 case 0x0a: /* grp d9/2 */
5890 /* check exceptions (FreeBSD FPU probe) */
5891 gen_helper_fwait(cpu_env
);
5897 case 0x0c: /* grp d9/4 */
5900 gen_helper_fchs_ST0(cpu_env
);
5903 gen_helper_fabs_ST0(cpu_env
);
5906 gen_helper_fldz_FT0(cpu_env
);
5907 gen_helper_fcom_ST0_FT0(cpu_env
);
5910 gen_helper_fxam_ST0(cpu_env
);
5916 case 0x0d: /* grp d9/5 */
5920 gen_helper_fpush(cpu_env
);
5921 gen_helper_fld1_ST0(cpu_env
);
5924 gen_helper_fpush(cpu_env
);
5925 gen_helper_fldl2t_ST0(cpu_env
);
5928 gen_helper_fpush(cpu_env
);
5929 gen_helper_fldl2e_ST0(cpu_env
);
5932 gen_helper_fpush(cpu_env
);
5933 gen_helper_fldpi_ST0(cpu_env
);
5936 gen_helper_fpush(cpu_env
);
5937 gen_helper_fldlg2_ST0(cpu_env
);
5940 gen_helper_fpush(cpu_env
);
5941 gen_helper_fldln2_ST0(cpu_env
);
5944 gen_helper_fpush(cpu_env
);
5945 gen_helper_fldz_ST0(cpu_env
);
5952 case 0x0e: /* grp d9/6 */
5955 gen_helper_f2xm1(cpu_env
);
5958 gen_helper_fyl2x(cpu_env
);
5961 gen_helper_fptan(cpu_env
);
5963 case 3: /* fpatan */
5964 gen_helper_fpatan(cpu_env
);
5966 case 4: /* fxtract */
5967 gen_helper_fxtract(cpu_env
);
5969 case 5: /* fprem1 */
5970 gen_helper_fprem1(cpu_env
);
5972 case 6: /* fdecstp */
5973 gen_helper_fdecstp(cpu_env
);
5976 case 7: /* fincstp */
5977 gen_helper_fincstp(cpu_env
);
5981 case 0x0f: /* grp d9/7 */
5984 gen_helper_fprem(cpu_env
);
5986 case 1: /* fyl2xp1 */
5987 gen_helper_fyl2xp1(cpu_env
);
5990 gen_helper_fsqrt(cpu_env
);
5992 case 3: /* fsincos */
5993 gen_helper_fsincos(cpu_env
);
5995 case 5: /* fscale */
5996 gen_helper_fscale(cpu_env
);
5998 case 4: /* frndint */
5999 gen_helper_frndint(cpu_env
);
6002 gen_helper_fsin(cpu_env
);
6006 gen_helper_fcos(cpu_env
);
6010 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6011 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6012 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6018 gen_helper_fp_arith_STN_ST0(op1
, opreg
);
6020 gen_helper_fpop(cpu_env
);
6022 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6023 gen_helper_fp_arith_ST0_FT0(op1
);
6027 case 0x02: /* fcom */
6028 case 0x22: /* fcom2, undocumented op */
6029 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6030 gen_helper_fcom_ST0_FT0(cpu_env
);
6032 case 0x03: /* fcomp */
6033 case 0x23: /* fcomp3, undocumented op */
6034 case 0x32: /* fcomp5, undocumented op */
6035 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6036 gen_helper_fcom_ST0_FT0(cpu_env
);
6037 gen_helper_fpop(cpu_env
);
6039 case 0x15: /* da/5 */
6041 case 1: /* fucompp */
6042 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6043 gen_helper_fucom_ST0_FT0(cpu_env
);
6044 gen_helper_fpop(cpu_env
);
6045 gen_helper_fpop(cpu_env
);
6053 case 0: /* feni (287 only, just do nop here) */
6055 case 1: /* fdisi (287 only, just do nop here) */
6058 gen_helper_fclex(cpu_env
);
6060 case 3: /* fninit */
6061 gen_helper_fninit(cpu_env
);
6063 case 4: /* fsetpm (287 only, just do nop here) */
6069 case 0x1d: /* fucomi */
6070 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6073 gen_update_cc_op(s
);
6074 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6075 gen_helper_fucomi_ST0_FT0(cpu_env
);
6076 set_cc_op(s
, CC_OP_EFLAGS
);
6078 case 0x1e: /* fcomi */
6079 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6082 gen_update_cc_op(s
);
6083 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6084 gen_helper_fcomi_ST0_FT0(cpu_env
);
6085 set_cc_op(s
, CC_OP_EFLAGS
);
6087 case 0x28: /* ffree sti */
6088 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6090 case 0x2a: /* fst sti */
6091 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6093 case 0x2b: /* fstp sti */
6094 case 0x0b: /* fstp1 sti, undocumented op */
6095 case 0x3a: /* fstp8 sti, undocumented op */
6096 case 0x3b: /* fstp9 sti, undocumented op */
6097 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6098 gen_helper_fpop(cpu_env
);
6100 case 0x2c: /* fucom st(i) */
6101 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6102 gen_helper_fucom_ST0_FT0(cpu_env
);
6104 case 0x2d: /* fucomp st(i) */
6105 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6106 gen_helper_fucom_ST0_FT0(cpu_env
);
6107 gen_helper_fpop(cpu_env
);
6109 case 0x33: /* de/3 */
6111 case 1: /* fcompp */
6112 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6113 gen_helper_fcom_ST0_FT0(cpu_env
);
6114 gen_helper_fpop(cpu_env
);
6115 gen_helper_fpop(cpu_env
);
6121 case 0x38: /* ffreep sti, undocumented op */
6122 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6123 gen_helper_fpop(cpu_env
);
6125 case 0x3c: /* df/4 */
6128 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
6129 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6130 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
6136 case 0x3d: /* fucomip */
6137 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6140 gen_update_cc_op(s
);
6141 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6142 gen_helper_fucomi_ST0_FT0(cpu_env
);
6143 gen_helper_fpop(cpu_env
);
6144 set_cc_op(s
, CC_OP_EFLAGS
);
6146 case 0x3e: /* fcomip */
6147 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6150 gen_update_cc_op(s
);
6151 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6152 gen_helper_fcomi_ST0_FT0(cpu_env
);
6153 gen_helper_fpop(cpu_env
);
6154 set_cc_op(s
, CC_OP_EFLAGS
);
6156 case 0x10 ... 0x13: /* fcmovxx */
6161 static const uint8_t fcmov_cc
[8] = {
6168 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6171 op1
= fcmov_cc
[op
& 3] | (((op
>> 3) & 1) ^ 1);
6172 l1
= gen_new_label();
6173 gen_jcc1_noeob(s
, op1
, l1
);
6174 gen_helper_fmov_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6183 /************************/
6186 case 0xa4: /* movsS */
6188 ot
= mo_b_d(b
, dflag
);
6189 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6190 gen_repz_movs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6196 case 0xaa: /* stosS */
6198 ot
= mo_b_d(b
, dflag
);
6199 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6200 gen_repz_stos(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6205 case 0xac: /* lodsS */
6207 ot
= mo_b_d(b
, dflag
);
6208 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6209 gen_repz_lods(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6214 case 0xae: /* scasS */
6216 ot
= mo_b_d(b
, dflag
);
6217 if (prefixes
& PREFIX_REPNZ
) {
6218 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6219 } else if (prefixes
& PREFIX_REPZ
) {
6220 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6226 case 0xa6: /* cmpsS */
6228 ot
= mo_b_d(b
, dflag
);
6229 if (prefixes
& PREFIX_REPNZ
) {
6230 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6231 } else if (prefixes
& PREFIX_REPZ
) {
6232 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6237 case 0x6c: /* insS */
6239 ot
= mo_b_d32(b
, dflag
);
6240 tcg_gen_ext16u_tl(cpu_T
[0], cpu_regs
[R_EDX
]);
6241 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6242 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
) | 4);
6243 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6244 gen_repz_ins(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6247 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6248 gen_jmp(s
, s
->pc
- s
->cs_base
);
6252 case 0x6e: /* outsS */
6254 ot
= mo_b_d32(b
, dflag
);
6255 tcg_gen_ext16u_tl(cpu_T
[0], cpu_regs
[R_EDX
]);
6256 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6257 svm_is_rep(prefixes
) | 4);
6258 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6259 gen_repz_outs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6262 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6263 gen_jmp(s
, s
->pc
- s
->cs_base
);
6268 /************************/
6273 ot
= mo_b_d32(b
, dflag
);
6274 val
= cpu_ldub_code(env
, s
->pc
++);
6275 tcg_gen_movi_tl(cpu_T
[0], val
);
6276 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6277 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6278 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6281 tcg_gen_movi_i32(cpu_tmp2_i32
, val
);
6282 gen_helper_in_func(ot
, cpu_T
[1], cpu_tmp2_i32
);
6283 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T
[1]);
6284 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6285 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6287 gen_jmp(s
, s
->pc
- s
->cs_base
);
6292 ot
= mo_b_d32(b
, dflag
);
6293 val
= cpu_ldub_code(env
, s
->pc
++);
6294 tcg_gen_movi_tl(cpu_T
[0], val
);
6295 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6296 svm_is_rep(prefixes
));
6297 gen_op_mov_v_reg(ot
, cpu_T
[1], R_EAX
);
6299 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6302 tcg_gen_movi_i32(cpu_tmp2_i32
, val
);
6303 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
6304 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6305 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6306 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6308 gen_jmp(s
, s
->pc
- s
->cs_base
);
6313 ot
= mo_b_d32(b
, dflag
);
6314 tcg_gen_ext16u_tl(cpu_T
[0], cpu_regs
[R_EDX
]);
6315 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6316 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6317 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6320 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6321 gen_helper_in_func(ot
, cpu_T
[1], cpu_tmp2_i32
);
6322 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T
[1]);
6323 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6324 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6326 gen_jmp(s
, s
->pc
- s
->cs_base
);
6331 ot
= mo_b_d32(b
, dflag
);
6332 tcg_gen_ext16u_tl(cpu_T
[0], cpu_regs
[R_EDX
]);
6333 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6334 svm_is_rep(prefixes
));
6335 gen_op_mov_v_reg(ot
, cpu_T
[1], R_EAX
);
6337 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6340 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6341 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
6342 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6343 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6344 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6346 gen_jmp(s
, s
->pc
- s
->cs_base
);
6350 /************************/
6352 case 0xc2: /* ret im */
6353 val
= cpu_ldsw_code(env
, s
->pc
);
6356 gen_stack_update(s
, val
+ (1 << ot
));
6357 /* Note that gen_pop_T0 uses a zero-extending load. */
6358 gen_op_jmp_v(cpu_T
[0]);
6361 case 0xc3: /* ret */
6363 gen_pop_update(s
, ot
);
6364 /* Note that gen_pop_T0 uses a zero-extending load. */
6365 gen_op_jmp_v(cpu_T
[0]);
6368 case 0xca: /* lret im */
6369 val
= cpu_ldsw_code(env
, s
->pc
);
6372 if (s
->pe
&& !s
->vm86
) {
6373 gen_update_cc_op(s
);
6374 gen_jmp_im(pc_start
- s
->cs_base
);
6375 gen_helper_lret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6376 tcg_const_i32(val
));
6380 gen_op_ld_v(s
, dflag
, cpu_T
[0], cpu_A0
);
6381 /* NOTE: keeping EIP updated is not a problem in case of
6383 gen_op_jmp_v(cpu_T
[0]);
6385 gen_op_addl_A0_im(1 << dflag
);
6386 gen_op_ld_v(s
, dflag
, cpu_T
[0], cpu_A0
);
6387 gen_op_movl_seg_T0_vm(R_CS
);
6388 /* add stack offset */
6389 gen_stack_update(s
, val
+ (2 << dflag
));
6393 case 0xcb: /* lret */
6396 case 0xcf: /* iret */
6397 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IRET
);
6400 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6401 set_cc_op(s
, CC_OP_EFLAGS
);
6402 } else if (s
->vm86
) {
6404 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6406 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6407 set_cc_op(s
, CC_OP_EFLAGS
);
6410 gen_helper_iret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6411 tcg_const_i32(s
->pc
- s
->cs_base
));
6412 set_cc_op(s
, CC_OP_EFLAGS
);
6416 case 0xe8: /* call im */
6418 if (dflag
!= MO_16
) {
6419 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6421 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6423 next_eip
= s
->pc
- s
->cs_base
;
6425 if (dflag
== MO_16
) {
6427 } else if (!CODE64(s
)) {
6430 tcg_gen_movi_tl(cpu_T
[0], next_eip
);
6431 gen_push_v(s
, cpu_T
[0]);
6435 case 0x9a: /* lcall im */
6437 unsigned int selector
, offset
;
6442 offset
= insn_get(env
, s
, ot
);
6443 selector
= insn_get(env
, s
, MO_16
);
6445 tcg_gen_movi_tl(cpu_T
[0], selector
);
6446 tcg_gen_movi_tl(cpu_T
[1], offset
);
6449 case 0xe9: /* jmp im */
6450 if (dflag
!= MO_16
) {
6451 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6453 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6455 tval
+= s
->pc
- s
->cs_base
;
6456 if (dflag
== MO_16
) {
6458 } else if (!CODE64(s
)) {
6463 case 0xea: /* ljmp im */
6465 unsigned int selector
, offset
;
6470 offset
= insn_get(env
, s
, ot
);
6471 selector
= insn_get(env
, s
, MO_16
);
6473 tcg_gen_movi_tl(cpu_T
[0], selector
);
6474 tcg_gen_movi_tl(cpu_T
[1], offset
);
6477 case 0xeb: /* jmp Jb */
6478 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6479 tval
+= s
->pc
- s
->cs_base
;
6480 if (dflag
== MO_16
) {
6485 case 0x70 ... 0x7f: /* jcc Jb */
6486 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6488 case 0x180 ... 0x18f: /* jcc Jv */
6489 if (dflag
!= MO_16
) {
6490 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6492 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6495 next_eip
= s
->pc
- s
->cs_base
;
6497 if (dflag
== MO_16
) {
6500 gen_jcc(s
, b
, tval
, next_eip
);
6503 case 0x190 ... 0x19f: /* setcc Gv */
6504 modrm
= cpu_ldub_code(env
, s
->pc
++);
6505 gen_setcc1(s
, b
, cpu_T
[0]);
6506 gen_ldst_modrm(env
, s
, modrm
, MO_8
, OR_TMP0
, 1);
6508 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6509 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6513 modrm
= cpu_ldub_code(env
, s
->pc
++);
6514 reg
= ((modrm
>> 3) & 7) | rex_r
;
6515 gen_cmovcc1(env
, s
, ot
, b
, modrm
, reg
);
6518 /************************/
6520 case 0x9c: /* pushf */
6521 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_PUSHF
);
6522 if (s
->vm86
&& s
->iopl
!= 3) {
6523 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6525 gen_update_cc_op(s
);
6526 gen_helper_read_eflags(cpu_T
[0], cpu_env
);
6527 gen_push_v(s
, cpu_T
[0]);
6530 case 0x9d: /* popf */
6531 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_POPF
);
6532 if (s
->vm86
&& s
->iopl
!= 3) {
6533 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6537 if (dflag
!= MO_16
) {
6538 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6539 tcg_const_i32((TF_MASK
| AC_MASK
|
6544 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6545 tcg_const_i32((TF_MASK
| AC_MASK
|
6547 IF_MASK
| IOPL_MASK
)
6551 if (s
->cpl
<= s
->iopl
) {
6552 if (dflag
!= MO_16
) {
6553 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6554 tcg_const_i32((TF_MASK
|
6560 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6561 tcg_const_i32((TF_MASK
|
6569 if (dflag
!= MO_16
) {
6570 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6571 tcg_const_i32((TF_MASK
| AC_MASK
|
6572 ID_MASK
| NT_MASK
)));
6574 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6575 tcg_const_i32((TF_MASK
| AC_MASK
|
6581 gen_pop_update(s
, ot
);
6582 set_cc_op(s
, CC_OP_EFLAGS
);
6583 /* abort translation because TF/AC flag may change */
6584 gen_jmp_im(s
->pc
- s
->cs_base
);
6588 case 0x9e: /* sahf */
6589 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6591 gen_op_mov_v_reg(MO_8
, cpu_T
[0], R_AH
);
6592 gen_compute_eflags(s
);
6593 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, CC_O
);
6594 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], CC_S
| CC_Z
| CC_A
| CC_P
| CC_C
);
6595 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, cpu_T
[0]);
6597 case 0x9f: /* lahf */
6598 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6600 gen_compute_eflags(s
);
6601 /* Note: gen_compute_eflags() only gives the condition codes */
6602 tcg_gen_ori_tl(cpu_T
[0], cpu_cc_src
, 0x02);
6603 gen_op_mov_reg_v(MO_8
, R_AH
, cpu_T
[0]);
6605 case 0xf5: /* cmc */
6606 gen_compute_eflags(s
);
6607 tcg_gen_xori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6609 case 0xf8: /* clc */
6610 gen_compute_eflags(s
);
6611 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_C
);
6613 case 0xf9: /* stc */
6614 gen_compute_eflags(s
);
6615 tcg_gen_ori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6617 case 0xfc: /* cld */
6618 tcg_gen_movi_i32(cpu_tmp2_i32
, 1);
6619 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6621 case 0xfd: /* std */
6622 tcg_gen_movi_i32(cpu_tmp2_i32
, -1);
6623 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6626 /************************/
6627 /* bit operations */
6628 case 0x1ba: /* bt/bts/btr/btc Gv, im */
6630 modrm
= cpu_ldub_code(env
, s
->pc
++);
6631 op
= (modrm
>> 3) & 7;
6632 mod
= (modrm
>> 6) & 3;
6633 rm
= (modrm
& 7) | REX_B(s
);
6636 gen_lea_modrm(env
, s
, modrm
);
6637 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
6639 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
6642 val
= cpu_ldub_code(env
, s
->pc
++);
6643 tcg_gen_movi_tl(cpu_T
[1], val
);
6648 case 0x1a3: /* bt Gv, Ev */
6651 case 0x1ab: /* bts */
6654 case 0x1b3: /* btr */
6657 case 0x1bb: /* btc */
6661 modrm
= cpu_ldub_code(env
, s
->pc
++);
6662 reg
= ((modrm
>> 3) & 7) | rex_r
;
6663 mod
= (modrm
>> 6) & 3;
6664 rm
= (modrm
& 7) | REX_B(s
);
6665 gen_op_mov_v_reg(MO_32
, cpu_T
[1], reg
);
6667 gen_lea_modrm(env
, s
, modrm
);
6668 /* specific case: we need to add a displacement */
6669 gen_exts(ot
, cpu_T
[1]);
6670 tcg_gen_sari_tl(cpu_tmp0
, cpu_T
[1], 3 + ot
);
6671 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, ot
);
6672 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
6673 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
6675 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
6678 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], (1 << (3 + ot
)) - 1);
6679 tcg_gen_shr_tl(cpu_tmp4
, cpu_T
[0], cpu_T
[1]);
6684 tcg_gen_movi_tl(cpu_tmp0
, 1);
6685 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
6686 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
6689 tcg_gen_movi_tl(cpu_tmp0
, 1);
6690 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
6691 tcg_gen_andc_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
6695 tcg_gen_movi_tl(cpu_tmp0
, 1);
6696 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
6697 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
6702 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
6704 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
6708 /* Delay all CC updates until after the store above. Note that
6709 C is the result of the test, Z is unchanged, and the others
6710 are all undefined. */
6712 case CC_OP_MULB
... CC_OP_MULQ
:
6713 case CC_OP_ADDB
... CC_OP_ADDQ
:
6714 case CC_OP_ADCB
... CC_OP_ADCQ
:
6715 case CC_OP_SUBB
... CC_OP_SUBQ
:
6716 case CC_OP_SBBB
... CC_OP_SBBQ
:
6717 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
6718 case CC_OP_INCB
... CC_OP_INCQ
:
6719 case CC_OP_DECB
... CC_OP_DECQ
:
6720 case CC_OP_SHLB
... CC_OP_SHLQ
:
6721 case CC_OP_SARB
... CC_OP_SARQ
:
6722 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
6723 /* Z was going to be computed from the non-zero status of CC_DST.
6724 We can get that same Z value (and the new C value) by leaving
6725 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
6727 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
6728 set_cc_op(s
, ((s
->cc_op
- CC_OP_MULB
) & 3) + CC_OP_SARB
);
6731 /* Otherwise, generate EFLAGS and replace the C bit. */
6732 gen_compute_eflags(s
);
6733 tcg_gen_deposit_tl(cpu_cc_src
, cpu_cc_src
, cpu_tmp4
,
6738 case 0x1bc: /* bsf / tzcnt */
6739 case 0x1bd: /* bsr / lzcnt */
6741 modrm
= cpu_ldub_code(env
, s
->pc
++);
6742 reg
= ((modrm
>> 3) & 7) | rex_r
;
6743 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
6744 gen_extu(ot
, cpu_T
[0]);
6746 /* Note that lzcnt and tzcnt are in different extensions. */
6747 if ((prefixes
& PREFIX_REPZ
)
6749 ? s
->cpuid_ext3_features
& CPUID_EXT3_ABM
6750 : s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)) {
6752 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
6754 /* For lzcnt, reduce the target_ulong result by the
6755 number of zeros that we expect to find at the top. */
6756 gen_helper_clz(cpu_T
[0], cpu_T
[0]);
6757 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], TARGET_LONG_BITS
- size
);
6759 /* For tzcnt, a zero input must return the operand size:
6760 force all bits outside the operand size to 1. */
6761 target_ulong mask
= (target_ulong
)-2 << (size
- 1);
6762 tcg_gen_ori_tl(cpu_T
[0], cpu_T
[0], mask
);
6763 gen_helper_ctz(cpu_T
[0], cpu_T
[0]);
6765 /* For lzcnt/tzcnt, C and Z bits are defined and are
6766 related to the result. */
6767 gen_op_update1_cc();
6768 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
6770 /* For bsr/bsf, only the Z bit is defined and it is related
6771 to the input and not the result. */
6772 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
6773 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
6775 /* For bsr, return the bit index of the first 1 bit,
6776 not the count of leading zeros. */
6777 gen_helper_clz(cpu_T
[0], cpu_T
[0]);
6778 tcg_gen_xori_tl(cpu_T
[0], cpu_T
[0], TARGET_LONG_BITS
- 1);
6780 gen_helper_ctz(cpu_T
[0], cpu_T
[0]);
6782 /* ??? The manual says that the output is undefined when the
6783 input is zero, but real hardware leaves it unchanged, and
6784 real programs appear to depend on that. */
6785 tcg_gen_movi_tl(cpu_tmp0
, 0);
6786 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_T
[0], cpu_cc_dst
, cpu_tmp0
,
6787 cpu_regs
[reg
], cpu_T
[0]);
6789 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
6791 /************************/
6793 case 0x27: /* daa */
6796 gen_update_cc_op(s
);
6797 gen_helper_daa(cpu_env
);
6798 set_cc_op(s
, CC_OP_EFLAGS
);
6800 case 0x2f: /* das */
6803 gen_update_cc_op(s
);
6804 gen_helper_das(cpu_env
);
6805 set_cc_op(s
, CC_OP_EFLAGS
);
6807 case 0x37: /* aaa */
6810 gen_update_cc_op(s
);
6811 gen_helper_aaa(cpu_env
);
6812 set_cc_op(s
, CC_OP_EFLAGS
);
6814 case 0x3f: /* aas */
6817 gen_update_cc_op(s
);
6818 gen_helper_aas(cpu_env
);
6819 set_cc_op(s
, CC_OP_EFLAGS
);
6821 case 0xd4: /* aam */
6824 val
= cpu_ldub_code(env
, s
->pc
++);
6826 gen_exception(s
, EXCP00_DIVZ
, pc_start
- s
->cs_base
);
6828 gen_helper_aam(cpu_env
, tcg_const_i32(val
));
6829 set_cc_op(s
, CC_OP_LOGICB
);
6832 case 0xd5: /* aad */
6835 val
= cpu_ldub_code(env
, s
->pc
++);
6836 gen_helper_aad(cpu_env
, tcg_const_i32(val
));
6837 set_cc_op(s
, CC_OP_LOGICB
);
6839 /************************/
6841 case 0x90: /* nop */
6842 /* XXX: correct lock test for all insn */
6843 if (prefixes
& PREFIX_LOCK
) {
6846 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
6848 goto do_xchg_reg_eax
;
6850 if (prefixes
& PREFIX_REPZ
) {
6851 gen_update_cc_op(s
);
6852 gen_jmp_im(pc_start
- s
->cs_base
);
6853 gen_helper_pause(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
6854 s
->is_jmp
= DISAS_TB_JUMP
;
6857 case 0x9b: /* fwait */
6858 if ((s
->flags
& (HF_MP_MASK
| HF_TS_MASK
)) ==
6859 (HF_MP_MASK
| HF_TS_MASK
)) {
6860 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
6862 gen_helper_fwait(cpu_env
);
6865 case 0xcc: /* int3 */
6866 gen_interrupt(s
, EXCP03_INT3
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6868 case 0xcd: /* int N */
6869 val
= cpu_ldub_code(env
, s
->pc
++);
6870 if (s
->vm86
&& s
->iopl
!= 3) {
6871 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6873 gen_interrupt(s
, val
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6876 case 0xce: /* into */
6879 gen_update_cc_op(s
);
6880 gen_jmp_im(pc_start
- s
->cs_base
);
6881 gen_helper_into(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
6884 case 0xf1: /* icebp (undocumented, exits to external debugger) */
6885 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_ICEBP
);
6887 gen_debug(s
, pc_start
- s
->cs_base
);
6890 tb_flush(CPU(x86_env_get_cpu(env
)));
6891 qemu_set_log(CPU_LOG_INT
| CPU_LOG_TB_IN_ASM
);
6895 case 0xfa: /* cli */
6897 if (s
->cpl
<= s
->iopl
) {
6898 gen_helper_cli(cpu_env
);
6900 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6904 gen_helper_cli(cpu_env
);
6906 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6910 case 0xfb: /* sti */
6912 if (s
->cpl
<= s
->iopl
) {
6914 gen_helper_sti(cpu_env
);
6915 /* interruptions are enabled only the first insn after sti */
6916 /* If several instructions disable interrupts, only the
6918 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
6919 gen_helper_set_inhibit_irq(cpu_env
);
6920 /* give a chance to handle pending irqs */
6921 gen_jmp_im(s
->pc
- s
->cs_base
);
6924 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6930 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6934 case 0x62: /* bound */
6938 modrm
= cpu_ldub_code(env
, s
->pc
++);
6939 reg
= (modrm
>> 3) & 7;
6940 mod
= (modrm
>> 6) & 3;
6943 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
6944 gen_lea_modrm(env
, s
, modrm
);
6945 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6947 gen_helper_boundw(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
6949 gen_helper_boundl(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
6952 case 0x1c8 ... 0x1cf: /* bswap reg */
6953 reg
= (b
& 7) | REX_B(s
);
6954 #ifdef TARGET_X86_64
6955 if (dflag
== MO_64
) {
6956 gen_op_mov_v_reg(MO_64
, cpu_T
[0], reg
);
6957 tcg_gen_bswap64_i64(cpu_T
[0], cpu_T
[0]);
6958 gen_op_mov_reg_v(MO_64
, reg
, cpu_T
[0]);
6962 gen_op_mov_v_reg(MO_32
, cpu_T
[0], reg
);
6963 tcg_gen_ext32u_tl(cpu_T
[0], cpu_T
[0]);
6964 tcg_gen_bswap32_tl(cpu_T
[0], cpu_T
[0]);
6965 gen_op_mov_reg_v(MO_32
, reg
, cpu_T
[0]);
6968 case 0xd6: /* salc */
6971 gen_compute_eflags_c(s
, cpu_T
[0]);
6972 tcg_gen_neg_tl(cpu_T
[0], cpu_T
[0]);
6973 gen_op_mov_reg_v(MO_8
, R_EAX
, cpu_T
[0]);
6975 case 0xe0: /* loopnz */
6976 case 0xe1: /* loopz */
6977 case 0xe2: /* loop */
6978 case 0xe3: /* jecxz */
6980 TCGLabel
*l1
, *l2
, *l3
;
6982 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6983 next_eip
= s
->pc
- s
->cs_base
;
6985 if (dflag
== MO_16
) {
6989 l1
= gen_new_label();
6990 l2
= gen_new_label();
6991 l3
= gen_new_label();
6994 case 0: /* loopnz */
6996 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
6997 gen_op_jz_ecx(s
->aflag
, l3
);
6998 gen_jcc1(s
, (JCC_Z
<< 1) | (b
^ 1), l1
);
7001 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
7002 gen_op_jnz_ecx(s
->aflag
, l1
);
7006 gen_op_jz_ecx(s
->aflag
, l1
);
7011 gen_jmp_im(next_eip
);
7020 case 0x130: /* wrmsr */
7021 case 0x132: /* rdmsr */
7023 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7025 gen_update_cc_op(s
);
7026 gen_jmp_im(pc_start
- s
->cs_base
);
7028 gen_helper_rdmsr(cpu_env
);
7030 gen_helper_wrmsr(cpu_env
);
7034 case 0x131: /* rdtsc */
7035 gen_update_cc_op(s
);
7036 gen_jmp_im(pc_start
- s
->cs_base
);
7037 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7040 gen_helper_rdtsc(cpu_env
);
7041 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7043 gen_jmp(s
, s
->pc
- s
->cs_base
);
7046 case 0x133: /* rdpmc */
7047 gen_update_cc_op(s
);
7048 gen_jmp_im(pc_start
- s
->cs_base
);
7049 gen_helper_rdpmc(cpu_env
);
7051 case 0x134: /* sysenter */
7052 /* For Intel SYSENTER is valid on 64-bit */
7053 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7056 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7058 gen_helper_sysenter(cpu_env
);
7062 case 0x135: /* sysexit */
7063 /* For Intel SYSEXIT is valid on 64-bit */
7064 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7067 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7069 gen_helper_sysexit(cpu_env
, tcg_const_i32(dflag
- 1));
7073 #ifdef TARGET_X86_64
7074 case 0x105: /* syscall */
7075 /* XXX: is it usable in real mode ? */
7076 gen_update_cc_op(s
);
7077 gen_jmp_im(pc_start
- s
->cs_base
);
7078 gen_helper_syscall(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7081 case 0x107: /* sysret */
7083 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7085 gen_helper_sysret(cpu_env
, tcg_const_i32(dflag
- 1));
7086 /* condition codes are modified only in long mode */
7088 set_cc_op(s
, CC_OP_EFLAGS
);
7094 case 0x1a2: /* cpuid */
7095 gen_update_cc_op(s
);
7096 gen_jmp_im(pc_start
- s
->cs_base
);
7097 gen_helper_cpuid(cpu_env
);
7099 case 0xf4: /* hlt */
7101 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7103 gen_update_cc_op(s
);
7104 gen_jmp_im(pc_start
- s
->cs_base
);
7105 gen_helper_hlt(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7106 s
->is_jmp
= DISAS_TB_JUMP
;
7110 modrm
= cpu_ldub_code(env
, s
->pc
++);
7111 mod
= (modrm
>> 6) & 3;
7112 op
= (modrm
>> 3) & 7;
7115 if (!s
->pe
|| s
->vm86
)
7117 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_READ
);
7118 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,ldt
.selector
));
7119 ot
= mod
== 3 ? dflag
: MO_16
;
7120 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7123 if (!s
->pe
|| s
->vm86
)
7126 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7128 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_WRITE
);
7129 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7130 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
7131 gen_helper_lldt(cpu_env
, cpu_tmp2_i32
);
7135 if (!s
->pe
|| s
->vm86
)
7137 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_READ
);
7138 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,tr
.selector
));
7139 ot
= mod
== 3 ? dflag
: MO_16
;
7140 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7143 if (!s
->pe
|| s
->vm86
)
7146 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7148 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_WRITE
);
7149 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7150 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
7151 gen_helper_ltr(cpu_env
, cpu_tmp2_i32
);
7156 if (!s
->pe
|| s
->vm86
)
7158 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7159 gen_update_cc_op(s
);
7161 gen_helper_verr(cpu_env
, cpu_T
[0]);
7163 gen_helper_verw(cpu_env
, cpu_T
[0]);
7165 set_cc_op(s
, CC_OP_EFLAGS
);
7172 modrm
= cpu_ldub_code(env
, s
->pc
++);
7173 mod
= (modrm
>> 6) & 3;
7174 op
= (modrm
>> 3) & 7;
7180 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_READ
);
7181 gen_lea_modrm(env
, s
, modrm
);
7182 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7183 gen_op_st_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
7184 gen_add_A0_im(s
, 2);
7185 tcg_gen_ld_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7186 if (dflag
== MO_16
) {
7187 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffffff);
7189 gen_op_st_v(s
, CODE64(s
) + MO_32
, cpu_T
[0], cpu_A0
);
7194 case 0: /* monitor */
7195 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) ||
7198 gen_update_cc_op(s
);
7199 gen_jmp_im(pc_start
- s
->cs_base
);
7200 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EAX
]);
7201 gen_extu(s
->aflag
, cpu_A0
);
7202 gen_add_A0_ds_seg(s
);
7203 gen_helper_monitor(cpu_env
, cpu_A0
);
7206 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) ||
7209 gen_update_cc_op(s
);
7210 gen_jmp_im(pc_start
- s
->cs_base
);
7211 gen_helper_mwait(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7215 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
) ||
7219 gen_helper_clac(cpu_env
);
7220 gen_jmp_im(s
->pc
- s
->cs_base
);
7224 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
) ||
7228 gen_helper_stac(cpu_env
);
7229 gen_jmp_im(s
->pc
- s
->cs_base
);
7236 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_READ
);
7237 gen_lea_modrm(env
, s
, modrm
);
7238 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7239 gen_op_st_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
7240 gen_add_A0_im(s
, 2);
7241 tcg_gen_ld_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, idt
.base
));
7242 if (dflag
== MO_16
) {
7243 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffffff);
7245 gen_op_st_v(s
, CODE64(s
) + MO_32
, cpu_T
[0], cpu_A0
);
7251 gen_update_cc_op(s
);
7252 gen_jmp_im(pc_start
- s
->cs_base
);
7255 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7258 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7261 gen_helper_vmrun(cpu_env
, tcg_const_i32(s
->aflag
- 1),
7262 tcg_const_i32(s
->pc
- pc_start
));
7264 s
->is_jmp
= DISAS_TB_JUMP
;
7267 case 1: /* VMMCALL */
7268 if (!(s
->flags
& HF_SVME_MASK
))
7270 gen_helper_vmmcall(cpu_env
);
7272 case 2: /* VMLOAD */
7273 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7276 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7279 gen_helper_vmload(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7282 case 3: /* VMSAVE */
7283 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7286 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7289 gen_helper_vmsave(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7293 if ((!(s
->flags
& HF_SVME_MASK
) &&
7294 !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
)) ||
7298 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7301 gen_helper_stgi(cpu_env
);
7305 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7308 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7311 gen_helper_clgi(cpu_env
);
7314 case 6: /* SKINIT */
7315 if ((!(s
->flags
& HF_SVME_MASK
) &&
7316 !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
)) ||
7319 gen_helper_skinit(cpu_env
);
7321 case 7: /* INVLPGA */
7322 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7325 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7328 gen_helper_invlpga(cpu_env
,
7329 tcg_const_i32(s
->aflag
- 1));
7335 } else if (s
->cpl
!= 0) {
7336 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7338 gen_svm_check_intercept(s
, pc_start
,
7339 op
==2 ? SVM_EXIT_GDTR_WRITE
: SVM_EXIT_IDTR_WRITE
);
7340 gen_lea_modrm(env
, s
, modrm
);
7341 gen_op_ld_v(s
, MO_16
, cpu_T
[1], cpu_A0
);
7342 gen_add_A0_im(s
, 2);
7343 gen_op_ld_v(s
, CODE64(s
) + MO_32
, cpu_T
[0], cpu_A0
);
7344 if (dflag
== MO_16
) {
7345 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffffff);
7348 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,gdt
.base
));
7349 tcg_gen_st32_tl(cpu_T
[1], cpu_env
, offsetof(CPUX86State
,gdt
.limit
));
7351 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,idt
.base
));
7352 tcg_gen_st32_tl(cpu_T
[1], cpu_env
, offsetof(CPUX86State
,idt
.limit
));
7357 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_CR0
);
7358 #if defined TARGET_X86_64 && defined HOST_WORDS_BIGENDIAN
7359 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,cr
[0]) + 4);
7361 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,cr
[0]));
7363 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 1);
7367 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7369 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7370 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7371 gen_helper_lmsw(cpu_env
, cpu_T
[0]);
7372 gen_jmp_im(s
->pc
- s
->cs_base
);
7377 if (mod
!= 3) { /* invlpg */
7379 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7381 gen_update_cc_op(s
);
7382 gen_jmp_im(pc_start
- s
->cs_base
);
7383 gen_lea_modrm(env
, s
, modrm
);
7384 gen_helper_invlpg(cpu_env
, cpu_A0
);
7385 gen_jmp_im(s
->pc
- s
->cs_base
);
7390 case 0: /* swapgs */
7391 #ifdef TARGET_X86_64
7394 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7396 tcg_gen_ld_tl(cpu_T
[0], cpu_env
,
7397 offsetof(CPUX86State
,segs
[R_GS
].base
));
7398 tcg_gen_ld_tl(cpu_T
[1], cpu_env
,
7399 offsetof(CPUX86State
,kernelgsbase
));
7400 tcg_gen_st_tl(cpu_T
[1], cpu_env
,
7401 offsetof(CPUX86State
,segs
[R_GS
].base
));
7402 tcg_gen_st_tl(cpu_T
[0], cpu_env
,
7403 offsetof(CPUX86State
,kernelgsbase
));
7411 case 1: /* rdtscp */
7412 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_RDTSCP
))
7414 gen_update_cc_op(s
);
7415 gen_jmp_im(pc_start
- s
->cs_base
);
7416 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7419 gen_helper_rdtscp(cpu_env
);
7420 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7422 gen_jmp(s
, s
->pc
- s
->cs_base
);
7434 case 0x108: /* invd */
7435 case 0x109: /* wbinvd */
7437 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7439 gen_svm_check_intercept(s
, pc_start
, (b
& 2) ? SVM_EXIT_INVD
: SVM_EXIT_WBINVD
);
7443 case 0x63: /* arpl or movslS (x86_64) */
7444 #ifdef TARGET_X86_64
7447 /* d_ot is the size of destination */
7450 modrm
= cpu_ldub_code(env
, s
->pc
++);
7451 reg
= ((modrm
>> 3) & 7) | rex_r
;
7452 mod
= (modrm
>> 6) & 3;
7453 rm
= (modrm
& 7) | REX_B(s
);
7456 gen_op_mov_v_reg(MO_32
, cpu_T
[0], rm
);
7458 if (d_ot
== MO_64
) {
7459 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
7461 gen_op_mov_reg_v(d_ot
, reg
, cpu_T
[0]);
7463 gen_lea_modrm(env
, s
, modrm
);
7464 gen_op_ld_v(s
, MO_32
| MO_SIGN
, cpu_T
[0], cpu_A0
);
7465 gen_op_mov_reg_v(d_ot
, reg
, cpu_T
[0]);
7471 TCGv t0
, t1
, t2
, a0
;
7473 if (!s
->pe
|| s
->vm86
)
7475 t0
= tcg_temp_local_new();
7476 t1
= tcg_temp_local_new();
7477 t2
= tcg_temp_local_new();
7479 modrm
= cpu_ldub_code(env
, s
->pc
++);
7480 reg
= (modrm
>> 3) & 7;
7481 mod
= (modrm
>> 6) & 3;
7484 gen_lea_modrm(env
, s
, modrm
);
7485 gen_op_ld_v(s
, ot
, t0
, cpu_A0
);
7486 a0
= tcg_temp_local_new();
7487 tcg_gen_mov_tl(a0
, cpu_A0
);
7489 gen_op_mov_v_reg(ot
, t0
, rm
);
7492 gen_op_mov_v_reg(ot
, t1
, reg
);
7493 tcg_gen_andi_tl(cpu_tmp0
, t0
, 3);
7494 tcg_gen_andi_tl(t1
, t1
, 3);
7495 tcg_gen_movi_tl(t2
, 0);
7496 label1
= gen_new_label();
7497 tcg_gen_brcond_tl(TCG_COND_GE
, cpu_tmp0
, t1
, label1
);
7498 tcg_gen_andi_tl(t0
, t0
, ~3);
7499 tcg_gen_or_tl(t0
, t0
, t1
);
7500 tcg_gen_movi_tl(t2
, CC_Z
);
7501 gen_set_label(label1
);
7503 gen_op_st_v(s
, ot
, t0
, a0
);
7506 gen_op_mov_reg_v(ot
, rm
, t0
);
7508 gen_compute_eflags(s
);
7509 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_Z
);
7510 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, t2
);
7516 case 0x102: /* lar */
7517 case 0x103: /* lsl */
7521 if (!s
->pe
|| s
->vm86
)
7523 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
7524 modrm
= cpu_ldub_code(env
, s
->pc
++);
7525 reg
= ((modrm
>> 3) & 7) | rex_r
;
7526 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7527 t0
= tcg_temp_local_new();
7528 gen_update_cc_op(s
);
7530 gen_helper_lar(t0
, cpu_env
, cpu_T
[0]);
7532 gen_helper_lsl(t0
, cpu_env
, cpu_T
[0]);
7534 tcg_gen_andi_tl(cpu_tmp0
, cpu_cc_src
, CC_Z
);
7535 label1
= gen_new_label();
7536 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
7537 gen_op_mov_reg_v(ot
, reg
, t0
);
7538 gen_set_label(label1
);
7539 set_cc_op(s
, CC_OP_EFLAGS
);
7544 modrm
= cpu_ldub_code(env
, s
->pc
++);
7545 mod
= (modrm
>> 6) & 3;
7546 op
= (modrm
>> 3) & 7;
7548 case 0: /* prefetchnta */
7549 case 1: /* prefetchnt0 */
7550 case 2: /* prefetchnt0 */
7551 case 3: /* prefetchnt0 */
7554 gen_lea_modrm(env
, s
, modrm
);
7555 /* nothing more to do */
7557 default: /* nop (multi byte) */
7558 gen_nop_modrm(env
, s
, modrm
);
7562 case 0x119 ... 0x11f: /* nop (multi byte) */
7563 modrm
= cpu_ldub_code(env
, s
->pc
++);
7564 gen_nop_modrm(env
, s
, modrm
);
7566 case 0x120: /* mov reg, crN */
7567 case 0x122: /* mov crN, reg */
7569 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7571 modrm
= cpu_ldub_code(env
, s
->pc
++);
7572 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7573 * AMD documentation (24594.pdf) and testing of
7574 * intel 386 and 486 processors all show that the mod bits
7575 * are assumed to be 1's, regardless of actual values.
7577 rm
= (modrm
& 7) | REX_B(s
);
7578 reg
= ((modrm
>> 3) & 7) | rex_r
;
7583 if ((prefixes
& PREFIX_LOCK
) && (reg
== 0) &&
7584 (s
->cpuid_ext3_features
& CPUID_EXT3_CR8LEG
)) {
7593 gen_update_cc_op(s
);
7594 gen_jmp_im(pc_start
- s
->cs_base
);
7596 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
7597 gen_helper_write_crN(cpu_env
, tcg_const_i32(reg
),
7599 gen_jmp_im(s
->pc
- s
->cs_base
);
7602 gen_helper_read_crN(cpu_T
[0], cpu_env
, tcg_const_i32(reg
));
7603 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
7611 case 0x121: /* mov reg, drN */
7612 case 0x123: /* mov drN, reg */
7614 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7616 modrm
= cpu_ldub_code(env
, s
->pc
++);
7617 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7618 * AMD documentation (24594.pdf) and testing of
7619 * intel 386 and 486 processors all show that the mod bits
7620 * are assumed to be 1's, regardless of actual values.
7622 rm
= (modrm
& 7) | REX_B(s
);
7623 reg
= ((modrm
>> 3) & 7) | rex_r
;
7632 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_DR0
+ reg
);
7633 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
7634 tcg_gen_movi_i32(cpu_tmp2_i32
, reg
);
7635 gen_helper_set_dr(cpu_env
, cpu_tmp2_i32
, cpu_T
[0]);
7636 gen_jmp_im(s
->pc
- s
->cs_base
);
7639 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_DR0
+ reg
);
7640 tcg_gen_movi_i32(cpu_tmp2_i32
, reg
);
7641 gen_helper_get_dr(cpu_T
[0], cpu_env
, cpu_tmp2_i32
);
7642 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
7646 case 0x106: /* clts */
7648 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7650 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7651 gen_helper_clts(cpu_env
);
7652 /* abort block because static cpu state changed */
7653 gen_jmp_im(s
->pc
- s
->cs_base
);
7657 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
7658 case 0x1c3: /* MOVNTI reg, mem */
7659 if (!(s
->cpuid_features
& CPUID_SSE2
))
7661 ot
= mo_64_32(dflag
);
7662 modrm
= cpu_ldub_code(env
, s
->pc
++);
7663 mod
= (modrm
>> 6) & 3;
7666 reg
= ((modrm
>> 3) & 7) | rex_r
;
7667 /* generate a generic store */
7668 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
7671 modrm
= cpu_ldub_code(env
, s
->pc
++);
7672 mod
= (modrm
>> 6) & 3;
7673 op
= (modrm
>> 3) & 7;
7675 case 0: /* fxsave */
7676 if (mod
== 3 || !(s
->cpuid_features
& CPUID_FXSR
) ||
7677 (s
->prefix
& PREFIX_LOCK
))
7679 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
7680 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7683 gen_lea_modrm(env
, s
, modrm
);
7684 gen_helper_fxsave(cpu_env
, cpu_A0
, tcg_const_i32(dflag
== MO_64
));
7686 case 1: /* fxrstor */
7687 if (mod
== 3 || !(s
->cpuid_features
& CPUID_FXSR
) ||
7688 (s
->prefix
& PREFIX_LOCK
))
7690 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
7691 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7694 gen_lea_modrm(env
, s
, modrm
);
7695 gen_helper_fxrstor(cpu_env
, cpu_A0
, tcg_const_i32(dflag
== MO_64
));
7697 case 2: /* ldmxcsr */
7698 case 3: /* stmxcsr */
7699 if (s
->flags
& HF_TS_MASK
) {
7700 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7703 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
) ||
7706 gen_lea_modrm(env
, s
, modrm
);
7708 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
7709 s
->mem_index
, MO_LEUL
);
7710 gen_helper_ldmxcsr(cpu_env
, cpu_tmp2_i32
);
7712 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, mxcsr
));
7713 gen_op_st_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
7716 case 5: /* lfence */
7717 if ((modrm
& 0xc7) != 0xc0 || !(s
->cpuid_features
& CPUID_SSE2
))
7720 case 6: /* mfence/clwb */
7721 if (s
->prefix
& PREFIX_DATA
) {
7723 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLWB
))
7725 gen_nop_modrm(env
, s
, modrm
);
7728 if ((modrm
& 0xc7) != 0xc0 || !(s
->cpuid_features
& CPUID_SSE2
))
7732 case 7: /* sfence / clflush / clflushopt / pcommit */
7733 if ((modrm
& 0xc7) == 0xc0) {
7734 if (s
->prefix
& PREFIX_DATA
) {
7736 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_PCOMMIT
))
7740 /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX */
7741 if (!(s
->cpuid_features
& CPUID_SSE
))
7745 if (s
->prefix
& PREFIX_DATA
) {
7747 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLFLUSHOPT
))
7751 if (!(s
->cpuid_features
& CPUID_CLFLUSH
))
7754 gen_lea_modrm(env
, s
, modrm
);
7761 case 0x10d: /* 3DNow! prefetch(w) */
7762 modrm
= cpu_ldub_code(env
, s
->pc
++);
7763 mod
= (modrm
>> 6) & 3;
7766 gen_lea_modrm(env
, s
, modrm
);
7767 /* ignore for now */
7769 case 0x1aa: /* rsm */
7770 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_RSM
);
7771 if (!(s
->flags
& HF_SMM_MASK
))
7773 gen_update_cc_op(s
);
7774 gen_jmp_im(s
->pc
- s
->cs_base
);
7775 gen_helper_rsm(cpu_env
);
7778 case 0x1b8: /* SSE4.2 popcnt */
7779 if ((prefixes
& (PREFIX_REPZ
| PREFIX_LOCK
| PREFIX_REPNZ
)) !=
7782 if (!(s
->cpuid_ext_features
& CPUID_EXT_POPCNT
))
7785 modrm
= cpu_ldub_code(env
, s
->pc
++);
7786 reg
= ((modrm
>> 3) & 7) | rex_r
;
7788 if (s
->prefix
& PREFIX_DATA
) {
7791 ot
= mo_64_32(dflag
);
7794 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
7795 gen_helper_popcnt(cpu_T
[0], cpu_env
, cpu_T
[0], tcg_const_i32(ot
));
7796 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
7798 set_cc_op(s
, CC_OP_EFLAGS
);
7800 case 0x10e ... 0x10f:
7801 /* 3DNow! instructions, ignore prefixes */
7802 s
->prefix
&= ~(PREFIX_REPZ
| PREFIX_REPNZ
| PREFIX_DATA
);
7803 case 0x110 ... 0x117:
7804 case 0x128 ... 0x12f:
7805 case 0x138 ... 0x13a:
7806 case 0x150 ... 0x179:
7807 case 0x17c ... 0x17f:
7809 case 0x1c4 ... 0x1c6:
7810 case 0x1d0 ... 0x1fe:
7811 gen_sse(env
, s
, b
, pc_start
, rex_r
);
7816 /* lock generation */
7817 if (s
->prefix
& PREFIX_LOCK
)
7818 gen_helper_unlock();
7821 if (s
->prefix
& PREFIX_LOCK
)
7822 gen_helper_unlock();
7823 /* XXX: ensure that no lock was generated */
7824 gen_exception(s
, EXCP06_ILLOP
, pc_start
- s
->cs_base
);
7828 void tcg_x86_init(void)
7830 static const char reg_names
[CPU_NB_REGS
][4] = {
7831 #ifdef TARGET_X86_64
7861 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
7862 cpu_cc_op
= tcg_global_mem_new_i32(TCG_AREG0
,
7863 offsetof(CPUX86State
, cc_op
), "cc_op");
7864 cpu_cc_dst
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_dst
),
7866 cpu_cc_src
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_src
),
7868 cpu_cc_src2
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_src2
),
7871 for (i
= 0; i
< CPU_NB_REGS
; ++i
) {
7872 cpu_regs
[i
] = tcg_global_mem_new(TCG_AREG0
,
7873 offsetof(CPUX86State
, regs
[i
]),
7880 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
7881 basic block 'tb'. */
7882 void gen_intermediate_code(CPUX86State
*env
, TranslationBlock
*tb
)
7884 X86CPU
*cpu
= x86_env_get_cpu(env
);
7885 CPUState
*cs
= CPU(cpu
);
7886 DisasContext dc1
, *dc
= &dc1
;
7887 target_ulong pc_ptr
;
7889 target_ulong pc_start
;
7890 target_ulong cs_base
;
7894 /* generate intermediate code */
7896 cs_base
= tb
->cs_base
;
7899 dc
->pe
= (flags
>> HF_PE_SHIFT
) & 1;
7900 dc
->code32
= (flags
>> HF_CS32_SHIFT
) & 1;
7901 dc
->ss32
= (flags
>> HF_SS32_SHIFT
) & 1;
7902 dc
->addseg
= (flags
>> HF_ADDSEG_SHIFT
) & 1;
7904 dc
->vm86
= (flags
>> VM_SHIFT
) & 1;
7905 dc
->cpl
= (flags
>> HF_CPL_SHIFT
) & 3;
7906 dc
->iopl
= (flags
>> IOPL_SHIFT
) & 3;
7907 dc
->tf
= (flags
>> TF_SHIFT
) & 1;
7908 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
7909 dc
->cc_op
= CC_OP_DYNAMIC
;
7910 dc
->cc_op_dirty
= false;
7911 dc
->cs_base
= cs_base
;
7913 dc
->popl_esp_hack
= 0;
7914 /* select memory access functions */
7916 if (flags
& HF_SOFTMMU_MASK
) {
7917 dc
->mem_index
= cpu_mmu_index(env
, false);
7919 dc
->cpuid_features
= env
->features
[FEAT_1_EDX
];
7920 dc
->cpuid_ext_features
= env
->features
[FEAT_1_ECX
];
7921 dc
->cpuid_ext2_features
= env
->features
[FEAT_8000_0001_EDX
];
7922 dc
->cpuid_ext3_features
= env
->features
[FEAT_8000_0001_ECX
];
7923 dc
->cpuid_7_0_ebx_features
= env
->features
[FEAT_7_0_EBX
];
7924 #ifdef TARGET_X86_64
7925 dc
->lma
= (flags
>> HF_LMA_SHIFT
) & 1;
7926 dc
->code64
= (flags
>> HF_CS64_SHIFT
) & 1;
7929 dc
->jmp_opt
= !(dc
->tf
|| cs
->singlestep_enabled
||
7930 (flags
& HF_INHIBIT_IRQ_MASK
)
7931 #ifndef CONFIG_SOFTMMU
7932 || (flags
& HF_SOFTMMU_MASK
)
7935 /* Do not optimize repz jumps at all in icount mode, because
7936 rep movsS instructions are execured with different paths
7937 in !repz_opt and repz_opt modes. The first one was used
7938 always except single step mode. And this setting
7939 disables jumps optimization and control paths become
7940 equivalent in run and single step modes.
7941 Now there will be no jump optimization for repz in
7942 record/replay modes and there will always be an
7943 additional step for ecx=0 when icount is enabled.
7945 dc
->repz_opt
= !dc
->jmp_opt
&& !(tb
->cflags
& CF_USE_ICOUNT
);
7947 /* check addseg logic */
7948 if (!dc
->addseg
&& (dc
->vm86
|| !dc
->pe
|| !dc
->code32
))
7949 printf("ERROR addseg\n");
7952 cpu_T
[0] = tcg_temp_new();
7953 cpu_T
[1] = tcg_temp_new();
7954 cpu_A0
= tcg_temp_new();
7956 cpu_tmp0
= tcg_temp_new();
7957 cpu_tmp1_i64
= tcg_temp_new_i64();
7958 cpu_tmp2_i32
= tcg_temp_new_i32();
7959 cpu_tmp3_i32
= tcg_temp_new_i32();
7960 cpu_tmp4
= tcg_temp_new();
7961 cpu_ptr0
= tcg_temp_new_ptr();
7962 cpu_ptr1
= tcg_temp_new_ptr();
7963 cpu_cc_srcT
= tcg_temp_local_new();
7965 dc
->is_jmp
= DISAS_NEXT
;
7968 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
7969 if (max_insns
== 0) {
7970 max_insns
= CF_COUNT_MASK
;
7972 if (max_insns
> TCG_MAX_INSNS
) {
7973 max_insns
= TCG_MAX_INSNS
;
7978 tcg_gen_insn_start(pc_ptr
, dc
->cc_op
);
7981 /* If RF is set, suppress an internally generated breakpoint. */
7982 if (unlikely(cpu_breakpoint_test(cs
, pc_ptr
,
7983 tb
->flags
& HF_RF_MASK
7984 ? BP_GDB
: BP_ANY
))) {
7985 gen_debug(dc
, pc_ptr
- dc
->cs_base
);
7986 /* The address covered by the breakpoint must be included in
7987 [tb->pc, tb->pc + tb->size) in order to for it to be
7988 properly cleared -- thus we increment the PC here so that
7989 the logic setting tb->size below does the right thing. */
7991 goto done_generating
;
7993 if (num_insns
== max_insns
&& (tb
->cflags
& CF_LAST_IO
)) {
7997 pc_ptr
= disas_insn(env
, dc
, pc_ptr
);
7998 /* stop translation if indicated */
8001 /* if single step mode, we generate only one instruction and
8002 generate an exception */
8003 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
8004 the flag and abort the translation to give the irqs a
8005 change to be happen */
8006 if (dc
->tf
|| dc
->singlestep_enabled
||
8007 (flags
& HF_INHIBIT_IRQ_MASK
)) {
8008 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8012 /* Do not cross the boundary of the pages in icount mode,
8013 it can cause an exception. Do it only when boundary is
8014 crossed by the first instruction in the block.
8015 If current instruction already crossed the bound - it's ok,
8016 because an exception hasn't stopped this code.
8018 if ((tb
->cflags
& CF_USE_ICOUNT
)
8019 && ((pc_ptr
& TARGET_PAGE_MASK
)
8020 != ((pc_ptr
+ TARGET_MAX_INSN_SIZE
- 1) & TARGET_PAGE_MASK
)
8021 || (pc_ptr
& ~TARGET_PAGE_MASK
) == 0)) {
8022 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8026 /* if too long translation, stop generation too */
8027 if (tcg_op_buf_full() ||
8028 (pc_ptr
- pc_start
) >= (TARGET_PAGE_SIZE
- 32) ||
8029 num_insns
>= max_insns
) {
8030 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8035 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8040 if (tb
->cflags
& CF_LAST_IO
)
8043 gen_tb_end(tb
, num_insns
);
8046 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
8048 qemu_log("----------------\n");
8049 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
8050 #ifdef TARGET_X86_64
8055 disas_flags
= !dc
->code32
;
8056 log_target_disas(cs
, pc_start
, pc_ptr
- pc_start
, disas_flags
);
8061 tb
->size
= pc_ptr
- pc_start
;
8062 tb
->icount
= num_insns
;
8065 void restore_state_to_opc(CPUX86State
*env
, TranslationBlock
*tb
,
8068 int cc_op
= data
[1];
8069 env
->eip
= data
[0] - tb
->cs_base
;
8070 if (cc_op
!= CC_OP_DYNAMIC
) {