4 * Copyright (c) 2003 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 #include "qemu/osdep.h"
21 #include "qemu/host-utils.h"
23 #include "disas/disas.h"
25 #include "exec/cpu_ldst.h"
27 #include "exec/helper-proto.h"
28 #include "exec/helper-gen.h"
30 #include "trace-tcg.h"
34 #define PREFIX_REPZ 0x01
35 #define PREFIX_REPNZ 0x02
36 #define PREFIX_LOCK 0x04
37 #define PREFIX_DATA 0x08
38 #define PREFIX_ADR 0x10
39 #define PREFIX_VEX 0x20
42 #define CODE64(s) ((s)->code64)
43 #define REX_X(s) ((s)->rex_x)
44 #define REX_B(s) ((s)->rex_b)
59 //#define MACRO_TEST 1
61 /* global register indexes */
62 static TCGv_ptr cpu_env
;
64 static TCGv cpu_cc_dst
, cpu_cc_src
, cpu_cc_src2
, cpu_cc_srcT
;
65 static TCGv_i32 cpu_cc_op
;
66 static TCGv cpu_regs
[CPU_NB_REGS
];
67 static TCGv cpu_seg_base
[6];
69 static TCGv cpu_T0
, cpu_T1
;
70 /* local register indexes (only used inside old micro ops) */
71 static TCGv cpu_tmp0
, cpu_tmp4
;
72 static TCGv_ptr cpu_ptr0
, cpu_ptr1
;
73 static TCGv_i32 cpu_tmp2_i32
, cpu_tmp3_i32
;
74 static TCGv_i64 cpu_tmp1_i64
;
76 #include "exec/gen-icount.h"
79 static int x86_64_hregs
;
82 typedef struct DisasContext
{
83 /* current insn context */
84 int override
; /* -1 if no override */
88 target_ulong pc
; /* pc = eip + cs_base */
89 int is_jmp
; /* 1 = means jump (stop translation), 2 means CPU
90 static state change (stop translation) */
91 /* current block context */
92 target_ulong cs_base
; /* base of CS segment */
93 int pe
; /* protected mode */
94 int code32
; /* 32 bit code segment */
96 int lma
; /* long mode active */
97 int code64
; /* 64 bit code segment */
100 int vex_l
; /* vex vector length */
101 int vex_v
; /* vex vvvv register, without 1's compliment. */
102 int ss32
; /* 32 bit stack segment */
103 CCOp cc_op
; /* current CC operation */
105 int addseg
; /* non zero if either DS/ES/SS have a non zero base */
106 int f_st
; /* currently unused */
107 int vm86
; /* vm86 mode */
110 int tf
; /* TF cpu flag */
111 int singlestep_enabled
; /* "hardware" single step enabled */
112 int jmp_opt
; /* use direct block chaining for direct jumps */
113 int repz_opt
; /* optimize jumps within repz instructions */
114 int mem_index
; /* select memory access functions */
115 uint64_t flags
; /* all execution flags */
116 struct TranslationBlock
*tb
;
117 int popl_esp_hack
; /* for correct popl with esp base handling */
118 int rip_offset
; /* only used in x86_64, but left for simplicity */
120 int cpuid_ext_features
;
121 int cpuid_ext2_features
;
122 int cpuid_ext3_features
;
123 int cpuid_7_0_ebx_features
;
126 static void gen_eob(DisasContext
*s
);
127 static void gen_jmp(DisasContext
*s
, target_ulong eip
);
128 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
);
129 static void gen_op(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
);
131 /* i386 arith/logic operations */
151 OP_SHL1
, /* undocumented */
167 /* I386 int registers */
168 OR_EAX
, /* MUST be even numbered */
177 OR_TMP0
= 16, /* temporary operand register */
179 OR_A0
, /* temporary register used when doing address evaluation */
189 /* Bit set if the global variable is live after setting CC_OP to X. */
190 static const uint8_t cc_op_live
[CC_OP_NB
] = {
191 [CC_OP_DYNAMIC
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
192 [CC_OP_EFLAGS
] = USES_CC_SRC
,
193 [CC_OP_MULB
... CC_OP_MULQ
] = USES_CC_DST
| USES_CC_SRC
,
194 [CC_OP_ADDB
... CC_OP_ADDQ
] = USES_CC_DST
| USES_CC_SRC
,
195 [CC_OP_ADCB
... CC_OP_ADCQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
196 [CC_OP_SUBB
... CC_OP_SUBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRCT
,
197 [CC_OP_SBBB
... CC_OP_SBBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
198 [CC_OP_LOGICB
... CC_OP_LOGICQ
] = USES_CC_DST
,
199 [CC_OP_INCB
... CC_OP_INCQ
] = USES_CC_DST
| USES_CC_SRC
,
200 [CC_OP_DECB
... CC_OP_DECQ
] = USES_CC_DST
| USES_CC_SRC
,
201 [CC_OP_SHLB
... CC_OP_SHLQ
] = USES_CC_DST
| USES_CC_SRC
,
202 [CC_OP_SARB
... CC_OP_SARQ
] = USES_CC_DST
| USES_CC_SRC
,
203 [CC_OP_BMILGB
... CC_OP_BMILGQ
] = USES_CC_DST
| USES_CC_SRC
,
204 [CC_OP_ADCX
] = USES_CC_DST
| USES_CC_SRC
,
205 [CC_OP_ADOX
] = USES_CC_SRC
| USES_CC_SRC2
,
206 [CC_OP_ADCOX
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
210 static void set_cc_op(DisasContext
*s
, CCOp op
)
214 if (s
->cc_op
== op
) {
218 /* Discard CC computation that will no longer be used. */
219 dead
= cc_op_live
[s
->cc_op
] & ~cc_op_live
[op
];
220 if (dead
& USES_CC_DST
) {
221 tcg_gen_discard_tl(cpu_cc_dst
);
223 if (dead
& USES_CC_SRC
) {
224 tcg_gen_discard_tl(cpu_cc_src
);
226 if (dead
& USES_CC_SRC2
) {
227 tcg_gen_discard_tl(cpu_cc_src2
);
229 if (dead
& USES_CC_SRCT
) {
230 tcg_gen_discard_tl(cpu_cc_srcT
);
233 if (op
== CC_OP_DYNAMIC
) {
234 /* The DYNAMIC setting is translator only, and should never be
235 stored. Thus we always consider it clean. */
236 s
->cc_op_dirty
= false;
238 /* Discard any computed CC_OP value (see shifts). */
239 if (s
->cc_op
== CC_OP_DYNAMIC
) {
240 tcg_gen_discard_i32(cpu_cc_op
);
242 s
->cc_op_dirty
= true;
247 static void gen_update_cc_op(DisasContext
*s
)
249 if (s
->cc_op_dirty
) {
250 tcg_gen_movi_i32(cpu_cc_op
, s
->cc_op
);
251 s
->cc_op_dirty
= false;
257 #define NB_OP_SIZES 4
259 #else /* !TARGET_X86_64 */
261 #define NB_OP_SIZES 3
263 #endif /* !TARGET_X86_64 */
265 #if defined(HOST_WORDS_BIGENDIAN)
266 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
267 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
268 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
269 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
270 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
272 #define REG_B_OFFSET 0
273 #define REG_H_OFFSET 1
274 #define REG_W_OFFSET 0
275 #define REG_L_OFFSET 0
276 #define REG_LH_OFFSET 4
279 /* In instruction encodings for byte register accesses the
280 * register number usually indicates "low 8 bits of register N";
281 * however there are some special cases where N 4..7 indicates
282 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
283 * true for this special case, false otherwise.
285 static inline bool byte_reg_is_xH(int reg
)
291 if (reg
>= 8 || x86_64_hregs
) {
298 /* Select the size of a push/pop operation. */
299 static inline TCGMemOp
mo_pushpop(DisasContext
*s
, TCGMemOp ot
)
302 return ot
== MO_16
? MO_16
: MO_64
;
308 /* Select the size of the stack pointer. */
309 static inline TCGMemOp
mo_stacksize(DisasContext
*s
)
311 return CODE64(s
) ? MO_64
: s
->ss32
? MO_32
: MO_16
;
314 /* Select only size 64 else 32. Used for SSE operand sizes. */
315 static inline TCGMemOp
mo_64_32(TCGMemOp ot
)
318 return ot
== MO_64
? MO_64
: MO_32
;
324 /* Select size 8 if lsb of B is clear, else OT. Used for decoding
325 byte vs word opcodes. */
326 static inline TCGMemOp
mo_b_d(int b
, TCGMemOp ot
)
328 return b
& 1 ? ot
: MO_8
;
331 /* Select size 8 if lsb of B is clear, else OT capped at 32.
332 Used for decoding operand size of port opcodes. */
333 static inline TCGMemOp
mo_b_d32(int b
, TCGMemOp ot
)
335 return b
& 1 ? (ot
== MO_16
? MO_16
: MO_32
) : MO_8
;
338 static void gen_op_mov_reg_v(TCGMemOp ot
, int reg
, TCGv t0
)
342 if (!byte_reg_is_xH(reg
)) {
343 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 8);
345 tcg_gen_deposit_tl(cpu_regs
[reg
- 4], cpu_regs
[reg
- 4], t0
, 8, 8);
349 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 16);
352 /* For x86_64, this sets the higher half of register to zero.
353 For i386, this is equivalent to a mov. */
354 tcg_gen_ext32u_tl(cpu_regs
[reg
], t0
);
358 tcg_gen_mov_tl(cpu_regs
[reg
], t0
);
366 static inline void gen_op_mov_v_reg(TCGMemOp ot
, TCGv t0
, int reg
)
368 if (ot
== MO_8
&& byte_reg_is_xH(reg
)) {
369 tcg_gen_shri_tl(t0
, cpu_regs
[reg
- 4], 8);
370 tcg_gen_ext8u_tl(t0
, t0
);
372 tcg_gen_mov_tl(t0
, cpu_regs
[reg
]);
376 static void gen_add_A0_im(DisasContext
*s
, int val
)
378 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, val
);
380 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
384 static inline void gen_op_jmp_v(TCGv dest
)
386 tcg_gen_st_tl(dest
, cpu_env
, offsetof(CPUX86State
, eip
));
389 static inline void gen_op_add_reg_im(TCGMemOp size
, int reg
, int32_t val
)
391 tcg_gen_addi_tl(cpu_tmp0
, cpu_regs
[reg
], val
);
392 gen_op_mov_reg_v(size
, reg
, cpu_tmp0
);
395 static inline void gen_op_add_reg_T0(TCGMemOp size
, int reg
)
397 tcg_gen_add_tl(cpu_tmp0
, cpu_regs
[reg
], cpu_T0
);
398 gen_op_mov_reg_v(size
, reg
, cpu_tmp0
);
401 static inline void gen_op_ld_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
403 tcg_gen_qemu_ld_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
406 static inline void gen_op_st_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
408 tcg_gen_qemu_st_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
411 static inline void gen_op_st_rm_T0_A0(DisasContext
*s
, int idx
, int d
)
414 gen_op_st_v(s
, idx
, cpu_T0
, cpu_A0
);
416 gen_op_mov_reg_v(idx
, d
, cpu_T0
);
420 static inline void gen_jmp_im(target_ulong pc
)
422 tcg_gen_movi_tl(cpu_tmp0
, pc
);
423 gen_op_jmp_v(cpu_tmp0
);
426 /* Compute SEG:REG into A0. SEG is selected from the override segment
427 (OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to
428 indicate no override. */
429 static void gen_lea_v_seg(DisasContext
*s
, TCGMemOp aflag
, TCGv a0
,
430 int def_seg
, int ovr_seg
)
436 tcg_gen_mov_tl(cpu_A0
, a0
);
447 tcg_gen_ext32u_tl(cpu_A0
, a0
);
457 tcg_gen_ext16u_tl(cpu_A0
, a0
);
458 /* ADDSEG will only be false in 16-bit mode for LEA. */
469 TCGv seg
= cpu_seg_base
[ovr_seg
];
471 if (aflag
== MO_64
) {
472 tcg_gen_add_tl(cpu_A0
, a0
, seg
);
473 } else if (CODE64(s
)) {
474 tcg_gen_ext32u_tl(cpu_A0
, a0
);
475 tcg_gen_add_tl(cpu_A0
, cpu_A0
, seg
);
477 tcg_gen_add_tl(cpu_A0
, a0
, seg
);
478 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
483 static inline void gen_string_movl_A0_ESI(DisasContext
*s
)
485 gen_lea_v_seg(s
, s
->aflag
, cpu_regs
[R_ESI
], R_DS
, s
->override
);
488 static inline void gen_string_movl_A0_EDI(DisasContext
*s
)
490 gen_lea_v_seg(s
, s
->aflag
, cpu_regs
[R_EDI
], R_ES
, -1);
493 static inline void gen_op_movl_T0_Dshift(TCGMemOp ot
)
495 tcg_gen_ld32s_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, df
));
496 tcg_gen_shli_tl(cpu_T0
, cpu_T0
, ot
);
499 static TCGv
gen_ext_tl(TCGv dst
, TCGv src
, TCGMemOp size
, bool sign
)
504 tcg_gen_ext8s_tl(dst
, src
);
506 tcg_gen_ext8u_tl(dst
, src
);
511 tcg_gen_ext16s_tl(dst
, src
);
513 tcg_gen_ext16u_tl(dst
, src
);
519 tcg_gen_ext32s_tl(dst
, src
);
521 tcg_gen_ext32u_tl(dst
, src
);
530 static void gen_extu(TCGMemOp ot
, TCGv reg
)
532 gen_ext_tl(reg
, reg
, ot
, false);
535 static void gen_exts(TCGMemOp ot
, TCGv reg
)
537 gen_ext_tl(reg
, reg
, ot
, true);
540 static inline void gen_op_jnz_ecx(TCGMemOp size
, TCGLabel
*label1
)
542 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[R_ECX
]);
543 gen_extu(size
, cpu_tmp0
);
544 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_tmp0
, 0, label1
);
547 static inline void gen_op_jz_ecx(TCGMemOp size
, TCGLabel
*label1
)
549 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[R_ECX
]);
550 gen_extu(size
, cpu_tmp0
);
551 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
554 static void gen_helper_in_func(TCGMemOp ot
, TCGv v
, TCGv_i32 n
)
558 gen_helper_inb(v
, cpu_env
, n
);
561 gen_helper_inw(v
, cpu_env
, n
);
564 gen_helper_inl(v
, cpu_env
, n
);
571 static void gen_helper_out_func(TCGMemOp ot
, TCGv_i32 v
, TCGv_i32 n
)
575 gen_helper_outb(cpu_env
, v
, n
);
578 gen_helper_outw(cpu_env
, v
, n
);
581 gen_helper_outl(cpu_env
, v
, n
);
588 static void gen_check_io(DisasContext
*s
, TCGMemOp ot
, target_ulong cur_eip
,
591 target_ulong next_eip
;
593 if (s
->pe
&& (s
->cpl
> s
->iopl
|| s
->vm86
)) {
594 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
597 gen_helper_check_iob(cpu_env
, cpu_tmp2_i32
);
600 gen_helper_check_iow(cpu_env
, cpu_tmp2_i32
);
603 gen_helper_check_iol(cpu_env
, cpu_tmp2_i32
);
609 if(s
->flags
& HF_SVMI_MASK
) {
612 svm_flags
|= (1 << (4 + ot
));
613 next_eip
= s
->pc
- s
->cs_base
;
614 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
615 gen_helper_svm_check_io(cpu_env
, cpu_tmp2_i32
,
616 tcg_const_i32(svm_flags
),
617 tcg_const_i32(next_eip
- cur_eip
));
621 static inline void gen_movs(DisasContext
*s
, TCGMemOp ot
)
623 gen_string_movl_A0_ESI(s
);
624 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
625 gen_string_movl_A0_EDI(s
);
626 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
627 gen_op_movl_T0_Dshift(ot
);
628 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
629 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
632 static void gen_op_update1_cc(void)
634 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
637 static void gen_op_update2_cc(void)
639 tcg_gen_mov_tl(cpu_cc_src
, cpu_T1
);
640 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
643 static void gen_op_update3_cc(TCGv reg
)
645 tcg_gen_mov_tl(cpu_cc_src2
, reg
);
646 tcg_gen_mov_tl(cpu_cc_src
, cpu_T1
);
647 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
650 static inline void gen_op_testl_T0_T1_cc(void)
652 tcg_gen_and_tl(cpu_cc_dst
, cpu_T0
, cpu_T1
);
655 static void gen_op_update_neg_cc(void)
657 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
658 tcg_gen_neg_tl(cpu_cc_src
, cpu_T0
);
659 tcg_gen_movi_tl(cpu_cc_srcT
, 0);
662 /* compute all eflags to cc_src */
663 static void gen_compute_eflags(DisasContext
*s
)
665 TCGv zero
, dst
, src1
, src2
;
668 if (s
->cc_op
== CC_OP_EFLAGS
) {
671 if (s
->cc_op
== CC_OP_CLR
) {
672 tcg_gen_movi_tl(cpu_cc_src
, CC_Z
| CC_P
);
673 set_cc_op(s
, CC_OP_EFLAGS
);
682 /* Take care to not read values that are not live. */
683 live
= cc_op_live
[s
->cc_op
] & ~USES_CC_SRCT
;
684 dead
= live
^ (USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
);
686 zero
= tcg_const_tl(0);
687 if (dead
& USES_CC_DST
) {
690 if (dead
& USES_CC_SRC
) {
693 if (dead
& USES_CC_SRC2
) {
699 gen_helper_cc_compute_all(cpu_cc_src
, dst
, src1
, src2
, cpu_cc_op
);
700 set_cc_op(s
, CC_OP_EFLAGS
);
707 typedef struct CCPrepare
{
717 /* compute eflags.C to reg */
718 static CCPrepare
gen_prepare_eflags_c(DisasContext
*s
, TCGv reg
)
724 case CC_OP_SUBB
... CC_OP_SUBQ
:
725 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
726 size
= s
->cc_op
- CC_OP_SUBB
;
727 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
728 /* If no temporary was used, be careful not to alias t1 and t0. */
729 t0
= TCGV_EQUAL(t1
, cpu_cc_src
) ? cpu_tmp0
: reg
;
730 tcg_gen_mov_tl(t0
, cpu_cc_srcT
);
734 case CC_OP_ADDB
... CC_OP_ADDQ
:
735 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
736 size
= s
->cc_op
- CC_OP_ADDB
;
737 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
738 t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
740 return (CCPrepare
) { .cond
= TCG_COND_LTU
, .reg
= t0
,
741 .reg2
= t1
, .mask
= -1, .use_reg2
= true };
743 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
745 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
747 case CC_OP_INCB
... CC_OP_INCQ
:
748 case CC_OP_DECB
... CC_OP_DECQ
:
749 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
750 .mask
= -1, .no_setcond
= true };
752 case CC_OP_SHLB
... CC_OP_SHLQ
:
753 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
754 size
= s
->cc_op
- CC_OP_SHLB
;
755 shift
= (8 << size
) - 1;
756 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
757 .mask
= (target_ulong
)1 << shift
};
759 case CC_OP_MULB
... CC_OP_MULQ
:
760 return (CCPrepare
) { .cond
= TCG_COND_NE
,
761 .reg
= cpu_cc_src
, .mask
= -1 };
763 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
764 size
= s
->cc_op
- CC_OP_BMILGB
;
765 t0
= gen_ext_tl(reg
, cpu_cc_src
, size
, false);
766 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
770 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_dst
,
771 .mask
= -1, .no_setcond
= true };
774 case CC_OP_SARB
... CC_OP_SARQ
:
776 return (CCPrepare
) { .cond
= TCG_COND_NE
,
777 .reg
= cpu_cc_src
, .mask
= CC_C
};
780 /* The need to compute only C from CC_OP_DYNAMIC is important
781 in efficiently implementing e.g. INC at the start of a TB. */
783 gen_helper_cc_compute_c(reg
, cpu_cc_dst
, cpu_cc_src
,
784 cpu_cc_src2
, cpu_cc_op
);
785 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
786 .mask
= -1, .no_setcond
= true };
790 /* compute eflags.P to reg */
791 static CCPrepare
gen_prepare_eflags_p(DisasContext
*s
, TCGv reg
)
793 gen_compute_eflags(s
);
794 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
798 /* compute eflags.S to reg */
799 static CCPrepare
gen_prepare_eflags_s(DisasContext
*s
, TCGv reg
)
803 gen_compute_eflags(s
);
809 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
812 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
815 TCGMemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
816 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, true);
817 return (CCPrepare
) { .cond
= TCG_COND_LT
, .reg
= t0
, .mask
= -1 };
822 /* compute eflags.O to reg */
823 static CCPrepare
gen_prepare_eflags_o(DisasContext
*s
, TCGv reg
)
828 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src2
,
829 .mask
= -1, .no_setcond
= true };
831 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
833 gen_compute_eflags(s
);
834 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
839 /* compute eflags.Z to reg */
840 static CCPrepare
gen_prepare_eflags_z(DisasContext
*s
, TCGv reg
)
844 gen_compute_eflags(s
);
850 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
853 return (CCPrepare
) { .cond
= TCG_COND_ALWAYS
, .mask
= -1 };
856 TCGMemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
857 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
858 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
863 /* perform a conditional store into register 'reg' according to jump opcode
864 value 'b'. In the fast case, T0 is guaranted not to be used. */
865 static CCPrepare
gen_prepare_cc(DisasContext
*s
, int b
, TCGv reg
)
867 int inv
, jcc_op
, cond
;
873 jcc_op
= (b
>> 1) & 7;
876 case CC_OP_SUBB
... CC_OP_SUBQ
:
877 /* We optimize relational operators for the cmp/jcc case. */
878 size
= s
->cc_op
- CC_OP_SUBB
;
881 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
882 gen_extu(size
, cpu_tmp4
);
883 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
884 cc
= (CCPrepare
) { .cond
= TCG_COND_LEU
, .reg
= cpu_tmp4
,
885 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
894 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
895 gen_exts(size
, cpu_tmp4
);
896 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, true);
897 cc
= (CCPrepare
) { .cond
= cond
, .reg
= cpu_tmp4
,
898 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
908 /* This actually generates good code for JC, JZ and JS. */
911 cc
= gen_prepare_eflags_o(s
, reg
);
914 cc
= gen_prepare_eflags_c(s
, reg
);
917 cc
= gen_prepare_eflags_z(s
, reg
);
920 gen_compute_eflags(s
);
921 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
922 .mask
= CC_Z
| CC_C
};
925 cc
= gen_prepare_eflags_s(s
, reg
);
928 cc
= gen_prepare_eflags_p(s
, reg
);
931 gen_compute_eflags(s
);
932 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
935 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
936 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
937 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
942 gen_compute_eflags(s
);
943 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
946 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
947 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
948 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
949 .mask
= CC_S
| CC_Z
};
956 cc
.cond
= tcg_invert_cond(cc
.cond
);
961 static void gen_setcc1(DisasContext
*s
, int b
, TCGv reg
)
963 CCPrepare cc
= gen_prepare_cc(s
, b
, reg
);
966 if (cc
.cond
== TCG_COND_EQ
) {
967 tcg_gen_xori_tl(reg
, cc
.reg
, 1);
969 tcg_gen_mov_tl(reg
, cc
.reg
);
974 if (cc
.cond
== TCG_COND_NE
&& !cc
.use_reg2
&& cc
.imm
== 0 &&
975 cc
.mask
!= 0 && (cc
.mask
& (cc
.mask
- 1)) == 0) {
976 tcg_gen_shri_tl(reg
, cc
.reg
, ctztl(cc
.mask
));
977 tcg_gen_andi_tl(reg
, reg
, 1);
981 tcg_gen_andi_tl(reg
, cc
.reg
, cc
.mask
);
985 tcg_gen_setcond_tl(cc
.cond
, reg
, cc
.reg
, cc
.reg2
);
987 tcg_gen_setcondi_tl(cc
.cond
, reg
, cc
.reg
, cc
.imm
);
991 static inline void gen_compute_eflags_c(DisasContext
*s
, TCGv reg
)
993 gen_setcc1(s
, JCC_B
<< 1, reg
);
996 /* generate a conditional jump to label 'l1' according to jump opcode
997 value 'b'. In the fast case, T0 is guaranted not to be used. */
998 static inline void gen_jcc1_noeob(DisasContext
*s
, int b
, TCGLabel
*l1
)
1000 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T0
);
1002 if (cc
.mask
!= -1) {
1003 tcg_gen_andi_tl(cpu_T0
, cc
.reg
, cc
.mask
);
1007 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1009 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1013 /* Generate a conditional jump to label 'l1' according to jump opcode
1014 value 'b'. In the fast case, T0 is guaranted not to be used.
1015 A translation block must end soon. */
1016 static inline void gen_jcc1(DisasContext
*s
, int b
, TCGLabel
*l1
)
1018 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T0
);
1020 gen_update_cc_op(s
);
1021 if (cc
.mask
!= -1) {
1022 tcg_gen_andi_tl(cpu_T0
, cc
.reg
, cc
.mask
);
1025 set_cc_op(s
, CC_OP_DYNAMIC
);
1027 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1029 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1033 /* XXX: does not work with gdbstub "ice" single step - not a
1035 static TCGLabel
*gen_jz_ecx_string(DisasContext
*s
, target_ulong next_eip
)
1037 TCGLabel
*l1
= gen_new_label();
1038 TCGLabel
*l2
= gen_new_label();
1039 gen_op_jnz_ecx(s
->aflag
, l1
);
1041 gen_jmp_tb(s
, next_eip
, 1);
1046 static inline void gen_stos(DisasContext
*s
, TCGMemOp ot
)
1048 gen_op_mov_v_reg(MO_32
, cpu_T0
, R_EAX
);
1049 gen_string_movl_A0_EDI(s
);
1050 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
1051 gen_op_movl_T0_Dshift(ot
);
1052 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1055 static inline void gen_lods(DisasContext
*s
, TCGMemOp ot
)
1057 gen_string_movl_A0_ESI(s
);
1058 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1059 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T0
);
1060 gen_op_movl_T0_Dshift(ot
);
1061 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1064 static inline void gen_scas(DisasContext
*s
, TCGMemOp ot
)
1066 gen_string_movl_A0_EDI(s
);
1067 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
1068 gen_op(s
, OP_CMPL
, ot
, R_EAX
);
1069 gen_op_movl_T0_Dshift(ot
);
1070 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1073 static inline void gen_cmps(DisasContext
*s
, TCGMemOp ot
)
1075 gen_string_movl_A0_EDI(s
);
1076 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
1077 gen_string_movl_A0_ESI(s
);
1078 gen_op(s
, OP_CMPL
, ot
, OR_TMP0
);
1079 gen_op_movl_T0_Dshift(ot
);
1080 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1081 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1084 static void gen_bpt_io(DisasContext
*s
, TCGv_i32 t_port
, int ot
)
1086 if (s
->flags
& HF_IOBPT_MASK
) {
1087 TCGv_i32 t_size
= tcg_const_i32(1 << ot
);
1088 TCGv t_next
= tcg_const_tl(s
->pc
- s
->cs_base
);
1090 gen_helper_bpt_io(cpu_env
, t_port
, t_size
, t_next
);
1091 tcg_temp_free_i32(t_size
);
1092 tcg_temp_free(t_next
);
1097 static inline void gen_ins(DisasContext
*s
, TCGMemOp ot
)
1099 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1102 gen_string_movl_A0_EDI(s
);
1103 /* Note: we must do this dummy write first to be restartable in
1104 case of page fault. */
1105 tcg_gen_movi_tl(cpu_T0
, 0);
1106 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
1107 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_EDX
]);
1108 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1109 gen_helper_in_func(ot
, cpu_T0
, cpu_tmp2_i32
);
1110 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
1111 gen_op_movl_T0_Dshift(ot
);
1112 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1113 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
1114 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1119 static inline void gen_outs(DisasContext
*s
, TCGMemOp ot
)
1121 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1124 gen_string_movl_A0_ESI(s
);
1125 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1127 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_EDX
]);
1128 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1129 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T0
);
1130 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1131 gen_op_movl_T0_Dshift(ot
);
1132 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1133 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
1134 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1139 /* same method as Valgrind : we generate jumps to current or next
1141 #define GEN_REPZ(op) \
1142 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1143 target_ulong cur_eip, target_ulong next_eip) \
1146 gen_update_cc_op(s); \
1147 l2 = gen_jz_ecx_string(s, next_eip); \
1148 gen_ ## op(s, ot); \
1149 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1150 /* a loop would cause two single step exceptions if ECX = 1 \
1151 before rep string_insn */ \
1153 gen_op_jz_ecx(s->aflag, l2); \
1154 gen_jmp(s, cur_eip); \
1157 #define GEN_REPZ2(op) \
1158 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1159 target_ulong cur_eip, \
1160 target_ulong next_eip, \
1164 gen_update_cc_op(s); \
1165 l2 = gen_jz_ecx_string(s, next_eip); \
1166 gen_ ## op(s, ot); \
1167 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1168 gen_update_cc_op(s); \
1169 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
1171 gen_op_jz_ecx(s->aflag, l2); \
1172 gen_jmp(s, cur_eip); \
1183 static void gen_helper_fp_arith_ST0_FT0(int op
)
1187 gen_helper_fadd_ST0_FT0(cpu_env
);
1190 gen_helper_fmul_ST0_FT0(cpu_env
);
1193 gen_helper_fcom_ST0_FT0(cpu_env
);
1196 gen_helper_fcom_ST0_FT0(cpu_env
);
1199 gen_helper_fsub_ST0_FT0(cpu_env
);
1202 gen_helper_fsubr_ST0_FT0(cpu_env
);
1205 gen_helper_fdiv_ST0_FT0(cpu_env
);
1208 gen_helper_fdivr_ST0_FT0(cpu_env
);
1213 /* NOTE the exception in "r" op ordering */
1214 static void gen_helper_fp_arith_STN_ST0(int op
, int opreg
)
1216 TCGv_i32 tmp
= tcg_const_i32(opreg
);
1219 gen_helper_fadd_STN_ST0(cpu_env
, tmp
);
1222 gen_helper_fmul_STN_ST0(cpu_env
, tmp
);
1225 gen_helper_fsubr_STN_ST0(cpu_env
, tmp
);
1228 gen_helper_fsub_STN_ST0(cpu_env
, tmp
);
1231 gen_helper_fdivr_STN_ST0(cpu_env
, tmp
);
1234 gen_helper_fdiv_STN_ST0(cpu_env
, tmp
);
1239 /* if d == OR_TMP0, it means memory operand (address in A0) */
1240 static void gen_op(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
)
1243 gen_op_mov_v_reg(ot
, cpu_T0
, d
);
1245 gen_op_ld_v(s1
, ot
, cpu_T0
, cpu_A0
);
1249 gen_compute_eflags_c(s1
, cpu_tmp4
);
1250 tcg_gen_add_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1251 tcg_gen_add_tl(cpu_T0
, cpu_T0
, cpu_tmp4
);
1252 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1253 gen_op_update3_cc(cpu_tmp4
);
1254 set_cc_op(s1
, CC_OP_ADCB
+ ot
);
1257 gen_compute_eflags_c(s1
, cpu_tmp4
);
1258 tcg_gen_sub_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1259 tcg_gen_sub_tl(cpu_T0
, cpu_T0
, cpu_tmp4
);
1260 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1261 gen_op_update3_cc(cpu_tmp4
);
1262 set_cc_op(s1
, CC_OP_SBBB
+ ot
);
1265 tcg_gen_add_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1266 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1267 gen_op_update2_cc();
1268 set_cc_op(s1
, CC_OP_ADDB
+ ot
);
1271 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T0
);
1272 tcg_gen_sub_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1273 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1274 gen_op_update2_cc();
1275 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1279 tcg_gen_and_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1280 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1281 gen_op_update1_cc();
1282 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1285 tcg_gen_or_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1286 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1287 gen_op_update1_cc();
1288 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1291 tcg_gen_xor_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1292 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1293 gen_op_update1_cc();
1294 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1297 tcg_gen_mov_tl(cpu_cc_src
, cpu_T1
);
1298 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T0
);
1299 tcg_gen_sub_tl(cpu_cc_dst
, cpu_T0
, cpu_T1
);
1300 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1305 /* if d == OR_TMP0, it means memory operand (address in A0) */
1306 static void gen_inc(DisasContext
*s1
, TCGMemOp ot
, int d
, int c
)
1309 gen_op_mov_v_reg(ot
, cpu_T0
, d
);
1311 gen_op_ld_v(s1
, ot
, cpu_T0
, cpu_A0
);
1313 gen_compute_eflags_c(s1
, cpu_cc_src
);
1315 tcg_gen_addi_tl(cpu_T0
, cpu_T0
, 1);
1316 set_cc_op(s1
, CC_OP_INCB
+ ot
);
1318 tcg_gen_addi_tl(cpu_T0
, cpu_T0
, -1);
1319 set_cc_op(s1
, CC_OP_DECB
+ ot
);
1321 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1322 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
1325 static void gen_shift_flags(DisasContext
*s
, TCGMemOp ot
, TCGv result
,
1326 TCGv shm1
, TCGv count
, bool is_right
)
1328 TCGv_i32 z32
, s32
, oldop
;
1331 /* Store the results into the CC variables. If we know that the
1332 variable must be dead, store unconditionally. Otherwise we'll
1333 need to not disrupt the current contents. */
1334 z_tl
= tcg_const_tl(0);
1335 if (cc_op_live
[s
->cc_op
] & USES_CC_DST
) {
1336 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_dst
, count
, z_tl
,
1337 result
, cpu_cc_dst
);
1339 tcg_gen_mov_tl(cpu_cc_dst
, result
);
1341 if (cc_op_live
[s
->cc_op
] & USES_CC_SRC
) {
1342 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_src
, count
, z_tl
,
1345 tcg_gen_mov_tl(cpu_cc_src
, shm1
);
1347 tcg_temp_free(z_tl
);
1349 /* Get the two potential CC_OP values into temporaries. */
1350 tcg_gen_movi_i32(cpu_tmp2_i32
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1351 if (s
->cc_op
== CC_OP_DYNAMIC
) {
1354 tcg_gen_movi_i32(cpu_tmp3_i32
, s
->cc_op
);
1355 oldop
= cpu_tmp3_i32
;
1358 /* Conditionally store the CC_OP value. */
1359 z32
= tcg_const_i32(0);
1360 s32
= tcg_temp_new_i32();
1361 tcg_gen_trunc_tl_i32(s32
, count
);
1362 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, s32
, z32
, cpu_tmp2_i32
, oldop
);
1363 tcg_temp_free_i32(z32
);
1364 tcg_temp_free_i32(s32
);
1366 /* The CC_OP value is no longer predictable. */
1367 set_cc_op(s
, CC_OP_DYNAMIC
);
1370 static void gen_shift_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1371 int is_right
, int is_arith
)
1373 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1376 if (op1
== OR_TMP0
) {
1377 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1379 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1382 tcg_gen_andi_tl(cpu_T1
, cpu_T1
, mask
);
1383 tcg_gen_subi_tl(cpu_tmp0
, cpu_T1
, 1);
1387 gen_exts(ot
, cpu_T0
);
1388 tcg_gen_sar_tl(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1389 tcg_gen_sar_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1391 gen_extu(ot
, cpu_T0
);
1392 tcg_gen_shr_tl(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1393 tcg_gen_shr_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1396 tcg_gen_shl_tl(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1397 tcg_gen_shl_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1401 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1403 gen_shift_flags(s
, ot
, cpu_T0
, cpu_tmp0
, cpu_T1
, is_right
);
1406 static void gen_shift_rm_im(DisasContext
*s
, TCGMemOp ot
, int op1
, int op2
,
1407 int is_right
, int is_arith
)
1409 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1413 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1415 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1421 gen_exts(ot
, cpu_T0
);
1422 tcg_gen_sari_tl(cpu_tmp4
, cpu_T0
, op2
- 1);
1423 tcg_gen_sari_tl(cpu_T0
, cpu_T0
, op2
);
1425 gen_extu(ot
, cpu_T0
);
1426 tcg_gen_shri_tl(cpu_tmp4
, cpu_T0
, op2
- 1);
1427 tcg_gen_shri_tl(cpu_T0
, cpu_T0
, op2
);
1430 tcg_gen_shli_tl(cpu_tmp4
, cpu_T0
, op2
- 1);
1431 tcg_gen_shli_tl(cpu_T0
, cpu_T0
, op2
);
1436 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1438 /* update eflags if non zero shift */
1440 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
1441 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
1442 set_cc_op(s
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1446 static void gen_rot_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
, int is_right
)
1448 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1452 if (op1
== OR_TMP0
) {
1453 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1455 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1458 tcg_gen_andi_tl(cpu_T1
, cpu_T1
, mask
);
1462 /* Replicate the 8-bit input so that a 32-bit rotate works. */
1463 tcg_gen_ext8u_tl(cpu_T0
, cpu_T0
);
1464 tcg_gen_muli_tl(cpu_T0
, cpu_T0
, 0x01010101);
1467 /* Replicate the 16-bit input so that a 32-bit rotate works. */
1468 tcg_gen_deposit_tl(cpu_T0
, cpu_T0
, cpu_T0
, 16, 16);
1471 #ifdef TARGET_X86_64
1473 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
1474 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T1
);
1476 tcg_gen_rotr_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1478 tcg_gen_rotl_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1480 tcg_gen_extu_i32_tl(cpu_T0
, cpu_tmp2_i32
);
1485 tcg_gen_rotr_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1487 tcg_gen_rotl_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1493 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1495 /* We'll need the flags computed into CC_SRC. */
1496 gen_compute_eflags(s
);
1498 /* The value that was "rotated out" is now present at the other end
1499 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1500 since we've computed the flags into CC_SRC, these variables are
1503 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T0
, mask
- 1);
1504 tcg_gen_shri_tl(cpu_cc_dst
, cpu_T0
, mask
);
1505 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1507 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T0
, mask
);
1508 tcg_gen_andi_tl(cpu_cc_dst
, cpu_T0
, 1);
1510 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1511 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1513 /* Now conditionally store the new CC_OP value. If the shift count
1514 is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1515 Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1516 exactly as we computed above. */
1517 t0
= tcg_const_i32(0);
1518 t1
= tcg_temp_new_i32();
1519 tcg_gen_trunc_tl_i32(t1
, cpu_T1
);
1520 tcg_gen_movi_i32(cpu_tmp2_i32
, CC_OP_ADCOX
);
1521 tcg_gen_movi_i32(cpu_tmp3_i32
, CC_OP_EFLAGS
);
1522 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, t1
, t0
,
1523 cpu_tmp2_i32
, cpu_tmp3_i32
);
1524 tcg_temp_free_i32(t0
);
1525 tcg_temp_free_i32(t1
);
1527 /* The CC_OP value is no longer predictable. */
1528 set_cc_op(s
, CC_OP_DYNAMIC
);
1531 static void gen_rot_rm_im(DisasContext
*s
, TCGMemOp ot
, int op1
, int op2
,
1534 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1538 if (op1
== OR_TMP0
) {
1539 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1541 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1547 #ifdef TARGET_X86_64
1549 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
1551 tcg_gen_rotri_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, op2
);
1553 tcg_gen_rotli_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, op2
);
1555 tcg_gen_extu_i32_tl(cpu_T0
, cpu_tmp2_i32
);
1560 tcg_gen_rotri_tl(cpu_T0
, cpu_T0
, op2
);
1562 tcg_gen_rotli_tl(cpu_T0
, cpu_T0
, op2
);
1573 shift
= mask
+ 1 - shift
;
1575 gen_extu(ot
, cpu_T0
);
1576 tcg_gen_shli_tl(cpu_tmp0
, cpu_T0
, shift
);
1577 tcg_gen_shri_tl(cpu_T0
, cpu_T0
, mask
+ 1 - shift
);
1578 tcg_gen_or_tl(cpu_T0
, cpu_T0
, cpu_tmp0
);
1584 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1587 /* Compute the flags into CC_SRC. */
1588 gen_compute_eflags(s
);
1590 /* The value that was "rotated out" is now present at the other end
1591 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1592 since we've computed the flags into CC_SRC, these variables are
1595 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T0
, mask
- 1);
1596 tcg_gen_shri_tl(cpu_cc_dst
, cpu_T0
, mask
);
1597 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1599 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T0
, mask
);
1600 tcg_gen_andi_tl(cpu_cc_dst
, cpu_T0
, 1);
1602 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1603 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1604 set_cc_op(s
, CC_OP_ADCOX
);
1608 /* XXX: add faster immediate = 1 case */
1609 static void gen_rotc_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1612 gen_compute_eflags(s
);
1613 assert(s
->cc_op
== CC_OP_EFLAGS
);
1617 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1619 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1624 gen_helper_rcrb(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1627 gen_helper_rcrw(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1630 gen_helper_rcrl(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1632 #ifdef TARGET_X86_64
1634 gen_helper_rcrq(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1643 gen_helper_rclb(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1646 gen_helper_rclw(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1649 gen_helper_rcll(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1651 #ifdef TARGET_X86_64
1653 gen_helper_rclq(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1661 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1664 /* XXX: add faster immediate case */
1665 static void gen_shiftd_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1666 bool is_right
, TCGv count_in
)
1668 target_ulong mask
= (ot
== MO_64
? 63 : 31);
1672 if (op1
== OR_TMP0
) {
1673 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1675 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1678 count
= tcg_temp_new();
1679 tcg_gen_andi_tl(count
, count_in
, mask
);
1683 /* Note: we implement the Intel behaviour for shift count > 16.
1684 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A
1685 portion by constructing it as a 32-bit value. */
1687 tcg_gen_deposit_tl(cpu_tmp0
, cpu_T0
, cpu_T1
, 16, 16);
1688 tcg_gen_mov_tl(cpu_T1
, cpu_T0
);
1689 tcg_gen_mov_tl(cpu_T0
, cpu_tmp0
);
1691 tcg_gen_deposit_tl(cpu_T1
, cpu_T0
, cpu_T1
, 16, 16);
1694 #ifdef TARGET_X86_64
1696 /* Concatenate the two 32-bit values and use a 64-bit shift. */
1697 tcg_gen_subi_tl(cpu_tmp0
, count
, 1);
1699 tcg_gen_concat_tl_i64(cpu_T0
, cpu_T0
, cpu_T1
);
1700 tcg_gen_shr_i64(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1701 tcg_gen_shr_i64(cpu_T0
, cpu_T0
, count
);
1703 tcg_gen_concat_tl_i64(cpu_T0
, cpu_T1
, cpu_T0
);
1704 tcg_gen_shl_i64(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1705 tcg_gen_shl_i64(cpu_T0
, cpu_T0
, count
);
1706 tcg_gen_shri_i64(cpu_tmp0
, cpu_tmp0
, 32);
1707 tcg_gen_shri_i64(cpu_T0
, cpu_T0
, 32);
1712 tcg_gen_subi_tl(cpu_tmp0
, count
, 1);
1714 tcg_gen_shr_tl(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1716 tcg_gen_subfi_tl(cpu_tmp4
, mask
+ 1, count
);
1717 tcg_gen_shr_tl(cpu_T0
, cpu_T0
, count
);
1718 tcg_gen_shl_tl(cpu_T1
, cpu_T1
, cpu_tmp4
);
1720 tcg_gen_shl_tl(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1722 /* Only needed if count > 16, for Intel behaviour. */
1723 tcg_gen_subfi_tl(cpu_tmp4
, 33, count
);
1724 tcg_gen_shr_tl(cpu_tmp4
, cpu_T1
, cpu_tmp4
);
1725 tcg_gen_or_tl(cpu_tmp0
, cpu_tmp0
, cpu_tmp4
);
1728 tcg_gen_subfi_tl(cpu_tmp4
, mask
+ 1, count
);
1729 tcg_gen_shl_tl(cpu_T0
, cpu_T0
, count
);
1730 tcg_gen_shr_tl(cpu_T1
, cpu_T1
, cpu_tmp4
);
1732 tcg_gen_movi_tl(cpu_tmp4
, 0);
1733 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_T1
, count
, cpu_tmp4
,
1735 tcg_gen_or_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1740 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1742 gen_shift_flags(s
, ot
, cpu_T0
, cpu_tmp0
, count
, is_right
);
1743 tcg_temp_free(count
);
1746 static void gen_shift(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
, int s
)
1749 gen_op_mov_v_reg(ot
, cpu_T1
, s
);
1752 gen_rot_rm_T1(s1
, ot
, d
, 0);
1755 gen_rot_rm_T1(s1
, ot
, d
, 1);
1759 gen_shift_rm_T1(s1
, ot
, d
, 0, 0);
1762 gen_shift_rm_T1(s1
, ot
, d
, 1, 0);
1765 gen_shift_rm_T1(s1
, ot
, d
, 1, 1);
1768 gen_rotc_rm_T1(s1
, ot
, d
, 0);
1771 gen_rotc_rm_T1(s1
, ot
, d
, 1);
1776 static void gen_shifti(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
, int c
)
1780 gen_rot_rm_im(s1
, ot
, d
, c
, 0);
1783 gen_rot_rm_im(s1
, ot
, d
, c
, 1);
1787 gen_shift_rm_im(s1
, ot
, d
, c
, 0, 0);
1790 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 0);
1793 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 1);
1796 /* currently not optimized */
1797 tcg_gen_movi_tl(cpu_T1
, c
);
1798 gen_shift(s1
, op
, ot
, d
, OR_TMP1
);
1803 static void gen_lea_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
1806 int havesib
, base
, index
, scale
;
1807 int mod
, rm
, code
, def_seg
, ovr_seg
;
1811 ovr_seg
= s
->override
;
1812 mod
= (modrm
>> 6) & 3;
1825 code
= cpu_ldub_code(env
, s
->pc
++);
1826 scale
= (code
>> 6) & 3;
1827 index
= ((code
>> 3) & 7) | REX_X(s
);
1829 index
= -1; /* no index */
1837 if ((base
& 7) == 5) {
1839 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
1841 if (CODE64(s
) && !havesib
) {
1842 disp
+= s
->pc
+ s
->rip_offset
;
1849 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
1853 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
1858 /* For correct popl handling with esp. */
1859 if (base
== R_ESP
&& s
->popl_esp_hack
) {
1860 disp
+= s
->popl_esp_hack
;
1863 /* Compute the address, with a minimum number of TCG ops. */
1867 sum
= cpu_regs
[index
];
1869 tcg_gen_shli_tl(cpu_A0
, cpu_regs
[index
], scale
);
1873 tcg_gen_add_tl(cpu_A0
, sum
, cpu_regs
[base
]);
1876 } else if (base
>= 0) {
1877 sum
= cpu_regs
[base
];
1879 if (TCGV_IS_UNUSED(sum
)) {
1880 tcg_gen_movi_tl(cpu_A0
, disp
);
1882 } else if (disp
!= 0) {
1883 tcg_gen_addi_tl(cpu_A0
, sum
, disp
);
1887 if (base
== R_EBP
|| base
== R_ESP
) {
1896 disp
= cpu_lduw_code(env
, s
->pc
);
1898 tcg_gen_movi_tl(cpu_A0
, disp
);
1902 } else if (mod
== 1) {
1903 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
1905 disp
= (int16_t)cpu_lduw_code(env
, s
->pc
);
1911 tcg_gen_add_tl(cpu_A0
, cpu_regs
[R_EBX
], cpu_regs
[R_ESI
]);
1914 tcg_gen_add_tl(cpu_A0
, cpu_regs
[R_EBX
], cpu_regs
[R_EDI
]);
1917 tcg_gen_add_tl(cpu_A0
, cpu_regs
[R_EBP
], cpu_regs
[R_ESI
]);
1921 tcg_gen_add_tl(cpu_A0
, cpu_regs
[R_EBP
], cpu_regs
[R_EDI
]);
1925 sum
= cpu_regs
[R_ESI
];
1928 sum
= cpu_regs
[R_EDI
];
1931 sum
= cpu_regs
[R_EBP
];
1936 sum
= cpu_regs
[R_EBX
];
1940 tcg_gen_addi_tl(cpu_A0
, sum
, disp
);
1949 gen_lea_v_seg(s
, s
->aflag
, sum
, def_seg
, ovr_seg
);
1952 static void gen_nop_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
1954 int mod
, rm
, base
, code
;
1956 mod
= (modrm
>> 6) & 3;
1967 code
= cpu_ldub_code(env
, s
->pc
++);
2009 /* used for LEA and MOV AX, mem */
2010 static void gen_add_A0_ds_seg(DisasContext
*s
)
2012 gen_lea_v_seg(s
, s
->aflag
, cpu_A0
, R_DS
, s
->override
);
2015 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2017 static void gen_ldst_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2018 TCGMemOp ot
, int reg
, int is_store
)
2022 mod
= (modrm
>> 6) & 3;
2023 rm
= (modrm
& 7) | REX_B(s
);
2027 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
2028 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
2030 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
2032 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
2035 gen_lea_modrm(env
, s
, modrm
);
2038 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
2039 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
2041 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
2043 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
2048 static inline uint32_t insn_get(CPUX86State
*env
, DisasContext
*s
, TCGMemOp ot
)
2054 ret
= cpu_ldub_code(env
, s
->pc
);
2058 ret
= cpu_lduw_code(env
, s
->pc
);
2062 #ifdef TARGET_X86_64
2065 ret
= cpu_ldl_code(env
, s
->pc
);
2074 static inline int insn_const_size(TCGMemOp ot
)
2083 static inline void gen_goto_tb(DisasContext
*s
, int tb_num
, target_ulong eip
)
2085 TranslationBlock
*tb
;
2088 pc
= s
->cs_base
+ eip
;
2090 /* NOTE: we handle the case where the TB spans two pages here */
2091 if ((pc
& TARGET_PAGE_MASK
) == (tb
->pc
& TARGET_PAGE_MASK
) ||
2092 (pc
& TARGET_PAGE_MASK
) == ((s
->pc
- 1) & TARGET_PAGE_MASK
)) {
2093 /* jump to same page: we can use a direct jump */
2094 tcg_gen_goto_tb(tb_num
);
2096 tcg_gen_exit_tb((uintptr_t)tb
+ tb_num
);
2098 /* jump to another page: currently not optimized */
2104 static inline void gen_jcc(DisasContext
*s
, int b
,
2105 target_ulong val
, target_ulong next_eip
)
2110 l1
= gen_new_label();
2113 gen_goto_tb(s
, 0, next_eip
);
2116 gen_goto_tb(s
, 1, val
);
2117 s
->is_jmp
= DISAS_TB_JUMP
;
2119 l1
= gen_new_label();
2120 l2
= gen_new_label();
2123 gen_jmp_im(next_eip
);
2133 static void gen_cmovcc1(CPUX86State
*env
, DisasContext
*s
, TCGMemOp ot
, int b
,
2138 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
2140 cc
= gen_prepare_cc(s
, b
, cpu_T1
);
2141 if (cc
.mask
!= -1) {
2142 TCGv t0
= tcg_temp_new();
2143 tcg_gen_andi_tl(t0
, cc
.reg
, cc
.mask
);
2147 cc
.reg2
= tcg_const_tl(cc
.imm
);
2150 tcg_gen_movcond_tl(cc
.cond
, cpu_T0
, cc
.reg
, cc
.reg2
,
2151 cpu_T0
, cpu_regs
[reg
]);
2152 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
2154 if (cc
.mask
!= -1) {
2155 tcg_temp_free(cc
.reg
);
2158 tcg_temp_free(cc
.reg2
);
2162 static inline void gen_op_movl_T0_seg(int seg_reg
)
2164 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
,
2165 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2168 static inline void gen_op_movl_seg_T0_vm(int seg_reg
)
2170 tcg_gen_ext16u_tl(cpu_T0
, cpu_T0
);
2171 tcg_gen_st32_tl(cpu_T0
, cpu_env
,
2172 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2173 tcg_gen_shli_tl(cpu_seg_base
[seg_reg
], cpu_T0
, 4);
2176 /* move T0 to seg_reg and compute if the CPU state may change. Never
2177 call this function with seg_reg == R_CS */
2178 static void gen_movl_seg_T0(DisasContext
*s
, int seg_reg
)
2180 if (s
->pe
&& !s
->vm86
) {
2181 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
2182 gen_helper_load_seg(cpu_env
, tcg_const_i32(seg_reg
), cpu_tmp2_i32
);
2183 /* abort translation because the addseg value may change or
2184 because ss32 may change. For R_SS, translation must always
2185 stop as a special handling must be done to disable hardware
2186 interrupts for the next instruction */
2187 if (seg_reg
== R_SS
|| (s
->code32
&& seg_reg
< R_FS
))
2188 s
->is_jmp
= DISAS_TB_JUMP
;
2190 gen_op_movl_seg_T0_vm(seg_reg
);
2191 if (seg_reg
== R_SS
)
2192 s
->is_jmp
= DISAS_TB_JUMP
;
2196 static inline int svm_is_rep(int prefixes
)
2198 return ((prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) ? 8 : 0);
2202 gen_svm_check_intercept_param(DisasContext
*s
, target_ulong pc_start
,
2203 uint32_t type
, uint64_t param
)
2205 /* no SVM activated; fast case */
2206 if (likely(!(s
->flags
& HF_SVMI_MASK
)))
2208 gen_update_cc_op(s
);
2209 gen_jmp_im(pc_start
- s
->cs_base
);
2210 gen_helper_svm_check_intercept_param(cpu_env
, tcg_const_i32(type
),
2211 tcg_const_i64(param
));
2215 gen_svm_check_intercept(DisasContext
*s
, target_ulong pc_start
, uint64_t type
)
2217 gen_svm_check_intercept_param(s
, pc_start
, type
, 0);
2220 static inline void gen_stack_update(DisasContext
*s
, int addend
)
2222 gen_op_add_reg_im(mo_stacksize(s
), R_ESP
, addend
);
2225 /* Generate a push. It depends on ss32, addseg and dflag. */
2226 static void gen_push_v(DisasContext
*s
, TCGv val
)
2228 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2229 TCGMemOp a_ot
= mo_stacksize(s
);
2230 int size
= 1 << d_ot
;
2231 TCGv new_esp
= cpu_A0
;
2233 tcg_gen_subi_tl(cpu_A0
, cpu_regs
[R_ESP
], size
);
2238 tcg_gen_mov_tl(new_esp
, cpu_A0
);
2240 gen_lea_v_seg(s
, a_ot
, cpu_A0
, R_SS
, -1);
2243 gen_op_st_v(s
, d_ot
, val
, cpu_A0
);
2244 gen_op_mov_reg_v(a_ot
, R_ESP
, new_esp
);
2247 /* two step pop is necessary for precise exceptions */
2248 static TCGMemOp
gen_pop_T0(DisasContext
*s
)
2250 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2252 gen_lea_v_seg(s
, mo_stacksize(s
), cpu_regs
[R_ESP
], R_SS
, -1);
2253 gen_op_ld_v(s
, d_ot
, cpu_T0
, cpu_A0
);
2258 static inline void gen_pop_update(DisasContext
*s
, TCGMemOp ot
)
2260 gen_stack_update(s
, 1 << ot
);
2263 static inline void gen_stack_A0(DisasContext
*s
)
2265 gen_lea_v_seg(s
, s
->ss32
? MO_32
: MO_16
, cpu_regs
[R_ESP
], R_SS
, -1);
2268 static void gen_pusha(DisasContext
*s
)
2270 TCGMemOp s_ot
= s
->ss32
? MO_32
: MO_16
;
2271 TCGMemOp d_ot
= s
->dflag
;
2272 int size
= 1 << d_ot
;
2275 for (i
= 0; i
< 8; i
++) {
2276 tcg_gen_addi_tl(cpu_A0
, cpu_regs
[R_ESP
], (i
- 8) * size
);
2277 gen_lea_v_seg(s
, s_ot
, cpu_A0
, R_SS
, -1);
2278 gen_op_st_v(s
, d_ot
, cpu_regs
[7 - i
], cpu_A0
);
2281 gen_stack_update(s
, -8 * size
);
2284 static void gen_popa(DisasContext
*s
)
2286 TCGMemOp s_ot
= s
->ss32
? MO_32
: MO_16
;
2287 TCGMemOp d_ot
= s
->dflag
;
2288 int size
= 1 << d_ot
;
2291 for (i
= 0; i
< 8; i
++) {
2292 /* ESP is not reloaded */
2293 if (7 - i
== R_ESP
) {
2296 tcg_gen_addi_tl(cpu_A0
, cpu_regs
[R_ESP
], i
* size
);
2297 gen_lea_v_seg(s
, s_ot
, cpu_A0
, R_SS
, -1);
2298 gen_op_ld_v(s
, d_ot
, cpu_T0
, cpu_A0
);
2299 gen_op_mov_reg_v(d_ot
, 7 - i
, cpu_T0
);
2302 gen_stack_update(s
, 8 * size
);
2305 static void gen_enter(DisasContext
*s
, int esp_addend
, int level
)
2307 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2308 TCGMemOp a_ot
= CODE64(s
) ? MO_64
: s
->ss32
? MO_32
: MO_16
;
2309 int size
= 1 << d_ot
;
2311 /* Push BP; compute FrameTemp into T1. */
2312 tcg_gen_subi_tl(cpu_T1
, cpu_regs
[R_ESP
], size
);
2313 gen_lea_v_seg(s
, a_ot
, cpu_T1
, R_SS
, -1);
2314 gen_op_st_v(s
, d_ot
, cpu_regs
[R_EBP
], cpu_A0
);
2320 /* Copy level-1 pointers from the previous frame. */
2321 for (i
= 1; i
< level
; ++i
) {
2322 tcg_gen_subi_tl(cpu_A0
, cpu_regs
[R_EBP
], size
* i
);
2323 gen_lea_v_seg(s
, a_ot
, cpu_A0
, R_SS
, -1);
2324 gen_op_ld_v(s
, d_ot
, cpu_tmp0
, cpu_A0
);
2326 tcg_gen_subi_tl(cpu_A0
, cpu_T1
, size
* i
);
2327 gen_lea_v_seg(s
, a_ot
, cpu_A0
, R_SS
, -1);
2328 gen_op_st_v(s
, d_ot
, cpu_tmp0
, cpu_A0
);
2331 /* Push the current FrameTemp as the last level. */
2332 tcg_gen_subi_tl(cpu_A0
, cpu_T1
, size
* level
);
2333 gen_lea_v_seg(s
, a_ot
, cpu_A0
, R_SS
, -1);
2334 gen_op_st_v(s
, d_ot
, cpu_T1
, cpu_A0
);
2337 /* Copy the FrameTemp value to EBP. */
2338 gen_op_mov_reg_v(a_ot
, R_EBP
, cpu_T1
);
2340 /* Compute the final value of ESP. */
2341 tcg_gen_subi_tl(cpu_T1
, cpu_T1
, esp_addend
+ size
* level
);
2342 gen_op_mov_reg_v(a_ot
, R_ESP
, cpu_T1
);
2345 static void gen_leave(DisasContext
*s
)
2347 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2348 TCGMemOp a_ot
= mo_stacksize(s
);
2350 gen_lea_v_seg(s
, a_ot
, cpu_regs
[R_EBP
], R_SS
, -1);
2351 gen_op_ld_v(s
, d_ot
, cpu_T0
, cpu_A0
);
2353 tcg_gen_addi_tl(cpu_T1
, cpu_regs
[R_EBP
], 1 << d_ot
);
2355 gen_op_mov_reg_v(d_ot
, R_EBP
, cpu_T0
);
2356 gen_op_mov_reg_v(a_ot
, R_ESP
, cpu_T1
);
2359 static void gen_exception(DisasContext
*s
, int trapno
, target_ulong cur_eip
)
2361 gen_update_cc_op(s
);
2362 gen_jmp_im(cur_eip
);
2363 gen_helper_raise_exception(cpu_env
, tcg_const_i32(trapno
));
2364 s
->is_jmp
= DISAS_TB_JUMP
;
2367 /* an interrupt is different from an exception because of the
2369 static void gen_interrupt(DisasContext
*s
, int intno
,
2370 target_ulong cur_eip
, target_ulong next_eip
)
2372 gen_update_cc_op(s
);
2373 gen_jmp_im(cur_eip
);
2374 gen_helper_raise_interrupt(cpu_env
, tcg_const_i32(intno
),
2375 tcg_const_i32(next_eip
- cur_eip
));
2376 s
->is_jmp
= DISAS_TB_JUMP
;
2379 static void gen_debug(DisasContext
*s
, target_ulong cur_eip
)
2381 gen_update_cc_op(s
);
2382 gen_jmp_im(cur_eip
);
2383 gen_helper_debug(cpu_env
);
2384 s
->is_jmp
= DISAS_TB_JUMP
;
2387 /* generate a generic end of block. Trace exception is also generated
2389 static void gen_eob(DisasContext
*s
)
2391 gen_update_cc_op(s
);
2392 if (s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
) {
2393 gen_helper_reset_inhibit_irq(cpu_env
);
2395 if (s
->tb
->flags
& HF_RF_MASK
) {
2396 gen_helper_reset_rf(cpu_env
);
2398 if (s
->singlestep_enabled
) {
2399 gen_helper_debug(cpu_env
);
2401 gen_helper_single_step(cpu_env
);
2405 s
->is_jmp
= DISAS_TB_JUMP
;
2408 /* generate a jump to eip. No segment change must happen before as a
2409 direct call to the next block may occur */
2410 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
)
2412 gen_update_cc_op(s
);
2413 set_cc_op(s
, CC_OP_DYNAMIC
);
2415 gen_goto_tb(s
, tb_num
, eip
);
2416 s
->is_jmp
= DISAS_TB_JUMP
;
2423 static void gen_jmp(DisasContext
*s
, target_ulong eip
)
2425 gen_jmp_tb(s
, eip
, 0);
2428 static inline void gen_ldq_env_A0(DisasContext
*s
, int offset
)
2430 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
2431 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2434 static inline void gen_stq_env_A0(DisasContext
*s
, int offset
)
2436 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2437 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
2440 static inline void gen_ldo_env_A0(DisasContext
*s
, int offset
)
2442 int mem_index
= s
->mem_index
;
2443 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, mem_index
, MO_LEQ
);
2444 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2445 tcg_gen_addi_tl(cpu_tmp0
, cpu_A0
, 8);
2446 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
, MO_LEQ
);
2447 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2450 static inline void gen_sto_env_A0(DisasContext
*s
, int offset
)
2452 int mem_index
= s
->mem_index
;
2453 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2454 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, mem_index
, MO_LEQ
);
2455 tcg_gen_addi_tl(cpu_tmp0
, cpu_A0
, 8);
2456 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2457 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
, MO_LEQ
);
2460 static inline void gen_op_movo(int d_offset
, int s_offset
)
2462 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2463 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2464 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2465 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2468 static inline void gen_op_movq(int d_offset
, int s_offset
)
2470 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
);
2471 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2474 static inline void gen_op_movl(int d_offset
, int s_offset
)
2476 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
, s_offset
);
2477 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, d_offset
);
2480 static inline void gen_op_movq_env_0(int d_offset
)
2482 tcg_gen_movi_i64(cpu_tmp1_i64
, 0);
2483 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2486 typedef void (*SSEFunc_i_ep
)(TCGv_i32 val
, TCGv_ptr env
, TCGv_ptr reg
);
2487 typedef void (*SSEFunc_l_ep
)(TCGv_i64 val
, TCGv_ptr env
, TCGv_ptr reg
);
2488 typedef void (*SSEFunc_0_epi
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i32 val
);
2489 typedef void (*SSEFunc_0_epl
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i64 val
);
2490 typedef void (*SSEFunc_0_epp
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
);
2491 typedef void (*SSEFunc_0_eppi
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2493 typedef void (*SSEFunc_0_ppi
)(TCGv_ptr reg_a
, TCGv_ptr reg_b
, TCGv_i32 val
);
2494 typedef void (*SSEFunc_0_eppt
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2497 #define SSE_SPECIAL ((void *)1)
2498 #define SSE_DUMMY ((void *)2)
2500 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2501 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2502 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2504 static const SSEFunc_0_epp sse_op_table1
[256][4] = {
2505 /* 3DNow! extensions */
2506 [0x0e] = { SSE_DUMMY
}, /* femms */
2507 [0x0f] = { SSE_DUMMY
}, /* pf... */
2508 /* pure SSE operations */
2509 [0x10] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2510 [0x11] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2511 [0x12] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd, movsldup, movddup */
2512 [0x13] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd */
2513 [0x14] = { gen_helper_punpckldq_xmm
, gen_helper_punpcklqdq_xmm
},
2514 [0x15] = { gen_helper_punpckhdq_xmm
, gen_helper_punpckhqdq_xmm
},
2515 [0x16] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd, movshdup */
2516 [0x17] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd */
2518 [0x28] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2519 [0x29] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2520 [0x2a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2521 [0x2b] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movntps, movntpd, movntss, movntsd */
2522 [0x2c] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2523 [0x2d] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2524 [0x2e] = { gen_helper_ucomiss
, gen_helper_ucomisd
},
2525 [0x2f] = { gen_helper_comiss
, gen_helper_comisd
},
2526 [0x50] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movmskps, movmskpd */
2527 [0x51] = SSE_FOP(sqrt
),
2528 [0x52] = { gen_helper_rsqrtps
, NULL
, gen_helper_rsqrtss
, NULL
},
2529 [0x53] = { gen_helper_rcpps
, NULL
, gen_helper_rcpss
, NULL
},
2530 [0x54] = { gen_helper_pand_xmm
, gen_helper_pand_xmm
}, /* andps, andpd */
2531 [0x55] = { gen_helper_pandn_xmm
, gen_helper_pandn_xmm
}, /* andnps, andnpd */
2532 [0x56] = { gen_helper_por_xmm
, gen_helper_por_xmm
}, /* orps, orpd */
2533 [0x57] = { gen_helper_pxor_xmm
, gen_helper_pxor_xmm
}, /* xorps, xorpd */
2534 [0x58] = SSE_FOP(add
),
2535 [0x59] = SSE_FOP(mul
),
2536 [0x5a] = { gen_helper_cvtps2pd
, gen_helper_cvtpd2ps
,
2537 gen_helper_cvtss2sd
, gen_helper_cvtsd2ss
},
2538 [0x5b] = { gen_helper_cvtdq2ps
, gen_helper_cvtps2dq
, gen_helper_cvttps2dq
},
2539 [0x5c] = SSE_FOP(sub
),
2540 [0x5d] = SSE_FOP(min
),
2541 [0x5e] = SSE_FOP(div
),
2542 [0x5f] = SSE_FOP(max
),
2544 [0xc2] = SSE_FOP(cmpeq
),
2545 [0xc6] = { (SSEFunc_0_epp
)gen_helper_shufps
,
2546 (SSEFunc_0_epp
)gen_helper_shufpd
}, /* XXX: casts */
2548 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */
2549 [0x38] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2550 [0x3a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2552 /* MMX ops and their SSE extensions */
2553 [0x60] = MMX_OP2(punpcklbw
),
2554 [0x61] = MMX_OP2(punpcklwd
),
2555 [0x62] = MMX_OP2(punpckldq
),
2556 [0x63] = MMX_OP2(packsswb
),
2557 [0x64] = MMX_OP2(pcmpgtb
),
2558 [0x65] = MMX_OP2(pcmpgtw
),
2559 [0x66] = MMX_OP2(pcmpgtl
),
2560 [0x67] = MMX_OP2(packuswb
),
2561 [0x68] = MMX_OP2(punpckhbw
),
2562 [0x69] = MMX_OP2(punpckhwd
),
2563 [0x6a] = MMX_OP2(punpckhdq
),
2564 [0x6b] = MMX_OP2(packssdw
),
2565 [0x6c] = { NULL
, gen_helper_punpcklqdq_xmm
},
2566 [0x6d] = { NULL
, gen_helper_punpckhqdq_xmm
},
2567 [0x6e] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movd mm, ea */
2568 [0x6f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, , movqdu */
2569 [0x70] = { (SSEFunc_0_epp
)gen_helper_pshufw_mmx
,
2570 (SSEFunc_0_epp
)gen_helper_pshufd_xmm
,
2571 (SSEFunc_0_epp
)gen_helper_pshufhw_xmm
,
2572 (SSEFunc_0_epp
)gen_helper_pshuflw_xmm
}, /* XXX: casts */
2573 [0x71] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftw */
2574 [0x72] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftd */
2575 [0x73] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftq */
2576 [0x74] = MMX_OP2(pcmpeqb
),
2577 [0x75] = MMX_OP2(pcmpeqw
),
2578 [0x76] = MMX_OP2(pcmpeql
),
2579 [0x77] = { SSE_DUMMY
}, /* emms */
2580 [0x78] = { NULL
, SSE_SPECIAL
, NULL
, SSE_SPECIAL
}, /* extrq_i, insertq_i */
2581 [0x79] = { NULL
, gen_helper_extrq_r
, NULL
, gen_helper_insertq_r
},
2582 [0x7c] = { NULL
, gen_helper_haddpd
, NULL
, gen_helper_haddps
},
2583 [0x7d] = { NULL
, gen_helper_hsubpd
, NULL
, gen_helper_hsubps
},
2584 [0x7e] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movd, movd, , movq */
2585 [0x7f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, movdqu */
2586 [0xc4] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pinsrw */
2587 [0xc5] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pextrw */
2588 [0xd0] = { NULL
, gen_helper_addsubpd
, NULL
, gen_helper_addsubps
},
2589 [0xd1] = MMX_OP2(psrlw
),
2590 [0xd2] = MMX_OP2(psrld
),
2591 [0xd3] = MMX_OP2(psrlq
),
2592 [0xd4] = MMX_OP2(paddq
),
2593 [0xd5] = MMX_OP2(pmullw
),
2594 [0xd6] = { NULL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2595 [0xd7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pmovmskb */
2596 [0xd8] = MMX_OP2(psubusb
),
2597 [0xd9] = MMX_OP2(psubusw
),
2598 [0xda] = MMX_OP2(pminub
),
2599 [0xdb] = MMX_OP2(pand
),
2600 [0xdc] = MMX_OP2(paddusb
),
2601 [0xdd] = MMX_OP2(paddusw
),
2602 [0xde] = MMX_OP2(pmaxub
),
2603 [0xdf] = MMX_OP2(pandn
),
2604 [0xe0] = MMX_OP2(pavgb
),
2605 [0xe1] = MMX_OP2(psraw
),
2606 [0xe2] = MMX_OP2(psrad
),
2607 [0xe3] = MMX_OP2(pavgw
),
2608 [0xe4] = MMX_OP2(pmulhuw
),
2609 [0xe5] = MMX_OP2(pmulhw
),
2610 [0xe6] = { NULL
, gen_helper_cvttpd2dq
, gen_helper_cvtdq2pd
, gen_helper_cvtpd2dq
},
2611 [0xe7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movntq, movntq */
2612 [0xe8] = MMX_OP2(psubsb
),
2613 [0xe9] = MMX_OP2(psubsw
),
2614 [0xea] = MMX_OP2(pminsw
),
2615 [0xeb] = MMX_OP2(por
),
2616 [0xec] = MMX_OP2(paddsb
),
2617 [0xed] = MMX_OP2(paddsw
),
2618 [0xee] = MMX_OP2(pmaxsw
),
2619 [0xef] = MMX_OP2(pxor
),
2620 [0xf0] = { NULL
, NULL
, NULL
, SSE_SPECIAL
}, /* lddqu */
2621 [0xf1] = MMX_OP2(psllw
),
2622 [0xf2] = MMX_OP2(pslld
),
2623 [0xf3] = MMX_OP2(psllq
),
2624 [0xf4] = MMX_OP2(pmuludq
),
2625 [0xf5] = MMX_OP2(pmaddwd
),
2626 [0xf6] = MMX_OP2(psadbw
),
2627 [0xf7] = { (SSEFunc_0_epp
)gen_helper_maskmov_mmx
,
2628 (SSEFunc_0_epp
)gen_helper_maskmov_xmm
}, /* XXX: casts */
2629 [0xf8] = MMX_OP2(psubb
),
2630 [0xf9] = MMX_OP2(psubw
),
2631 [0xfa] = MMX_OP2(psubl
),
2632 [0xfb] = MMX_OP2(psubq
),
2633 [0xfc] = MMX_OP2(paddb
),
2634 [0xfd] = MMX_OP2(paddw
),
2635 [0xfe] = MMX_OP2(paddl
),
2638 static const SSEFunc_0_epp sse_op_table2
[3 * 8][2] = {
2639 [0 + 2] = MMX_OP2(psrlw
),
2640 [0 + 4] = MMX_OP2(psraw
),
2641 [0 + 6] = MMX_OP2(psllw
),
2642 [8 + 2] = MMX_OP2(psrld
),
2643 [8 + 4] = MMX_OP2(psrad
),
2644 [8 + 6] = MMX_OP2(pslld
),
2645 [16 + 2] = MMX_OP2(psrlq
),
2646 [16 + 3] = { NULL
, gen_helper_psrldq_xmm
},
2647 [16 + 6] = MMX_OP2(psllq
),
2648 [16 + 7] = { NULL
, gen_helper_pslldq_xmm
},
2651 static const SSEFunc_0_epi sse_op_table3ai
[] = {
2652 gen_helper_cvtsi2ss
,
2656 #ifdef TARGET_X86_64
2657 static const SSEFunc_0_epl sse_op_table3aq
[] = {
2658 gen_helper_cvtsq2ss
,
2663 static const SSEFunc_i_ep sse_op_table3bi
[] = {
2664 gen_helper_cvttss2si
,
2665 gen_helper_cvtss2si
,
2666 gen_helper_cvttsd2si
,
2670 #ifdef TARGET_X86_64
2671 static const SSEFunc_l_ep sse_op_table3bq
[] = {
2672 gen_helper_cvttss2sq
,
2673 gen_helper_cvtss2sq
,
2674 gen_helper_cvttsd2sq
,
2679 static const SSEFunc_0_epp sse_op_table4
[8][4] = {
2690 static const SSEFunc_0_epp sse_op_table5
[256] = {
2691 [0x0c] = gen_helper_pi2fw
,
2692 [0x0d] = gen_helper_pi2fd
,
2693 [0x1c] = gen_helper_pf2iw
,
2694 [0x1d] = gen_helper_pf2id
,
2695 [0x8a] = gen_helper_pfnacc
,
2696 [0x8e] = gen_helper_pfpnacc
,
2697 [0x90] = gen_helper_pfcmpge
,
2698 [0x94] = gen_helper_pfmin
,
2699 [0x96] = gen_helper_pfrcp
,
2700 [0x97] = gen_helper_pfrsqrt
,
2701 [0x9a] = gen_helper_pfsub
,
2702 [0x9e] = gen_helper_pfadd
,
2703 [0xa0] = gen_helper_pfcmpgt
,
2704 [0xa4] = gen_helper_pfmax
,
2705 [0xa6] = gen_helper_movq
, /* pfrcpit1; no need to actually increase precision */
2706 [0xa7] = gen_helper_movq
, /* pfrsqit1 */
2707 [0xaa] = gen_helper_pfsubr
,
2708 [0xae] = gen_helper_pfacc
,
2709 [0xb0] = gen_helper_pfcmpeq
,
2710 [0xb4] = gen_helper_pfmul
,
2711 [0xb6] = gen_helper_movq
, /* pfrcpit2 */
2712 [0xb7] = gen_helper_pmulhrw_mmx
,
2713 [0xbb] = gen_helper_pswapd
,
2714 [0xbf] = gen_helper_pavgb_mmx
/* pavgusb */
2717 struct SSEOpHelper_epp
{
2718 SSEFunc_0_epp op
[2];
2722 struct SSEOpHelper_eppi
{
2723 SSEFunc_0_eppi op
[2];
2727 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
2728 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
2729 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
2730 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
2731 #define PCLMULQDQ_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, \
2732 CPUID_EXT_PCLMULQDQ }
2733 #define AESNI_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_AES }
2735 static const struct SSEOpHelper_epp sse_op_table6
[256] = {
2736 [0x00] = SSSE3_OP(pshufb
),
2737 [0x01] = SSSE3_OP(phaddw
),
2738 [0x02] = SSSE3_OP(phaddd
),
2739 [0x03] = SSSE3_OP(phaddsw
),
2740 [0x04] = SSSE3_OP(pmaddubsw
),
2741 [0x05] = SSSE3_OP(phsubw
),
2742 [0x06] = SSSE3_OP(phsubd
),
2743 [0x07] = SSSE3_OP(phsubsw
),
2744 [0x08] = SSSE3_OP(psignb
),
2745 [0x09] = SSSE3_OP(psignw
),
2746 [0x0a] = SSSE3_OP(psignd
),
2747 [0x0b] = SSSE3_OP(pmulhrsw
),
2748 [0x10] = SSE41_OP(pblendvb
),
2749 [0x14] = SSE41_OP(blendvps
),
2750 [0x15] = SSE41_OP(blendvpd
),
2751 [0x17] = SSE41_OP(ptest
),
2752 [0x1c] = SSSE3_OP(pabsb
),
2753 [0x1d] = SSSE3_OP(pabsw
),
2754 [0x1e] = SSSE3_OP(pabsd
),
2755 [0x20] = SSE41_OP(pmovsxbw
),
2756 [0x21] = SSE41_OP(pmovsxbd
),
2757 [0x22] = SSE41_OP(pmovsxbq
),
2758 [0x23] = SSE41_OP(pmovsxwd
),
2759 [0x24] = SSE41_OP(pmovsxwq
),
2760 [0x25] = SSE41_OP(pmovsxdq
),
2761 [0x28] = SSE41_OP(pmuldq
),
2762 [0x29] = SSE41_OP(pcmpeqq
),
2763 [0x2a] = SSE41_SPECIAL
, /* movntqda */
2764 [0x2b] = SSE41_OP(packusdw
),
2765 [0x30] = SSE41_OP(pmovzxbw
),
2766 [0x31] = SSE41_OP(pmovzxbd
),
2767 [0x32] = SSE41_OP(pmovzxbq
),
2768 [0x33] = SSE41_OP(pmovzxwd
),
2769 [0x34] = SSE41_OP(pmovzxwq
),
2770 [0x35] = SSE41_OP(pmovzxdq
),
2771 [0x37] = SSE42_OP(pcmpgtq
),
2772 [0x38] = SSE41_OP(pminsb
),
2773 [0x39] = SSE41_OP(pminsd
),
2774 [0x3a] = SSE41_OP(pminuw
),
2775 [0x3b] = SSE41_OP(pminud
),
2776 [0x3c] = SSE41_OP(pmaxsb
),
2777 [0x3d] = SSE41_OP(pmaxsd
),
2778 [0x3e] = SSE41_OP(pmaxuw
),
2779 [0x3f] = SSE41_OP(pmaxud
),
2780 [0x40] = SSE41_OP(pmulld
),
2781 [0x41] = SSE41_OP(phminposuw
),
2782 [0xdb] = AESNI_OP(aesimc
),
2783 [0xdc] = AESNI_OP(aesenc
),
2784 [0xdd] = AESNI_OP(aesenclast
),
2785 [0xde] = AESNI_OP(aesdec
),
2786 [0xdf] = AESNI_OP(aesdeclast
),
2789 static const struct SSEOpHelper_eppi sse_op_table7
[256] = {
2790 [0x08] = SSE41_OP(roundps
),
2791 [0x09] = SSE41_OP(roundpd
),
2792 [0x0a] = SSE41_OP(roundss
),
2793 [0x0b] = SSE41_OP(roundsd
),
2794 [0x0c] = SSE41_OP(blendps
),
2795 [0x0d] = SSE41_OP(blendpd
),
2796 [0x0e] = SSE41_OP(pblendw
),
2797 [0x0f] = SSSE3_OP(palignr
),
2798 [0x14] = SSE41_SPECIAL
, /* pextrb */
2799 [0x15] = SSE41_SPECIAL
, /* pextrw */
2800 [0x16] = SSE41_SPECIAL
, /* pextrd/pextrq */
2801 [0x17] = SSE41_SPECIAL
, /* extractps */
2802 [0x20] = SSE41_SPECIAL
, /* pinsrb */
2803 [0x21] = SSE41_SPECIAL
, /* insertps */
2804 [0x22] = SSE41_SPECIAL
, /* pinsrd/pinsrq */
2805 [0x40] = SSE41_OP(dpps
),
2806 [0x41] = SSE41_OP(dppd
),
2807 [0x42] = SSE41_OP(mpsadbw
),
2808 [0x44] = PCLMULQDQ_OP(pclmulqdq
),
2809 [0x60] = SSE42_OP(pcmpestrm
),
2810 [0x61] = SSE42_OP(pcmpestri
),
2811 [0x62] = SSE42_OP(pcmpistrm
),
2812 [0x63] = SSE42_OP(pcmpistri
),
2813 [0xdf] = AESNI_OP(aeskeygenassist
),
2816 static void gen_sse(CPUX86State
*env
, DisasContext
*s
, int b
,
2817 target_ulong pc_start
, int rex_r
)
2819 int b1
, op1_offset
, op2_offset
, is_xmm
, val
;
2820 int modrm
, mod
, rm
, reg
;
2821 SSEFunc_0_epp sse_fn_epp
;
2822 SSEFunc_0_eppi sse_fn_eppi
;
2823 SSEFunc_0_ppi sse_fn_ppi
;
2824 SSEFunc_0_eppt sse_fn_eppt
;
2828 if (s
->prefix
& PREFIX_DATA
)
2830 else if (s
->prefix
& PREFIX_REPZ
)
2832 else if (s
->prefix
& PREFIX_REPNZ
)
2836 sse_fn_epp
= sse_op_table1
[b
][b1
];
2840 if ((b
<= 0x5f && b
>= 0x10) || b
== 0xc6 || b
== 0xc2) {
2850 /* simple MMX/SSE operation */
2851 if (s
->flags
& HF_TS_MASK
) {
2852 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
2855 if (s
->flags
& HF_EM_MASK
) {
2857 gen_exception(s
, EXCP06_ILLOP
, pc_start
- s
->cs_base
);
2860 if (is_xmm
&& !(s
->flags
& HF_OSFXSR_MASK
))
2861 if ((b
!= 0x38 && b
!= 0x3a) || (s
->prefix
& PREFIX_DATA
))
2864 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
))
2867 gen_helper_emms(cpu_env
);
2872 gen_helper_emms(cpu_env
);
2875 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
2876 the static cpu state) */
2878 gen_helper_enter_mmx(cpu_env
);
2881 modrm
= cpu_ldub_code(env
, s
->pc
++);
2882 reg
= ((modrm
>> 3) & 7);
2885 mod
= (modrm
>> 6) & 3;
2886 if (sse_fn_epp
== SSE_SPECIAL
) {
2889 case 0x0e7: /* movntq */
2892 gen_lea_modrm(env
, s
, modrm
);
2893 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
2895 case 0x1e7: /* movntdq */
2896 case 0x02b: /* movntps */
2897 case 0x12b: /* movntps */
2900 gen_lea_modrm(env
, s
, modrm
);
2901 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
2903 case 0x3f0: /* lddqu */
2906 gen_lea_modrm(env
, s
, modrm
);
2907 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
2909 case 0x22b: /* movntss */
2910 case 0x32b: /* movntsd */
2913 gen_lea_modrm(env
, s
, modrm
);
2915 gen_stq_env_A0(s
, offsetof(CPUX86State
,
2916 xmm_regs
[reg
].ZMM_Q(0)));
2918 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,
2919 xmm_regs
[reg
].ZMM_L(0)));
2920 gen_op_st_v(s
, MO_32
, cpu_T0
, cpu_A0
);
2923 case 0x6e: /* movd mm, ea */
2924 #ifdef TARGET_X86_64
2925 if (s
->dflag
== MO_64
) {
2926 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
2927 tcg_gen_st_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,fpregs
[reg
].mmx
));
2931 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
2932 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
2933 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
2934 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
2935 gen_helper_movl_mm_T0_mmx(cpu_ptr0
, cpu_tmp2_i32
);
2938 case 0x16e: /* movd xmm, ea */
2939 #ifdef TARGET_X86_64
2940 if (s
->dflag
== MO_64
) {
2941 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
2942 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
2943 offsetof(CPUX86State
,xmm_regs
[reg
]));
2944 gen_helper_movq_mm_T0_xmm(cpu_ptr0
, cpu_T0
);
2948 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
2949 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
2950 offsetof(CPUX86State
,xmm_regs
[reg
]));
2951 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
2952 gen_helper_movl_mm_T0_xmm(cpu_ptr0
, cpu_tmp2_i32
);
2955 case 0x6f: /* movq mm, ea */
2957 gen_lea_modrm(env
, s
, modrm
);
2958 gen_ldq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
2961 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
2962 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
2963 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
2964 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
2967 case 0x010: /* movups */
2968 case 0x110: /* movupd */
2969 case 0x028: /* movaps */
2970 case 0x128: /* movapd */
2971 case 0x16f: /* movdqa xmm, ea */
2972 case 0x26f: /* movdqu xmm, ea */
2974 gen_lea_modrm(env
, s
, modrm
);
2975 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
2977 rm
= (modrm
& 7) | REX_B(s
);
2978 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[reg
]),
2979 offsetof(CPUX86State
,xmm_regs
[rm
]));
2982 case 0x210: /* movss xmm, ea */
2984 gen_lea_modrm(env
, s
, modrm
);
2985 gen_op_ld_v(s
, MO_32
, cpu_T0
, cpu_A0
);
2986 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
2987 tcg_gen_movi_tl(cpu_T0
, 0);
2988 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)));
2989 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)));
2990 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)));
2992 rm
= (modrm
& 7) | REX_B(s
);
2993 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)),
2994 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)));
2997 case 0x310: /* movsd xmm, ea */
2999 gen_lea_modrm(env
, s
, modrm
);
3000 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3001 xmm_regs
[reg
].ZMM_Q(0)));
3002 tcg_gen_movi_tl(cpu_T0
, 0);
3003 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)));
3004 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)));
3006 rm
= (modrm
& 7) | REX_B(s
);
3007 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3008 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3011 case 0x012: /* movlps */
3012 case 0x112: /* movlpd */
3014 gen_lea_modrm(env
, s
, modrm
);
3015 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3016 xmm_regs
[reg
].ZMM_Q(0)));
3019 rm
= (modrm
& 7) | REX_B(s
);
3020 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3021 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(1)));
3024 case 0x212: /* movsldup */
3026 gen_lea_modrm(env
, s
, modrm
);
3027 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3029 rm
= (modrm
& 7) | REX_B(s
);
3030 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)),
3031 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)));
3032 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)),
3033 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(2)));
3035 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)),
3036 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3037 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)),
3038 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)));
3040 case 0x312: /* movddup */
3042 gen_lea_modrm(env
, s
, modrm
);
3043 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3044 xmm_regs
[reg
].ZMM_Q(0)));
3046 rm
= (modrm
& 7) | REX_B(s
);
3047 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3048 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3050 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)),
3051 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3053 case 0x016: /* movhps */
3054 case 0x116: /* movhpd */
3056 gen_lea_modrm(env
, s
, modrm
);
3057 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3058 xmm_regs
[reg
].ZMM_Q(1)));
3061 rm
= (modrm
& 7) | REX_B(s
);
3062 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)),
3063 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3066 case 0x216: /* movshdup */
3068 gen_lea_modrm(env
, s
, modrm
);
3069 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3071 rm
= (modrm
& 7) | REX_B(s
);
3072 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)),
3073 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(1)));
3074 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)),
3075 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(3)));
3077 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)),
3078 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)));
3079 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)),
3080 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)));
3085 int bit_index
, field_length
;
3087 if (b1
== 1 && reg
!= 0)
3089 field_length
= cpu_ldub_code(env
, s
->pc
++) & 0x3F;
3090 bit_index
= cpu_ldub_code(env
, s
->pc
++) & 0x3F;
3091 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3092 offsetof(CPUX86State
,xmm_regs
[reg
]));
3094 gen_helper_extrq_i(cpu_env
, cpu_ptr0
,
3095 tcg_const_i32(bit_index
),
3096 tcg_const_i32(field_length
));
3098 gen_helper_insertq_i(cpu_env
, cpu_ptr0
,
3099 tcg_const_i32(bit_index
),
3100 tcg_const_i32(field_length
));
3103 case 0x7e: /* movd ea, mm */
3104 #ifdef TARGET_X86_64
3105 if (s
->dflag
== MO_64
) {
3106 tcg_gen_ld_i64(cpu_T0
, cpu_env
,
3107 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3108 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3112 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
,
3113 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_L(0)));
3114 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3117 case 0x17e: /* movd ea, xmm */
3118 #ifdef TARGET_X86_64
3119 if (s
->dflag
== MO_64
) {
3120 tcg_gen_ld_i64(cpu_T0
, cpu_env
,
3121 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3122 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3126 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
,
3127 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3128 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3131 case 0x27e: /* movq xmm, ea */
3133 gen_lea_modrm(env
, s
, modrm
);
3134 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3135 xmm_regs
[reg
].ZMM_Q(0)));
3137 rm
= (modrm
& 7) | REX_B(s
);
3138 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3139 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3141 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)));
3143 case 0x7f: /* movq ea, mm */
3145 gen_lea_modrm(env
, s
, modrm
);
3146 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3149 gen_op_movq(offsetof(CPUX86State
,fpregs
[rm
].mmx
),
3150 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3153 case 0x011: /* movups */
3154 case 0x111: /* movupd */
3155 case 0x029: /* movaps */
3156 case 0x129: /* movapd */
3157 case 0x17f: /* movdqa ea, xmm */
3158 case 0x27f: /* movdqu ea, xmm */
3160 gen_lea_modrm(env
, s
, modrm
);
3161 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3163 rm
= (modrm
& 7) | REX_B(s
);
3164 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[rm
]),
3165 offsetof(CPUX86State
,xmm_regs
[reg
]));
3168 case 0x211: /* movss ea, xmm */
3170 gen_lea_modrm(env
, s
, modrm
);
3171 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3172 gen_op_st_v(s
, MO_32
, cpu_T0
, cpu_A0
);
3174 rm
= (modrm
& 7) | REX_B(s
);
3175 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)),
3176 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3179 case 0x311: /* movsd ea, xmm */
3181 gen_lea_modrm(env
, s
, modrm
);
3182 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3183 xmm_regs
[reg
].ZMM_Q(0)));
3185 rm
= (modrm
& 7) | REX_B(s
);
3186 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)),
3187 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3190 case 0x013: /* movlps */
3191 case 0x113: /* movlpd */
3193 gen_lea_modrm(env
, s
, modrm
);
3194 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3195 xmm_regs
[reg
].ZMM_Q(0)));
3200 case 0x017: /* movhps */
3201 case 0x117: /* movhpd */
3203 gen_lea_modrm(env
, s
, modrm
);
3204 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3205 xmm_regs
[reg
].ZMM_Q(1)));
3210 case 0x71: /* shift mm, im */
3213 case 0x171: /* shift xmm, im */
3219 val
= cpu_ldub_code(env
, s
->pc
++);
3221 tcg_gen_movi_tl(cpu_T0
, val
);
3222 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_t0
.ZMM_L(0)));
3223 tcg_gen_movi_tl(cpu_T0
, 0);
3224 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_t0
.ZMM_L(1)));
3225 op1_offset
= offsetof(CPUX86State
,xmm_t0
);
3227 tcg_gen_movi_tl(cpu_T0
, val
);
3228 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,mmx_t0
.MMX_L(0)));
3229 tcg_gen_movi_tl(cpu_T0
, 0);
3230 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,mmx_t0
.MMX_L(1)));
3231 op1_offset
= offsetof(CPUX86State
,mmx_t0
);
3233 sse_fn_epp
= sse_op_table2
[((b
- 1) & 3) * 8 +
3234 (((modrm
>> 3)) & 7)][b1
];
3239 rm
= (modrm
& 7) | REX_B(s
);
3240 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3243 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3245 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3246 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op1_offset
);
3247 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3249 case 0x050: /* movmskps */
3250 rm
= (modrm
& 7) | REX_B(s
);
3251 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3252 offsetof(CPUX86State
,xmm_regs
[rm
]));
3253 gen_helper_movmskps(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3254 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3256 case 0x150: /* movmskpd */
3257 rm
= (modrm
& 7) | REX_B(s
);
3258 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3259 offsetof(CPUX86State
,xmm_regs
[rm
]));
3260 gen_helper_movmskpd(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3261 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3263 case 0x02a: /* cvtpi2ps */
3264 case 0x12a: /* cvtpi2pd */
3265 gen_helper_enter_mmx(cpu_env
);
3267 gen_lea_modrm(env
, s
, modrm
);
3268 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3269 gen_ldq_env_A0(s
, op2_offset
);
3272 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3274 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3275 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3276 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3279 gen_helper_cvtpi2ps(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3283 gen_helper_cvtpi2pd(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3287 case 0x22a: /* cvtsi2ss */
3288 case 0x32a: /* cvtsi2sd */
3289 ot
= mo_64_32(s
->dflag
);
3290 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3291 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3292 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3294 SSEFunc_0_epi sse_fn_epi
= sse_op_table3ai
[(b
>> 8) & 1];
3295 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
3296 sse_fn_epi(cpu_env
, cpu_ptr0
, cpu_tmp2_i32
);
3298 #ifdef TARGET_X86_64
3299 SSEFunc_0_epl sse_fn_epl
= sse_op_table3aq
[(b
>> 8) & 1];
3300 sse_fn_epl(cpu_env
, cpu_ptr0
, cpu_T0
);
3306 case 0x02c: /* cvttps2pi */
3307 case 0x12c: /* cvttpd2pi */
3308 case 0x02d: /* cvtps2pi */
3309 case 0x12d: /* cvtpd2pi */
3310 gen_helper_enter_mmx(cpu_env
);
3312 gen_lea_modrm(env
, s
, modrm
);
3313 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3314 gen_ldo_env_A0(s
, op2_offset
);
3316 rm
= (modrm
& 7) | REX_B(s
);
3317 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3319 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
);
3320 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3321 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3324 gen_helper_cvttps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3327 gen_helper_cvttpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3330 gen_helper_cvtps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3333 gen_helper_cvtpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3337 case 0x22c: /* cvttss2si */
3338 case 0x32c: /* cvttsd2si */
3339 case 0x22d: /* cvtss2si */
3340 case 0x32d: /* cvtsd2si */
3341 ot
= mo_64_32(s
->dflag
);
3343 gen_lea_modrm(env
, s
, modrm
);
3345 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.ZMM_Q(0)));
3347 gen_op_ld_v(s
, MO_32
, cpu_T0
, cpu_A0
);
3348 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_t0
.ZMM_L(0)));
3350 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3352 rm
= (modrm
& 7) | REX_B(s
);
3353 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3355 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3357 SSEFunc_i_ep sse_fn_i_ep
=
3358 sse_op_table3bi
[((b
>> 7) & 2) | (b
& 1)];
3359 sse_fn_i_ep(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3360 tcg_gen_extu_i32_tl(cpu_T0
, cpu_tmp2_i32
);
3362 #ifdef TARGET_X86_64
3363 SSEFunc_l_ep sse_fn_l_ep
=
3364 sse_op_table3bq
[((b
>> 7) & 2) | (b
& 1)];
3365 sse_fn_l_ep(cpu_T0
, cpu_env
, cpu_ptr0
);
3370 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3372 case 0xc4: /* pinsrw */
3375 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
3376 val
= cpu_ldub_code(env
, s
->pc
++);
3379 tcg_gen_st16_tl(cpu_T0
, cpu_env
,
3380 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_W(val
)));
3383 tcg_gen_st16_tl(cpu_T0
, cpu_env
,
3384 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_W(val
)));
3387 case 0xc5: /* pextrw */
3391 ot
= mo_64_32(s
->dflag
);
3392 val
= cpu_ldub_code(env
, s
->pc
++);
3395 rm
= (modrm
& 7) | REX_B(s
);
3396 tcg_gen_ld16u_tl(cpu_T0
, cpu_env
,
3397 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_W(val
)));
3401 tcg_gen_ld16u_tl(cpu_T0
, cpu_env
,
3402 offsetof(CPUX86State
,fpregs
[rm
].mmx
.MMX_W(val
)));
3404 reg
= ((modrm
>> 3) & 7) | rex_r
;
3405 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3407 case 0x1d6: /* movq ea, xmm */
3409 gen_lea_modrm(env
, s
, modrm
);
3410 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3411 xmm_regs
[reg
].ZMM_Q(0)));
3413 rm
= (modrm
& 7) | REX_B(s
);
3414 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)),
3415 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3416 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(1)));
3419 case 0x2d6: /* movq2dq */
3420 gen_helper_enter_mmx(cpu_env
);
3422 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3423 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3424 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)));
3426 case 0x3d6: /* movdq2q */
3427 gen_helper_enter_mmx(cpu_env
);
3428 rm
= (modrm
& 7) | REX_B(s
);
3429 gen_op_movq(offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
),
3430 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3432 case 0xd7: /* pmovmskb */
3437 rm
= (modrm
& 7) | REX_B(s
);
3438 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[rm
]));
3439 gen_helper_pmovmskb_xmm(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3442 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3443 gen_helper_pmovmskb_mmx(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3445 reg
= ((modrm
>> 3) & 7) | rex_r
;
3446 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3452 if ((b
& 0xf0) == 0xf0) {
3455 modrm
= cpu_ldub_code(env
, s
->pc
++);
3457 reg
= ((modrm
>> 3) & 7) | rex_r
;
3458 mod
= (modrm
>> 6) & 3;
3463 sse_fn_epp
= sse_op_table6
[b
].op
[b1
];
3467 if (!(s
->cpuid_ext_features
& sse_op_table6
[b
].ext_mask
))
3471 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3473 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
3475 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3476 gen_lea_modrm(env
, s
, modrm
);
3478 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3479 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3480 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3481 gen_ldq_env_A0(s
, op2_offset
+
3482 offsetof(ZMMReg
, ZMM_Q(0)));
3484 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3485 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3486 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
3487 s
->mem_index
, MO_LEUL
);
3488 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, op2_offset
+
3489 offsetof(ZMMReg
, ZMM_L(0)));
3491 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3492 tcg_gen_qemu_ld_tl(cpu_tmp0
, cpu_A0
,
3493 s
->mem_index
, MO_LEUW
);
3494 tcg_gen_st16_tl(cpu_tmp0
, cpu_env
, op2_offset
+
3495 offsetof(ZMMReg
, ZMM_W(0)));
3497 case 0x2a: /* movntqda */
3498 gen_ldo_env_A0(s
, op1_offset
);
3501 gen_ldo_env_A0(s
, op2_offset
);
3505 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
3507 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3509 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3510 gen_lea_modrm(env
, s
, modrm
);
3511 gen_ldq_env_A0(s
, op2_offset
);
3514 if (sse_fn_epp
== SSE_SPECIAL
) {
3518 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3519 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3520 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3523 set_cc_op(s
, CC_OP_EFLAGS
);
3530 /* Various integer extensions at 0f 38 f[0-f]. */
3531 b
= modrm
| (b1
<< 8);
3532 modrm
= cpu_ldub_code(env
, s
->pc
++);
3533 reg
= ((modrm
>> 3) & 7) | rex_r
;
3536 case 0x3f0: /* crc32 Gd,Eb */
3537 case 0x3f1: /* crc32 Gd,Ey */
3539 if (!(s
->cpuid_ext_features
& CPUID_EXT_SSE42
)) {
3542 if ((b
& 0xff) == 0xf0) {
3544 } else if (s
->dflag
!= MO_64
) {
3545 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3550 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[reg
]);
3551 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3552 gen_helper_crc32(cpu_T0
, cpu_tmp2_i32
,
3553 cpu_T0
, tcg_const_i32(8 << ot
));
3555 ot
= mo_64_32(s
->dflag
);
3556 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3559 case 0x1f0: /* crc32 or movbe */
3561 /* For these insns, the f3 prefix is supposed to have priority
3562 over the 66 prefix, but that's not what we implement above
3564 if (s
->prefix
& PREFIX_REPNZ
) {
3568 case 0x0f0: /* movbe Gy,My */
3569 case 0x0f1: /* movbe My,Gy */
3570 if (!(s
->cpuid_ext_features
& CPUID_EXT_MOVBE
)) {
3573 if (s
->dflag
!= MO_64
) {
3574 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3579 gen_lea_modrm(env
, s
, modrm
);
3581 tcg_gen_qemu_ld_tl(cpu_T0
, cpu_A0
,
3582 s
->mem_index
, ot
| MO_BE
);
3583 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3585 tcg_gen_qemu_st_tl(cpu_regs
[reg
], cpu_A0
,
3586 s
->mem_index
, ot
| MO_BE
);
3590 case 0x0f2: /* andn Gy, By, Ey */
3591 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3592 || !(s
->prefix
& PREFIX_VEX
)
3596 ot
= mo_64_32(s
->dflag
);
3597 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3598 tcg_gen_andc_tl(cpu_T0
, cpu_regs
[s
->vex_v
], cpu_T0
);
3599 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3600 gen_op_update1_cc();
3601 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3604 case 0x0f7: /* bextr Gy, Ey, By */
3605 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3606 || !(s
->prefix
& PREFIX_VEX
)
3610 ot
= mo_64_32(s
->dflag
);
3614 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3615 /* Extract START, and shift the operand.
3616 Shifts larger than operand size get zeros. */
3617 tcg_gen_ext8u_tl(cpu_A0
, cpu_regs
[s
->vex_v
]);
3618 tcg_gen_shr_tl(cpu_T0
, cpu_T0
, cpu_A0
);
3620 bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3621 zero
= tcg_const_tl(0);
3622 tcg_gen_movcond_tl(TCG_COND_LEU
, cpu_T0
, cpu_A0
, bound
,
3624 tcg_temp_free(zero
);
3626 /* Extract the LEN into a mask. Lengths larger than
3627 operand size get all ones. */
3628 tcg_gen_shri_tl(cpu_A0
, cpu_regs
[s
->vex_v
], 8);
3629 tcg_gen_ext8u_tl(cpu_A0
, cpu_A0
);
3630 tcg_gen_movcond_tl(TCG_COND_LEU
, cpu_A0
, cpu_A0
, bound
,
3632 tcg_temp_free(bound
);
3633 tcg_gen_movi_tl(cpu_T1
, 1);
3634 tcg_gen_shl_tl(cpu_T1
, cpu_T1
, cpu_A0
);
3635 tcg_gen_subi_tl(cpu_T1
, cpu_T1
, 1);
3636 tcg_gen_and_tl(cpu_T0
, cpu_T0
, cpu_T1
);
3638 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3639 gen_op_update1_cc();
3640 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3644 case 0x0f5: /* bzhi Gy, Ey, By */
3645 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3646 || !(s
->prefix
& PREFIX_VEX
)
3650 ot
= mo_64_32(s
->dflag
);
3651 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3652 tcg_gen_ext8u_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3654 TCGv bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3655 /* Note that since we're using BMILG (in order to get O
3656 cleared) we need to store the inverse into C. */
3657 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_cc_src
,
3659 tcg_gen_movcond_tl(TCG_COND_GT
, cpu_T1
, cpu_T1
,
3660 bound
, bound
, cpu_T1
);
3661 tcg_temp_free(bound
);
3663 tcg_gen_movi_tl(cpu_A0
, -1);
3664 tcg_gen_shl_tl(cpu_A0
, cpu_A0
, cpu_T1
);
3665 tcg_gen_andc_tl(cpu_T0
, cpu_T0
, cpu_A0
);
3666 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3667 gen_op_update1_cc();
3668 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
3671 case 0x3f6: /* mulx By, Gy, rdx, Ey */
3672 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3673 || !(s
->prefix
& PREFIX_VEX
)
3677 ot
= mo_64_32(s
->dflag
);
3678 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3681 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
3682 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EDX
]);
3683 tcg_gen_mulu2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
3684 cpu_tmp2_i32
, cpu_tmp3_i32
);
3685 tcg_gen_extu_i32_tl(cpu_regs
[s
->vex_v
], cpu_tmp2_i32
);
3686 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp3_i32
);
3688 #ifdef TARGET_X86_64
3690 tcg_gen_mulu2_i64(cpu_T0
, cpu_T1
,
3691 cpu_T0
, cpu_regs
[R_EDX
]);
3692 tcg_gen_mov_i64(cpu_regs
[s
->vex_v
], cpu_T0
);
3693 tcg_gen_mov_i64(cpu_regs
[reg
], cpu_T1
);
3699 case 0x3f5: /* pdep Gy, By, Ey */
3700 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3701 || !(s
->prefix
& PREFIX_VEX
)
3705 ot
= mo_64_32(s
->dflag
);
3706 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3707 /* Note that by zero-extending the mask operand, we
3708 automatically handle zero-extending the result. */
3710 tcg_gen_mov_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3712 tcg_gen_ext32u_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3714 gen_helper_pdep(cpu_regs
[reg
], cpu_T0
, cpu_T1
);
3717 case 0x2f5: /* pext Gy, By, Ey */
3718 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3719 || !(s
->prefix
& PREFIX_VEX
)
3723 ot
= mo_64_32(s
->dflag
);
3724 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3725 /* Note that by zero-extending the mask operand, we
3726 automatically handle zero-extending the result. */
3728 tcg_gen_mov_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3730 tcg_gen_ext32u_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3732 gen_helper_pext(cpu_regs
[reg
], cpu_T0
, cpu_T1
);
3735 case 0x1f6: /* adcx Gy, Ey */
3736 case 0x2f6: /* adox Gy, Ey */
3737 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_ADX
)) {
3740 TCGv carry_in
, carry_out
, zero
;
3743 ot
= mo_64_32(s
->dflag
);
3744 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3746 /* Re-use the carry-out from a previous round. */
3747 TCGV_UNUSED(carry_in
);
3748 carry_out
= (b
== 0x1f6 ? cpu_cc_dst
: cpu_cc_src2
);
3752 carry_in
= cpu_cc_dst
;
3753 end_op
= CC_OP_ADCX
;
3755 end_op
= CC_OP_ADCOX
;
3760 end_op
= CC_OP_ADCOX
;
3762 carry_in
= cpu_cc_src2
;
3763 end_op
= CC_OP_ADOX
;
3767 end_op
= CC_OP_ADCOX
;
3768 carry_in
= carry_out
;
3771 end_op
= (b
== 0x1f6 ? CC_OP_ADCX
: CC_OP_ADOX
);
3774 /* If we can't reuse carry-out, get it out of EFLAGS. */
3775 if (TCGV_IS_UNUSED(carry_in
)) {
3776 if (s
->cc_op
!= CC_OP_ADCX
&& s
->cc_op
!= CC_OP_ADOX
) {
3777 gen_compute_eflags(s
);
3779 carry_in
= cpu_tmp0
;
3780 tcg_gen_shri_tl(carry_in
, cpu_cc_src
,
3781 ctz32(b
== 0x1f6 ? CC_C
: CC_O
));
3782 tcg_gen_andi_tl(carry_in
, carry_in
, 1);
3786 #ifdef TARGET_X86_64
3788 /* If we know TL is 64-bit, and we want a 32-bit
3789 result, just do everything in 64-bit arithmetic. */
3790 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_regs
[reg
]);
3791 tcg_gen_ext32u_i64(cpu_T0
, cpu_T0
);
3792 tcg_gen_add_i64(cpu_T0
, cpu_T0
, cpu_regs
[reg
]);
3793 tcg_gen_add_i64(cpu_T0
, cpu_T0
, carry_in
);
3794 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_T0
);
3795 tcg_gen_shri_i64(carry_out
, cpu_T0
, 32);
3799 /* Otherwise compute the carry-out in two steps. */
3800 zero
= tcg_const_tl(0);
3801 tcg_gen_add2_tl(cpu_T0
, carry_out
,
3804 tcg_gen_add2_tl(cpu_regs
[reg
], carry_out
,
3805 cpu_regs
[reg
], carry_out
,
3807 tcg_temp_free(zero
);
3810 set_cc_op(s
, end_op
);
3814 case 0x1f7: /* shlx Gy, Ey, By */
3815 case 0x2f7: /* sarx Gy, Ey, By */
3816 case 0x3f7: /* shrx Gy, Ey, By */
3817 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3818 || !(s
->prefix
& PREFIX_VEX
)
3822 ot
= mo_64_32(s
->dflag
);
3823 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3825 tcg_gen_andi_tl(cpu_T1
, cpu_regs
[s
->vex_v
], 63);
3827 tcg_gen_andi_tl(cpu_T1
, cpu_regs
[s
->vex_v
], 31);
3830 tcg_gen_shl_tl(cpu_T0
, cpu_T0
, cpu_T1
);
3831 } else if (b
== 0x2f7) {
3833 tcg_gen_ext32s_tl(cpu_T0
, cpu_T0
);
3835 tcg_gen_sar_tl(cpu_T0
, cpu_T0
, cpu_T1
);
3838 tcg_gen_ext32u_tl(cpu_T0
, cpu_T0
);
3840 tcg_gen_shr_tl(cpu_T0
, cpu_T0
, cpu_T1
);
3842 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3848 case 0x3f3: /* Group 17 */
3849 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3850 || !(s
->prefix
& PREFIX_VEX
)
3854 ot
= mo_64_32(s
->dflag
);
3855 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3858 case 1: /* blsr By,Ey */
3859 tcg_gen_neg_tl(cpu_T1
, cpu_T0
);
3860 tcg_gen_and_tl(cpu_T0
, cpu_T0
, cpu_T1
);
3861 gen_op_mov_reg_v(ot
, s
->vex_v
, cpu_T0
);
3862 gen_op_update2_cc();
3863 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
3866 case 2: /* blsmsk By,Ey */
3867 tcg_gen_mov_tl(cpu_cc_src
, cpu_T0
);
3868 tcg_gen_subi_tl(cpu_T0
, cpu_T0
, 1);
3869 tcg_gen_xor_tl(cpu_T0
, cpu_T0
, cpu_cc_src
);
3870 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
3871 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
3874 case 3: /* blsi By, Ey */
3875 tcg_gen_mov_tl(cpu_cc_src
, cpu_T0
);
3876 tcg_gen_subi_tl(cpu_T0
, cpu_T0
, 1);
3877 tcg_gen_and_tl(cpu_T0
, cpu_T0
, cpu_cc_src
);
3878 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
3879 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
3895 modrm
= cpu_ldub_code(env
, s
->pc
++);
3897 reg
= ((modrm
>> 3) & 7) | rex_r
;
3898 mod
= (modrm
>> 6) & 3;
3903 sse_fn_eppi
= sse_op_table7
[b
].op
[b1
];
3907 if (!(s
->cpuid_ext_features
& sse_op_table7
[b
].ext_mask
))
3910 if (sse_fn_eppi
== SSE_SPECIAL
) {
3911 ot
= mo_64_32(s
->dflag
);
3912 rm
= (modrm
& 7) | REX_B(s
);
3914 gen_lea_modrm(env
, s
, modrm
);
3915 reg
= ((modrm
>> 3) & 7) | rex_r
;
3916 val
= cpu_ldub_code(env
, s
->pc
++);
3918 case 0x14: /* pextrb */
3919 tcg_gen_ld8u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,
3920 xmm_regs
[reg
].ZMM_B(val
& 15)));
3922 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
3924 tcg_gen_qemu_st_tl(cpu_T0
, cpu_A0
,
3925 s
->mem_index
, MO_UB
);
3928 case 0x15: /* pextrw */
3929 tcg_gen_ld16u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,
3930 xmm_regs
[reg
].ZMM_W(val
& 7)));
3932 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
3934 tcg_gen_qemu_st_tl(cpu_T0
, cpu_A0
,
3935 s
->mem_index
, MO_LEUW
);
3939 if (ot
== MO_32
) { /* pextrd */
3940 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
3941 offsetof(CPUX86State
,
3942 xmm_regs
[reg
].ZMM_L(val
& 3)));
3944 tcg_gen_extu_i32_tl(cpu_regs
[rm
], cpu_tmp2_i32
);
3946 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
3947 s
->mem_index
, MO_LEUL
);
3949 } else { /* pextrq */
3950 #ifdef TARGET_X86_64
3951 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
3952 offsetof(CPUX86State
,
3953 xmm_regs
[reg
].ZMM_Q(val
& 1)));
3955 tcg_gen_mov_i64(cpu_regs
[rm
], cpu_tmp1_i64
);
3957 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
3958 s
->mem_index
, MO_LEQ
);
3965 case 0x17: /* extractps */
3966 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,
3967 xmm_regs
[reg
].ZMM_L(val
& 3)));
3969 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
3971 tcg_gen_qemu_st_tl(cpu_T0
, cpu_A0
,
3972 s
->mem_index
, MO_LEUL
);
3975 case 0x20: /* pinsrb */
3977 gen_op_mov_v_reg(MO_32
, cpu_T0
, rm
);
3979 tcg_gen_qemu_ld_tl(cpu_T0
, cpu_A0
,
3980 s
->mem_index
, MO_UB
);
3982 tcg_gen_st8_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,
3983 xmm_regs
[reg
].ZMM_B(val
& 15)));
3985 case 0x21: /* insertps */
3987 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
3988 offsetof(CPUX86State
,xmm_regs
[rm
]
3989 .ZMM_L((val
>> 6) & 3)));
3991 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
3992 s
->mem_index
, MO_LEUL
);
3994 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
3995 offsetof(CPUX86State
,xmm_regs
[reg
]
3996 .ZMM_L((val
>> 4) & 3)));
3998 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
3999 cpu_env
, offsetof(CPUX86State
,
4000 xmm_regs
[reg
].ZMM_L(0)));
4002 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4003 cpu_env
, offsetof(CPUX86State
,
4004 xmm_regs
[reg
].ZMM_L(1)));
4006 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4007 cpu_env
, offsetof(CPUX86State
,
4008 xmm_regs
[reg
].ZMM_L(2)));
4010 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4011 cpu_env
, offsetof(CPUX86State
,
4012 xmm_regs
[reg
].ZMM_L(3)));
4015 if (ot
== MO_32
) { /* pinsrd */
4017 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[rm
]);
4019 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
4020 s
->mem_index
, MO_LEUL
);
4022 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4023 offsetof(CPUX86State
,
4024 xmm_regs
[reg
].ZMM_L(val
& 3)));
4025 } else { /* pinsrq */
4026 #ifdef TARGET_X86_64
4028 gen_op_mov_v_reg(ot
, cpu_tmp1_i64
, rm
);
4030 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
4031 s
->mem_index
, MO_LEQ
);
4033 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
4034 offsetof(CPUX86State
,
4035 xmm_regs
[reg
].ZMM_Q(val
& 1)));
4046 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4048 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
4050 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4051 gen_lea_modrm(env
, s
, modrm
);
4052 gen_ldo_env_A0(s
, op2_offset
);
4055 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4057 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4059 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4060 gen_lea_modrm(env
, s
, modrm
);
4061 gen_ldq_env_A0(s
, op2_offset
);
4064 val
= cpu_ldub_code(env
, s
->pc
++);
4066 if ((b
& 0xfc) == 0x60) { /* pcmpXstrX */
4067 set_cc_op(s
, CC_OP_EFLAGS
);
4069 if (s
->dflag
== MO_64
) {
4070 /* The helper must use entire 64-bit gp registers */
4075 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4076 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4077 sse_fn_eppi(cpu_env
, cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4081 /* Various integer extensions at 0f 3a f[0-f]. */
4082 b
= modrm
| (b1
<< 8);
4083 modrm
= cpu_ldub_code(env
, s
->pc
++);
4084 reg
= ((modrm
>> 3) & 7) | rex_r
;
4087 case 0x3f0: /* rorx Gy,Ey, Ib */
4088 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4089 || !(s
->prefix
& PREFIX_VEX
)
4093 ot
= mo_64_32(s
->dflag
);
4094 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4095 b
= cpu_ldub_code(env
, s
->pc
++);
4097 tcg_gen_rotri_tl(cpu_T0
, cpu_T0
, b
& 63);
4099 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
4100 tcg_gen_rotri_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, b
& 31);
4101 tcg_gen_extu_i32_tl(cpu_T0
, cpu_tmp2_i32
);
4103 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
4115 /* generic MMX or SSE operation */
4117 case 0x70: /* pshufx insn */
4118 case 0xc6: /* pshufx insn */
4119 case 0xc2: /* compare insns */
4126 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4130 gen_lea_modrm(env
, s
, modrm
);
4131 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4137 /* Most sse scalar operations. */
4140 } else if (b1
== 3) {
4145 case 0x2e: /* ucomis[sd] */
4146 case 0x2f: /* comis[sd] */
4158 gen_op_ld_v(s
, MO_32
, cpu_T0
, cpu_A0
);
4159 tcg_gen_st32_tl(cpu_T0
, cpu_env
,
4160 offsetof(CPUX86State
,xmm_t0
.ZMM_L(0)));
4164 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.ZMM_D(0)));
4167 /* 128 bit access */
4168 gen_ldo_env_A0(s
, op2_offset
);
4172 rm
= (modrm
& 7) | REX_B(s
);
4173 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
4176 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4178 gen_lea_modrm(env
, s
, modrm
);
4179 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4180 gen_ldq_env_A0(s
, op2_offset
);
4183 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4187 case 0x0f: /* 3DNow! data insns */
4188 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
))
4190 val
= cpu_ldub_code(env
, s
->pc
++);
4191 sse_fn_epp
= sse_op_table5
[val
];
4195 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4196 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4197 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4199 case 0x70: /* pshufx insn */
4200 case 0xc6: /* pshufx insn */
4201 val
= cpu_ldub_code(env
, s
->pc
++);
4202 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4203 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4204 /* XXX: introduce a new table? */
4205 sse_fn_ppi
= (SSEFunc_0_ppi
)sse_fn_epp
;
4206 sse_fn_ppi(cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4210 val
= cpu_ldub_code(env
, s
->pc
++);
4213 sse_fn_epp
= sse_op_table4
[val
][b1
];
4215 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4216 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4217 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4220 /* maskmov : we must prepare A0 */
4223 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EDI
]);
4224 gen_extu(s
->aflag
, cpu_A0
);
4225 gen_add_A0_ds_seg(s
);
4227 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4228 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4229 /* XXX: introduce a new table? */
4230 sse_fn_eppt
= (SSEFunc_0_eppt
)sse_fn_epp
;
4231 sse_fn_eppt(cpu_env
, cpu_ptr0
, cpu_ptr1
, cpu_A0
);
4234 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4235 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4236 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4239 if (b
== 0x2e || b
== 0x2f) {
4240 set_cc_op(s
, CC_OP_EFLAGS
);
4245 /* convert one instruction. s->is_jmp is set if the translation must
4246 be stopped. Return the next pc value */
4247 static target_ulong
disas_insn(CPUX86State
*env
, DisasContext
*s
,
4248 target_ulong pc_start
)
4252 TCGMemOp ot
, aflag
, dflag
;
4253 int modrm
, reg
, rm
, mod
, op
, opreg
, val
;
4254 target_ulong next_eip
, tval
;
4262 #ifdef TARGET_X86_64
4267 s
->rip_offset
= 0; /* for relative ip address */
4271 b
= cpu_ldub_code(env
, s
->pc
);
4273 /* Collect prefixes. */
4276 prefixes
|= PREFIX_REPZ
;
4279 prefixes
|= PREFIX_REPNZ
;
4282 prefixes
|= PREFIX_LOCK
;
4303 prefixes
|= PREFIX_DATA
;
4306 prefixes
|= PREFIX_ADR
;
4308 #ifdef TARGET_X86_64
4312 rex_w
= (b
>> 3) & 1;
4313 rex_r
= (b
& 0x4) << 1;
4314 s
->rex_x
= (b
& 0x2) << 2;
4315 REX_B(s
) = (b
& 0x1) << 3;
4316 x86_64_hregs
= 1; /* select uniform byte register addressing */
4321 case 0xc5: /* 2-byte VEX */
4322 case 0xc4: /* 3-byte VEX */
4323 /* VEX prefixes cannot be used except in 32-bit mode.
4324 Otherwise the instruction is LES or LDS. */
4325 if (s
->code32
&& !s
->vm86
) {
4326 static const int pp_prefix
[4] = {
4327 0, PREFIX_DATA
, PREFIX_REPZ
, PREFIX_REPNZ
4329 int vex3
, vex2
= cpu_ldub_code(env
, s
->pc
);
4331 if (!CODE64(s
) && (vex2
& 0xc0) != 0xc0) {
4332 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4333 otherwise the instruction is LES or LDS. */
4338 /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
4339 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
4340 | PREFIX_LOCK
| PREFIX_DATA
)) {
4343 #ifdef TARGET_X86_64
4348 rex_r
= (~vex2
>> 4) & 8;
4351 b
= cpu_ldub_code(env
, s
->pc
++);
4353 #ifdef TARGET_X86_64
4354 s
->rex_x
= (~vex2
>> 3) & 8;
4355 s
->rex_b
= (~vex2
>> 2) & 8;
4357 vex3
= cpu_ldub_code(env
, s
->pc
++);
4358 rex_w
= (vex3
>> 7) & 1;
4359 switch (vex2
& 0x1f) {
4360 case 0x01: /* Implied 0f leading opcode bytes. */
4361 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4363 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4366 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4369 default: /* Reserved for future use. */
4373 s
->vex_v
= (~vex3
>> 3) & 0xf;
4374 s
->vex_l
= (vex3
>> 2) & 1;
4375 prefixes
|= pp_prefix
[vex3
& 3] | PREFIX_VEX
;
4380 /* Post-process prefixes. */
4382 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit
4383 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4384 over 0x66 if both are present. */
4385 dflag
= (rex_w
> 0 ? MO_64
: prefixes
& PREFIX_DATA
? MO_16
: MO_32
);
4386 /* In 64-bit mode, 0x67 selects 32-bit addressing. */
4387 aflag
= (prefixes
& PREFIX_ADR
? MO_32
: MO_64
);
4389 /* In 16/32-bit mode, 0x66 selects the opposite data size. */
4390 if (s
->code32
^ ((prefixes
& PREFIX_DATA
) != 0)) {
4395 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */
4396 if (s
->code32
^ ((prefixes
& PREFIX_ADR
) != 0)) {
4403 s
->prefix
= prefixes
;
4407 /* lock generation */
4408 if (prefixes
& PREFIX_LOCK
)
4411 /* now check op code */
4415 /**************************/
4416 /* extended op code */
4417 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4420 /**************************/
4435 ot
= mo_b_d(b
, dflag
);
4438 case 0: /* OP Ev, Gv */
4439 modrm
= cpu_ldub_code(env
, s
->pc
++);
4440 reg
= ((modrm
>> 3) & 7) | rex_r
;
4441 mod
= (modrm
>> 6) & 3;
4442 rm
= (modrm
& 7) | REX_B(s
);
4444 gen_lea_modrm(env
, s
, modrm
);
4446 } else if (op
== OP_XORL
&& rm
== reg
) {
4448 /* xor reg, reg optimisation */
4449 set_cc_op(s
, CC_OP_CLR
);
4450 tcg_gen_movi_tl(cpu_T0
, 0);
4451 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
4456 gen_op_mov_v_reg(ot
, cpu_T1
, reg
);
4457 gen_op(s
, op
, ot
, opreg
);
4459 case 1: /* OP Gv, Ev */
4460 modrm
= cpu_ldub_code(env
, s
->pc
++);
4461 mod
= (modrm
>> 6) & 3;
4462 reg
= ((modrm
>> 3) & 7) | rex_r
;
4463 rm
= (modrm
& 7) | REX_B(s
);
4465 gen_lea_modrm(env
, s
, modrm
);
4466 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
4467 } else if (op
== OP_XORL
&& rm
== reg
) {
4470 gen_op_mov_v_reg(ot
, cpu_T1
, rm
);
4472 gen_op(s
, op
, ot
, reg
);
4474 case 2: /* OP A, Iv */
4475 val
= insn_get(env
, s
, ot
);
4476 tcg_gen_movi_tl(cpu_T1
, val
);
4477 gen_op(s
, op
, ot
, OR_EAX
);
4486 case 0x80: /* GRP1 */
4492 ot
= mo_b_d(b
, dflag
);
4494 modrm
= cpu_ldub_code(env
, s
->pc
++);
4495 mod
= (modrm
>> 6) & 3;
4496 rm
= (modrm
& 7) | REX_B(s
);
4497 op
= (modrm
>> 3) & 7;
4503 s
->rip_offset
= insn_const_size(ot
);
4504 gen_lea_modrm(env
, s
, modrm
);
4515 val
= insn_get(env
, s
, ot
);
4518 val
= (int8_t)insn_get(env
, s
, MO_8
);
4521 tcg_gen_movi_tl(cpu_T1
, val
);
4522 gen_op(s
, op
, ot
, opreg
);
4526 /**************************/
4527 /* inc, dec, and other misc arith */
4528 case 0x40 ... 0x47: /* inc Gv */
4530 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), 1);
4532 case 0x48 ... 0x4f: /* dec Gv */
4534 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), -1);
4536 case 0xf6: /* GRP3 */
4538 ot
= mo_b_d(b
, dflag
);
4540 modrm
= cpu_ldub_code(env
, s
->pc
++);
4541 mod
= (modrm
>> 6) & 3;
4542 rm
= (modrm
& 7) | REX_B(s
);
4543 op
= (modrm
>> 3) & 7;
4546 s
->rip_offset
= insn_const_size(ot
);
4547 gen_lea_modrm(env
, s
, modrm
);
4548 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
4550 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
4555 val
= insn_get(env
, s
, ot
);
4556 tcg_gen_movi_tl(cpu_T1
, val
);
4557 gen_op_testl_T0_T1_cc();
4558 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4561 tcg_gen_not_tl(cpu_T0
, cpu_T0
);
4563 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
4565 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
4569 tcg_gen_neg_tl(cpu_T0
, cpu_T0
);
4571 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
4573 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
4575 gen_op_update_neg_cc();
4576 set_cc_op(s
, CC_OP_SUBB
+ ot
);
4581 gen_op_mov_v_reg(MO_8
, cpu_T1
, R_EAX
);
4582 tcg_gen_ext8u_tl(cpu_T0
, cpu_T0
);
4583 tcg_gen_ext8u_tl(cpu_T1
, cpu_T1
);
4584 /* XXX: use 32 bit mul which could be faster */
4585 tcg_gen_mul_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4586 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
4587 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
4588 tcg_gen_andi_tl(cpu_cc_src
, cpu_T0
, 0xff00);
4589 set_cc_op(s
, CC_OP_MULB
);
4592 gen_op_mov_v_reg(MO_16
, cpu_T1
, R_EAX
);
4593 tcg_gen_ext16u_tl(cpu_T0
, cpu_T0
);
4594 tcg_gen_ext16u_tl(cpu_T1
, cpu_T1
);
4595 /* XXX: use 32 bit mul which could be faster */
4596 tcg_gen_mul_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4597 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
4598 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
4599 tcg_gen_shri_tl(cpu_T0
, cpu_T0
, 16);
4600 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T0
);
4601 tcg_gen_mov_tl(cpu_cc_src
, cpu_T0
);
4602 set_cc_op(s
, CC_OP_MULW
);
4606 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
4607 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
4608 tcg_gen_mulu2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4609 cpu_tmp2_i32
, cpu_tmp3_i32
);
4610 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
4611 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
4612 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4613 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4614 set_cc_op(s
, CC_OP_MULL
);
4616 #ifdef TARGET_X86_64
4618 tcg_gen_mulu2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4619 cpu_T0
, cpu_regs
[R_EAX
]);
4620 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4621 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4622 set_cc_op(s
, CC_OP_MULQ
);
4630 gen_op_mov_v_reg(MO_8
, cpu_T1
, R_EAX
);
4631 tcg_gen_ext8s_tl(cpu_T0
, cpu_T0
);
4632 tcg_gen_ext8s_tl(cpu_T1
, cpu_T1
);
4633 /* XXX: use 32 bit mul which could be faster */
4634 tcg_gen_mul_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4635 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
4636 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
4637 tcg_gen_ext8s_tl(cpu_tmp0
, cpu_T0
);
4638 tcg_gen_sub_tl(cpu_cc_src
, cpu_T0
, cpu_tmp0
);
4639 set_cc_op(s
, CC_OP_MULB
);
4642 gen_op_mov_v_reg(MO_16
, cpu_T1
, R_EAX
);
4643 tcg_gen_ext16s_tl(cpu_T0
, cpu_T0
);
4644 tcg_gen_ext16s_tl(cpu_T1
, cpu_T1
);
4645 /* XXX: use 32 bit mul which could be faster */
4646 tcg_gen_mul_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4647 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
4648 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
4649 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T0
);
4650 tcg_gen_sub_tl(cpu_cc_src
, cpu_T0
, cpu_tmp0
);
4651 tcg_gen_shri_tl(cpu_T0
, cpu_T0
, 16);
4652 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T0
);
4653 set_cc_op(s
, CC_OP_MULW
);
4657 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
4658 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
4659 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4660 cpu_tmp2_i32
, cpu_tmp3_i32
);
4661 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
4662 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
4663 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
4664 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4665 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
4666 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
4667 set_cc_op(s
, CC_OP_MULL
);
4669 #ifdef TARGET_X86_64
4671 tcg_gen_muls2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4672 cpu_T0
, cpu_regs
[R_EAX
]);
4673 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4674 tcg_gen_sari_tl(cpu_cc_src
, cpu_regs
[R_EAX
], 63);
4675 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_regs
[R_EDX
]);
4676 set_cc_op(s
, CC_OP_MULQ
);
4684 gen_helper_divb_AL(cpu_env
, cpu_T0
);
4687 gen_helper_divw_AX(cpu_env
, cpu_T0
);
4691 gen_helper_divl_EAX(cpu_env
, cpu_T0
);
4693 #ifdef TARGET_X86_64
4695 gen_helper_divq_EAX(cpu_env
, cpu_T0
);
4703 gen_helper_idivb_AL(cpu_env
, cpu_T0
);
4706 gen_helper_idivw_AX(cpu_env
, cpu_T0
);
4710 gen_helper_idivl_EAX(cpu_env
, cpu_T0
);
4712 #ifdef TARGET_X86_64
4714 gen_helper_idivq_EAX(cpu_env
, cpu_T0
);
4724 case 0xfe: /* GRP4 */
4725 case 0xff: /* GRP5 */
4726 ot
= mo_b_d(b
, dflag
);
4728 modrm
= cpu_ldub_code(env
, s
->pc
++);
4729 mod
= (modrm
>> 6) & 3;
4730 rm
= (modrm
& 7) | REX_B(s
);
4731 op
= (modrm
>> 3) & 7;
4732 if (op
>= 2 && b
== 0xfe) {
4736 if (op
== 2 || op
== 4) {
4737 /* operand size for jumps is 64 bit */
4739 } else if (op
== 3 || op
== 5) {
4740 ot
= dflag
!= MO_16
? MO_32
+ (rex_w
== 1) : MO_16
;
4741 } else if (op
== 6) {
4742 /* default push size is 64 bit */
4743 ot
= mo_pushpop(s
, dflag
);
4747 gen_lea_modrm(env
, s
, modrm
);
4748 if (op
>= 2 && op
!= 3 && op
!= 5)
4749 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
4751 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
4755 case 0: /* inc Ev */
4760 gen_inc(s
, ot
, opreg
, 1);
4762 case 1: /* dec Ev */
4767 gen_inc(s
, ot
, opreg
, -1);
4769 case 2: /* call Ev */
4770 /* XXX: optimize if memory (no 'and' is necessary) */
4771 if (dflag
== MO_16
) {
4772 tcg_gen_ext16u_tl(cpu_T0
, cpu_T0
);
4774 next_eip
= s
->pc
- s
->cs_base
;
4775 tcg_gen_movi_tl(cpu_T1
, next_eip
);
4776 gen_push_v(s
, cpu_T1
);
4777 gen_op_jmp_v(cpu_T0
);
4780 case 3: /* lcall Ev */
4781 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
4782 gen_add_A0_im(s
, 1 << ot
);
4783 gen_op_ld_v(s
, MO_16
, cpu_T0
, cpu_A0
);
4785 if (s
->pe
&& !s
->vm86
) {
4786 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
4787 gen_helper_lcall_protected(cpu_env
, cpu_tmp2_i32
, cpu_T1
,
4788 tcg_const_i32(dflag
- 1),
4789 tcg_const_tl(s
->pc
- s
->cs_base
));
4791 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
4792 gen_helper_lcall_real(cpu_env
, cpu_tmp2_i32
, cpu_T1
,
4793 tcg_const_i32(dflag
- 1),
4794 tcg_const_i32(s
->pc
- s
->cs_base
));
4798 case 4: /* jmp Ev */
4799 if (dflag
== MO_16
) {
4800 tcg_gen_ext16u_tl(cpu_T0
, cpu_T0
);
4802 gen_op_jmp_v(cpu_T0
);
4805 case 5: /* ljmp Ev */
4806 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
4807 gen_add_A0_im(s
, 1 << ot
);
4808 gen_op_ld_v(s
, MO_16
, cpu_T0
, cpu_A0
);
4810 if (s
->pe
&& !s
->vm86
) {
4811 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
4812 gen_helper_ljmp_protected(cpu_env
, cpu_tmp2_i32
, cpu_T1
,
4813 tcg_const_tl(s
->pc
- s
->cs_base
));
4815 gen_op_movl_seg_T0_vm(R_CS
);
4816 gen_op_jmp_v(cpu_T1
);
4820 case 6: /* push Ev */
4821 gen_push_v(s
, cpu_T0
);
4828 case 0x84: /* test Ev, Gv */
4830 ot
= mo_b_d(b
, dflag
);
4832 modrm
= cpu_ldub_code(env
, s
->pc
++);
4833 reg
= ((modrm
>> 3) & 7) | rex_r
;
4835 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4836 gen_op_mov_v_reg(ot
, cpu_T1
, reg
);
4837 gen_op_testl_T0_T1_cc();
4838 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4841 case 0xa8: /* test eAX, Iv */
4843 ot
= mo_b_d(b
, dflag
);
4844 val
= insn_get(env
, s
, ot
);
4846 gen_op_mov_v_reg(ot
, cpu_T0
, OR_EAX
);
4847 tcg_gen_movi_tl(cpu_T1
, val
);
4848 gen_op_testl_T0_T1_cc();
4849 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4852 case 0x98: /* CWDE/CBW */
4854 #ifdef TARGET_X86_64
4856 gen_op_mov_v_reg(MO_32
, cpu_T0
, R_EAX
);
4857 tcg_gen_ext32s_tl(cpu_T0
, cpu_T0
);
4858 gen_op_mov_reg_v(MO_64
, R_EAX
, cpu_T0
);
4862 gen_op_mov_v_reg(MO_16
, cpu_T0
, R_EAX
);
4863 tcg_gen_ext16s_tl(cpu_T0
, cpu_T0
);
4864 gen_op_mov_reg_v(MO_32
, R_EAX
, cpu_T0
);
4867 gen_op_mov_v_reg(MO_8
, cpu_T0
, R_EAX
);
4868 tcg_gen_ext8s_tl(cpu_T0
, cpu_T0
);
4869 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
4875 case 0x99: /* CDQ/CWD */
4877 #ifdef TARGET_X86_64
4879 gen_op_mov_v_reg(MO_64
, cpu_T0
, R_EAX
);
4880 tcg_gen_sari_tl(cpu_T0
, cpu_T0
, 63);
4881 gen_op_mov_reg_v(MO_64
, R_EDX
, cpu_T0
);
4885 gen_op_mov_v_reg(MO_32
, cpu_T0
, R_EAX
);
4886 tcg_gen_ext32s_tl(cpu_T0
, cpu_T0
);
4887 tcg_gen_sari_tl(cpu_T0
, cpu_T0
, 31);
4888 gen_op_mov_reg_v(MO_32
, R_EDX
, cpu_T0
);
4891 gen_op_mov_v_reg(MO_16
, cpu_T0
, R_EAX
);
4892 tcg_gen_ext16s_tl(cpu_T0
, cpu_T0
);
4893 tcg_gen_sari_tl(cpu_T0
, cpu_T0
, 15);
4894 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T0
);
4900 case 0x1af: /* imul Gv, Ev */
4901 case 0x69: /* imul Gv, Ev, I */
4904 modrm
= cpu_ldub_code(env
, s
->pc
++);
4905 reg
= ((modrm
>> 3) & 7) | rex_r
;
4907 s
->rip_offset
= insn_const_size(ot
);
4910 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4912 val
= insn_get(env
, s
, ot
);
4913 tcg_gen_movi_tl(cpu_T1
, val
);
4914 } else if (b
== 0x6b) {
4915 val
= (int8_t)insn_get(env
, s
, MO_8
);
4916 tcg_gen_movi_tl(cpu_T1
, val
);
4918 gen_op_mov_v_reg(ot
, cpu_T1
, reg
);
4921 #ifdef TARGET_X86_64
4923 tcg_gen_muls2_i64(cpu_regs
[reg
], cpu_T1
, cpu_T0
, cpu_T1
);
4924 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
4925 tcg_gen_sari_tl(cpu_cc_src
, cpu_cc_dst
, 63);
4926 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_T1
);
4930 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
4931 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T1
);
4932 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4933 cpu_tmp2_i32
, cpu_tmp3_i32
);
4934 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
4935 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
4936 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
4937 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
4938 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
4941 tcg_gen_ext16s_tl(cpu_T0
, cpu_T0
);
4942 tcg_gen_ext16s_tl(cpu_T1
, cpu_T1
);
4943 /* XXX: use 32 bit mul which could be faster */
4944 tcg_gen_mul_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4945 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
4946 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T0
);
4947 tcg_gen_sub_tl(cpu_cc_src
, cpu_T0
, cpu_tmp0
);
4948 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
4951 set_cc_op(s
, CC_OP_MULB
+ ot
);
4954 case 0x1c1: /* xadd Ev, Gv */
4955 ot
= mo_b_d(b
, dflag
);
4956 modrm
= cpu_ldub_code(env
, s
->pc
++);
4957 reg
= ((modrm
>> 3) & 7) | rex_r
;
4958 mod
= (modrm
>> 6) & 3;
4960 rm
= (modrm
& 7) | REX_B(s
);
4961 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
4962 gen_op_mov_v_reg(ot
, cpu_T1
, rm
);
4963 tcg_gen_add_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4964 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
4965 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
4967 gen_lea_modrm(env
, s
, modrm
);
4968 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
4969 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
4970 tcg_gen_add_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4971 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
4972 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
4974 gen_op_update2_cc();
4975 set_cc_op(s
, CC_OP_ADDB
+ ot
);
4978 case 0x1b1: /* cmpxchg Ev, Gv */
4980 TCGLabel
*label1
, *label2
;
4981 TCGv t0
, t1
, t2
, a0
;
4983 ot
= mo_b_d(b
, dflag
);
4984 modrm
= cpu_ldub_code(env
, s
->pc
++);
4985 reg
= ((modrm
>> 3) & 7) | rex_r
;
4986 mod
= (modrm
>> 6) & 3;
4987 t0
= tcg_temp_local_new();
4988 t1
= tcg_temp_local_new();
4989 t2
= tcg_temp_local_new();
4990 a0
= tcg_temp_local_new();
4991 gen_op_mov_v_reg(ot
, t1
, reg
);
4993 rm
= (modrm
& 7) | REX_B(s
);
4994 gen_op_mov_v_reg(ot
, t0
, rm
);
4996 gen_lea_modrm(env
, s
, modrm
);
4997 tcg_gen_mov_tl(a0
, cpu_A0
);
4998 gen_op_ld_v(s
, ot
, t0
, a0
);
4999 rm
= 0; /* avoid warning */
5001 label1
= gen_new_label();
5002 tcg_gen_mov_tl(t2
, cpu_regs
[R_EAX
]);
5005 tcg_gen_brcond_tl(TCG_COND_EQ
, t2
, t0
, label1
);
5006 label2
= gen_new_label();
5008 gen_op_mov_reg_v(ot
, R_EAX
, t0
);
5010 gen_set_label(label1
);
5011 gen_op_mov_reg_v(ot
, rm
, t1
);
5013 /* perform no-op store cycle like physical cpu; must be
5014 before changing accumulator to ensure idempotency if
5015 the store faults and the instruction is restarted */
5016 gen_op_st_v(s
, ot
, t0
, a0
);
5017 gen_op_mov_reg_v(ot
, R_EAX
, t0
);
5019 gen_set_label(label1
);
5020 gen_op_st_v(s
, ot
, t1
, a0
);
5022 gen_set_label(label2
);
5023 tcg_gen_mov_tl(cpu_cc_src
, t0
);
5024 tcg_gen_mov_tl(cpu_cc_srcT
, t2
);
5025 tcg_gen_sub_tl(cpu_cc_dst
, t2
, t0
);
5026 set_cc_op(s
, CC_OP_SUBB
+ ot
);
5033 case 0x1c7: /* cmpxchg8b */
5034 modrm
= cpu_ldub_code(env
, s
->pc
++);
5035 mod
= (modrm
>> 6) & 3;
5036 if ((mod
== 3) || ((modrm
& 0x38) != 0x8))
5038 #ifdef TARGET_X86_64
5039 if (dflag
== MO_64
) {
5040 if (!(s
->cpuid_ext_features
& CPUID_EXT_CX16
))
5042 gen_lea_modrm(env
, s
, modrm
);
5043 gen_helper_cmpxchg16b(cpu_env
, cpu_A0
);
5047 if (!(s
->cpuid_features
& CPUID_CX8
))
5049 gen_lea_modrm(env
, s
, modrm
);
5050 gen_helper_cmpxchg8b(cpu_env
, cpu_A0
);
5052 set_cc_op(s
, CC_OP_EFLAGS
);
5055 /**************************/
5057 case 0x50 ... 0x57: /* push */
5058 gen_op_mov_v_reg(MO_32
, cpu_T0
, (b
& 7) | REX_B(s
));
5059 gen_push_v(s
, cpu_T0
);
5061 case 0x58 ... 0x5f: /* pop */
5063 /* NOTE: order is important for pop %sp */
5064 gen_pop_update(s
, ot
);
5065 gen_op_mov_reg_v(ot
, (b
& 7) | REX_B(s
), cpu_T0
);
5067 case 0x60: /* pusha */
5072 case 0x61: /* popa */
5077 case 0x68: /* push Iv */
5079 ot
= mo_pushpop(s
, dflag
);
5081 val
= insn_get(env
, s
, ot
);
5083 val
= (int8_t)insn_get(env
, s
, MO_8
);
5084 tcg_gen_movi_tl(cpu_T0
, val
);
5085 gen_push_v(s
, cpu_T0
);
5087 case 0x8f: /* pop Ev */
5088 modrm
= cpu_ldub_code(env
, s
->pc
++);
5089 mod
= (modrm
>> 6) & 3;
5092 /* NOTE: order is important for pop %sp */
5093 gen_pop_update(s
, ot
);
5094 rm
= (modrm
& 7) | REX_B(s
);
5095 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
5097 /* NOTE: order is important too for MMU exceptions */
5098 s
->popl_esp_hack
= 1 << ot
;
5099 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5100 s
->popl_esp_hack
= 0;
5101 gen_pop_update(s
, ot
);
5104 case 0xc8: /* enter */
5107 val
= cpu_lduw_code(env
, s
->pc
);
5109 level
= cpu_ldub_code(env
, s
->pc
++);
5110 gen_enter(s
, val
, level
);
5113 case 0xc9: /* leave */
5116 case 0x06: /* push es */
5117 case 0x0e: /* push cs */
5118 case 0x16: /* push ss */
5119 case 0x1e: /* push ds */
5122 gen_op_movl_T0_seg(b
>> 3);
5123 gen_push_v(s
, cpu_T0
);
5125 case 0x1a0: /* push fs */
5126 case 0x1a8: /* push gs */
5127 gen_op_movl_T0_seg((b
>> 3) & 7);
5128 gen_push_v(s
, cpu_T0
);
5130 case 0x07: /* pop es */
5131 case 0x17: /* pop ss */
5132 case 0x1f: /* pop ds */
5137 gen_movl_seg_T0(s
, reg
);
5138 gen_pop_update(s
, ot
);
5140 /* if reg == SS, inhibit interrupts/trace. */
5141 /* If several instructions disable interrupts, only the
5143 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
5144 gen_helper_set_inhibit_irq(cpu_env
);
5148 gen_jmp_im(s
->pc
- s
->cs_base
);
5152 case 0x1a1: /* pop fs */
5153 case 0x1a9: /* pop gs */
5155 gen_movl_seg_T0(s
, (b
>> 3) & 7);
5156 gen_pop_update(s
, ot
);
5158 gen_jmp_im(s
->pc
- s
->cs_base
);
5163 /**************************/
5166 case 0x89: /* mov Gv, Ev */
5167 ot
= mo_b_d(b
, dflag
);
5168 modrm
= cpu_ldub_code(env
, s
->pc
++);
5169 reg
= ((modrm
>> 3) & 7) | rex_r
;
5171 /* generate a generic store */
5172 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
5175 case 0xc7: /* mov Ev, Iv */
5176 ot
= mo_b_d(b
, dflag
);
5177 modrm
= cpu_ldub_code(env
, s
->pc
++);
5178 mod
= (modrm
>> 6) & 3;
5180 s
->rip_offset
= insn_const_size(ot
);
5181 gen_lea_modrm(env
, s
, modrm
);
5183 val
= insn_get(env
, s
, ot
);
5184 tcg_gen_movi_tl(cpu_T0
, val
);
5186 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
5188 gen_op_mov_reg_v(ot
, (modrm
& 7) | REX_B(s
), cpu_T0
);
5192 case 0x8b: /* mov Ev, Gv */
5193 ot
= mo_b_d(b
, dflag
);
5194 modrm
= cpu_ldub_code(env
, s
->pc
++);
5195 reg
= ((modrm
>> 3) & 7) | rex_r
;
5197 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5198 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
5200 case 0x8e: /* mov seg, Gv */
5201 modrm
= cpu_ldub_code(env
, s
->pc
++);
5202 reg
= (modrm
>> 3) & 7;
5203 if (reg
>= 6 || reg
== R_CS
)
5205 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
5206 gen_movl_seg_T0(s
, reg
);
5208 /* if reg == SS, inhibit interrupts/trace */
5209 /* If several instructions disable interrupts, only the
5211 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
5212 gen_helper_set_inhibit_irq(cpu_env
);
5216 gen_jmp_im(s
->pc
- s
->cs_base
);
5220 case 0x8c: /* mov Gv, seg */
5221 modrm
= cpu_ldub_code(env
, s
->pc
++);
5222 reg
= (modrm
>> 3) & 7;
5223 mod
= (modrm
>> 6) & 3;
5226 gen_op_movl_T0_seg(reg
);
5227 ot
= mod
== 3 ? dflag
: MO_16
;
5228 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5231 case 0x1b6: /* movzbS Gv, Eb */
5232 case 0x1b7: /* movzwS Gv, Eb */
5233 case 0x1be: /* movsbS Gv, Eb */
5234 case 0x1bf: /* movswS Gv, Eb */
5239 /* d_ot is the size of destination */
5241 /* ot is the size of source */
5242 ot
= (b
& 1) + MO_8
;
5243 /* s_ot is the sign+size of source */
5244 s_ot
= b
& 8 ? MO_SIGN
| ot
: ot
;
5246 modrm
= cpu_ldub_code(env
, s
->pc
++);
5247 reg
= ((modrm
>> 3) & 7) | rex_r
;
5248 mod
= (modrm
>> 6) & 3;
5249 rm
= (modrm
& 7) | REX_B(s
);
5252 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
5255 tcg_gen_ext8u_tl(cpu_T0
, cpu_T0
);
5258 tcg_gen_ext8s_tl(cpu_T0
, cpu_T0
);
5261 tcg_gen_ext16u_tl(cpu_T0
, cpu_T0
);
5265 tcg_gen_ext16s_tl(cpu_T0
, cpu_T0
);
5268 gen_op_mov_reg_v(d_ot
, reg
, cpu_T0
);
5270 gen_lea_modrm(env
, s
, modrm
);
5271 gen_op_ld_v(s
, s_ot
, cpu_T0
, cpu_A0
);
5272 gen_op_mov_reg_v(d_ot
, reg
, cpu_T0
);
5277 case 0x8d: /* lea */
5279 modrm
= cpu_ldub_code(env
, s
->pc
++);
5280 mod
= (modrm
>> 6) & 3;
5283 reg
= ((modrm
>> 3) & 7) | rex_r
;
5284 /* we must ensure that no segment is added */
5288 gen_lea_modrm(env
, s
, modrm
);
5290 gen_op_mov_reg_v(ot
, reg
, cpu_A0
);
5293 case 0xa0: /* mov EAX, Ov */
5295 case 0xa2: /* mov Ov, EAX */
5298 target_ulong offset_addr
;
5300 ot
= mo_b_d(b
, dflag
);
5302 #ifdef TARGET_X86_64
5304 offset_addr
= cpu_ldq_code(env
, s
->pc
);
5309 offset_addr
= insn_get(env
, s
, s
->aflag
);
5312 tcg_gen_movi_tl(cpu_A0
, offset_addr
);
5313 gen_add_A0_ds_seg(s
);
5315 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
5316 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T0
);
5318 gen_op_mov_v_reg(ot
, cpu_T0
, R_EAX
);
5319 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
5323 case 0xd7: /* xlat */
5324 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EBX
]);
5325 tcg_gen_ext8u_tl(cpu_T0
, cpu_regs
[R_EAX
]);
5326 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_T0
);
5327 gen_extu(s
->aflag
, cpu_A0
);
5328 gen_add_A0_ds_seg(s
);
5329 gen_op_ld_v(s
, MO_8
, cpu_T0
, cpu_A0
);
5330 gen_op_mov_reg_v(MO_8
, R_EAX
, cpu_T0
);
5332 case 0xb0 ... 0xb7: /* mov R, Ib */
5333 val
= insn_get(env
, s
, MO_8
);
5334 tcg_gen_movi_tl(cpu_T0
, val
);
5335 gen_op_mov_reg_v(MO_8
, (b
& 7) | REX_B(s
), cpu_T0
);
5337 case 0xb8 ... 0xbf: /* mov R, Iv */
5338 #ifdef TARGET_X86_64
5339 if (dflag
== MO_64
) {
5342 tmp
= cpu_ldq_code(env
, s
->pc
);
5344 reg
= (b
& 7) | REX_B(s
);
5345 tcg_gen_movi_tl(cpu_T0
, tmp
);
5346 gen_op_mov_reg_v(MO_64
, reg
, cpu_T0
);
5351 val
= insn_get(env
, s
, ot
);
5352 reg
= (b
& 7) | REX_B(s
);
5353 tcg_gen_movi_tl(cpu_T0
, val
);
5354 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
5358 case 0x91 ... 0x97: /* xchg R, EAX */
5361 reg
= (b
& 7) | REX_B(s
);
5365 case 0x87: /* xchg Ev, Gv */
5366 ot
= mo_b_d(b
, dflag
);
5367 modrm
= cpu_ldub_code(env
, s
->pc
++);
5368 reg
= ((modrm
>> 3) & 7) | rex_r
;
5369 mod
= (modrm
>> 6) & 3;
5371 rm
= (modrm
& 7) | REX_B(s
);
5373 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
5374 gen_op_mov_v_reg(ot
, cpu_T1
, rm
);
5375 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
5376 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
5378 gen_lea_modrm(env
, s
, modrm
);
5379 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
5380 /* for xchg, lock is implicit */
5381 if (!(prefixes
& PREFIX_LOCK
))
5383 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
5384 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
5385 if (!(prefixes
& PREFIX_LOCK
))
5386 gen_helper_unlock();
5387 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
5390 case 0xc4: /* les Gv */
5391 /* In CODE64 this is VEX3; see above. */
5394 case 0xc5: /* lds Gv */
5395 /* In CODE64 this is VEX2; see above. */
5398 case 0x1b2: /* lss Gv */
5401 case 0x1b4: /* lfs Gv */
5404 case 0x1b5: /* lgs Gv */
5407 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
5408 modrm
= cpu_ldub_code(env
, s
->pc
++);
5409 reg
= ((modrm
>> 3) & 7) | rex_r
;
5410 mod
= (modrm
>> 6) & 3;
5413 gen_lea_modrm(env
, s
, modrm
);
5414 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
5415 gen_add_A0_im(s
, 1 << ot
);
5416 /* load the segment first to handle exceptions properly */
5417 gen_op_ld_v(s
, MO_16
, cpu_T0
, cpu_A0
);
5418 gen_movl_seg_T0(s
, op
);
5419 /* then put the data */
5420 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
5422 gen_jmp_im(s
->pc
- s
->cs_base
);
5427 /************************/
5435 ot
= mo_b_d(b
, dflag
);
5436 modrm
= cpu_ldub_code(env
, s
->pc
++);
5437 mod
= (modrm
>> 6) & 3;
5438 op
= (modrm
>> 3) & 7;
5444 gen_lea_modrm(env
, s
, modrm
);
5447 opreg
= (modrm
& 7) | REX_B(s
);
5452 gen_shift(s
, op
, ot
, opreg
, OR_ECX
);
5455 shift
= cpu_ldub_code(env
, s
->pc
++);
5457 gen_shifti(s
, op
, ot
, opreg
, shift
);
5472 case 0x1a4: /* shld imm */
5476 case 0x1a5: /* shld cl */
5480 case 0x1ac: /* shrd imm */
5484 case 0x1ad: /* shrd cl */
5489 modrm
= cpu_ldub_code(env
, s
->pc
++);
5490 mod
= (modrm
>> 6) & 3;
5491 rm
= (modrm
& 7) | REX_B(s
);
5492 reg
= ((modrm
>> 3) & 7) | rex_r
;
5494 gen_lea_modrm(env
, s
, modrm
);
5499 gen_op_mov_v_reg(ot
, cpu_T1
, reg
);
5502 TCGv imm
= tcg_const_tl(cpu_ldub_code(env
, s
->pc
++));
5503 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, imm
);
5506 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, cpu_regs
[R_ECX
]);
5510 /************************/
5513 if (s
->flags
& (HF_EM_MASK
| HF_TS_MASK
)) {
5514 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5515 /* XXX: what to do if illegal op ? */
5516 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
5519 modrm
= cpu_ldub_code(env
, s
->pc
++);
5520 mod
= (modrm
>> 6) & 3;
5522 op
= ((b
& 7) << 3) | ((modrm
>> 3) & 7);
5525 gen_lea_modrm(env
, s
, modrm
);
5527 case 0x00 ... 0x07: /* fxxxs */
5528 case 0x10 ... 0x17: /* fixxxl */
5529 case 0x20 ... 0x27: /* fxxxl */
5530 case 0x30 ... 0x37: /* fixxx */
5537 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5538 s
->mem_index
, MO_LEUL
);
5539 gen_helper_flds_FT0(cpu_env
, cpu_tmp2_i32
);
5542 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5543 s
->mem_index
, MO_LEUL
);
5544 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
5547 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
5548 s
->mem_index
, MO_LEQ
);
5549 gen_helper_fldl_FT0(cpu_env
, cpu_tmp1_i64
);
5553 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5554 s
->mem_index
, MO_LESW
);
5555 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
5559 gen_helper_fp_arith_ST0_FT0(op1
);
5561 /* fcomp needs pop */
5562 gen_helper_fpop(cpu_env
);
5566 case 0x08: /* flds */
5567 case 0x0a: /* fsts */
5568 case 0x0b: /* fstps */
5569 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5570 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5571 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5576 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5577 s
->mem_index
, MO_LEUL
);
5578 gen_helper_flds_ST0(cpu_env
, cpu_tmp2_i32
);
5581 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5582 s
->mem_index
, MO_LEUL
);
5583 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
5586 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
5587 s
->mem_index
, MO_LEQ
);
5588 gen_helper_fldl_ST0(cpu_env
, cpu_tmp1_i64
);
5592 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5593 s
->mem_index
, MO_LESW
);
5594 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
5599 /* XXX: the corresponding CPUID bit must be tested ! */
5602 gen_helper_fisttl_ST0(cpu_tmp2_i32
, cpu_env
);
5603 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5604 s
->mem_index
, MO_LEUL
);
5607 gen_helper_fisttll_ST0(cpu_tmp1_i64
, cpu_env
);
5608 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
5609 s
->mem_index
, MO_LEQ
);
5613 gen_helper_fistt_ST0(cpu_tmp2_i32
, cpu_env
);
5614 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5615 s
->mem_index
, MO_LEUW
);
5618 gen_helper_fpop(cpu_env
);
5623 gen_helper_fsts_ST0(cpu_tmp2_i32
, cpu_env
);
5624 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5625 s
->mem_index
, MO_LEUL
);
5628 gen_helper_fistl_ST0(cpu_tmp2_i32
, cpu_env
);
5629 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5630 s
->mem_index
, MO_LEUL
);
5633 gen_helper_fstl_ST0(cpu_tmp1_i64
, cpu_env
);
5634 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
5635 s
->mem_index
, MO_LEQ
);
5639 gen_helper_fist_ST0(cpu_tmp2_i32
, cpu_env
);
5640 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5641 s
->mem_index
, MO_LEUW
);
5645 gen_helper_fpop(cpu_env
);
5649 case 0x0c: /* fldenv mem */
5650 gen_helper_fldenv(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5652 case 0x0d: /* fldcw mem */
5653 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5654 s
->mem_index
, MO_LEUW
);
5655 gen_helper_fldcw(cpu_env
, cpu_tmp2_i32
);
5657 case 0x0e: /* fnstenv mem */
5658 gen_helper_fstenv(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5660 case 0x0f: /* fnstcw mem */
5661 gen_helper_fnstcw(cpu_tmp2_i32
, cpu_env
);
5662 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5663 s
->mem_index
, MO_LEUW
);
5665 case 0x1d: /* fldt mem */
5666 gen_helper_fldt_ST0(cpu_env
, cpu_A0
);
5668 case 0x1f: /* fstpt mem */
5669 gen_helper_fstt_ST0(cpu_env
, cpu_A0
);
5670 gen_helper_fpop(cpu_env
);
5672 case 0x2c: /* frstor mem */
5673 gen_helper_frstor(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5675 case 0x2e: /* fnsave mem */
5676 gen_helper_fsave(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5678 case 0x2f: /* fnstsw mem */
5679 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
5680 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5681 s
->mem_index
, MO_LEUW
);
5683 case 0x3c: /* fbld */
5684 gen_helper_fbld_ST0(cpu_env
, cpu_A0
);
5686 case 0x3e: /* fbstp */
5687 gen_helper_fbst_ST0(cpu_env
, cpu_A0
);
5688 gen_helper_fpop(cpu_env
);
5690 case 0x3d: /* fildll */
5691 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
5692 gen_helper_fildll_ST0(cpu_env
, cpu_tmp1_i64
);
5694 case 0x3f: /* fistpll */
5695 gen_helper_fistll_ST0(cpu_tmp1_i64
, cpu_env
);
5696 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
5697 gen_helper_fpop(cpu_env
);
5703 /* register float ops */
5707 case 0x08: /* fld sti */
5708 gen_helper_fpush(cpu_env
);
5709 gen_helper_fmov_ST0_STN(cpu_env
,
5710 tcg_const_i32((opreg
+ 1) & 7));
5712 case 0x09: /* fxchg sti */
5713 case 0x29: /* fxchg4 sti, undocumented op */
5714 case 0x39: /* fxchg7 sti, undocumented op */
5715 gen_helper_fxchg_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
5717 case 0x0a: /* grp d9/2 */
5720 /* check exceptions (FreeBSD FPU probe) */
5721 gen_helper_fwait(cpu_env
);
5727 case 0x0c: /* grp d9/4 */
5730 gen_helper_fchs_ST0(cpu_env
);
5733 gen_helper_fabs_ST0(cpu_env
);
5736 gen_helper_fldz_FT0(cpu_env
);
5737 gen_helper_fcom_ST0_FT0(cpu_env
);
5740 gen_helper_fxam_ST0(cpu_env
);
5746 case 0x0d: /* grp d9/5 */
5750 gen_helper_fpush(cpu_env
);
5751 gen_helper_fld1_ST0(cpu_env
);
5754 gen_helper_fpush(cpu_env
);
5755 gen_helper_fldl2t_ST0(cpu_env
);
5758 gen_helper_fpush(cpu_env
);
5759 gen_helper_fldl2e_ST0(cpu_env
);
5762 gen_helper_fpush(cpu_env
);
5763 gen_helper_fldpi_ST0(cpu_env
);
5766 gen_helper_fpush(cpu_env
);
5767 gen_helper_fldlg2_ST0(cpu_env
);
5770 gen_helper_fpush(cpu_env
);
5771 gen_helper_fldln2_ST0(cpu_env
);
5774 gen_helper_fpush(cpu_env
);
5775 gen_helper_fldz_ST0(cpu_env
);
5782 case 0x0e: /* grp d9/6 */
5785 gen_helper_f2xm1(cpu_env
);
5788 gen_helper_fyl2x(cpu_env
);
5791 gen_helper_fptan(cpu_env
);
5793 case 3: /* fpatan */
5794 gen_helper_fpatan(cpu_env
);
5796 case 4: /* fxtract */
5797 gen_helper_fxtract(cpu_env
);
5799 case 5: /* fprem1 */
5800 gen_helper_fprem1(cpu_env
);
5802 case 6: /* fdecstp */
5803 gen_helper_fdecstp(cpu_env
);
5806 case 7: /* fincstp */
5807 gen_helper_fincstp(cpu_env
);
5811 case 0x0f: /* grp d9/7 */
5814 gen_helper_fprem(cpu_env
);
5816 case 1: /* fyl2xp1 */
5817 gen_helper_fyl2xp1(cpu_env
);
5820 gen_helper_fsqrt(cpu_env
);
5822 case 3: /* fsincos */
5823 gen_helper_fsincos(cpu_env
);
5825 case 5: /* fscale */
5826 gen_helper_fscale(cpu_env
);
5828 case 4: /* frndint */
5829 gen_helper_frndint(cpu_env
);
5832 gen_helper_fsin(cpu_env
);
5836 gen_helper_fcos(cpu_env
);
5840 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
5841 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
5842 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
5848 gen_helper_fp_arith_STN_ST0(op1
, opreg
);
5850 gen_helper_fpop(cpu_env
);
5852 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
5853 gen_helper_fp_arith_ST0_FT0(op1
);
5857 case 0x02: /* fcom */
5858 case 0x22: /* fcom2, undocumented op */
5859 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
5860 gen_helper_fcom_ST0_FT0(cpu_env
);
5862 case 0x03: /* fcomp */
5863 case 0x23: /* fcomp3, undocumented op */
5864 case 0x32: /* fcomp5, undocumented op */
5865 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
5866 gen_helper_fcom_ST0_FT0(cpu_env
);
5867 gen_helper_fpop(cpu_env
);
5869 case 0x15: /* da/5 */
5871 case 1: /* fucompp */
5872 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
5873 gen_helper_fucom_ST0_FT0(cpu_env
);
5874 gen_helper_fpop(cpu_env
);
5875 gen_helper_fpop(cpu_env
);
5883 case 0: /* feni (287 only, just do nop here) */
5885 case 1: /* fdisi (287 only, just do nop here) */
5888 gen_helper_fclex(cpu_env
);
5890 case 3: /* fninit */
5891 gen_helper_fninit(cpu_env
);
5893 case 4: /* fsetpm (287 only, just do nop here) */
5899 case 0x1d: /* fucomi */
5900 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
5903 gen_update_cc_op(s
);
5904 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
5905 gen_helper_fucomi_ST0_FT0(cpu_env
);
5906 set_cc_op(s
, CC_OP_EFLAGS
);
5908 case 0x1e: /* fcomi */
5909 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
5912 gen_update_cc_op(s
);
5913 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
5914 gen_helper_fcomi_ST0_FT0(cpu_env
);
5915 set_cc_op(s
, CC_OP_EFLAGS
);
5917 case 0x28: /* ffree sti */
5918 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
5920 case 0x2a: /* fst sti */
5921 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
5923 case 0x2b: /* fstp sti */
5924 case 0x0b: /* fstp1 sti, undocumented op */
5925 case 0x3a: /* fstp8 sti, undocumented op */
5926 case 0x3b: /* fstp9 sti, undocumented op */
5927 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
5928 gen_helper_fpop(cpu_env
);
5930 case 0x2c: /* fucom st(i) */
5931 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
5932 gen_helper_fucom_ST0_FT0(cpu_env
);
5934 case 0x2d: /* fucomp st(i) */
5935 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
5936 gen_helper_fucom_ST0_FT0(cpu_env
);
5937 gen_helper_fpop(cpu_env
);
5939 case 0x33: /* de/3 */
5941 case 1: /* fcompp */
5942 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
5943 gen_helper_fcom_ST0_FT0(cpu_env
);
5944 gen_helper_fpop(cpu_env
);
5945 gen_helper_fpop(cpu_env
);
5951 case 0x38: /* ffreep sti, undocumented op */
5952 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
5953 gen_helper_fpop(cpu_env
);
5955 case 0x3c: /* df/4 */
5958 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
5959 tcg_gen_extu_i32_tl(cpu_T0
, cpu_tmp2_i32
);
5960 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
5966 case 0x3d: /* fucomip */
5967 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
5970 gen_update_cc_op(s
);
5971 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
5972 gen_helper_fucomi_ST0_FT0(cpu_env
);
5973 gen_helper_fpop(cpu_env
);
5974 set_cc_op(s
, CC_OP_EFLAGS
);
5976 case 0x3e: /* fcomip */
5977 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
5980 gen_update_cc_op(s
);
5981 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
5982 gen_helper_fcomi_ST0_FT0(cpu_env
);
5983 gen_helper_fpop(cpu_env
);
5984 set_cc_op(s
, CC_OP_EFLAGS
);
5986 case 0x10 ... 0x13: /* fcmovxx */
5991 static const uint8_t fcmov_cc
[8] = {
5998 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6001 op1
= fcmov_cc
[op
& 3] | (((op
>> 3) & 1) ^ 1);
6002 l1
= gen_new_label();
6003 gen_jcc1_noeob(s
, op1
, l1
);
6004 gen_helper_fmov_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6013 /************************/
6016 case 0xa4: /* movsS */
6018 ot
= mo_b_d(b
, dflag
);
6019 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6020 gen_repz_movs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6026 case 0xaa: /* stosS */
6028 ot
= mo_b_d(b
, dflag
);
6029 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6030 gen_repz_stos(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6035 case 0xac: /* lodsS */
6037 ot
= mo_b_d(b
, dflag
);
6038 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6039 gen_repz_lods(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6044 case 0xae: /* scasS */
6046 ot
= mo_b_d(b
, dflag
);
6047 if (prefixes
& PREFIX_REPNZ
) {
6048 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6049 } else if (prefixes
& PREFIX_REPZ
) {
6050 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6056 case 0xa6: /* cmpsS */
6058 ot
= mo_b_d(b
, dflag
);
6059 if (prefixes
& PREFIX_REPNZ
) {
6060 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6061 } else if (prefixes
& PREFIX_REPZ
) {
6062 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6067 case 0x6c: /* insS */
6069 ot
= mo_b_d32(b
, dflag
);
6070 tcg_gen_ext16u_tl(cpu_T0
, cpu_regs
[R_EDX
]);
6071 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6072 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
) | 4);
6073 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6074 gen_repz_ins(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6077 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6078 gen_jmp(s
, s
->pc
- s
->cs_base
);
6082 case 0x6e: /* outsS */
6084 ot
= mo_b_d32(b
, dflag
);
6085 tcg_gen_ext16u_tl(cpu_T0
, cpu_regs
[R_EDX
]);
6086 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6087 svm_is_rep(prefixes
) | 4);
6088 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6089 gen_repz_outs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6092 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6093 gen_jmp(s
, s
->pc
- s
->cs_base
);
6098 /************************/
6103 ot
= mo_b_d32(b
, dflag
);
6104 val
= cpu_ldub_code(env
, s
->pc
++);
6105 tcg_gen_movi_tl(cpu_T0
, val
);
6106 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6107 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6108 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6111 tcg_gen_movi_i32(cpu_tmp2_i32
, val
);
6112 gen_helper_in_func(ot
, cpu_T1
, cpu_tmp2_i32
);
6113 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T1
);
6114 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6115 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6117 gen_jmp(s
, s
->pc
- s
->cs_base
);
6122 ot
= mo_b_d32(b
, dflag
);
6123 val
= cpu_ldub_code(env
, s
->pc
++);
6124 tcg_gen_movi_tl(cpu_T0
, val
);
6125 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6126 svm_is_rep(prefixes
));
6127 gen_op_mov_v_reg(ot
, cpu_T1
, R_EAX
);
6129 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6132 tcg_gen_movi_i32(cpu_tmp2_i32
, val
);
6133 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T1
);
6134 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6135 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6136 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6138 gen_jmp(s
, s
->pc
- s
->cs_base
);
6143 ot
= mo_b_d32(b
, dflag
);
6144 tcg_gen_ext16u_tl(cpu_T0
, cpu_regs
[R_EDX
]);
6145 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6146 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6147 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6150 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
6151 gen_helper_in_func(ot
, cpu_T1
, cpu_tmp2_i32
);
6152 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T1
);
6153 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6154 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6156 gen_jmp(s
, s
->pc
- s
->cs_base
);
6161 ot
= mo_b_d32(b
, dflag
);
6162 tcg_gen_ext16u_tl(cpu_T0
, cpu_regs
[R_EDX
]);
6163 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6164 svm_is_rep(prefixes
));
6165 gen_op_mov_v_reg(ot
, cpu_T1
, R_EAX
);
6167 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6170 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
6171 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T1
);
6172 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6173 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6174 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6176 gen_jmp(s
, s
->pc
- s
->cs_base
);
6180 /************************/
6182 case 0xc2: /* ret im */
6183 val
= cpu_ldsw_code(env
, s
->pc
);
6186 gen_stack_update(s
, val
+ (1 << ot
));
6187 /* Note that gen_pop_T0 uses a zero-extending load. */
6188 gen_op_jmp_v(cpu_T0
);
6191 case 0xc3: /* ret */
6193 gen_pop_update(s
, ot
);
6194 /* Note that gen_pop_T0 uses a zero-extending load. */
6195 gen_op_jmp_v(cpu_T0
);
6198 case 0xca: /* lret im */
6199 val
= cpu_ldsw_code(env
, s
->pc
);
6202 if (s
->pe
&& !s
->vm86
) {
6203 gen_update_cc_op(s
);
6204 gen_jmp_im(pc_start
- s
->cs_base
);
6205 gen_helper_lret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6206 tcg_const_i32(val
));
6210 gen_op_ld_v(s
, dflag
, cpu_T0
, cpu_A0
);
6211 /* NOTE: keeping EIP updated is not a problem in case of
6213 gen_op_jmp_v(cpu_T0
);
6215 gen_add_A0_im(s
, 1 << dflag
);
6216 gen_op_ld_v(s
, dflag
, cpu_T0
, cpu_A0
);
6217 gen_op_movl_seg_T0_vm(R_CS
);
6218 /* add stack offset */
6219 gen_stack_update(s
, val
+ (2 << dflag
));
6223 case 0xcb: /* lret */
6226 case 0xcf: /* iret */
6227 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IRET
);
6230 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6231 set_cc_op(s
, CC_OP_EFLAGS
);
6232 } else if (s
->vm86
) {
6234 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6236 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6237 set_cc_op(s
, CC_OP_EFLAGS
);
6240 gen_helper_iret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6241 tcg_const_i32(s
->pc
- s
->cs_base
));
6242 set_cc_op(s
, CC_OP_EFLAGS
);
6246 case 0xe8: /* call im */
6248 if (dflag
!= MO_16
) {
6249 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6251 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6253 next_eip
= s
->pc
- s
->cs_base
;
6255 if (dflag
== MO_16
) {
6257 } else if (!CODE64(s
)) {
6260 tcg_gen_movi_tl(cpu_T0
, next_eip
);
6261 gen_push_v(s
, cpu_T0
);
6265 case 0x9a: /* lcall im */
6267 unsigned int selector
, offset
;
6272 offset
= insn_get(env
, s
, ot
);
6273 selector
= insn_get(env
, s
, MO_16
);
6275 tcg_gen_movi_tl(cpu_T0
, selector
);
6276 tcg_gen_movi_tl(cpu_T1
, offset
);
6279 case 0xe9: /* jmp im */
6280 if (dflag
!= MO_16
) {
6281 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6283 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6285 tval
+= s
->pc
- s
->cs_base
;
6286 if (dflag
== MO_16
) {
6288 } else if (!CODE64(s
)) {
6293 case 0xea: /* ljmp im */
6295 unsigned int selector
, offset
;
6300 offset
= insn_get(env
, s
, ot
);
6301 selector
= insn_get(env
, s
, MO_16
);
6303 tcg_gen_movi_tl(cpu_T0
, selector
);
6304 tcg_gen_movi_tl(cpu_T1
, offset
);
6307 case 0xeb: /* jmp Jb */
6308 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6309 tval
+= s
->pc
- s
->cs_base
;
6310 if (dflag
== MO_16
) {
6315 case 0x70 ... 0x7f: /* jcc Jb */
6316 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6318 case 0x180 ... 0x18f: /* jcc Jv */
6319 if (dflag
!= MO_16
) {
6320 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6322 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6325 next_eip
= s
->pc
- s
->cs_base
;
6327 if (dflag
== MO_16
) {
6330 gen_jcc(s
, b
, tval
, next_eip
);
6333 case 0x190 ... 0x19f: /* setcc Gv */
6334 modrm
= cpu_ldub_code(env
, s
->pc
++);
6335 gen_setcc1(s
, b
, cpu_T0
);
6336 gen_ldst_modrm(env
, s
, modrm
, MO_8
, OR_TMP0
, 1);
6338 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6339 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6343 modrm
= cpu_ldub_code(env
, s
->pc
++);
6344 reg
= ((modrm
>> 3) & 7) | rex_r
;
6345 gen_cmovcc1(env
, s
, ot
, b
, modrm
, reg
);
6348 /************************/
6350 case 0x9c: /* pushf */
6351 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_PUSHF
);
6352 if (s
->vm86
&& s
->iopl
!= 3) {
6353 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6355 gen_update_cc_op(s
);
6356 gen_helper_read_eflags(cpu_T0
, cpu_env
);
6357 gen_push_v(s
, cpu_T0
);
6360 case 0x9d: /* popf */
6361 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_POPF
);
6362 if (s
->vm86
&& s
->iopl
!= 3) {
6363 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6367 if (dflag
!= MO_16
) {
6368 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6369 tcg_const_i32((TF_MASK
| AC_MASK
|
6374 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6375 tcg_const_i32((TF_MASK
| AC_MASK
|
6377 IF_MASK
| IOPL_MASK
)
6381 if (s
->cpl
<= s
->iopl
) {
6382 if (dflag
!= MO_16
) {
6383 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6384 tcg_const_i32((TF_MASK
|
6390 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6391 tcg_const_i32((TF_MASK
|
6399 if (dflag
!= MO_16
) {
6400 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6401 tcg_const_i32((TF_MASK
| AC_MASK
|
6402 ID_MASK
| NT_MASK
)));
6404 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6405 tcg_const_i32((TF_MASK
| AC_MASK
|
6411 gen_pop_update(s
, ot
);
6412 set_cc_op(s
, CC_OP_EFLAGS
);
6413 /* abort translation because TF/AC flag may change */
6414 gen_jmp_im(s
->pc
- s
->cs_base
);
6418 case 0x9e: /* sahf */
6419 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6421 gen_op_mov_v_reg(MO_8
, cpu_T0
, R_AH
);
6422 gen_compute_eflags(s
);
6423 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, CC_O
);
6424 tcg_gen_andi_tl(cpu_T0
, cpu_T0
, CC_S
| CC_Z
| CC_A
| CC_P
| CC_C
);
6425 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, cpu_T0
);
6427 case 0x9f: /* lahf */
6428 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6430 gen_compute_eflags(s
);
6431 /* Note: gen_compute_eflags() only gives the condition codes */
6432 tcg_gen_ori_tl(cpu_T0
, cpu_cc_src
, 0x02);
6433 gen_op_mov_reg_v(MO_8
, R_AH
, cpu_T0
);
6435 case 0xf5: /* cmc */
6436 gen_compute_eflags(s
);
6437 tcg_gen_xori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6439 case 0xf8: /* clc */
6440 gen_compute_eflags(s
);
6441 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_C
);
6443 case 0xf9: /* stc */
6444 gen_compute_eflags(s
);
6445 tcg_gen_ori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6447 case 0xfc: /* cld */
6448 tcg_gen_movi_i32(cpu_tmp2_i32
, 1);
6449 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6451 case 0xfd: /* std */
6452 tcg_gen_movi_i32(cpu_tmp2_i32
, -1);
6453 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6456 /************************/
6457 /* bit operations */
6458 case 0x1ba: /* bt/bts/btr/btc Gv, im */
6460 modrm
= cpu_ldub_code(env
, s
->pc
++);
6461 op
= (modrm
>> 3) & 7;
6462 mod
= (modrm
>> 6) & 3;
6463 rm
= (modrm
& 7) | REX_B(s
);
6466 gen_lea_modrm(env
, s
, modrm
);
6467 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
6469 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
6472 val
= cpu_ldub_code(env
, s
->pc
++);
6473 tcg_gen_movi_tl(cpu_T1
, val
);
6478 case 0x1a3: /* bt Gv, Ev */
6481 case 0x1ab: /* bts */
6484 case 0x1b3: /* btr */
6487 case 0x1bb: /* btc */
6491 modrm
= cpu_ldub_code(env
, s
->pc
++);
6492 reg
= ((modrm
>> 3) & 7) | rex_r
;
6493 mod
= (modrm
>> 6) & 3;
6494 rm
= (modrm
& 7) | REX_B(s
);
6495 gen_op_mov_v_reg(MO_32
, cpu_T1
, reg
);
6497 gen_lea_modrm(env
, s
, modrm
);
6498 /* specific case: we need to add a displacement */
6499 gen_exts(ot
, cpu_T1
);
6500 tcg_gen_sari_tl(cpu_tmp0
, cpu_T1
, 3 + ot
);
6501 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, ot
);
6502 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
6503 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
6505 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
6508 tcg_gen_andi_tl(cpu_T1
, cpu_T1
, (1 << (3 + ot
)) - 1);
6509 tcg_gen_shr_tl(cpu_tmp4
, cpu_T0
, cpu_T1
);
6514 tcg_gen_movi_tl(cpu_tmp0
, 1);
6515 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T1
);
6516 tcg_gen_or_tl(cpu_T0
, cpu_T0
, cpu_tmp0
);
6519 tcg_gen_movi_tl(cpu_tmp0
, 1);
6520 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T1
);
6521 tcg_gen_andc_tl(cpu_T0
, cpu_T0
, cpu_tmp0
);
6525 tcg_gen_movi_tl(cpu_tmp0
, 1);
6526 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T1
);
6527 tcg_gen_xor_tl(cpu_T0
, cpu_T0
, cpu_tmp0
);
6532 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
6534 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
6538 /* Delay all CC updates until after the store above. Note that
6539 C is the result of the test, Z is unchanged, and the others
6540 are all undefined. */
6542 case CC_OP_MULB
... CC_OP_MULQ
:
6543 case CC_OP_ADDB
... CC_OP_ADDQ
:
6544 case CC_OP_ADCB
... CC_OP_ADCQ
:
6545 case CC_OP_SUBB
... CC_OP_SUBQ
:
6546 case CC_OP_SBBB
... CC_OP_SBBQ
:
6547 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
6548 case CC_OP_INCB
... CC_OP_INCQ
:
6549 case CC_OP_DECB
... CC_OP_DECQ
:
6550 case CC_OP_SHLB
... CC_OP_SHLQ
:
6551 case CC_OP_SARB
... CC_OP_SARQ
:
6552 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
6553 /* Z was going to be computed from the non-zero status of CC_DST.
6554 We can get that same Z value (and the new C value) by leaving
6555 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
6557 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
6558 set_cc_op(s
, ((s
->cc_op
- CC_OP_MULB
) & 3) + CC_OP_SARB
);
6561 /* Otherwise, generate EFLAGS and replace the C bit. */
6562 gen_compute_eflags(s
);
6563 tcg_gen_deposit_tl(cpu_cc_src
, cpu_cc_src
, cpu_tmp4
,
6568 case 0x1bc: /* bsf / tzcnt */
6569 case 0x1bd: /* bsr / lzcnt */
6571 modrm
= cpu_ldub_code(env
, s
->pc
++);
6572 reg
= ((modrm
>> 3) & 7) | rex_r
;
6573 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
6574 gen_extu(ot
, cpu_T0
);
6576 /* Note that lzcnt and tzcnt are in different extensions. */
6577 if ((prefixes
& PREFIX_REPZ
)
6579 ? s
->cpuid_ext3_features
& CPUID_EXT3_ABM
6580 : s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)) {
6582 tcg_gen_mov_tl(cpu_cc_src
, cpu_T0
);
6584 /* For lzcnt, reduce the target_ulong result by the
6585 number of zeros that we expect to find at the top. */
6586 gen_helper_clz(cpu_T0
, cpu_T0
);
6587 tcg_gen_subi_tl(cpu_T0
, cpu_T0
, TARGET_LONG_BITS
- size
);
6589 /* For tzcnt, a zero input must return the operand size:
6590 force all bits outside the operand size to 1. */
6591 target_ulong mask
= (target_ulong
)-2 << (size
- 1);
6592 tcg_gen_ori_tl(cpu_T0
, cpu_T0
, mask
);
6593 gen_helper_ctz(cpu_T0
, cpu_T0
);
6595 /* For lzcnt/tzcnt, C and Z bits are defined and are
6596 related to the result. */
6597 gen_op_update1_cc();
6598 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
6600 /* For bsr/bsf, only the Z bit is defined and it is related
6601 to the input and not the result. */
6602 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
6603 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
6605 /* For bsr, return the bit index of the first 1 bit,
6606 not the count of leading zeros. */
6607 gen_helper_clz(cpu_T0
, cpu_T0
);
6608 tcg_gen_xori_tl(cpu_T0
, cpu_T0
, TARGET_LONG_BITS
- 1);
6610 gen_helper_ctz(cpu_T0
, cpu_T0
);
6612 /* ??? The manual says that the output is undefined when the
6613 input is zero, but real hardware leaves it unchanged, and
6614 real programs appear to depend on that. */
6615 tcg_gen_movi_tl(cpu_tmp0
, 0);
6616 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_T0
, cpu_cc_dst
, cpu_tmp0
,
6617 cpu_regs
[reg
], cpu_T0
);
6619 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
6621 /************************/
6623 case 0x27: /* daa */
6626 gen_update_cc_op(s
);
6627 gen_helper_daa(cpu_env
);
6628 set_cc_op(s
, CC_OP_EFLAGS
);
6630 case 0x2f: /* das */
6633 gen_update_cc_op(s
);
6634 gen_helper_das(cpu_env
);
6635 set_cc_op(s
, CC_OP_EFLAGS
);
6637 case 0x37: /* aaa */
6640 gen_update_cc_op(s
);
6641 gen_helper_aaa(cpu_env
);
6642 set_cc_op(s
, CC_OP_EFLAGS
);
6644 case 0x3f: /* aas */
6647 gen_update_cc_op(s
);
6648 gen_helper_aas(cpu_env
);
6649 set_cc_op(s
, CC_OP_EFLAGS
);
6651 case 0xd4: /* aam */
6654 val
= cpu_ldub_code(env
, s
->pc
++);
6656 gen_exception(s
, EXCP00_DIVZ
, pc_start
- s
->cs_base
);
6658 gen_helper_aam(cpu_env
, tcg_const_i32(val
));
6659 set_cc_op(s
, CC_OP_LOGICB
);
6662 case 0xd5: /* aad */
6665 val
= cpu_ldub_code(env
, s
->pc
++);
6666 gen_helper_aad(cpu_env
, tcg_const_i32(val
));
6667 set_cc_op(s
, CC_OP_LOGICB
);
6669 /************************/
6671 case 0x90: /* nop */
6672 /* XXX: correct lock test for all insn */
6673 if (prefixes
& PREFIX_LOCK
) {
6676 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
6678 goto do_xchg_reg_eax
;
6680 if (prefixes
& PREFIX_REPZ
) {
6681 gen_update_cc_op(s
);
6682 gen_jmp_im(pc_start
- s
->cs_base
);
6683 gen_helper_pause(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
6684 s
->is_jmp
= DISAS_TB_JUMP
;
6687 case 0x9b: /* fwait */
6688 if ((s
->flags
& (HF_MP_MASK
| HF_TS_MASK
)) ==
6689 (HF_MP_MASK
| HF_TS_MASK
)) {
6690 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
6692 gen_helper_fwait(cpu_env
);
6695 case 0xcc: /* int3 */
6696 gen_interrupt(s
, EXCP03_INT3
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6698 case 0xcd: /* int N */
6699 val
= cpu_ldub_code(env
, s
->pc
++);
6700 if (s
->vm86
&& s
->iopl
!= 3) {
6701 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6703 gen_interrupt(s
, val
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6706 case 0xce: /* into */
6709 gen_update_cc_op(s
);
6710 gen_jmp_im(pc_start
- s
->cs_base
);
6711 gen_helper_into(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
6714 case 0xf1: /* icebp (undocumented, exits to external debugger) */
6715 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_ICEBP
);
6717 gen_debug(s
, pc_start
- s
->cs_base
);
6720 tb_flush(CPU(x86_env_get_cpu(env
)));
6721 qemu_set_log(CPU_LOG_INT
| CPU_LOG_TB_IN_ASM
);
6725 case 0xfa: /* cli */
6727 if (s
->cpl
<= s
->iopl
) {
6728 gen_helper_cli(cpu_env
);
6730 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6734 gen_helper_cli(cpu_env
);
6736 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6740 case 0xfb: /* sti */
6742 if (s
->cpl
<= s
->iopl
) {
6744 gen_helper_sti(cpu_env
);
6745 /* interruptions are enabled only the first insn after sti */
6746 /* If several instructions disable interrupts, only the
6748 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
6749 gen_helper_set_inhibit_irq(cpu_env
);
6750 /* give a chance to handle pending irqs */
6751 gen_jmp_im(s
->pc
- s
->cs_base
);
6754 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6760 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6764 case 0x62: /* bound */
6768 modrm
= cpu_ldub_code(env
, s
->pc
++);
6769 reg
= (modrm
>> 3) & 7;
6770 mod
= (modrm
>> 6) & 3;
6773 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
6774 gen_lea_modrm(env
, s
, modrm
);
6775 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
6777 gen_helper_boundw(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
6779 gen_helper_boundl(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
6782 case 0x1c8 ... 0x1cf: /* bswap reg */
6783 reg
= (b
& 7) | REX_B(s
);
6784 #ifdef TARGET_X86_64
6785 if (dflag
== MO_64
) {
6786 gen_op_mov_v_reg(MO_64
, cpu_T0
, reg
);
6787 tcg_gen_bswap64_i64(cpu_T0
, cpu_T0
);
6788 gen_op_mov_reg_v(MO_64
, reg
, cpu_T0
);
6792 gen_op_mov_v_reg(MO_32
, cpu_T0
, reg
);
6793 tcg_gen_ext32u_tl(cpu_T0
, cpu_T0
);
6794 tcg_gen_bswap32_tl(cpu_T0
, cpu_T0
);
6795 gen_op_mov_reg_v(MO_32
, reg
, cpu_T0
);
6798 case 0xd6: /* salc */
6801 gen_compute_eflags_c(s
, cpu_T0
);
6802 tcg_gen_neg_tl(cpu_T0
, cpu_T0
);
6803 gen_op_mov_reg_v(MO_8
, R_EAX
, cpu_T0
);
6805 case 0xe0: /* loopnz */
6806 case 0xe1: /* loopz */
6807 case 0xe2: /* loop */
6808 case 0xe3: /* jecxz */
6810 TCGLabel
*l1
, *l2
, *l3
;
6812 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6813 next_eip
= s
->pc
- s
->cs_base
;
6815 if (dflag
== MO_16
) {
6819 l1
= gen_new_label();
6820 l2
= gen_new_label();
6821 l3
= gen_new_label();
6824 case 0: /* loopnz */
6826 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
6827 gen_op_jz_ecx(s
->aflag
, l3
);
6828 gen_jcc1(s
, (JCC_Z
<< 1) | (b
^ 1), l1
);
6831 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
6832 gen_op_jnz_ecx(s
->aflag
, l1
);
6836 gen_op_jz_ecx(s
->aflag
, l1
);
6841 gen_jmp_im(next_eip
);
6850 case 0x130: /* wrmsr */
6851 case 0x132: /* rdmsr */
6853 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6855 gen_update_cc_op(s
);
6856 gen_jmp_im(pc_start
- s
->cs_base
);
6858 gen_helper_rdmsr(cpu_env
);
6860 gen_helper_wrmsr(cpu_env
);
6864 case 0x131: /* rdtsc */
6865 gen_update_cc_op(s
);
6866 gen_jmp_im(pc_start
- s
->cs_base
);
6867 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6870 gen_helper_rdtsc(cpu_env
);
6871 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6873 gen_jmp(s
, s
->pc
- s
->cs_base
);
6876 case 0x133: /* rdpmc */
6877 gen_update_cc_op(s
);
6878 gen_jmp_im(pc_start
- s
->cs_base
);
6879 gen_helper_rdpmc(cpu_env
);
6881 case 0x134: /* sysenter */
6882 /* For Intel SYSENTER is valid on 64-bit */
6883 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
6886 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6888 gen_helper_sysenter(cpu_env
);
6892 case 0x135: /* sysexit */
6893 /* For Intel SYSEXIT is valid on 64-bit */
6894 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
6897 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6899 gen_helper_sysexit(cpu_env
, tcg_const_i32(dflag
- 1));
6903 #ifdef TARGET_X86_64
6904 case 0x105: /* syscall */
6905 /* XXX: is it usable in real mode ? */
6906 gen_update_cc_op(s
);
6907 gen_jmp_im(pc_start
- s
->cs_base
);
6908 gen_helper_syscall(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
6911 case 0x107: /* sysret */
6913 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6915 gen_helper_sysret(cpu_env
, tcg_const_i32(dflag
- 1));
6916 /* condition codes are modified only in long mode */
6918 set_cc_op(s
, CC_OP_EFLAGS
);
6924 case 0x1a2: /* cpuid */
6925 gen_update_cc_op(s
);
6926 gen_jmp_im(pc_start
- s
->cs_base
);
6927 gen_helper_cpuid(cpu_env
);
6929 case 0xf4: /* hlt */
6931 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6933 gen_update_cc_op(s
);
6934 gen_jmp_im(pc_start
- s
->cs_base
);
6935 gen_helper_hlt(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
6936 s
->is_jmp
= DISAS_TB_JUMP
;
6940 modrm
= cpu_ldub_code(env
, s
->pc
++);
6941 mod
= (modrm
>> 6) & 3;
6942 op
= (modrm
>> 3) & 7;
6945 if (!s
->pe
|| s
->vm86
)
6947 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_READ
);
6948 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
,
6949 offsetof(CPUX86State
, ldt
.selector
));
6950 ot
= mod
== 3 ? dflag
: MO_16
;
6951 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
6954 if (!s
->pe
|| s
->vm86
)
6957 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6959 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_WRITE
);
6960 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
6961 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
6962 gen_helper_lldt(cpu_env
, cpu_tmp2_i32
);
6966 if (!s
->pe
|| s
->vm86
)
6968 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_READ
);
6969 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
,
6970 offsetof(CPUX86State
, tr
.selector
));
6971 ot
= mod
== 3 ? dflag
: MO_16
;
6972 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
6975 if (!s
->pe
|| s
->vm86
)
6978 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6980 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_WRITE
);
6981 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
6982 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
6983 gen_helper_ltr(cpu_env
, cpu_tmp2_i32
);
6988 if (!s
->pe
|| s
->vm86
)
6990 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
6991 gen_update_cc_op(s
);
6993 gen_helper_verr(cpu_env
, cpu_T0
);
6995 gen_helper_verw(cpu_env
, cpu_T0
);
6997 set_cc_op(s
, CC_OP_EFLAGS
);
7004 modrm
= cpu_ldub_code(env
, s
->pc
++);
7005 mod
= (modrm
>> 6) & 3;
7006 op
= (modrm
>> 3) & 7;
7012 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_READ
);
7013 gen_lea_modrm(env
, s
, modrm
);
7014 tcg_gen_ld32u_tl(cpu_T0
,
7015 cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7016 gen_op_st_v(s
, MO_16
, cpu_T0
, cpu_A0
);
7017 gen_add_A0_im(s
, 2);
7018 tcg_gen_ld_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7019 if (dflag
== MO_16
) {
7020 tcg_gen_andi_tl(cpu_T0
, cpu_T0
, 0xffffff);
7022 gen_op_st_v(s
, CODE64(s
) + MO_32
, cpu_T0
, cpu_A0
);
7027 case 0: /* monitor */
7028 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) ||
7031 gen_update_cc_op(s
);
7032 gen_jmp_im(pc_start
- s
->cs_base
);
7033 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EAX
]);
7034 gen_extu(s
->aflag
, cpu_A0
);
7035 gen_add_A0_ds_seg(s
);
7036 gen_helper_monitor(cpu_env
, cpu_A0
);
7039 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) ||
7042 gen_update_cc_op(s
);
7043 gen_jmp_im(pc_start
- s
->cs_base
);
7044 gen_helper_mwait(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7048 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
) ||
7052 gen_helper_clac(cpu_env
);
7053 gen_jmp_im(s
->pc
- s
->cs_base
);
7057 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
) ||
7061 gen_helper_stac(cpu_env
);
7062 gen_jmp_im(s
->pc
- s
->cs_base
);
7069 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_READ
);
7070 gen_lea_modrm(env
, s
, modrm
);
7071 tcg_gen_ld32u_tl(cpu_T0
,
7072 cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7073 gen_op_st_v(s
, MO_16
, cpu_T0
, cpu_A0
);
7074 gen_add_A0_im(s
, 2);
7075 tcg_gen_ld_tl(cpu_T0
,
7076 cpu_env
, offsetof(CPUX86State
, idt
.base
));
7077 if (dflag
== MO_16
) {
7078 tcg_gen_andi_tl(cpu_T0
, cpu_T0
, 0xffffff);
7080 gen_op_st_v(s
, CODE64(s
) + MO_32
, cpu_T0
, cpu_A0
);
7086 gen_update_cc_op(s
);
7087 gen_jmp_im(pc_start
- s
->cs_base
);
7090 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7093 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7096 gen_helper_vmrun(cpu_env
, tcg_const_i32(s
->aflag
- 1),
7097 tcg_const_i32(s
->pc
- pc_start
));
7099 s
->is_jmp
= DISAS_TB_JUMP
;
7102 case 1: /* VMMCALL */
7103 if (!(s
->flags
& HF_SVME_MASK
))
7105 gen_helper_vmmcall(cpu_env
);
7107 case 2: /* VMLOAD */
7108 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7111 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7114 gen_helper_vmload(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7117 case 3: /* VMSAVE */
7118 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7121 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7124 gen_helper_vmsave(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7128 if ((!(s
->flags
& HF_SVME_MASK
) &&
7129 !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
)) ||
7133 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7136 gen_helper_stgi(cpu_env
);
7140 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7143 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7146 gen_helper_clgi(cpu_env
);
7149 case 6: /* SKINIT */
7150 if ((!(s
->flags
& HF_SVME_MASK
) &&
7151 !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
)) ||
7154 gen_helper_skinit(cpu_env
);
7156 case 7: /* INVLPGA */
7157 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7160 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7163 gen_helper_invlpga(cpu_env
,
7164 tcg_const_i32(s
->aflag
- 1));
7170 } else if (s
->cpl
!= 0) {
7171 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7173 gen_svm_check_intercept(s
, pc_start
,
7174 op
==2 ? SVM_EXIT_GDTR_WRITE
: SVM_EXIT_IDTR_WRITE
);
7175 gen_lea_modrm(env
, s
, modrm
);
7176 gen_op_ld_v(s
, MO_16
, cpu_T1
, cpu_A0
);
7177 gen_add_A0_im(s
, 2);
7178 gen_op_ld_v(s
, CODE64(s
) + MO_32
, cpu_T0
, cpu_A0
);
7179 if (dflag
== MO_16
) {
7180 tcg_gen_andi_tl(cpu_T0
, cpu_T0
, 0xffffff);
7183 tcg_gen_st_tl(cpu_T0
, cpu_env
,
7184 offsetof(CPUX86State
, gdt
.base
));
7185 tcg_gen_st32_tl(cpu_T1
, cpu_env
,
7186 offsetof(CPUX86State
, gdt
.limit
));
7188 tcg_gen_st_tl(cpu_T0
, cpu_env
,
7189 offsetof(CPUX86State
, idt
.base
));
7190 tcg_gen_st32_tl(cpu_T1
, cpu_env
,
7191 offsetof(CPUX86State
, idt
.limit
));
7196 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_CR0
);
7197 #if defined TARGET_X86_64 && defined HOST_WORDS_BIGENDIAN
7198 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, cr
[0]) + 4);
7200 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, cr
[0]));
7202 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 1);
7206 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7208 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7209 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7210 gen_helper_lmsw(cpu_env
, cpu_T0
);
7211 gen_jmp_im(s
->pc
- s
->cs_base
);
7216 if (mod
!= 3) { /* invlpg */
7218 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7220 gen_update_cc_op(s
);
7221 gen_jmp_im(pc_start
- s
->cs_base
);
7222 gen_lea_modrm(env
, s
, modrm
);
7223 gen_helper_invlpg(cpu_env
, cpu_A0
);
7224 gen_jmp_im(s
->pc
- s
->cs_base
);
7229 case 0: /* swapgs */
7230 #ifdef TARGET_X86_64
7233 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7235 tcg_gen_mov_tl(cpu_T0
, cpu_seg_base
[R_GS
]);
7236 tcg_gen_ld_tl(cpu_seg_base
[R_GS
], cpu_env
,
7237 offsetof(CPUX86State
, kernelgsbase
));
7238 tcg_gen_st_tl(cpu_T0
, cpu_env
,
7239 offsetof(CPUX86State
, kernelgsbase
));
7245 case 1: /* rdtscp */
7246 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_RDTSCP
))
7248 gen_update_cc_op(s
);
7249 gen_jmp_im(pc_start
- s
->cs_base
);
7250 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7253 gen_helper_rdtscp(cpu_env
);
7254 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7256 gen_jmp(s
, s
->pc
- s
->cs_base
);
7268 case 0x108: /* invd */
7269 case 0x109: /* wbinvd */
7271 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7273 gen_svm_check_intercept(s
, pc_start
, (b
& 2) ? SVM_EXIT_INVD
: SVM_EXIT_WBINVD
);
7277 case 0x63: /* arpl or movslS (x86_64) */
7278 #ifdef TARGET_X86_64
7281 /* d_ot is the size of destination */
7284 modrm
= cpu_ldub_code(env
, s
->pc
++);
7285 reg
= ((modrm
>> 3) & 7) | rex_r
;
7286 mod
= (modrm
>> 6) & 3;
7287 rm
= (modrm
& 7) | REX_B(s
);
7290 gen_op_mov_v_reg(MO_32
, cpu_T0
, rm
);
7292 if (d_ot
== MO_64
) {
7293 tcg_gen_ext32s_tl(cpu_T0
, cpu_T0
);
7295 gen_op_mov_reg_v(d_ot
, reg
, cpu_T0
);
7297 gen_lea_modrm(env
, s
, modrm
);
7298 gen_op_ld_v(s
, MO_32
| MO_SIGN
, cpu_T0
, cpu_A0
);
7299 gen_op_mov_reg_v(d_ot
, reg
, cpu_T0
);
7305 TCGv t0
, t1
, t2
, a0
;
7307 if (!s
->pe
|| s
->vm86
)
7309 t0
= tcg_temp_local_new();
7310 t1
= tcg_temp_local_new();
7311 t2
= tcg_temp_local_new();
7313 modrm
= cpu_ldub_code(env
, s
->pc
++);
7314 reg
= (modrm
>> 3) & 7;
7315 mod
= (modrm
>> 6) & 3;
7318 gen_lea_modrm(env
, s
, modrm
);
7319 gen_op_ld_v(s
, ot
, t0
, cpu_A0
);
7320 a0
= tcg_temp_local_new();
7321 tcg_gen_mov_tl(a0
, cpu_A0
);
7323 gen_op_mov_v_reg(ot
, t0
, rm
);
7326 gen_op_mov_v_reg(ot
, t1
, reg
);
7327 tcg_gen_andi_tl(cpu_tmp0
, t0
, 3);
7328 tcg_gen_andi_tl(t1
, t1
, 3);
7329 tcg_gen_movi_tl(t2
, 0);
7330 label1
= gen_new_label();
7331 tcg_gen_brcond_tl(TCG_COND_GE
, cpu_tmp0
, t1
, label1
);
7332 tcg_gen_andi_tl(t0
, t0
, ~3);
7333 tcg_gen_or_tl(t0
, t0
, t1
);
7334 tcg_gen_movi_tl(t2
, CC_Z
);
7335 gen_set_label(label1
);
7337 gen_op_st_v(s
, ot
, t0
, a0
);
7340 gen_op_mov_reg_v(ot
, rm
, t0
);
7342 gen_compute_eflags(s
);
7343 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_Z
);
7344 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, t2
);
7350 case 0x102: /* lar */
7351 case 0x103: /* lsl */
7355 if (!s
->pe
|| s
->vm86
)
7357 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
7358 modrm
= cpu_ldub_code(env
, s
->pc
++);
7359 reg
= ((modrm
>> 3) & 7) | rex_r
;
7360 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7361 t0
= tcg_temp_local_new();
7362 gen_update_cc_op(s
);
7364 gen_helper_lar(t0
, cpu_env
, cpu_T0
);
7366 gen_helper_lsl(t0
, cpu_env
, cpu_T0
);
7368 tcg_gen_andi_tl(cpu_tmp0
, cpu_cc_src
, CC_Z
);
7369 label1
= gen_new_label();
7370 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
7371 gen_op_mov_reg_v(ot
, reg
, t0
);
7372 gen_set_label(label1
);
7373 set_cc_op(s
, CC_OP_EFLAGS
);
7378 modrm
= cpu_ldub_code(env
, s
->pc
++);
7379 mod
= (modrm
>> 6) & 3;
7380 op
= (modrm
>> 3) & 7;
7382 case 0: /* prefetchnta */
7383 case 1: /* prefetchnt0 */
7384 case 2: /* prefetchnt0 */
7385 case 3: /* prefetchnt0 */
7388 gen_lea_modrm(env
, s
, modrm
);
7389 /* nothing more to do */
7391 default: /* nop (multi byte) */
7392 gen_nop_modrm(env
, s
, modrm
);
7396 case 0x119 ... 0x11f: /* nop (multi byte) */
7397 modrm
= cpu_ldub_code(env
, s
->pc
++);
7398 gen_nop_modrm(env
, s
, modrm
);
7400 case 0x120: /* mov reg, crN */
7401 case 0x122: /* mov crN, reg */
7403 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7405 modrm
= cpu_ldub_code(env
, s
->pc
++);
7406 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7407 * AMD documentation (24594.pdf) and testing of
7408 * intel 386 and 486 processors all show that the mod bits
7409 * are assumed to be 1's, regardless of actual values.
7411 rm
= (modrm
& 7) | REX_B(s
);
7412 reg
= ((modrm
>> 3) & 7) | rex_r
;
7417 if ((prefixes
& PREFIX_LOCK
) && (reg
== 0) &&
7418 (s
->cpuid_ext3_features
& CPUID_EXT3_CR8LEG
)) {
7427 gen_update_cc_op(s
);
7428 gen_jmp_im(pc_start
- s
->cs_base
);
7430 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
7431 gen_helper_write_crN(cpu_env
, tcg_const_i32(reg
),
7433 gen_jmp_im(s
->pc
- s
->cs_base
);
7436 gen_helper_read_crN(cpu_T0
, cpu_env
, tcg_const_i32(reg
));
7437 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
7445 case 0x121: /* mov reg, drN */
7446 case 0x123: /* mov drN, reg */
7448 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7450 modrm
= cpu_ldub_code(env
, s
->pc
++);
7451 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7452 * AMD documentation (24594.pdf) and testing of
7453 * intel 386 and 486 processors all show that the mod bits
7454 * are assumed to be 1's, regardless of actual values.
7456 rm
= (modrm
& 7) | REX_B(s
);
7457 reg
= ((modrm
>> 3) & 7) | rex_r
;
7466 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_DR0
+ reg
);
7467 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
7468 tcg_gen_movi_i32(cpu_tmp2_i32
, reg
);
7469 gen_helper_set_dr(cpu_env
, cpu_tmp2_i32
, cpu_T0
);
7470 gen_jmp_im(s
->pc
- s
->cs_base
);
7473 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_DR0
+ reg
);
7474 tcg_gen_movi_i32(cpu_tmp2_i32
, reg
);
7475 gen_helper_get_dr(cpu_T0
, cpu_env
, cpu_tmp2_i32
);
7476 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
7480 case 0x106: /* clts */
7482 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7484 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7485 gen_helper_clts(cpu_env
);
7486 /* abort block because static cpu state changed */
7487 gen_jmp_im(s
->pc
- s
->cs_base
);
7491 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
7492 case 0x1c3: /* MOVNTI reg, mem */
7493 if (!(s
->cpuid_features
& CPUID_SSE2
))
7495 ot
= mo_64_32(dflag
);
7496 modrm
= cpu_ldub_code(env
, s
->pc
++);
7497 mod
= (modrm
>> 6) & 3;
7500 reg
= ((modrm
>> 3) & 7) | rex_r
;
7501 /* generate a generic store */
7502 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
7505 modrm
= cpu_ldub_code(env
, s
->pc
++);
7506 mod
= (modrm
>> 6) & 3;
7507 op
= (modrm
>> 3) & 7;
7509 case 0: /* fxsave */
7510 if (mod
== 3 || !(s
->cpuid_features
& CPUID_FXSR
) ||
7511 (s
->prefix
& PREFIX_LOCK
))
7513 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
7514 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7517 gen_lea_modrm(env
, s
, modrm
);
7518 gen_helper_fxsave(cpu_env
, cpu_A0
, tcg_const_i32(dflag
== MO_64
));
7520 case 1: /* fxrstor */
7521 if (mod
== 3 || !(s
->cpuid_features
& CPUID_FXSR
) ||
7522 (s
->prefix
& PREFIX_LOCK
))
7524 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
7525 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7528 gen_lea_modrm(env
, s
, modrm
);
7529 gen_helper_fxrstor(cpu_env
, cpu_A0
, tcg_const_i32(dflag
== MO_64
));
7531 case 2: /* ldmxcsr */
7532 case 3: /* stmxcsr */
7533 if (s
->flags
& HF_TS_MASK
) {
7534 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7537 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
) ||
7540 gen_lea_modrm(env
, s
, modrm
);
7542 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
7543 s
->mem_index
, MO_LEUL
);
7544 gen_helper_ldmxcsr(cpu_env
, cpu_tmp2_i32
);
7546 tcg_gen_ld32u_tl(cpu_T0
,
7547 cpu_env
, offsetof(CPUX86State
, mxcsr
));
7548 gen_op_st_v(s
, MO_32
, cpu_T0
, cpu_A0
);
7551 case 5: /* lfence */
7552 if ((modrm
& 0xc7) != 0xc0 || !(s
->cpuid_features
& CPUID_SSE2
))
7555 case 6: /* mfence/clwb */
7556 if (s
->prefix
& PREFIX_DATA
) {
7558 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLWB
))
7560 gen_nop_modrm(env
, s
, modrm
);
7563 if ((modrm
& 0xc7) != 0xc0 || !(s
->cpuid_features
& CPUID_SSE2
))
7567 case 7: /* sfence / clflush / clflushopt / pcommit */
7568 if ((modrm
& 0xc7) == 0xc0) {
7569 if (s
->prefix
& PREFIX_DATA
) {
7571 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_PCOMMIT
))
7575 /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX */
7576 if (!(s
->cpuid_features
& CPUID_SSE
))
7580 if (s
->prefix
& PREFIX_DATA
) {
7582 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLFLUSHOPT
))
7586 if (!(s
->cpuid_features
& CPUID_CLFLUSH
))
7589 gen_lea_modrm(env
, s
, modrm
);
7596 case 0x10d: /* 3DNow! prefetch(w) */
7597 modrm
= cpu_ldub_code(env
, s
->pc
++);
7598 mod
= (modrm
>> 6) & 3;
7601 gen_lea_modrm(env
, s
, modrm
);
7602 /* ignore for now */
7604 case 0x1aa: /* rsm */
7605 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_RSM
);
7606 if (!(s
->flags
& HF_SMM_MASK
))
7608 gen_update_cc_op(s
);
7609 gen_jmp_im(s
->pc
- s
->cs_base
);
7610 gen_helper_rsm(cpu_env
);
7613 case 0x1b8: /* SSE4.2 popcnt */
7614 if ((prefixes
& (PREFIX_REPZ
| PREFIX_LOCK
| PREFIX_REPNZ
)) !=
7617 if (!(s
->cpuid_ext_features
& CPUID_EXT_POPCNT
))
7620 modrm
= cpu_ldub_code(env
, s
->pc
++);
7621 reg
= ((modrm
>> 3) & 7) | rex_r
;
7623 if (s
->prefix
& PREFIX_DATA
) {
7626 ot
= mo_64_32(dflag
);
7629 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
7630 gen_helper_popcnt(cpu_T0
, cpu_env
, cpu_T0
, tcg_const_i32(ot
));
7631 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
7633 set_cc_op(s
, CC_OP_EFLAGS
);
7635 case 0x10e ... 0x10f:
7636 /* 3DNow! instructions, ignore prefixes */
7637 s
->prefix
&= ~(PREFIX_REPZ
| PREFIX_REPNZ
| PREFIX_DATA
);
7638 case 0x110 ... 0x117:
7639 case 0x128 ... 0x12f:
7640 case 0x138 ... 0x13a:
7641 case 0x150 ... 0x179:
7642 case 0x17c ... 0x17f:
7644 case 0x1c4 ... 0x1c6:
7645 case 0x1d0 ... 0x1fe:
7646 gen_sse(env
, s
, b
, pc_start
, rex_r
);
7651 /* lock generation */
7652 if (s
->prefix
& PREFIX_LOCK
)
7653 gen_helper_unlock();
7656 if (s
->prefix
& PREFIX_LOCK
)
7657 gen_helper_unlock();
7658 /* XXX: ensure that no lock was generated */
7659 gen_exception(s
, EXCP06_ILLOP
, pc_start
- s
->cs_base
);
7663 void tcg_x86_init(void)
7665 static const char reg_names
[CPU_NB_REGS
][4] = {
7666 #ifdef TARGET_X86_64
7694 static const char seg_base_names
[6][8] = {
7704 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
7705 cpu_cc_op
= tcg_global_mem_new_i32(cpu_env
,
7706 offsetof(CPUX86State
, cc_op
), "cc_op");
7707 cpu_cc_dst
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_dst
),
7709 cpu_cc_src
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_src
),
7711 cpu_cc_src2
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_src2
),
7714 for (i
= 0; i
< CPU_NB_REGS
; ++i
) {
7715 cpu_regs
[i
] = tcg_global_mem_new(cpu_env
,
7716 offsetof(CPUX86State
, regs
[i
]),
7720 for (i
= 0; i
< 6; ++i
) {
7722 = tcg_global_mem_new(cpu_env
,
7723 offsetof(CPUX86State
, segs
[i
].base
),
7730 /* generate intermediate code for basic block 'tb'. */
7731 void gen_intermediate_code(CPUX86State
*env
, TranslationBlock
*tb
)
7733 X86CPU
*cpu
= x86_env_get_cpu(env
);
7734 CPUState
*cs
= CPU(cpu
);
7735 DisasContext dc1
, *dc
= &dc1
;
7736 target_ulong pc_ptr
;
7738 target_ulong pc_start
;
7739 target_ulong cs_base
;
7743 /* generate intermediate code */
7745 cs_base
= tb
->cs_base
;
7748 dc
->pe
= (flags
>> HF_PE_SHIFT
) & 1;
7749 dc
->code32
= (flags
>> HF_CS32_SHIFT
) & 1;
7750 dc
->ss32
= (flags
>> HF_SS32_SHIFT
) & 1;
7751 dc
->addseg
= (flags
>> HF_ADDSEG_SHIFT
) & 1;
7753 dc
->vm86
= (flags
>> VM_SHIFT
) & 1;
7754 dc
->cpl
= (flags
>> HF_CPL_SHIFT
) & 3;
7755 dc
->iopl
= (flags
>> IOPL_SHIFT
) & 3;
7756 dc
->tf
= (flags
>> TF_SHIFT
) & 1;
7757 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
7758 dc
->cc_op
= CC_OP_DYNAMIC
;
7759 dc
->cc_op_dirty
= false;
7760 dc
->cs_base
= cs_base
;
7762 dc
->popl_esp_hack
= 0;
7763 /* select memory access functions */
7765 if (flags
& HF_SOFTMMU_MASK
) {
7766 dc
->mem_index
= cpu_mmu_index(env
, false);
7768 dc
->cpuid_features
= env
->features
[FEAT_1_EDX
];
7769 dc
->cpuid_ext_features
= env
->features
[FEAT_1_ECX
];
7770 dc
->cpuid_ext2_features
= env
->features
[FEAT_8000_0001_EDX
];
7771 dc
->cpuid_ext3_features
= env
->features
[FEAT_8000_0001_ECX
];
7772 dc
->cpuid_7_0_ebx_features
= env
->features
[FEAT_7_0_EBX
];
7773 #ifdef TARGET_X86_64
7774 dc
->lma
= (flags
>> HF_LMA_SHIFT
) & 1;
7775 dc
->code64
= (flags
>> HF_CS64_SHIFT
) & 1;
7778 dc
->jmp_opt
= !(dc
->tf
|| cs
->singlestep_enabled
||
7779 (flags
& HF_INHIBIT_IRQ_MASK
)
7780 #ifndef CONFIG_SOFTMMU
7781 || (flags
& HF_SOFTMMU_MASK
)
7784 /* Do not optimize repz jumps at all in icount mode, because
7785 rep movsS instructions are execured with different paths
7786 in !repz_opt and repz_opt modes. The first one was used
7787 always except single step mode. And this setting
7788 disables jumps optimization and control paths become
7789 equivalent in run and single step modes.
7790 Now there will be no jump optimization for repz in
7791 record/replay modes and there will always be an
7792 additional step for ecx=0 when icount is enabled.
7794 dc
->repz_opt
= !dc
->jmp_opt
&& !(tb
->cflags
& CF_USE_ICOUNT
);
7796 /* check addseg logic */
7797 if (!dc
->addseg
&& (dc
->vm86
|| !dc
->pe
|| !dc
->code32
))
7798 printf("ERROR addseg\n");
7801 cpu_T0
= tcg_temp_new();
7802 cpu_T1
= tcg_temp_new();
7803 cpu_A0
= tcg_temp_new();
7805 cpu_tmp0
= tcg_temp_new();
7806 cpu_tmp1_i64
= tcg_temp_new_i64();
7807 cpu_tmp2_i32
= tcg_temp_new_i32();
7808 cpu_tmp3_i32
= tcg_temp_new_i32();
7809 cpu_tmp4
= tcg_temp_new();
7810 cpu_ptr0
= tcg_temp_new_ptr();
7811 cpu_ptr1
= tcg_temp_new_ptr();
7812 cpu_cc_srcT
= tcg_temp_local_new();
7814 dc
->is_jmp
= DISAS_NEXT
;
7817 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
7818 if (max_insns
== 0) {
7819 max_insns
= CF_COUNT_MASK
;
7821 if (max_insns
> TCG_MAX_INSNS
) {
7822 max_insns
= TCG_MAX_INSNS
;
7827 tcg_gen_insn_start(pc_ptr
, dc
->cc_op
);
7830 /* If RF is set, suppress an internally generated breakpoint. */
7831 if (unlikely(cpu_breakpoint_test(cs
, pc_ptr
,
7832 tb
->flags
& HF_RF_MASK
7833 ? BP_GDB
: BP_ANY
))) {
7834 gen_debug(dc
, pc_ptr
- dc
->cs_base
);
7835 /* The address covered by the breakpoint must be included in
7836 [tb->pc, tb->pc + tb->size) in order to for it to be
7837 properly cleared -- thus we increment the PC here so that
7838 the logic setting tb->size below does the right thing. */
7840 goto done_generating
;
7842 if (num_insns
== max_insns
&& (tb
->cflags
& CF_LAST_IO
)) {
7846 pc_ptr
= disas_insn(env
, dc
, pc_ptr
);
7847 /* stop translation if indicated */
7850 /* if single step mode, we generate only one instruction and
7851 generate an exception */
7852 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
7853 the flag and abort the translation to give the irqs a
7854 change to be happen */
7855 if (dc
->tf
|| dc
->singlestep_enabled
||
7856 (flags
& HF_INHIBIT_IRQ_MASK
)) {
7857 gen_jmp_im(pc_ptr
- dc
->cs_base
);
7861 /* Do not cross the boundary of the pages in icount mode,
7862 it can cause an exception. Do it only when boundary is
7863 crossed by the first instruction in the block.
7864 If current instruction already crossed the bound - it's ok,
7865 because an exception hasn't stopped this code.
7867 if ((tb
->cflags
& CF_USE_ICOUNT
)
7868 && ((pc_ptr
& TARGET_PAGE_MASK
)
7869 != ((pc_ptr
+ TARGET_MAX_INSN_SIZE
- 1) & TARGET_PAGE_MASK
)
7870 || (pc_ptr
& ~TARGET_PAGE_MASK
) == 0)) {
7871 gen_jmp_im(pc_ptr
- dc
->cs_base
);
7875 /* if too long translation, stop generation too */
7876 if (tcg_op_buf_full() ||
7877 (pc_ptr
- pc_start
) >= (TARGET_PAGE_SIZE
- 32) ||
7878 num_insns
>= max_insns
) {
7879 gen_jmp_im(pc_ptr
- dc
->cs_base
);
7884 gen_jmp_im(pc_ptr
- dc
->cs_base
);
7889 if (tb
->cflags
& CF_LAST_IO
)
7892 gen_tb_end(tb
, num_insns
);
7895 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
7897 qemu_log("----------------\n");
7898 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
7899 #ifdef TARGET_X86_64
7904 disas_flags
= !dc
->code32
;
7905 log_target_disas(cs
, pc_start
, pc_ptr
- pc_start
, disas_flags
);
7910 tb
->size
= pc_ptr
- pc_start
;
7911 tb
->icount
= num_insns
;
7914 void restore_state_to_opc(CPUX86State
*env
, TranslationBlock
*tb
,
7917 int cc_op
= data
[1];
7918 env
->eip
= data
[0] - tb
->cs_base
;
7919 if (cc_op
!= CC_OP_DYNAMIC
) {