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
];
69 /* local register indexes (only used inside old micro ops) */
70 static TCGv cpu_tmp0
, cpu_tmp4
;
71 static TCGv_ptr cpu_ptr0
, cpu_ptr1
;
72 static TCGv_i32 cpu_tmp2_i32
, cpu_tmp3_i32
;
73 static TCGv_i64 cpu_tmp1_i64
;
75 #include "exec/gen-icount.h"
78 static int x86_64_hregs
;
81 typedef struct DisasContext
{
82 /* current insn context */
83 int override
; /* -1 if no override */
87 target_ulong pc
; /* pc = eip + cs_base */
88 int is_jmp
; /* 1 = means jump (stop translation), 2 means CPU
89 static state change (stop translation) */
90 /* current block context */
91 target_ulong cs_base
; /* base of CS segment */
92 int pe
; /* protected mode */
93 int code32
; /* 32 bit code segment */
95 int lma
; /* long mode active */
96 int code64
; /* 64 bit code segment */
99 int vex_l
; /* vex vector length */
100 int vex_v
; /* vex vvvv register, without 1's compliment. */
101 int ss32
; /* 32 bit stack segment */
102 CCOp cc_op
; /* current CC operation */
104 int addseg
; /* non zero if either DS/ES/SS have a non zero base */
105 int f_st
; /* currently unused */
106 int vm86
; /* vm86 mode */
109 int tf
; /* TF cpu flag */
110 int singlestep_enabled
; /* "hardware" single step enabled */
111 int jmp_opt
; /* use direct block chaining for direct jumps */
112 int repz_opt
; /* optimize jumps within repz instructions */
113 int mem_index
; /* select memory access functions */
114 uint64_t flags
; /* all execution flags */
115 struct TranslationBlock
*tb
;
116 int popl_esp_hack
; /* for correct popl with esp base handling */
117 int rip_offset
; /* only used in x86_64, but left for simplicity */
119 int cpuid_ext_features
;
120 int cpuid_ext2_features
;
121 int cpuid_ext3_features
;
122 int cpuid_7_0_ebx_features
;
125 static void gen_eob(DisasContext
*s
);
126 static void gen_jmp(DisasContext
*s
, target_ulong eip
);
127 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
);
128 static void gen_op(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
);
130 /* i386 arith/logic operations */
150 OP_SHL1
, /* undocumented */
166 /* I386 int registers */
167 OR_EAX
, /* MUST be even numbered */
176 OR_TMP0
= 16, /* temporary operand register */
178 OR_A0
, /* temporary register used when doing address evaluation */
188 /* Bit set if the global variable is live after setting CC_OP to X. */
189 static const uint8_t cc_op_live
[CC_OP_NB
] = {
190 [CC_OP_DYNAMIC
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
191 [CC_OP_EFLAGS
] = USES_CC_SRC
,
192 [CC_OP_MULB
... CC_OP_MULQ
] = USES_CC_DST
| USES_CC_SRC
,
193 [CC_OP_ADDB
... CC_OP_ADDQ
] = USES_CC_DST
| USES_CC_SRC
,
194 [CC_OP_ADCB
... CC_OP_ADCQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
195 [CC_OP_SUBB
... CC_OP_SUBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRCT
,
196 [CC_OP_SBBB
... CC_OP_SBBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
197 [CC_OP_LOGICB
... CC_OP_LOGICQ
] = USES_CC_DST
,
198 [CC_OP_INCB
... CC_OP_INCQ
] = USES_CC_DST
| USES_CC_SRC
,
199 [CC_OP_DECB
... CC_OP_DECQ
] = USES_CC_DST
| USES_CC_SRC
,
200 [CC_OP_SHLB
... CC_OP_SHLQ
] = USES_CC_DST
| USES_CC_SRC
,
201 [CC_OP_SARB
... CC_OP_SARQ
] = USES_CC_DST
| USES_CC_SRC
,
202 [CC_OP_BMILGB
... CC_OP_BMILGQ
] = USES_CC_DST
| USES_CC_SRC
,
203 [CC_OP_ADCX
] = USES_CC_DST
| USES_CC_SRC
,
204 [CC_OP_ADOX
] = USES_CC_SRC
| USES_CC_SRC2
,
205 [CC_OP_ADCOX
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
209 static void set_cc_op(DisasContext
*s
, CCOp op
)
213 if (s
->cc_op
== op
) {
217 /* Discard CC computation that will no longer be used. */
218 dead
= cc_op_live
[s
->cc_op
] & ~cc_op_live
[op
];
219 if (dead
& USES_CC_DST
) {
220 tcg_gen_discard_tl(cpu_cc_dst
);
222 if (dead
& USES_CC_SRC
) {
223 tcg_gen_discard_tl(cpu_cc_src
);
225 if (dead
& USES_CC_SRC2
) {
226 tcg_gen_discard_tl(cpu_cc_src2
);
228 if (dead
& USES_CC_SRCT
) {
229 tcg_gen_discard_tl(cpu_cc_srcT
);
232 if (op
== CC_OP_DYNAMIC
) {
233 /* The DYNAMIC setting is translator only, and should never be
234 stored. Thus we always consider it clean. */
235 s
->cc_op_dirty
= false;
237 /* Discard any computed CC_OP value (see shifts). */
238 if (s
->cc_op
== CC_OP_DYNAMIC
) {
239 tcg_gen_discard_i32(cpu_cc_op
);
241 s
->cc_op_dirty
= true;
246 static void gen_update_cc_op(DisasContext
*s
)
248 if (s
->cc_op_dirty
) {
249 tcg_gen_movi_i32(cpu_cc_op
, s
->cc_op
);
250 s
->cc_op_dirty
= false;
256 #define NB_OP_SIZES 4
258 #else /* !TARGET_X86_64 */
260 #define NB_OP_SIZES 3
262 #endif /* !TARGET_X86_64 */
264 #if defined(HOST_WORDS_BIGENDIAN)
265 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
266 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
267 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
268 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
269 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
271 #define REG_B_OFFSET 0
272 #define REG_H_OFFSET 1
273 #define REG_W_OFFSET 0
274 #define REG_L_OFFSET 0
275 #define REG_LH_OFFSET 4
278 /* In instruction encodings for byte register accesses the
279 * register number usually indicates "low 8 bits of register N";
280 * however there are some special cases where N 4..7 indicates
281 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
282 * true for this special case, false otherwise.
284 static inline bool byte_reg_is_xH(int reg
)
290 if (reg
>= 8 || x86_64_hregs
) {
297 /* Select the size of a push/pop operation. */
298 static inline TCGMemOp
mo_pushpop(DisasContext
*s
, TCGMemOp ot
)
301 return ot
== MO_16
? MO_16
: MO_64
;
307 /* Select only size 64 else 32. Used for SSE operand sizes. */
308 static inline TCGMemOp
mo_64_32(TCGMemOp ot
)
311 return ot
== MO_64
? MO_64
: MO_32
;
317 /* Select size 8 if lsb of B is clear, else OT. Used for decoding
318 byte vs word opcodes. */
319 static inline TCGMemOp
mo_b_d(int b
, TCGMemOp ot
)
321 return b
& 1 ? ot
: MO_8
;
324 /* Select size 8 if lsb of B is clear, else OT capped at 32.
325 Used for decoding operand size of port opcodes. */
326 static inline TCGMemOp
mo_b_d32(int b
, TCGMemOp ot
)
328 return b
& 1 ? (ot
== MO_16
? MO_16
: MO_32
) : MO_8
;
331 static void gen_op_mov_reg_v(TCGMemOp ot
, int reg
, TCGv t0
)
335 if (!byte_reg_is_xH(reg
)) {
336 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 8);
338 tcg_gen_deposit_tl(cpu_regs
[reg
- 4], cpu_regs
[reg
- 4], t0
, 8, 8);
342 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 16);
345 /* For x86_64, this sets the higher half of register to zero.
346 For i386, this is equivalent to a mov. */
347 tcg_gen_ext32u_tl(cpu_regs
[reg
], t0
);
351 tcg_gen_mov_tl(cpu_regs
[reg
], t0
);
359 static inline void gen_op_mov_v_reg(TCGMemOp ot
, TCGv t0
, int reg
)
361 if (ot
== MO_8
&& byte_reg_is_xH(reg
)) {
362 tcg_gen_shri_tl(t0
, cpu_regs
[reg
- 4], 8);
363 tcg_gen_ext8u_tl(t0
, t0
);
365 tcg_gen_mov_tl(t0
, cpu_regs
[reg
]);
369 static inline void gen_op_movl_A0_reg(int reg
)
371 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[reg
]);
374 static inline void gen_op_addl_A0_im(int32_t val
)
376 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, val
);
378 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffffffff);
383 static inline void gen_op_addq_A0_im(int64_t val
)
385 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, val
);
389 static void gen_add_A0_im(DisasContext
*s
, int val
)
393 gen_op_addq_A0_im(val
);
396 gen_op_addl_A0_im(val
);
399 static inline void gen_op_jmp_v(TCGv dest
)
401 tcg_gen_st_tl(dest
, cpu_env
, offsetof(CPUX86State
, eip
));
404 static inline void gen_op_add_reg_im(TCGMemOp size
, int reg
, int32_t val
)
406 tcg_gen_addi_tl(cpu_tmp0
, cpu_regs
[reg
], val
);
407 gen_op_mov_reg_v(size
, reg
, cpu_tmp0
);
410 static inline void gen_op_add_reg_T0(TCGMemOp size
, int reg
)
412 tcg_gen_add_tl(cpu_tmp0
, cpu_regs
[reg
], cpu_T
[0]);
413 gen_op_mov_reg_v(size
, reg
, cpu_tmp0
);
416 static inline void gen_op_addl_A0_seg(DisasContext
*s
, int reg
)
418 tcg_gen_ld_tl(cpu_tmp0
, cpu_env
, offsetof(CPUX86State
, segs
[reg
].base
));
420 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
421 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
423 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
424 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
428 static inline void gen_op_ld_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
430 tcg_gen_qemu_ld_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
433 static inline void gen_op_st_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
435 tcg_gen_qemu_st_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
438 static inline void gen_op_st_rm_T0_A0(DisasContext
*s
, int idx
, int d
)
441 gen_op_st_v(s
, idx
, cpu_T
[0], cpu_A0
);
443 gen_op_mov_reg_v(idx
, d
, cpu_T
[0]);
447 static inline void gen_jmp_im(target_ulong pc
)
449 tcg_gen_movi_tl(cpu_tmp0
, pc
);
450 gen_op_jmp_v(cpu_tmp0
);
453 /* Compute SEG:REG into A0. SEG is selected from the override segment
454 (OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to
455 indicate no override. */
456 static void gen_lea_v_seg(DisasContext
*s
, TCGv a0
, int def_seg
, int ovr_seg
)
458 TCGMemOp aflag
= s
->aflag
;
464 tcg_gen_mov_tl(cpu_A0
, a0
);
475 tcg_gen_ext32u_tl(cpu_A0
, a0
);
485 tcg_gen_ext16u_tl(cpu_A0
, a0
);
486 /* ADDSEG will only be false in 16-bit mode for LEA. */
497 TCGv seg
= tcg_temp_new();
499 tcg_gen_ld_tl(seg
, cpu_env
, offsetof(CPUX86State
, segs
[ovr_seg
].base
));
501 if (aflag
== MO_64
) {
502 tcg_gen_add_tl(cpu_A0
, a0
, seg
);
503 } else if (CODE64(s
)) {
504 tcg_gen_ext32u_tl(cpu_A0
, a0
);
505 tcg_gen_add_tl(cpu_A0
, cpu_A0
, seg
);
507 tcg_gen_add_tl(cpu_A0
, a0
, seg
);
508 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
515 static inline void gen_string_movl_A0_ESI(DisasContext
*s
)
517 gen_lea_v_seg(s
, cpu_regs
[R_ESI
], R_DS
, s
->override
);
520 static inline void gen_string_movl_A0_EDI(DisasContext
*s
)
522 gen_lea_v_seg(s
, cpu_regs
[R_EDI
], R_ES
, -1);
525 static inline void gen_op_movl_T0_Dshift(TCGMemOp ot
)
527 tcg_gen_ld32s_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, df
));
528 tcg_gen_shli_tl(cpu_T
[0], cpu_T
[0], ot
);
531 static TCGv
gen_ext_tl(TCGv dst
, TCGv src
, TCGMemOp size
, bool sign
)
536 tcg_gen_ext8s_tl(dst
, src
);
538 tcg_gen_ext8u_tl(dst
, src
);
543 tcg_gen_ext16s_tl(dst
, src
);
545 tcg_gen_ext16u_tl(dst
, src
);
551 tcg_gen_ext32s_tl(dst
, src
);
553 tcg_gen_ext32u_tl(dst
, src
);
562 static void gen_extu(TCGMemOp ot
, TCGv reg
)
564 gen_ext_tl(reg
, reg
, ot
, false);
567 static void gen_exts(TCGMemOp ot
, TCGv reg
)
569 gen_ext_tl(reg
, reg
, ot
, true);
572 static inline void gen_op_jnz_ecx(TCGMemOp size
, TCGLabel
*label1
)
574 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[R_ECX
]);
575 gen_extu(size
, cpu_tmp0
);
576 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_tmp0
, 0, label1
);
579 static inline void gen_op_jz_ecx(TCGMemOp size
, TCGLabel
*label1
)
581 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[R_ECX
]);
582 gen_extu(size
, cpu_tmp0
);
583 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
586 static void gen_helper_in_func(TCGMemOp ot
, TCGv v
, TCGv_i32 n
)
590 gen_helper_inb(v
, cpu_env
, n
);
593 gen_helper_inw(v
, cpu_env
, n
);
596 gen_helper_inl(v
, cpu_env
, n
);
603 static void gen_helper_out_func(TCGMemOp ot
, TCGv_i32 v
, TCGv_i32 n
)
607 gen_helper_outb(cpu_env
, v
, n
);
610 gen_helper_outw(cpu_env
, v
, n
);
613 gen_helper_outl(cpu_env
, v
, n
);
620 static void gen_check_io(DisasContext
*s
, TCGMemOp ot
, target_ulong cur_eip
,
623 target_ulong next_eip
;
625 if (s
->pe
&& (s
->cpl
> s
->iopl
|| s
->vm86
)) {
626 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
629 gen_helper_check_iob(cpu_env
, cpu_tmp2_i32
);
632 gen_helper_check_iow(cpu_env
, cpu_tmp2_i32
);
635 gen_helper_check_iol(cpu_env
, cpu_tmp2_i32
);
641 if(s
->flags
& HF_SVMI_MASK
) {
644 svm_flags
|= (1 << (4 + ot
));
645 next_eip
= s
->pc
- s
->cs_base
;
646 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
647 gen_helper_svm_check_io(cpu_env
, cpu_tmp2_i32
,
648 tcg_const_i32(svm_flags
),
649 tcg_const_i32(next_eip
- cur_eip
));
653 static inline void gen_movs(DisasContext
*s
, TCGMemOp ot
)
655 gen_string_movl_A0_ESI(s
);
656 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
657 gen_string_movl_A0_EDI(s
);
658 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
659 gen_op_movl_T0_Dshift(ot
);
660 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
661 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
664 static void gen_op_update1_cc(void)
666 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
669 static void gen_op_update2_cc(void)
671 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
672 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
675 static void gen_op_update3_cc(TCGv reg
)
677 tcg_gen_mov_tl(cpu_cc_src2
, reg
);
678 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
679 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
682 static inline void gen_op_testl_T0_T1_cc(void)
684 tcg_gen_and_tl(cpu_cc_dst
, cpu_T
[0], cpu_T
[1]);
687 static void gen_op_update_neg_cc(void)
689 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
690 tcg_gen_neg_tl(cpu_cc_src
, cpu_T
[0]);
691 tcg_gen_movi_tl(cpu_cc_srcT
, 0);
694 /* compute all eflags to cc_src */
695 static void gen_compute_eflags(DisasContext
*s
)
697 TCGv zero
, dst
, src1
, src2
;
700 if (s
->cc_op
== CC_OP_EFLAGS
) {
703 if (s
->cc_op
== CC_OP_CLR
) {
704 tcg_gen_movi_tl(cpu_cc_src
, CC_Z
| CC_P
);
705 set_cc_op(s
, CC_OP_EFLAGS
);
714 /* Take care to not read values that are not live. */
715 live
= cc_op_live
[s
->cc_op
] & ~USES_CC_SRCT
;
716 dead
= live
^ (USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
);
718 zero
= tcg_const_tl(0);
719 if (dead
& USES_CC_DST
) {
722 if (dead
& USES_CC_SRC
) {
725 if (dead
& USES_CC_SRC2
) {
731 gen_helper_cc_compute_all(cpu_cc_src
, dst
, src1
, src2
, cpu_cc_op
);
732 set_cc_op(s
, CC_OP_EFLAGS
);
739 typedef struct CCPrepare
{
749 /* compute eflags.C to reg */
750 static CCPrepare
gen_prepare_eflags_c(DisasContext
*s
, TCGv reg
)
756 case CC_OP_SUBB
... CC_OP_SUBQ
:
757 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
758 size
= s
->cc_op
- CC_OP_SUBB
;
759 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
760 /* If no temporary was used, be careful not to alias t1 and t0. */
761 t0
= TCGV_EQUAL(t1
, cpu_cc_src
) ? cpu_tmp0
: reg
;
762 tcg_gen_mov_tl(t0
, cpu_cc_srcT
);
766 case CC_OP_ADDB
... CC_OP_ADDQ
:
767 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
768 size
= s
->cc_op
- CC_OP_ADDB
;
769 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
770 t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
772 return (CCPrepare
) { .cond
= TCG_COND_LTU
, .reg
= t0
,
773 .reg2
= t1
, .mask
= -1, .use_reg2
= true };
775 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
777 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
779 case CC_OP_INCB
... CC_OP_INCQ
:
780 case CC_OP_DECB
... CC_OP_DECQ
:
781 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
782 .mask
= -1, .no_setcond
= true };
784 case CC_OP_SHLB
... CC_OP_SHLQ
:
785 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
786 size
= s
->cc_op
- CC_OP_SHLB
;
787 shift
= (8 << size
) - 1;
788 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
789 .mask
= (target_ulong
)1 << shift
};
791 case CC_OP_MULB
... CC_OP_MULQ
:
792 return (CCPrepare
) { .cond
= TCG_COND_NE
,
793 .reg
= cpu_cc_src
, .mask
= -1 };
795 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
796 size
= s
->cc_op
- CC_OP_BMILGB
;
797 t0
= gen_ext_tl(reg
, cpu_cc_src
, size
, false);
798 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
802 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_dst
,
803 .mask
= -1, .no_setcond
= true };
806 case CC_OP_SARB
... CC_OP_SARQ
:
808 return (CCPrepare
) { .cond
= TCG_COND_NE
,
809 .reg
= cpu_cc_src
, .mask
= CC_C
};
812 /* The need to compute only C from CC_OP_DYNAMIC is important
813 in efficiently implementing e.g. INC at the start of a TB. */
815 gen_helper_cc_compute_c(reg
, cpu_cc_dst
, cpu_cc_src
,
816 cpu_cc_src2
, cpu_cc_op
);
817 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
818 .mask
= -1, .no_setcond
= true };
822 /* compute eflags.P to reg */
823 static CCPrepare
gen_prepare_eflags_p(DisasContext
*s
, TCGv reg
)
825 gen_compute_eflags(s
);
826 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
830 /* compute eflags.S to reg */
831 static CCPrepare
gen_prepare_eflags_s(DisasContext
*s
, TCGv reg
)
835 gen_compute_eflags(s
);
841 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
844 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
847 TCGMemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
848 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, true);
849 return (CCPrepare
) { .cond
= TCG_COND_LT
, .reg
= t0
, .mask
= -1 };
854 /* compute eflags.O to reg */
855 static CCPrepare
gen_prepare_eflags_o(DisasContext
*s
, TCGv reg
)
860 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src2
,
861 .mask
= -1, .no_setcond
= true };
863 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
865 gen_compute_eflags(s
);
866 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
871 /* compute eflags.Z to reg */
872 static CCPrepare
gen_prepare_eflags_z(DisasContext
*s
, TCGv reg
)
876 gen_compute_eflags(s
);
882 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
885 return (CCPrepare
) { .cond
= TCG_COND_ALWAYS
, .mask
= -1 };
888 TCGMemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
889 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
890 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
895 /* perform a conditional store into register 'reg' according to jump opcode
896 value 'b'. In the fast case, T0 is guaranted not to be used. */
897 static CCPrepare
gen_prepare_cc(DisasContext
*s
, int b
, TCGv reg
)
899 int inv
, jcc_op
, cond
;
905 jcc_op
= (b
>> 1) & 7;
908 case CC_OP_SUBB
... CC_OP_SUBQ
:
909 /* We optimize relational operators for the cmp/jcc case. */
910 size
= s
->cc_op
- CC_OP_SUBB
;
913 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
914 gen_extu(size
, cpu_tmp4
);
915 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
916 cc
= (CCPrepare
) { .cond
= TCG_COND_LEU
, .reg
= cpu_tmp4
,
917 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
926 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
927 gen_exts(size
, cpu_tmp4
);
928 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, true);
929 cc
= (CCPrepare
) { .cond
= cond
, .reg
= cpu_tmp4
,
930 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
940 /* This actually generates good code for JC, JZ and JS. */
943 cc
= gen_prepare_eflags_o(s
, reg
);
946 cc
= gen_prepare_eflags_c(s
, reg
);
949 cc
= gen_prepare_eflags_z(s
, reg
);
952 gen_compute_eflags(s
);
953 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
954 .mask
= CC_Z
| CC_C
};
957 cc
= gen_prepare_eflags_s(s
, reg
);
960 cc
= gen_prepare_eflags_p(s
, reg
);
963 gen_compute_eflags(s
);
964 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
967 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
968 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
969 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
974 gen_compute_eflags(s
);
975 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
978 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
979 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
980 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
981 .mask
= CC_S
| CC_Z
};
988 cc
.cond
= tcg_invert_cond(cc
.cond
);
993 static void gen_setcc1(DisasContext
*s
, int b
, TCGv reg
)
995 CCPrepare cc
= gen_prepare_cc(s
, b
, reg
);
998 if (cc
.cond
== TCG_COND_EQ
) {
999 tcg_gen_xori_tl(reg
, cc
.reg
, 1);
1001 tcg_gen_mov_tl(reg
, cc
.reg
);
1006 if (cc
.cond
== TCG_COND_NE
&& !cc
.use_reg2
&& cc
.imm
== 0 &&
1007 cc
.mask
!= 0 && (cc
.mask
& (cc
.mask
- 1)) == 0) {
1008 tcg_gen_shri_tl(reg
, cc
.reg
, ctztl(cc
.mask
));
1009 tcg_gen_andi_tl(reg
, reg
, 1);
1012 if (cc
.mask
!= -1) {
1013 tcg_gen_andi_tl(reg
, cc
.reg
, cc
.mask
);
1017 tcg_gen_setcond_tl(cc
.cond
, reg
, cc
.reg
, cc
.reg2
);
1019 tcg_gen_setcondi_tl(cc
.cond
, reg
, cc
.reg
, cc
.imm
);
1023 static inline void gen_compute_eflags_c(DisasContext
*s
, TCGv reg
)
1025 gen_setcc1(s
, JCC_B
<< 1, reg
);
1028 /* generate a conditional jump to label 'l1' according to jump opcode
1029 value 'b'. In the fast case, T0 is guaranted not to be used. */
1030 static inline void gen_jcc1_noeob(DisasContext
*s
, int b
, TCGLabel
*l1
)
1032 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T
[0]);
1034 if (cc
.mask
!= -1) {
1035 tcg_gen_andi_tl(cpu_T
[0], cc
.reg
, cc
.mask
);
1039 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1041 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1045 /* Generate a conditional jump to label 'l1' according to jump opcode
1046 value 'b'. In the fast case, T0 is guaranted not to be used.
1047 A translation block must end soon. */
1048 static inline void gen_jcc1(DisasContext
*s
, int b
, TCGLabel
*l1
)
1050 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T
[0]);
1052 gen_update_cc_op(s
);
1053 if (cc
.mask
!= -1) {
1054 tcg_gen_andi_tl(cpu_T
[0], cc
.reg
, cc
.mask
);
1057 set_cc_op(s
, CC_OP_DYNAMIC
);
1059 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1061 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1065 /* XXX: does not work with gdbstub "ice" single step - not a
1067 static TCGLabel
*gen_jz_ecx_string(DisasContext
*s
, target_ulong next_eip
)
1069 TCGLabel
*l1
= gen_new_label();
1070 TCGLabel
*l2
= gen_new_label();
1071 gen_op_jnz_ecx(s
->aflag
, l1
);
1073 gen_jmp_tb(s
, next_eip
, 1);
1078 static inline void gen_stos(DisasContext
*s
, TCGMemOp ot
)
1080 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EAX
);
1081 gen_string_movl_A0_EDI(s
);
1082 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
1083 gen_op_movl_T0_Dshift(ot
);
1084 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1087 static inline void gen_lods(DisasContext
*s
, TCGMemOp ot
)
1089 gen_string_movl_A0_ESI(s
);
1090 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1091 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T
[0]);
1092 gen_op_movl_T0_Dshift(ot
);
1093 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1096 static inline void gen_scas(DisasContext
*s
, TCGMemOp ot
)
1098 gen_string_movl_A0_EDI(s
);
1099 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
1100 gen_op(s
, OP_CMPL
, ot
, R_EAX
);
1101 gen_op_movl_T0_Dshift(ot
);
1102 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1105 static inline void gen_cmps(DisasContext
*s
, TCGMemOp ot
)
1107 gen_string_movl_A0_EDI(s
);
1108 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
1109 gen_string_movl_A0_ESI(s
);
1110 gen_op(s
, OP_CMPL
, ot
, OR_TMP0
);
1111 gen_op_movl_T0_Dshift(ot
);
1112 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1113 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1116 static void gen_bpt_io(DisasContext
*s
, TCGv_i32 t_port
, int ot
)
1118 if (s
->flags
& HF_IOBPT_MASK
) {
1119 TCGv_i32 t_size
= tcg_const_i32(1 << ot
);
1120 TCGv t_next
= tcg_const_tl(s
->pc
- s
->cs_base
);
1122 gen_helper_bpt_io(cpu_env
, t_port
, t_size
, t_next
);
1123 tcg_temp_free_i32(t_size
);
1124 tcg_temp_free(t_next
);
1129 static inline void gen_ins(DisasContext
*s
, TCGMemOp ot
)
1131 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1134 gen_string_movl_A0_EDI(s
);
1135 /* Note: we must do this dummy write first to be restartable in
1136 case of page fault. */
1137 tcg_gen_movi_tl(cpu_T
[0], 0);
1138 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
1139 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_EDX
]);
1140 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1141 gen_helper_in_func(ot
, cpu_T
[0], cpu_tmp2_i32
);
1142 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
1143 gen_op_movl_T0_Dshift(ot
);
1144 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1145 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
1146 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1151 static inline void gen_outs(DisasContext
*s
, TCGMemOp ot
)
1153 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1156 gen_string_movl_A0_ESI(s
);
1157 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1159 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_EDX
]);
1160 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1161 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[0]);
1162 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1163 gen_op_movl_T0_Dshift(ot
);
1164 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1165 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
1166 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1171 /* same method as Valgrind : we generate jumps to current or next
1173 #define GEN_REPZ(op) \
1174 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1175 target_ulong cur_eip, target_ulong next_eip) \
1178 gen_update_cc_op(s); \
1179 l2 = gen_jz_ecx_string(s, next_eip); \
1180 gen_ ## op(s, ot); \
1181 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1182 /* a loop would cause two single step exceptions if ECX = 1 \
1183 before rep string_insn */ \
1185 gen_op_jz_ecx(s->aflag, l2); \
1186 gen_jmp(s, cur_eip); \
1189 #define GEN_REPZ2(op) \
1190 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1191 target_ulong cur_eip, \
1192 target_ulong next_eip, \
1196 gen_update_cc_op(s); \
1197 l2 = gen_jz_ecx_string(s, next_eip); \
1198 gen_ ## op(s, ot); \
1199 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1200 gen_update_cc_op(s); \
1201 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
1203 gen_op_jz_ecx(s->aflag, l2); \
1204 gen_jmp(s, cur_eip); \
1215 static void gen_helper_fp_arith_ST0_FT0(int op
)
1219 gen_helper_fadd_ST0_FT0(cpu_env
);
1222 gen_helper_fmul_ST0_FT0(cpu_env
);
1225 gen_helper_fcom_ST0_FT0(cpu_env
);
1228 gen_helper_fcom_ST0_FT0(cpu_env
);
1231 gen_helper_fsub_ST0_FT0(cpu_env
);
1234 gen_helper_fsubr_ST0_FT0(cpu_env
);
1237 gen_helper_fdiv_ST0_FT0(cpu_env
);
1240 gen_helper_fdivr_ST0_FT0(cpu_env
);
1245 /* NOTE the exception in "r" op ordering */
1246 static void gen_helper_fp_arith_STN_ST0(int op
, int opreg
)
1248 TCGv_i32 tmp
= tcg_const_i32(opreg
);
1251 gen_helper_fadd_STN_ST0(cpu_env
, tmp
);
1254 gen_helper_fmul_STN_ST0(cpu_env
, tmp
);
1257 gen_helper_fsubr_STN_ST0(cpu_env
, tmp
);
1260 gen_helper_fsub_STN_ST0(cpu_env
, tmp
);
1263 gen_helper_fdivr_STN_ST0(cpu_env
, tmp
);
1266 gen_helper_fdiv_STN_ST0(cpu_env
, tmp
);
1271 /* if d == OR_TMP0, it means memory operand (address in A0) */
1272 static void gen_op(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
)
1275 gen_op_mov_v_reg(ot
, cpu_T
[0], d
);
1277 gen_op_ld_v(s1
, ot
, cpu_T
[0], cpu_A0
);
1281 gen_compute_eflags_c(s1
, cpu_tmp4
);
1282 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1283 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_tmp4
);
1284 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1285 gen_op_update3_cc(cpu_tmp4
);
1286 set_cc_op(s1
, CC_OP_ADCB
+ ot
);
1289 gen_compute_eflags_c(s1
, cpu_tmp4
);
1290 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1291 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_tmp4
);
1292 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1293 gen_op_update3_cc(cpu_tmp4
);
1294 set_cc_op(s1
, CC_OP_SBBB
+ ot
);
1297 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1298 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1299 gen_op_update2_cc();
1300 set_cc_op(s1
, CC_OP_ADDB
+ ot
);
1303 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T
[0]);
1304 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1305 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1306 gen_op_update2_cc();
1307 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1311 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1312 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1313 gen_op_update1_cc();
1314 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1317 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1318 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1319 gen_op_update1_cc();
1320 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1323 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1324 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1325 gen_op_update1_cc();
1326 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1329 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
1330 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T
[0]);
1331 tcg_gen_sub_tl(cpu_cc_dst
, cpu_T
[0], cpu_T
[1]);
1332 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1337 /* if d == OR_TMP0, it means memory operand (address in A0) */
1338 static void gen_inc(DisasContext
*s1
, TCGMemOp ot
, int d
, int c
)
1341 gen_op_mov_v_reg(ot
, cpu_T
[0], d
);
1343 gen_op_ld_v(s1
, ot
, cpu_T
[0], cpu_A0
);
1345 gen_compute_eflags_c(s1
, cpu_cc_src
);
1347 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], 1);
1348 set_cc_op(s1
, CC_OP_INCB
+ ot
);
1350 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], -1);
1351 set_cc_op(s1
, CC_OP_DECB
+ ot
);
1353 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1354 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
1357 static void gen_shift_flags(DisasContext
*s
, TCGMemOp ot
, TCGv result
,
1358 TCGv shm1
, TCGv count
, bool is_right
)
1360 TCGv_i32 z32
, s32
, oldop
;
1363 /* Store the results into the CC variables. If we know that the
1364 variable must be dead, store unconditionally. Otherwise we'll
1365 need to not disrupt the current contents. */
1366 z_tl
= tcg_const_tl(0);
1367 if (cc_op_live
[s
->cc_op
] & USES_CC_DST
) {
1368 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_dst
, count
, z_tl
,
1369 result
, cpu_cc_dst
);
1371 tcg_gen_mov_tl(cpu_cc_dst
, result
);
1373 if (cc_op_live
[s
->cc_op
] & USES_CC_SRC
) {
1374 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_src
, count
, z_tl
,
1377 tcg_gen_mov_tl(cpu_cc_src
, shm1
);
1379 tcg_temp_free(z_tl
);
1381 /* Get the two potential CC_OP values into temporaries. */
1382 tcg_gen_movi_i32(cpu_tmp2_i32
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1383 if (s
->cc_op
== CC_OP_DYNAMIC
) {
1386 tcg_gen_movi_i32(cpu_tmp3_i32
, s
->cc_op
);
1387 oldop
= cpu_tmp3_i32
;
1390 /* Conditionally store the CC_OP value. */
1391 z32
= tcg_const_i32(0);
1392 s32
= tcg_temp_new_i32();
1393 tcg_gen_trunc_tl_i32(s32
, count
);
1394 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, s32
, z32
, cpu_tmp2_i32
, oldop
);
1395 tcg_temp_free_i32(z32
);
1396 tcg_temp_free_i32(s32
);
1398 /* The CC_OP value is no longer predictable. */
1399 set_cc_op(s
, CC_OP_DYNAMIC
);
1402 static void gen_shift_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1403 int is_right
, int is_arith
)
1405 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1408 if (op1
== OR_TMP0
) {
1409 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1411 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1414 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], mask
);
1415 tcg_gen_subi_tl(cpu_tmp0
, cpu_T
[1], 1);
1419 gen_exts(ot
, cpu_T
[0]);
1420 tcg_gen_sar_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1421 tcg_gen_sar_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1423 gen_extu(ot
, cpu_T
[0]);
1424 tcg_gen_shr_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1425 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1428 tcg_gen_shl_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1429 tcg_gen_shl_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1433 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1435 gen_shift_flags(s
, ot
, cpu_T
[0], cpu_tmp0
, cpu_T
[1], is_right
);
1438 static void gen_shift_rm_im(DisasContext
*s
, TCGMemOp ot
, int op1
, int op2
,
1439 int is_right
, int is_arith
)
1441 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1445 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1447 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1453 gen_exts(ot
, cpu_T
[0]);
1454 tcg_gen_sari_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1455 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], op2
);
1457 gen_extu(ot
, cpu_T
[0]);
1458 tcg_gen_shri_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1459 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], op2
);
1462 tcg_gen_shli_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1463 tcg_gen_shli_tl(cpu_T
[0], cpu_T
[0], op2
);
1468 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1470 /* update eflags if non zero shift */
1472 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
1473 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
1474 set_cc_op(s
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1478 static void gen_rot_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
, int is_right
)
1480 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1484 if (op1
== OR_TMP0
) {
1485 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1487 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1490 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], mask
);
1494 /* Replicate the 8-bit input so that a 32-bit rotate works. */
1495 tcg_gen_ext8u_tl(cpu_T
[0], cpu_T
[0]);
1496 tcg_gen_muli_tl(cpu_T
[0], cpu_T
[0], 0x01010101);
1499 /* Replicate the 16-bit input so that a 32-bit rotate works. */
1500 tcg_gen_deposit_tl(cpu_T
[0], cpu_T
[0], cpu_T
[0], 16, 16);
1503 #ifdef TARGET_X86_64
1505 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
1506 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
1508 tcg_gen_rotr_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1510 tcg_gen_rotl_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1512 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
1517 tcg_gen_rotr_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1519 tcg_gen_rotl_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1525 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1527 /* We'll need the flags computed into CC_SRC. */
1528 gen_compute_eflags(s
);
1530 /* The value that was "rotated out" is now present at the other end
1531 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1532 since we've computed the flags into CC_SRC, these variables are
1535 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T
[0], mask
- 1);
1536 tcg_gen_shri_tl(cpu_cc_dst
, cpu_T
[0], mask
);
1537 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1539 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T
[0], mask
);
1540 tcg_gen_andi_tl(cpu_cc_dst
, cpu_T
[0], 1);
1542 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1543 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1545 /* Now conditionally store the new CC_OP value. If the shift count
1546 is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1547 Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1548 exactly as we computed above. */
1549 t0
= tcg_const_i32(0);
1550 t1
= tcg_temp_new_i32();
1551 tcg_gen_trunc_tl_i32(t1
, cpu_T
[1]);
1552 tcg_gen_movi_i32(cpu_tmp2_i32
, CC_OP_ADCOX
);
1553 tcg_gen_movi_i32(cpu_tmp3_i32
, CC_OP_EFLAGS
);
1554 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, t1
, t0
,
1555 cpu_tmp2_i32
, cpu_tmp3_i32
);
1556 tcg_temp_free_i32(t0
);
1557 tcg_temp_free_i32(t1
);
1559 /* The CC_OP value is no longer predictable. */
1560 set_cc_op(s
, CC_OP_DYNAMIC
);
1563 static void gen_rot_rm_im(DisasContext
*s
, TCGMemOp ot
, int op1
, int op2
,
1566 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1570 if (op1
== OR_TMP0
) {
1571 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1573 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1579 #ifdef TARGET_X86_64
1581 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
1583 tcg_gen_rotri_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, op2
);
1585 tcg_gen_rotli_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, op2
);
1587 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
1592 tcg_gen_rotri_tl(cpu_T
[0], cpu_T
[0], op2
);
1594 tcg_gen_rotli_tl(cpu_T
[0], cpu_T
[0], op2
);
1605 shift
= mask
+ 1 - shift
;
1607 gen_extu(ot
, cpu_T
[0]);
1608 tcg_gen_shli_tl(cpu_tmp0
, cpu_T
[0], shift
);
1609 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], mask
+ 1 - shift
);
1610 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
1616 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1619 /* Compute the flags into CC_SRC. */
1620 gen_compute_eflags(s
);
1622 /* The value that was "rotated out" is now present at the other end
1623 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1624 since we've computed the flags into CC_SRC, these variables are
1627 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T
[0], mask
- 1);
1628 tcg_gen_shri_tl(cpu_cc_dst
, cpu_T
[0], mask
);
1629 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1631 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T
[0], mask
);
1632 tcg_gen_andi_tl(cpu_cc_dst
, cpu_T
[0], 1);
1634 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1635 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1636 set_cc_op(s
, CC_OP_ADCOX
);
1640 /* XXX: add faster immediate = 1 case */
1641 static void gen_rotc_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1644 gen_compute_eflags(s
);
1645 assert(s
->cc_op
== CC_OP_EFLAGS
);
1649 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1651 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1656 gen_helper_rcrb(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1659 gen_helper_rcrw(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1662 gen_helper_rcrl(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1664 #ifdef TARGET_X86_64
1666 gen_helper_rcrq(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1675 gen_helper_rclb(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1678 gen_helper_rclw(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1681 gen_helper_rcll(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1683 #ifdef TARGET_X86_64
1685 gen_helper_rclq(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1693 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1696 /* XXX: add faster immediate case */
1697 static void gen_shiftd_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1698 bool is_right
, TCGv count_in
)
1700 target_ulong mask
= (ot
== MO_64
? 63 : 31);
1704 if (op1
== OR_TMP0
) {
1705 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1707 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1710 count
= tcg_temp_new();
1711 tcg_gen_andi_tl(count
, count_in
, mask
);
1715 /* Note: we implement the Intel behaviour for shift count > 16.
1716 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A
1717 portion by constructing it as a 32-bit value. */
1719 tcg_gen_deposit_tl(cpu_tmp0
, cpu_T
[0], cpu_T
[1], 16, 16);
1720 tcg_gen_mov_tl(cpu_T
[1], cpu_T
[0]);
1721 tcg_gen_mov_tl(cpu_T
[0], cpu_tmp0
);
1723 tcg_gen_deposit_tl(cpu_T
[1], cpu_T
[0], cpu_T
[1], 16, 16);
1726 #ifdef TARGET_X86_64
1728 /* Concatenate the two 32-bit values and use a 64-bit shift. */
1729 tcg_gen_subi_tl(cpu_tmp0
, count
, 1);
1731 tcg_gen_concat_tl_i64(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1732 tcg_gen_shr_i64(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1733 tcg_gen_shr_i64(cpu_T
[0], cpu_T
[0], count
);
1735 tcg_gen_concat_tl_i64(cpu_T
[0], cpu_T
[1], cpu_T
[0]);
1736 tcg_gen_shl_i64(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1737 tcg_gen_shl_i64(cpu_T
[0], cpu_T
[0], count
);
1738 tcg_gen_shri_i64(cpu_tmp0
, cpu_tmp0
, 32);
1739 tcg_gen_shri_i64(cpu_T
[0], cpu_T
[0], 32);
1744 tcg_gen_subi_tl(cpu_tmp0
, count
, 1);
1746 tcg_gen_shr_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1748 tcg_gen_subfi_tl(cpu_tmp4
, mask
+ 1, count
);
1749 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], count
);
1750 tcg_gen_shl_tl(cpu_T
[1], cpu_T
[1], cpu_tmp4
);
1752 tcg_gen_shl_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1754 /* Only needed if count > 16, for Intel behaviour. */
1755 tcg_gen_subfi_tl(cpu_tmp4
, 33, count
);
1756 tcg_gen_shr_tl(cpu_tmp4
, cpu_T
[1], cpu_tmp4
);
1757 tcg_gen_or_tl(cpu_tmp0
, cpu_tmp0
, cpu_tmp4
);
1760 tcg_gen_subfi_tl(cpu_tmp4
, mask
+ 1, count
);
1761 tcg_gen_shl_tl(cpu_T
[0], cpu_T
[0], count
);
1762 tcg_gen_shr_tl(cpu_T
[1], cpu_T
[1], cpu_tmp4
);
1764 tcg_gen_movi_tl(cpu_tmp4
, 0);
1765 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_T
[1], count
, cpu_tmp4
,
1766 cpu_tmp4
, cpu_T
[1]);
1767 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1772 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1774 gen_shift_flags(s
, ot
, cpu_T
[0], cpu_tmp0
, count
, is_right
);
1775 tcg_temp_free(count
);
1778 static void gen_shift(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
, int s
)
1781 gen_op_mov_v_reg(ot
, cpu_T
[1], s
);
1784 gen_rot_rm_T1(s1
, ot
, d
, 0);
1787 gen_rot_rm_T1(s1
, ot
, d
, 1);
1791 gen_shift_rm_T1(s1
, ot
, d
, 0, 0);
1794 gen_shift_rm_T1(s1
, ot
, d
, 1, 0);
1797 gen_shift_rm_T1(s1
, ot
, d
, 1, 1);
1800 gen_rotc_rm_T1(s1
, ot
, d
, 0);
1803 gen_rotc_rm_T1(s1
, ot
, d
, 1);
1808 static void gen_shifti(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
, int c
)
1812 gen_rot_rm_im(s1
, ot
, d
, c
, 0);
1815 gen_rot_rm_im(s1
, ot
, d
, c
, 1);
1819 gen_shift_rm_im(s1
, ot
, d
, c
, 0, 0);
1822 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 0);
1825 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 1);
1828 /* currently not optimized */
1829 tcg_gen_movi_tl(cpu_T
[1], c
);
1830 gen_shift(s1
, op
, ot
, d
, OR_TMP1
);
1835 static void gen_lea_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
1842 int mod
, rm
, code
, override
, must_add_seg
;
1845 override
= s
->override
;
1846 must_add_seg
= s
->addseg
;
1849 mod
= (modrm
>> 6) & 3;
1862 code
= cpu_ldub_code(env
, s
->pc
++);
1863 scale
= (code
>> 6) & 3;
1864 index
= ((code
>> 3) & 7) | REX_X(s
);
1866 index
= -1; /* no index */
1874 if ((base
& 7) == 5) {
1876 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
1878 if (CODE64(s
) && !havesib
) {
1879 disp
+= s
->pc
+ s
->rip_offset
;
1886 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
1890 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
1895 /* For correct popl handling with esp. */
1896 if (base
== R_ESP
&& s
->popl_esp_hack
) {
1897 disp
+= s
->popl_esp_hack
;
1900 /* Compute the address, with a minimum number of TCG ops. */
1904 sum
= cpu_regs
[index
];
1906 tcg_gen_shli_tl(cpu_A0
, cpu_regs
[index
], scale
);
1910 tcg_gen_add_tl(cpu_A0
, sum
, cpu_regs
[base
]);
1913 } else if (base
>= 0) {
1914 sum
= cpu_regs
[base
];
1916 if (TCGV_IS_UNUSED(sum
)) {
1917 tcg_gen_movi_tl(cpu_A0
, disp
);
1919 tcg_gen_addi_tl(cpu_A0
, sum
, disp
);
1924 if (base
== R_EBP
|| base
== R_ESP
) {
1931 tcg_gen_ld_tl(cpu_tmp0
, cpu_env
,
1932 offsetof(CPUX86State
, segs
[override
].base
));
1934 if (s
->aflag
== MO_32
) {
1935 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
1937 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
1941 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
1944 if (s
->aflag
== MO_32
) {
1945 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
1953 disp
= cpu_lduw_code(env
, s
->pc
);
1955 tcg_gen_movi_tl(cpu_A0
, disp
);
1956 rm
= 0; /* avoid SS override */
1963 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
1967 disp
= (int16_t)cpu_lduw_code(env
, s
->pc
);
1975 tcg_gen_add_tl(cpu_A0
, cpu_regs
[R_EBX
], cpu_regs
[R_ESI
]);
1978 tcg_gen_add_tl(cpu_A0
, cpu_regs
[R_EBX
], cpu_regs
[R_EDI
]);
1981 tcg_gen_add_tl(cpu_A0
, cpu_regs
[R_EBP
], cpu_regs
[R_ESI
]);
1984 tcg_gen_add_tl(cpu_A0
, cpu_regs
[R_EBP
], cpu_regs
[R_EDI
]);
1987 sum
= cpu_regs
[R_ESI
];
1990 sum
= cpu_regs
[R_EDI
];
1993 sum
= cpu_regs
[R_EBP
];
1997 sum
= cpu_regs
[R_EBX
];
2000 tcg_gen_addi_tl(cpu_A0
, sum
, disp
);
2001 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2005 if (rm
== 2 || rm
== 3 || rm
== 6) {
2011 gen_op_addl_A0_seg(s
, override
);
2020 static void gen_nop_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2022 int mod
, rm
, base
, code
;
2024 mod
= (modrm
>> 6) & 3;
2035 code
= cpu_ldub_code(env
, s
->pc
++);
2077 /* used for LEA and MOV AX, mem */
2078 static void gen_add_A0_ds_seg(DisasContext
*s
)
2080 gen_lea_v_seg(s
, cpu_A0
, R_DS
, s
->override
);
2083 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2085 static void gen_ldst_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2086 TCGMemOp ot
, int reg
, int is_store
)
2090 mod
= (modrm
>> 6) & 3;
2091 rm
= (modrm
& 7) | REX_B(s
);
2095 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
2096 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
2098 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
2100 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
2103 gen_lea_modrm(env
, s
, modrm
);
2106 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
2107 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
2109 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
2111 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
2116 static inline uint32_t insn_get(CPUX86State
*env
, DisasContext
*s
, TCGMemOp ot
)
2122 ret
= cpu_ldub_code(env
, s
->pc
);
2126 ret
= cpu_lduw_code(env
, s
->pc
);
2130 #ifdef TARGET_X86_64
2133 ret
= cpu_ldl_code(env
, s
->pc
);
2142 static inline int insn_const_size(TCGMemOp ot
)
2151 static inline void gen_goto_tb(DisasContext
*s
, int tb_num
, target_ulong eip
)
2153 TranslationBlock
*tb
;
2156 pc
= s
->cs_base
+ eip
;
2158 /* NOTE: we handle the case where the TB spans two pages here */
2159 if ((pc
& TARGET_PAGE_MASK
) == (tb
->pc
& TARGET_PAGE_MASK
) ||
2160 (pc
& TARGET_PAGE_MASK
) == ((s
->pc
- 1) & TARGET_PAGE_MASK
)) {
2161 /* jump to same page: we can use a direct jump */
2162 tcg_gen_goto_tb(tb_num
);
2164 tcg_gen_exit_tb((uintptr_t)tb
+ tb_num
);
2166 /* jump to another page: currently not optimized */
2172 static inline void gen_jcc(DisasContext
*s
, int b
,
2173 target_ulong val
, target_ulong next_eip
)
2178 l1
= gen_new_label();
2181 gen_goto_tb(s
, 0, next_eip
);
2184 gen_goto_tb(s
, 1, val
);
2185 s
->is_jmp
= DISAS_TB_JUMP
;
2187 l1
= gen_new_label();
2188 l2
= gen_new_label();
2191 gen_jmp_im(next_eip
);
2201 static void gen_cmovcc1(CPUX86State
*env
, DisasContext
*s
, TCGMemOp ot
, int b
,
2206 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
2208 cc
= gen_prepare_cc(s
, b
, cpu_T
[1]);
2209 if (cc
.mask
!= -1) {
2210 TCGv t0
= tcg_temp_new();
2211 tcg_gen_andi_tl(t0
, cc
.reg
, cc
.mask
);
2215 cc
.reg2
= tcg_const_tl(cc
.imm
);
2218 tcg_gen_movcond_tl(cc
.cond
, cpu_T
[0], cc
.reg
, cc
.reg2
,
2219 cpu_T
[0], cpu_regs
[reg
]);
2220 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
2222 if (cc
.mask
!= -1) {
2223 tcg_temp_free(cc
.reg
);
2226 tcg_temp_free(cc
.reg2
);
2230 static inline void gen_op_movl_T0_seg(int seg_reg
)
2232 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
,
2233 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2236 static inline void gen_op_movl_seg_T0_vm(int seg_reg
)
2238 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffff);
2239 tcg_gen_st32_tl(cpu_T
[0], cpu_env
,
2240 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2241 tcg_gen_shli_tl(cpu_T
[0], cpu_T
[0], 4);
2242 tcg_gen_st_tl(cpu_T
[0], cpu_env
,
2243 offsetof(CPUX86State
,segs
[seg_reg
].base
));
2246 /* move T0 to seg_reg and compute if the CPU state may change. Never
2247 call this function with seg_reg == R_CS */
2248 static void gen_movl_seg_T0(DisasContext
*s
, int seg_reg
)
2250 if (s
->pe
&& !s
->vm86
) {
2251 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
2252 gen_helper_load_seg(cpu_env
, tcg_const_i32(seg_reg
), cpu_tmp2_i32
);
2253 /* abort translation because the addseg value may change or
2254 because ss32 may change. For R_SS, translation must always
2255 stop as a special handling must be done to disable hardware
2256 interrupts for the next instruction */
2257 if (seg_reg
== R_SS
|| (s
->code32
&& seg_reg
< R_FS
))
2258 s
->is_jmp
= DISAS_TB_JUMP
;
2260 gen_op_movl_seg_T0_vm(seg_reg
);
2261 if (seg_reg
== R_SS
)
2262 s
->is_jmp
= DISAS_TB_JUMP
;
2266 static inline int svm_is_rep(int prefixes
)
2268 return ((prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) ? 8 : 0);
2272 gen_svm_check_intercept_param(DisasContext
*s
, target_ulong pc_start
,
2273 uint32_t type
, uint64_t param
)
2275 /* no SVM activated; fast case */
2276 if (likely(!(s
->flags
& HF_SVMI_MASK
)))
2278 gen_update_cc_op(s
);
2279 gen_jmp_im(pc_start
- s
->cs_base
);
2280 gen_helper_svm_check_intercept_param(cpu_env
, tcg_const_i32(type
),
2281 tcg_const_i64(param
));
2285 gen_svm_check_intercept(DisasContext
*s
, target_ulong pc_start
, uint64_t type
)
2287 gen_svm_check_intercept_param(s
, pc_start
, type
, 0);
2290 static inline void gen_stack_update(DisasContext
*s
, int addend
)
2292 #ifdef TARGET_X86_64
2294 gen_op_add_reg_im(MO_64
, R_ESP
, addend
);
2298 gen_op_add_reg_im(MO_32
, R_ESP
, addend
);
2300 gen_op_add_reg_im(MO_16
, R_ESP
, addend
);
2304 /* Generate a push. It depends on ss32, addseg and dflag. */
2305 static void gen_push_v(DisasContext
*s
, TCGv val
)
2307 TCGMemOp a_ot
, d_ot
= mo_pushpop(s
, s
->dflag
);
2308 int size
= 1 << d_ot
;
2309 TCGv new_esp
= cpu_A0
;
2311 tcg_gen_subi_tl(cpu_A0
, cpu_regs
[R_ESP
], size
);
2315 } else if (s
->ss32
) {
2319 tcg_gen_mov_tl(new_esp
, cpu_A0
);
2320 gen_op_addl_A0_seg(s
, R_SS
);
2322 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
2327 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2328 tcg_gen_mov_tl(new_esp
, cpu_A0
);
2329 gen_op_addl_A0_seg(s
, R_SS
);
2332 gen_op_st_v(s
, d_ot
, val
, cpu_A0
);
2333 gen_op_mov_reg_v(a_ot
, R_ESP
, new_esp
);
2336 /* two step pop is necessary for precise exceptions */
2337 static TCGMemOp
gen_pop_T0(DisasContext
*s
)
2339 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2343 addr
= cpu_regs
[R_ESP
];
2344 } else if (!s
->ss32
) {
2345 tcg_gen_ext16u_tl(cpu_A0
, cpu_regs
[R_ESP
]);
2346 gen_op_addl_A0_seg(s
, R_SS
);
2347 } else if (s
->addseg
) {
2348 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_ESP
]);
2349 gen_op_addl_A0_seg(s
, R_SS
);
2351 tcg_gen_ext32u_tl(cpu_A0
, cpu_regs
[R_ESP
]);
2354 gen_op_ld_v(s
, d_ot
, cpu_T
[0], addr
);
2358 static void gen_pop_update(DisasContext
*s
, TCGMemOp ot
)
2360 gen_stack_update(s
, 1 << ot
);
2363 static void gen_stack_A0(DisasContext
*s
)
2365 gen_op_movl_A0_reg(R_ESP
);
2367 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2368 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2370 gen_op_addl_A0_seg(s
, R_SS
);
2373 /* NOTE: wrap around in 16 bit not fully handled */
2374 static void gen_pusha(DisasContext
*s
)
2377 gen_op_movl_A0_reg(R_ESP
);
2378 gen_op_addl_A0_im(-(8 << s
->dflag
));
2380 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2381 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2383 gen_op_addl_A0_seg(s
, R_SS
);
2384 for(i
= 0;i
< 8; i
++) {
2385 gen_op_mov_v_reg(MO_32
, cpu_T
[0], 7 - i
);
2386 gen_op_st_v(s
, s
->dflag
, cpu_T
[0], cpu_A0
);
2387 gen_op_addl_A0_im(1 << s
->dflag
);
2389 gen_op_mov_reg_v(MO_16
+ s
->ss32
, R_ESP
, cpu_T
[1]);
2392 /* NOTE: wrap around in 16 bit not fully handled */
2393 static void gen_popa(DisasContext
*s
)
2396 gen_op_movl_A0_reg(R_ESP
);
2398 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2399 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2400 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], 8 << s
->dflag
);
2402 gen_op_addl_A0_seg(s
, R_SS
);
2403 for(i
= 0;i
< 8; i
++) {
2404 /* ESP is not reloaded */
2406 gen_op_ld_v(s
, s
->dflag
, cpu_T
[0], cpu_A0
);
2407 gen_op_mov_reg_v(s
->dflag
, 7 - i
, cpu_T
[0]);
2409 gen_op_addl_A0_im(1 << s
->dflag
);
2411 gen_op_mov_reg_v(MO_16
+ s
->ss32
, R_ESP
, cpu_T
[1]);
2414 static void gen_enter(DisasContext
*s
, int esp_addend
, int level
)
2416 TCGMemOp ot
= mo_pushpop(s
, s
->dflag
);
2417 int opsize
= 1 << ot
;
2420 #ifdef TARGET_X86_64
2422 gen_op_movl_A0_reg(R_ESP
);
2423 gen_op_addq_A0_im(-opsize
);
2424 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2427 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EBP
);
2428 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
2430 /* XXX: must save state */
2431 gen_helper_enter64_level(cpu_env
, tcg_const_i32(level
),
2432 tcg_const_i32((ot
== MO_64
)),
2435 gen_op_mov_reg_v(ot
, R_EBP
, cpu_T
[1]);
2436 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], -esp_addend
+ (-opsize
* level
));
2437 gen_op_mov_reg_v(MO_64
, R_ESP
, cpu_T
[1]);
2441 gen_op_movl_A0_reg(R_ESP
);
2442 gen_op_addl_A0_im(-opsize
);
2444 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2445 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2447 gen_op_addl_A0_seg(s
, R_SS
);
2449 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EBP
);
2450 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
2452 /* XXX: must save state */
2453 gen_helper_enter_level(cpu_env
, tcg_const_i32(level
),
2454 tcg_const_i32(s
->dflag
- 1),
2457 gen_op_mov_reg_v(ot
, R_EBP
, cpu_T
[1]);
2458 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], -esp_addend
+ (-opsize
* level
));
2459 gen_op_mov_reg_v(MO_16
+ s
->ss32
, R_ESP
, cpu_T
[1]);
2463 static void gen_exception(DisasContext
*s
, int trapno
, target_ulong cur_eip
)
2465 gen_update_cc_op(s
);
2466 gen_jmp_im(cur_eip
);
2467 gen_helper_raise_exception(cpu_env
, tcg_const_i32(trapno
));
2468 s
->is_jmp
= DISAS_TB_JUMP
;
2471 /* an interrupt is different from an exception because of the
2473 static void gen_interrupt(DisasContext
*s
, int intno
,
2474 target_ulong cur_eip
, target_ulong next_eip
)
2476 gen_update_cc_op(s
);
2477 gen_jmp_im(cur_eip
);
2478 gen_helper_raise_interrupt(cpu_env
, tcg_const_i32(intno
),
2479 tcg_const_i32(next_eip
- cur_eip
));
2480 s
->is_jmp
= DISAS_TB_JUMP
;
2483 static void gen_debug(DisasContext
*s
, target_ulong cur_eip
)
2485 gen_update_cc_op(s
);
2486 gen_jmp_im(cur_eip
);
2487 gen_helper_debug(cpu_env
);
2488 s
->is_jmp
= DISAS_TB_JUMP
;
2491 /* generate a generic end of block. Trace exception is also generated
2493 static void gen_eob(DisasContext
*s
)
2495 gen_update_cc_op(s
);
2496 if (s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
) {
2497 gen_helper_reset_inhibit_irq(cpu_env
);
2499 if (s
->tb
->flags
& HF_RF_MASK
) {
2500 gen_helper_reset_rf(cpu_env
);
2502 if (s
->singlestep_enabled
) {
2503 gen_helper_debug(cpu_env
);
2505 gen_helper_single_step(cpu_env
);
2509 s
->is_jmp
= DISAS_TB_JUMP
;
2512 /* generate a jump to eip. No segment change must happen before as a
2513 direct call to the next block may occur */
2514 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
)
2516 gen_update_cc_op(s
);
2517 set_cc_op(s
, CC_OP_DYNAMIC
);
2519 gen_goto_tb(s
, tb_num
, eip
);
2520 s
->is_jmp
= DISAS_TB_JUMP
;
2527 static void gen_jmp(DisasContext
*s
, target_ulong eip
)
2529 gen_jmp_tb(s
, eip
, 0);
2532 static inline void gen_ldq_env_A0(DisasContext
*s
, int offset
)
2534 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
2535 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2538 static inline void gen_stq_env_A0(DisasContext
*s
, int offset
)
2540 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2541 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
2544 static inline void gen_ldo_env_A0(DisasContext
*s
, int offset
)
2546 int mem_index
= s
->mem_index
;
2547 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, mem_index
, MO_LEQ
);
2548 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2549 tcg_gen_addi_tl(cpu_tmp0
, cpu_A0
, 8);
2550 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
, MO_LEQ
);
2551 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2554 static inline void gen_sto_env_A0(DisasContext
*s
, int offset
)
2556 int mem_index
= s
->mem_index
;
2557 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2558 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, mem_index
, MO_LEQ
);
2559 tcg_gen_addi_tl(cpu_tmp0
, cpu_A0
, 8);
2560 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2561 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
, MO_LEQ
);
2564 static inline void gen_op_movo(int d_offset
, int s_offset
)
2566 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2567 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2568 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2569 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2572 static inline void gen_op_movq(int d_offset
, int s_offset
)
2574 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
);
2575 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2578 static inline void gen_op_movl(int d_offset
, int s_offset
)
2580 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
, s_offset
);
2581 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, d_offset
);
2584 static inline void gen_op_movq_env_0(int d_offset
)
2586 tcg_gen_movi_i64(cpu_tmp1_i64
, 0);
2587 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2590 typedef void (*SSEFunc_i_ep
)(TCGv_i32 val
, TCGv_ptr env
, TCGv_ptr reg
);
2591 typedef void (*SSEFunc_l_ep
)(TCGv_i64 val
, TCGv_ptr env
, TCGv_ptr reg
);
2592 typedef void (*SSEFunc_0_epi
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i32 val
);
2593 typedef void (*SSEFunc_0_epl
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i64 val
);
2594 typedef void (*SSEFunc_0_epp
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
);
2595 typedef void (*SSEFunc_0_eppi
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2597 typedef void (*SSEFunc_0_ppi
)(TCGv_ptr reg_a
, TCGv_ptr reg_b
, TCGv_i32 val
);
2598 typedef void (*SSEFunc_0_eppt
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2601 #define SSE_SPECIAL ((void *)1)
2602 #define SSE_DUMMY ((void *)2)
2604 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2605 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2606 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2608 static const SSEFunc_0_epp sse_op_table1
[256][4] = {
2609 /* 3DNow! extensions */
2610 [0x0e] = { SSE_DUMMY
}, /* femms */
2611 [0x0f] = { SSE_DUMMY
}, /* pf... */
2612 /* pure SSE operations */
2613 [0x10] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2614 [0x11] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2615 [0x12] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd, movsldup, movddup */
2616 [0x13] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd */
2617 [0x14] = { gen_helper_punpckldq_xmm
, gen_helper_punpcklqdq_xmm
},
2618 [0x15] = { gen_helper_punpckhdq_xmm
, gen_helper_punpckhqdq_xmm
},
2619 [0x16] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd, movshdup */
2620 [0x17] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd */
2622 [0x28] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2623 [0x29] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2624 [0x2a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2625 [0x2b] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movntps, movntpd, movntss, movntsd */
2626 [0x2c] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2627 [0x2d] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2628 [0x2e] = { gen_helper_ucomiss
, gen_helper_ucomisd
},
2629 [0x2f] = { gen_helper_comiss
, gen_helper_comisd
},
2630 [0x50] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movmskps, movmskpd */
2631 [0x51] = SSE_FOP(sqrt
),
2632 [0x52] = { gen_helper_rsqrtps
, NULL
, gen_helper_rsqrtss
, NULL
},
2633 [0x53] = { gen_helper_rcpps
, NULL
, gen_helper_rcpss
, NULL
},
2634 [0x54] = { gen_helper_pand_xmm
, gen_helper_pand_xmm
}, /* andps, andpd */
2635 [0x55] = { gen_helper_pandn_xmm
, gen_helper_pandn_xmm
}, /* andnps, andnpd */
2636 [0x56] = { gen_helper_por_xmm
, gen_helper_por_xmm
}, /* orps, orpd */
2637 [0x57] = { gen_helper_pxor_xmm
, gen_helper_pxor_xmm
}, /* xorps, xorpd */
2638 [0x58] = SSE_FOP(add
),
2639 [0x59] = SSE_FOP(mul
),
2640 [0x5a] = { gen_helper_cvtps2pd
, gen_helper_cvtpd2ps
,
2641 gen_helper_cvtss2sd
, gen_helper_cvtsd2ss
},
2642 [0x5b] = { gen_helper_cvtdq2ps
, gen_helper_cvtps2dq
, gen_helper_cvttps2dq
},
2643 [0x5c] = SSE_FOP(sub
),
2644 [0x5d] = SSE_FOP(min
),
2645 [0x5e] = SSE_FOP(div
),
2646 [0x5f] = SSE_FOP(max
),
2648 [0xc2] = SSE_FOP(cmpeq
),
2649 [0xc6] = { (SSEFunc_0_epp
)gen_helper_shufps
,
2650 (SSEFunc_0_epp
)gen_helper_shufpd
}, /* XXX: casts */
2652 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */
2653 [0x38] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2654 [0x3a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2656 /* MMX ops and their SSE extensions */
2657 [0x60] = MMX_OP2(punpcklbw
),
2658 [0x61] = MMX_OP2(punpcklwd
),
2659 [0x62] = MMX_OP2(punpckldq
),
2660 [0x63] = MMX_OP2(packsswb
),
2661 [0x64] = MMX_OP2(pcmpgtb
),
2662 [0x65] = MMX_OP2(pcmpgtw
),
2663 [0x66] = MMX_OP2(pcmpgtl
),
2664 [0x67] = MMX_OP2(packuswb
),
2665 [0x68] = MMX_OP2(punpckhbw
),
2666 [0x69] = MMX_OP2(punpckhwd
),
2667 [0x6a] = MMX_OP2(punpckhdq
),
2668 [0x6b] = MMX_OP2(packssdw
),
2669 [0x6c] = { NULL
, gen_helper_punpcklqdq_xmm
},
2670 [0x6d] = { NULL
, gen_helper_punpckhqdq_xmm
},
2671 [0x6e] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movd mm, ea */
2672 [0x6f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, , movqdu */
2673 [0x70] = { (SSEFunc_0_epp
)gen_helper_pshufw_mmx
,
2674 (SSEFunc_0_epp
)gen_helper_pshufd_xmm
,
2675 (SSEFunc_0_epp
)gen_helper_pshufhw_xmm
,
2676 (SSEFunc_0_epp
)gen_helper_pshuflw_xmm
}, /* XXX: casts */
2677 [0x71] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftw */
2678 [0x72] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftd */
2679 [0x73] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftq */
2680 [0x74] = MMX_OP2(pcmpeqb
),
2681 [0x75] = MMX_OP2(pcmpeqw
),
2682 [0x76] = MMX_OP2(pcmpeql
),
2683 [0x77] = { SSE_DUMMY
}, /* emms */
2684 [0x78] = { NULL
, SSE_SPECIAL
, NULL
, SSE_SPECIAL
}, /* extrq_i, insertq_i */
2685 [0x79] = { NULL
, gen_helper_extrq_r
, NULL
, gen_helper_insertq_r
},
2686 [0x7c] = { NULL
, gen_helper_haddpd
, NULL
, gen_helper_haddps
},
2687 [0x7d] = { NULL
, gen_helper_hsubpd
, NULL
, gen_helper_hsubps
},
2688 [0x7e] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movd, movd, , movq */
2689 [0x7f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, movdqu */
2690 [0xc4] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pinsrw */
2691 [0xc5] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pextrw */
2692 [0xd0] = { NULL
, gen_helper_addsubpd
, NULL
, gen_helper_addsubps
},
2693 [0xd1] = MMX_OP2(psrlw
),
2694 [0xd2] = MMX_OP2(psrld
),
2695 [0xd3] = MMX_OP2(psrlq
),
2696 [0xd4] = MMX_OP2(paddq
),
2697 [0xd5] = MMX_OP2(pmullw
),
2698 [0xd6] = { NULL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2699 [0xd7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pmovmskb */
2700 [0xd8] = MMX_OP2(psubusb
),
2701 [0xd9] = MMX_OP2(psubusw
),
2702 [0xda] = MMX_OP2(pminub
),
2703 [0xdb] = MMX_OP2(pand
),
2704 [0xdc] = MMX_OP2(paddusb
),
2705 [0xdd] = MMX_OP2(paddusw
),
2706 [0xde] = MMX_OP2(pmaxub
),
2707 [0xdf] = MMX_OP2(pandn
),
2708 [0xe0] = MMX_OP2(pavgb
),
2709 [0xe1] = MMX_OP2(psraw
),
2710 [0xe2] = MMX_OP2(psrad
),
2711 [0xe3] = MMX_OP2(pavgw
),
2712 [0xe4] = MMX_OP2(pmulhuw
),
2713 [0xe5] = MMX_OP2(pmulhw
),
2714 [0xe6] = { NULL
, gen_helper_cvttpd2dq
, gen_helper_cvtdq2pd
, gen_helper_cvtpd2dq
},
2715 [0xe7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movntq, movntq */
2716 [0xe8] = MMX_OP2(psubsb
),
2717 [0xe9] = MMX_OP2(psubsw
),
2718 [0xea] = MMX_OP2(pminsw
),
2719 [0xeb] = MMX_OP2(por
),
2720 [0xec] = MMX_OP2(paddsb
),
2721 [0xed] = MMX_OP2(paddsw
),
2722 [0xee] = MMX_OP2(pmaxsw
),
2723 [0xef] = MMX_OP2(pxor
),
2724 [0xf0] = { NULL
, NULL
, NULL
, SSE_SPECIAL
}, /* lddqu */
2725 [0xf1] = MMX_OP2(psllw
),
2726 [0xf2] = MMX_OP2(pslld
),
2727 [0xf3] = MMX_OP2(psllq
),
2728 [0xf4] = MMX_OP2(pmuludq
),
2729 [0xf5] = MMX_OP2(pmaddwd
),
2730 [0xf6] = MMX_OP2(psadbw
),
2731 [0xf7] = { (SSEFunc_0_epp
)gen_helper_maskmov_mmx
,
2732 (SSEFunc_0_epp
)gen_helper_maskmov_xmm
}, /* XXX: casts */
2733 [0xf8] = MMX_OP2(psubb
),
2734 [0xf9] = MMX_OP2(psubw
),
2735 [0xfa] = MMX_OP2(psubl
),
2736 [0xfb] = MMX_OP2(psubq
),
2737 [0xfc] = MMX_OP2(paddb
),
2738 [0xfd] = MMX_OP2(paddw
),
2739 [0xfe] = MMX_OP2(paddl
),
2742 static const SSEFunc_0_epp sse_op_table2
[3 * 8][2] = {
2743 [0 + 2] = MMX_OP2(psrlw
),
2744 [0 + 4] = MMX_OP2(psraw
),
2745 [0 + 6] = MMX_OP2(psllw
),
2746 [8 + 2] = MMX_OP2(psrld
),
2747 [8 + 4] = MMX_OP2(psrad
),
2748 [8 + 6] = MMX_OP2(pslld
),
2749 [16 + 2] = MMX_OP2(psrlq
),
2750 [16 + 3] = { NULL
, gen_helper_psrldq_xmm
},
2751 [16 + 6] = MMX_OP2(psllq
),
2752 [16 + 7] = { NULL
, gen_helper_pslldq_xmm
},
2755 static const SSEFunc_0_epi sse_op_table3ai
[] = {
2756 gen_helper_cvtsi2ss
,
2760 #ifdef TARGET_X86_64
2761 static const SSEFunc_0_epl sse_op_table3aq
[] = {
2762 gen_helper_cvtsq2ss
,
2767 static const SSEFunc_i_ep sse_op_table3bi
[] = {
2768 gen_helper_cvttss2si
,
2769 gen_helper_cvtss2si
,
2770 gen_helper_cvttsd2si
,
2774 #ifdef TARGET_X86_64
2775 static const SSEFunc_l_ep sse_op_table3bq
[] = {
2776 gen_helper_cvttss2sq
,
2777 gen_helper_cvtss2sq
,
2778 gen_helper_cvttsd2sq
,
2783 static const SSEFunc_0_epp sse_op_table4
[8][4] = {
2794 static const SSEFunc_0_epp sse_op_table5
[256] = {
2795 [0x0c] = gen_helper_pi2fw
,
2796 [0x0d] = gen_helper_pi2fd
,
2797 [0x1c] = gen_helper_pf2iw
,
2798 [0x1d] = gen_helper_pf2id
,
2799 [0x8a] = gen_helper_pfnacc
,
2800 [0x8e] = gen_helper_pfpnacc
,
2801 [0x90] = gen_helper_pfcmpge
,
2802 [0x94] = gen_helper_pfmin
,
2803 [0x96] = gen_helper_pfrcp
,
2804 [0x97] = gen_helper_pfrsqrt
,
2805 [0x9a] = gen_helper_pfsub
,
2806 [0x9e] = gen_helper_pfadd
,
2807 [0xa0] = gen_helper_pfcmpgt
,
2808 [0xa4] = gen_helper_pfmax
,
2809 [0xa6] = gen_helper_movq
, /* pfrcpit1; no need to actually increase precision */
2810 [0xa7] = gen_helper_movq
, /* pfrsqit1 */
2811 [0xaa] = gen_helper_pfsubr
,
2812 [0xae] = gen_helper_pfacc
,
2813 [0xb0] = gen_helper_pfcmpeq
,
2814 [0xb4] = gen_helper_pfmul
,
2815 [0xb6] = gen_helper_movq
, /* pfrcpit2 */
2816 [0xb7] = gen_helper_pmulhrw_mmx
,
2817 [0xbb] = gen_helper_pswapd
,
2818 [0xbf] = gen_helper_pavgb_mmx
/* pavgusb */
2821 struct SSEOpHelper_epp
{
2822 SSEFunc_0_epp op
[2];
2826 struct SSEOpHelper_eppi
{
2827 SSEFunc_0_eppi op
[2];
2831 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
2832 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
2833 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
2834 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
2835 #define PCLMULQDQ_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, \
2836 CPUID_EXT_PCLMULQDQ }
2837 #define AESNI_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_AES }
2839 static const struct SSEOpHelper_epp sse_op_table6
[256] = {
2840 [0x00] = SSSE3_OP(pshufb
),
2841 [0x01] = SSSE3_OP(phaddw
),
2842 [0x02] = SSSE3_OP(phaddd
),
2843 [0x03] = SSSE3_OP(phaddsw
),
2844 [0x04] = SSSE3_OP(pmaddubsw
),
2845 [0x05] = SSSE3_OP(phsubw
),
2846 [0x06] = SSSE3_OP(phsubd
),
2847 [0x07] = SSSE3_OP(phsubsw
),
2848 [0x08] = SSSE3_OP(psignb
),
2849 [0x09] = SSSE3_OP(psignw
),
2850 [0x0a] = SSSE3_OP(psignd
),
2851 [0x0b] = SSSE3_OP(pmulhrsw
),
2852 [0x10] = SSE41_OP(pblendvb
),
2853 [0x14] = SSE41_OP(blendvps
),
2854 [0x15] = SSE41_OP(blendvpd
),
2855 [0x17] = SSE41_OP(ptest
),
2856 [0x1c] = SSSE3_OP(pabsb
),
2857 [0x1d] = SSSE3_OP(pabsw
),
2858 [0x1e] = SSSE3_OP(pabsd
),
2859 [0x20] = SSE41_OP(pmovsxbw
),
2860 [0x21] = SSE41_OP(pmovsxbd
),
2861 [0x22] = SSE41_OP(pmovsxbq
),
2862 [0x23] = SSE41_OP(pmovsxwd
),
2863 [0x24] = SSE41_OP(pmovsxwq
),
2864 [0x25] = SSE41_OP(pmovsxdq
),
2865 [0x28] = SSE41_OP(pmuldq
),
2866 [0x29] = SSE41_OP(pcmpeqq
),
2867 [0x2a] = SSE41_SPECIAL
, /* movntqda */
2868 [0x2b] = SSE41_OP(packusdw
),
2869 [0x30] = SSE41_OP(pmovzxbw
),
2870 [0x31] = SSE41_OP(pmovzxbd
),
2871 [0x32] = SSE41_OP(pmovzxbq
),
2872 [0x33] = SSE41_OP(pmovzxwd
),
2873 [0x34] = SSE41_OP(pmovzxwq
),
2874 [0x35] = SSE41_OP(pmovzxdq
),
2875 [0x37] = SSE42_OP(pcmpgtq
),
2876 [0x38] = SSE41_OP(pminsb
),
2877 [0x39] = SSE41_OP(pminsd
),
2878 [0x3a] = SSE41_OP(pminuw
),
2879 [0x3b] = SSE41_OP(pminud
),
2880 [0x3c] = SSE41_OP(pmaxsb
),
2881 [0x3d] = SSE41_OP(pmaxsd
),
2882 [0x3e] = SSE41_OP(pmaxuw
),
2883 [0x3f] = SSE41_OP(pmaxud
),
2884 [0x40] = SSE41_OP(pmulld
),
2885 [0x41] = SSE41_OP(phminposuw
),
2886 [0xdb] = AESNI_OP(aesimc
),
2887 [0xdc] = AESNI_OP(aesenc
),
2888 [0xdd] = AESNI_OP(aesenclast
),
2889 [0xde] = AESNI_OP(aesdec
),
2890 [0xdf] = AESNI_OP(aesdeclast
),
2893 static const struct SSEOpHelper_eppi sse_op_table7
[256] = {
2894 [0x08] = SSE41_OP(roundps
),
2895 [0x09] = SSE41_OP(roundpd
),
2896 [0x0a] = SSE41_OP(roundss
),
2897 [0x0b] = SSE41_OP(roundsd
),
2898 [0x0c] = SSE41_OP(blendps
),
2899 [0x0d] = SSE41_OP(blendpd
),
2900 [0x0e] = SSE41_OP(pblendw
),
2901 [0x0f] = SSSE3_OP(palignr
),
2902 [0x14] = SSE41_SPECIAL
, /* pextrb */
2903 [0x15] = SSE41_SPECIAL
, /* pextrw */
2904 [0x16] = SSE41_SPECIAL
, /* pextrd/pextrq */
2905 [0x17] = SSE41_SPECIAL
, /* extractps */
2906 [0x20] = SSE41_SPECIAL
, /* pinsrb */
2907 [0x21] = SSE41_SPECIAL
, /* insertps */
2908 [0x22] = SSE41_SPECIAL
, /* pinsrd/pinsrq */
2909 [0x40] = SSE41_OP(dpps
),
2910 [0x41] = SSE41_OP(dppd
),
2911 [0x42] = SSE41_OP(mpsadbw
),
2912 [0x44] = PCLMULQDQ_OP(pclmulqdq
),
2913 [0x60] = SSE42_OP(pcmpestrm
),
2914 [0x61] = SSE42_OP(pcmpestri
),
2915 [0x62] = SSE42_OP(pcmpistrm
),
2916 [0x63] = SSE42_OP(pcmpistri
),
2917 [0xdf] = AESNI_OP(aeskeygenassist
),
2920 static void gen_sse(CPUX86State
*env
, DisasContext
*s
, int b
,
2921 target_ulong pc_start
, int rex_r
)
2923 int b1
, op1_offset
, op2_offset
, is_xmm
, val
;
2924 int modrm
, mod
, rm
, reg
;
2925 SSEFunc_0_epp sse_fn_epp
;
2926 SSEFunc_0_eppi sse_fn_eppi
;
2927 SSEFunc_0_ppi sse_fn_ppi
;
2928 SSEFunc_0_eppt sse_fn_eppt
;
2932 if (s
->prefix
& PREFIX_DATA
)
2934 else if (s
->prefix
& PREFIX_REPZ
)
2936 else if (s
->prefix
& PREFIX_REPNZ
)
2940 sse_fn_epp
= sse_op_table1
[b
][b1
];
2944 if ((b
<= 0x5f && b
>= 0x10) || b
== 0xc6 || b
== 0xc2) {
2954 /* simple MMX/SSE operation */
2955 if (s
->flags
& HF_TS_MASK
) {
2956 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
2959 if (s
->flags
& HF_EM_MASK
) {
2961 gen_exception(s
, EXCP06_ILLOP
, pc_start
- s
->cs_base
);
2964 if (is_xmm
&& !(s
->flags
& HF_OSFXSR_MASK
))
2965 if ((b
!= 0x38 && b
!= 0x3a) || (s
->prefix
& PREFIX_DATA
))
2968 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
))
2971 gen_helper_emms(cpu_env
);
2976 gen_helper_emms(cpu_env
);
2979 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
2980 the static cpu state) */
2982 gen_helper_enter_mmx(cpu_env
);
2985 modrm
= cpu_ldub_code(env
, s
->pc
++);
2986 reg
= ((modrm
>> 3) & 7);
2989 mod
= (modrm
>> 6) & 3;
2990 if (sse_fn_epp
== SSE_SPECIAL
) {
2993 case 0x0e7: /* movntq */
2996 gen_lea_modrm(env
, s
, modrm
);
2997 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
2999 case 0x1e7: /* movntdq */
3000 case 0x02b: /* movntps */
3001 case 0x12b: /* movntps */
3004 gen_lea_modrm(env
, s
, modrm
);
3005 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3007 case 0x3f0: /* lddqu */
3010 gen_lea_modrm(env
, s
, modrm
);
3011 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3013 case 0x22b: /* movntss */
3014 case 0x32b: /* movntsd */
3017 gen_lea_modrm(env
, s
, modrm
);
3019 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3020 xmm_regs
[reg
].ZMM_Q(0)));
3022 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
3023 xmm_regs
[reg
].ZMM_L(0)));
3024 gen_op_st_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
3027 case 0x6e: /* movd mm, ea */
3028 #ifdef TARGET_X86_64
3029 if (s
->dflag
== MO_64
) {
3030 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3031 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3035 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3036 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3037 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3038 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3039 gen_helper_movl_mm_T0_mmx(cpu_ptr0
, cpu_tmp2_i32
);
3042 case 0x16e: /* movd xmm, ea */
3043 #ifdef TARGET_X86_64
3044 if (s
->dflag
== MO_64
) {
3045 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3046 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3047 offsetof(CPUX86State
,xmm_regs
[reg
]));
3048 gen_helper_movq_mm_T0_xmm(cpu_ptr0
, cpu_T
[0]);
3052 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3053 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3054 offsetof(CPUX86State
,xmm_regs
[reg
]));
3055 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3056 gen_helper_movl_mm_T0_xmm(cpu_ptr0
, cpu_tmp2_i32
);
3059 case 0x6f: /* movq mm, ea */
3061 gen_lea_modrm(env
, s
, modrm
);
3062 gen_ldq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3065 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
3066 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3067 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
3068 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3071 case 0x010: /* movups */
3072 case 0x110: /* movupd */
3073 case 0x028: /* movaps */
3074 case 0x128: /* movapd */
3075 case 0x16f: /* movdqa xmm, ea */
3076 case 0x26f: /* movdqu xmm, ea */
3078 gen_lea_modrm(env
, s
, modrm
);
3079 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3081 rm
= (modrm
& 7) | REX_B(s
);
3082 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[reg
]),
3083 offsetof(CPUX86State
,xmm_regs
[rm
]));
3086 case 0x210: /* movss xmm, ea */
3088 gen_lea_modrm(env
, s
, modrm
);
3089 gen_op_ld_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
3090 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3091 tcg_gen_movi_tl(cpu_T
[0], 0);
3092 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)));
3093 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)));
3094 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)));
3096 rm
= (modrm
& 7) | REX_B(s
);
3097 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)),
3098 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)));
3101 case 0x310: /* movsd xmm, ea */
3103 gen_lea_modrm(env
, s
, modrm
);
3104 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3105 xmm_regs
[reg
].ZMM_Q(0)));
3106 tcg_gen_movi_tl(cpu_T
[0], 0);
3107 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)));
3108 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)));
3110 rm
= (modrm
& 7) | REX_B(s
);
3111 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3112 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3115 case 0x012: /* movlps */
3116 case 0x112: /* movlpd */
3118 gen_lea_modrm(env
, s
, modrm
);
3119 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3120 xmm_regs
[reg
].ZMM_Q(0)));
3123 rm
= (modrm
& 7) | REX_B(s
);
3124 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3125 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(1)));
3128 case 0x212: /* movsldup */
3130 gen_lea_modrm(env
, s
, modrm
);
3131 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3133 rm
= (modrm
& 7) | REX_B(s
);
3134 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)),
3135 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)));
3136 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)),
3137 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(2)));
3139 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)),
3140 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3141 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)),
3142 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)));
3144 case 0x312: /* movddup */
3146 gen_lea_modrm(env
, s
, modrm
);
3147 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3148 xmm_regs
[reg
].ZMM_Q(0)));
3150 rm
= (modrm
& 7) | REX_B(s
);
3151 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3152 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3154 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)),
3155 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3157 case 0x016: /* movhps */
3158 case 0x116: /* movhpd */
3160 gen_lea_modrm(env
, s
, modrm
);
3161 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3162 xmm_regs
[reg
].ZMM_Q(1)));
3165 rm
= (modrm
& 7) | REX_B(s
);
3166 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)),
3167 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3170 case 0x216: /* movshdup */
3172 gen_lea_modrm(env
, s
, modrm
);
3173 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3175 rm
= (modrm
& 7) | REX_B(s
);
3176 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)),
3177 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(1)));
3178 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)),
3179 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(3)));
3181 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)),
3182 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)));
3183 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)),
3184 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)));
3189 int bit_index
, field_length
;
3191 if (b1
== 1 && reg
!= 0)
3193 field_length
= cpu_ldub_code(env
, s
->pc
++) & 0x3F;
3194 bit_index
= cpu_ldub_code(env
, s
->pc
++) & 0x3F;
3195 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3196 offsetof(CPUX86State
,xmm_regs
[reg
]));
3198 gen_helper_extrq_i(cpu_env
, cpu_ptr0
,
3199 tcg_const_i32(bit_index
),
3200 tcg_const_i32(field_length
));
3202 gen_helper_insertq_i(cpu_env
, cpu_ptr0
,
3203 tcg_const_i32(bit_index
),
3204 tcg_const_i32(field_length
));
3207 case 0x7e: /* movd ea, mm */
3208 #ifdef TARGET_X86_64
3209 if (s
->dflag
== MO_64
) {
3210 tcg_gen_ld_i64(cpu_T
[0], cpu_env
,
3211 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3212 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3216 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
,
3217 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_L(0)));
3218 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3221 case 0x17e: /* movd ea, xmm */
3222 #ifdef TARGET_X86_64
3223 if (s
->dflag
== MO_64
) {
3224 tcg_gen_ld_i64(cpu_T
[0], cpu_env
,
3225 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3226 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3230 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
,
3231 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3232 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3235 case 0x27e: /* movq xmm, ea */
3237 gen_lea_modrm(env
, s
, modrm
);
3238 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3239 xmm_regs
[reg
].ZMM_Q(0)));
3241 rm
= (modrm
& 7) | REX_B(s
);
3242 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3243 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3245 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)));
3247 case 0x7f: /* movq ea, mm */
3249 gen_lea_modrm(env
, s
, modrm
);
3250 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3253 gen_op_movq(offsetof(CPUX86State
,fpregs
[rm
].mmx
),
3254 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3257 case 0x011: /* movups */
3258 case 0x111: /* movupd */
3259 case 0x029: /* movaps */
3260 case 0x129: /* movapd */
3261 case 0x17f: /* movdqa ea, xmm */
3262 case 0x27f: /* movdqu ea, xmm */
3264 gen_lea_modrm(env
, s
, modrm
);
3265 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3267 rm
= (modrm
& 7) | REX_B(s
);
3268 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[rm
]),
3269 offsetof(CPUX86State
,xmm_regs
[reg
]));
3272 case 0x211: /* movss ea, xmm */
3274 gen_lea_modrm(env
, s
, modrm
);
3275 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3276 gen_op_st_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
3278 rm
= (modrm
& 7) | REX_B(s
);
3279 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)),
3280 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3283 case 0x311: /* movsd ea, xmm */
3285 gen_lea_modrm(env
, s
, modrm
);
3286 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3287 xmm_regs
[reg
].ZMM_Q(0)));
3289 rm
= (modrm
& 7) | REX_B(s
);
3290 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)),
3291 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3294 case 0x013: /* movlps */
3295 case 0x113: /* movlpd */
3297 gen_lea_modrm(env
, s
, modrm
);
3298 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3299 xmm_regs
[reg
].ZMM_Q(0)));
3304 case 0x017: /* movhps */
3305 case 0x117: /* movhpd */
3307 gen_lea_modrm(env
, s
, modrm
);
3308 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3309 xmm_regs
[reg
].ZMM_Q(1)));
3314 case 0x71: /* shift mm, im */
3317 case 0x171: /* shift xmm, im */
3323 val
= cpu_ldub_code(env
, s
->pc
++);
3325 tcg_gen_movi_tl(cpu_T
[0], val
);
3326 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.ZMM_L(0)));
3327 tcg_gen_movi_tl(cpu_T
[0], 0);
3328 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.ZMM_L(1)));
3329 op1_offset
= offsetof(CPUX86State
,xmm_t0
);
3331 tcg_gen_movi_tl(cpu_T
[0], val
);
3332 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,mmx_t0
.MMX_L(0)));
3333 tcg_gen_movi_tl(cpu_T
[0], 0);
3334 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,mmx_t0
.MMX_L(1)));
3335 op1_offset
= offsetof(CPUX86State
,mmx_t0
);
3337 sse_fn_epp
= sse_op_table2
[((b
- 1) & 3) * 8 +
3338 (((modrm
>> 3)) & 7)][b1
];
3343 rm
= (modrm
& 7) | REX_B(s
);
3344 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3347 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3349 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3350 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op1_offset
);
3351 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3353 case 0x050: /* movmskps */
3354 rm
= (modrm
& 7) | REX_B(s
);
3355 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3356 offsetof(CPUX86State
,xmm_regs
[rm
]));
3357 gen_helper_movmskps(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3358 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3360 case 0x150: /* movmskpd */
3361 rm
= (modrm
& 7) | REX_B(s
);
3362 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3363 offsetof(CPUX86State
,xmm_regs
[rm
]));
3364 gen_helper_movmskpd(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3365 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3367 case 0x02a: /* cvtpi2ps */
3368 case 0x12a: /* cvtpi2pd */
3369 gen_helper_enter_mmx(cpu_env
);
3371 gen_lea_modrm(env
, s
, modrm
);
3372 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3373 gen_ldq_env_A0(s
, op2_offset
);
3376 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3378 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3379 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3380 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3383 gen_helper_cvtpi2ps(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3387 gen_helper_cvtpi2pd(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3391 case 0x22a: /* cvtsi2ss */
3392 case 0x32a: /* cvtsi2sd */
3393 ot
= mo_64_32(s
->dflag
);
3394 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3395 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3396 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3398 SSEFunc_0_epi sse_fn_epi
= sse_op_table3ai
[(b
>> 8) & 1];
3399 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3400 sse_fn_epi(cpu_env
, cpu_ptr0
, cpu_tmp2_i32
);
3402 #ifdef TARGET_X86_64
3403 SSEFunc_0_epl sse_fn_epl
= sse_op_table3aq
[(b
>> 8) & 1];
3404 sse_fn_epl(cpu_env
, cpu_ptr0
, cpu_T
[0]);
3410 case 0x02c: /* cvttps2pi */
3411 case 0x12c: /* cvttpd2pi */
3412 case 0x02d: /* cvtps2pi */
3413 case 0x12d: /* cvtpd2pi */
3414 gen_helper_enter_mmx(cpu_env
);
3416 gen_lea_modrm(env
, s
, modrm
);
3417 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3418 gen_ldo_env_A0(s
, op2_offset
);
3420 rm
= (modrm
& 7) | REX_B(s
);
3421 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3423 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
);
3424 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3425 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3428 gen_helper_cvttps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3431 gen_helper_cvttpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3434 gen_helper_cvtps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3437 gen_helper_cvtpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3441 case 0x22c: /* cvttss2si */
3442 case 0x32c: /* cvttsd2si */
3443 case 0x22d: /* cvtss2si */
3444 case 0x32d: /* cvtsd2si */
3445 ot
= mo_64_32(s
->dflag
);
3447 gen_lea_modrm(env
, s
, modrm
);
3449 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.ZMM_Q(0)));
3451 gen_op_ld_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
3452 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.ZMM_L(0)));
3454 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3456 rm
= (modrm
& 7) | REX_B(s
);
3457 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3459 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3461 SSEFunc_i_ep sse_fn_i_ep
=
3462 sse_op_table3bi
[((b
>> 7) & 2) | (b
& 1)];
3463 sse_fn_i_ep(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3464 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
3466 #ifdef TARGET_X86_64
3467 SSEFunc_l_ep sse_fn_l_ep
=
3468 sse_op_table3bq
[((b
>> 7) & 2) | (b
& 1)];
3469 sse_fn_l_ep(cpu_T
[0], cpu_env
, cpu_ptr0
);
3474 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3476 case 0xc4: /* pinsrw */
3479 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
3480 val
= cpu_ldub_code(env
, s
->pc
++);
3483 tcg_gen_st16_tl(cpu_T
[0], cpu_env
,
3484 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_W(val
)));
3487 tcg_gen_st16_tl(cpu_T
[0], cpu_env
,
3488 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_W(val
)));
3491 case 0xc5: /* pextrw */
3495 ot
= mo_64_32(s
->dflag
);
3496 val
= cpu_ldub_code(env
, s
->pc
++);
3499 rm
= (modrm
& 7) | REX_B(s
);
3500 tcg_gen_ld16u_tl(cpu_T
[0], cpu_env
,
3501 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_W(val
)));
3505 tcg_gen_ld16u_tl(cpu_T
[0], cpu_env
,
3506 offsetof(CPUX86State
,fpregs
[rm
].mmx
.MMX_W(val
)));
3508 reg
= ((modrm
>> 3) & 7) | rex_r
;
3509 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3511 case 0x1d6: /* movq ea, xmm */
3513 gen_lea_modrm(env
, s
, modrm
);
3514 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3515 xmm_regs
[reg
].ZMM_Q(0)));
3517 rm
= (modrm
& 7) | REX_B(s
);
3518 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)),
3519 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3520 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(1)));
3523 case 0x2d6: /* movq2dq */
3524 gen_helper_enter_mmx(cpu_env
);
3526 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3527 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3528 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)));
3530 case 0x3d6: /* movdq2q */
3531 gen_helper_enter_mmx(cpu_env
);
3532 rm
= (modrm
& 7) | REX_B(s
);
3533 gen_op_movq(offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
),
3534 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3536 case 0xd7: /* pmovmskb */
3541 rm
= (modrm
& 7) | REX_B(s
);
3542 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[rm
]));
3543 gen_helper_pmovmskb_xmm(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3546 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3547 gen_helper_pmovmskb_mmx(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3549 reg
= ((modrm
>> 3) & 7) | rex_r
;
3550 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3556 if ((b
& 0xf0) == 0xf0) {
3559 modrm
= cpu_ldub_code(env
, s
->pc
++);
3561 reg
= ((modrm
>> 3) & 7) | rex_r
;
3562 mod
= (modrm
>> 6) & 3;
3567 sse_fn_epp
= sse_op_table6
[b
].op
[b1
];
3571 if (!(s
->cpuid_ext_features
& sse_op_table6
[b
].ext_mask
))
3575 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3577 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
3579 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3580 gen_lea_modrm(env
, s
, modrm
);
3582 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3583 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3584 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3585 gen_ldq_env_A0(s
, op2_offset
+
3586 offsetof(ZMMReg
, ZMM_Q(0)));
3588 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3589 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3590 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
3591 s
->mem_index
, MO_LEUL
);
3592 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, op2_offset
+
3593 offsetof(ZMMReg
, ZMM_L(0)));
3595 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3596 tcg_gen_qemu_ld_tl(cpu_tmp0
, cpu_A0
,
3597 s
->mem_index
, MO_LEUW
);
3598 tcg_gen_st16_tl(cpu_tmp0
, cpu_env
, op2_offset
+
3599 offsetof(ZMMReg
, ZMM_W(0)));
3601 case 0x2a: /* movntqda */
3602 gen_ldo_env_A0(s
, op1_offset
);
3605 gen_ldo_env_A0(s
, op2_offset
);
3609 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
3611 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3613 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3614 gen_lea_modrm(env
, s
, modrm
);
3615 gen_ldq_env_A0(s
, op2_offset
);
3618 if (sse_fn_epp
== SSE_SPECIAL
) {
3622 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3623 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3624 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3627 set_cc_op(s
, CC_OP_EFLAGS
);
3634 /* Various integer extensions at 0f 38 f[0-f]. */
3635 b
= modrm
| (b1
<< 8);
3636 modrm
= cpu_ldub_code(env
, s
->pc
++);
3637 reg
= ((modrm
>> 3) & 7) | rex_r
;
3640 case 0x3f0: /* crc32 Gd,Eb */
3641 case 0x3f1: /* crc32 Gd,Ey */
3643 if (!(s
->cpuid_ext_features
& CPUID_EXT_SSE42
)) {
3646 if ((b
& 0xff) == 0xf0) {
3648 } else if (s
->dflag
!= MO_64
) {
3649 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3654 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[reg
]);
3655 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3656 gen_helper_crc32(cpu_T
[0], cpu_tmp2_i32
,
3657 cpu_T
[0], tcg_const_i32(8 << ot
));
3659 ot
= mo_64_32(s
->dflag
);
3660 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3663 case 0x1f0: /* crc32 or movbe */
3665 /* For these insns, the f3 prefix is supposed to have priority
3666 over the 66 prefix, but that's not what we implement above
3668 if (s
->prefix
& PREFIX_REPNZ
) {
3672 case 0x0f0: /* movbe Gy,My */
3673 case 0x0f1: /* movbe My,Gy */
3674 if (!(s
->cpuid_ext_features
& CPUID_EXT_MOVBE
)) {
3677 if (s
->dflag
!= MO_64
) {
3678 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3683 gen_lea_modrm(env
, s
, modrm
);
3685 tcg_gen_qemu_ld_tl(cpu_T
[0], cpu_A0
,
3686 s
->mem_index
, ot
| MO_BE
);
3687 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3689 tcg_gen_qemu_st_tl(cpu_regs
[reg
], cpu_A0
,
3690 s
->mem_index
, ot
| MO_BE
);
3694 case 0x0f2: /* andn Gy, By, Ey */
3695 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3696 || !(s
->prefix
& PREFIX_VEX
)
3700 ot
= mo_64_32(s
->dflag
);
3701 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3702 tcg_gen_andc_tl(cpu_T
[0], cpu_regs
[s
->vex_v
], cpu_T
[0]);
3703 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3704 gen_op_update1_cc();
3705 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3708 case 0x0f7: /* bextr Gy, Ey, By */
3709 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3710 || !(s
->prefix
& PREFIX_VEX
)
3714 ot
= mo_64_32(s
->dflag
);
3718 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3719 /* Extract START, and shift the operand.
3720 Shifts larger than operand size get zeros. */
3721 tcg_gen_ext8u_tl(cpu_A0
, cpu_regs
[s
->vex_v
]);
3722 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], cpu_A0
);
3724 bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3725 zero
= tcg_const_tl(0);
3726 tcg_gen_movcond_tl(TCG_COND_LEU
, cpu_T
[0], cpu_A0
, bound
,
3728 tcg_temp_free(zero
);
3730 /* Extract the LEN into a mask. Lengths larger than
3731 operand size get all ones. */
3732 tcg_gen_shri_tl(cpu_A0
, cpu_regs
[s
->vex_v
], 8);
3733 tcg_gen_ext8u_tl(cpu_A0
, cpu_A0
);
3734 tcg_gen_movcond_tl(TCG_COND_LEU
, cpu_A0
, cpu_A0
, bound
,
3736 tcg_temp_free(bound
);
3737 tcg_gen_movi_tl(cpu_T
[1], 1);
3738 tcg_gen_shl_tl(cpu_T
[1], cpu_T
[1], cpu_A0
);
3739 tcg_gen_subi_tl(cpu_T
[1], cpu_T
[1], 1);
3740 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
3742 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3743 gen_op_update1_cc();
3744 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3748 case 0x0f5: /* bzhi Gy, Ey, By */
3749 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3750 || !(s
->prefix
& PREFIX_VEX
)
3754 ot
= mo_64_32(s
->dflag
);
3755 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3756 tcg_gen_ext8u_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
3758 TCGv bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3759 /* Note that since we're using BMILG (in order to get O
3760 cleared) we need to store the inverse into C. */
3761 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_cc_src
,
3763 tcg_gen_movcond_tl(TCG_COND_GT
, cpu_T
[1], cpu_T
[1],
3764 bound
, bound
, cpu_T
[1]);
3765 tcg_temp_free(bound
);
3767 tcg_gen_movi_tl(cpu_A0
, -1);
3768 tcg_gen_shl_tl(cpu_A0
, cpu_A0
, cpu_T
[1]);
3769 tcg_gen_andc_tl(cpu_T
[0], cpu_T
[0], cpu_A0
);
3770 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3771 gen_op_update1_cc();
3772 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
3775 case 0x3f6: /* mulx By, Gy, rdx, Ey */
3776 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3777 || !(s
->prefix
& PREFIX_VEX
)
3781 ot
= mo_64_32(s
->dflag
);
3782 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3785 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3786 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EDX
]);
3787 tcg_gen_mulu2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
3788 cpu_tmp2_i32
, cpu_tmp3_i32
);
3789 tcg_gen_extu_i32_tl(cpu_regs
[s
->vex_v
], cpu_tmp2_i32
);
3790 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp3_i32
);
3792 #ifdef TARGET_X86_64
3794 tcg_gen_mulu2_i64(cpu_T
[0], cpu_T
[1],
3795 cpu_T
[0], cpu_regs
[R_EDX
]);
3796 tcg_gen_mov_i64(cpu_regs
[s
->vex_v
], cpu_T
[0]);
3797 tcg_gen_mov_i64(cpu_regs
[reg
], cpu_T
[1]);
3803 case 0x3f5: /* pdep Gy, By, Ey */
3804 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3805 || !(s
->prefix
& PREFIX_VEX
)
3809 ot
= mo_64_32(s
->dflag
);
3810 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3811 /* Note that by zero-extending the mask operand, we
3812 automatically handle zero-extending the result. */
3814 tcg_gen_mov_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
3816 tcg_gen_ext32u_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
3818 gen_helper_pdep(cpu_regs
[reg
], cpu_T
[0], cpu_T
[1]);
3821 case 0x2f5: /* pext Gy, By, Ey */
3822 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3823 || !(s
->prefix
& PREFIX_VEX
)
3827 ot
= mo_64_32(s
->dflag
);
3828 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3829 /* Note that by zero-extending the mask operand, we
3830 automatically handle zero-extending the result. */
3832 tcg_gen_mov_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
3834 tcg_gen_ext32u_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
3836 gen_helper_pext(cpu_regs
[reg
], cpu_T
[0], cpu_T
[1]);
3839 case 0x1f6: /* adcx Gy, Ey */
3840 case 0x2f6: /* adox Gy, Ey */
3841 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_ADX
)) {
3844 TCGv carry_in
, carry_out
, zero
;
3847 ot
= mo_64_32(s
->dflag
);
3848 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3850 /* Re-use the carry-out from a previous round. */
3851 TCGV_UNUSED(carry_in
);
3852 carry_out
= (b
== 0x1f6 ? cpu_cc_dst
: cpu_cc_src2
);
3856 carry_in
= cpu_cc_dst
;
3857 end_op
= CC_OP_ADCX
;
3859 end_op
= CC_OP_ADCOX
;
3864 end_op
= CC_OP_ADCOX
;
3866 carry_in
= cpu_cc_src2
;
3867 end_op
= CC_OP_ADOX
;
3871 end_op
= CC_OP_ADCOX
;
3872 carry_in
= carry_out
;
3875 end_op
= (b
== 0x1f6 ? CC_OP_ADCX
: CC_OP_ADOX
);
3878 /* If we can't reuse carry-out, get it out of EFLAGS. */
3879 if (TCGV_IS_UNUSED(carry_in
)) {
3880 if (s
->cc_op
!= CC_OP_ADCX
&& s
->cc_op
!= CC_OP_ADOX
) {
3881 gen_compute_eflags(s
);
3883 carry_in
= cpu_tmp0
;
3884 tcg_gen_shri_tl(carry_in
, cpu_cc_src
,
3885 ctz32(b
== 0x1f6 ? CC_C
: CC_O
));
3886 tcg_gen_andi_tl(carry_in
, carry_in
, 1);
3890 #ifdef TARGET_X86_64
3892 /* If we know TL is 64-bit, and we want a 32-bit
3893 result, just do everything in 64-bit arithmetic. */
3894 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_regs
[reg
]);
3895 tcg_gen_ext32u_i64(cpu_T
[0], cpu_T
[0]);
3896 tcg_gen_add_i64(cpu_T
[0], cpu_T
[0], cpu_regs
[reg
]);
3897 tcg_gen_add_i64(cpu_T
[0], cpu_T
[0], carry_in
);
3898 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_T
[0]);
3899 tcg_gen_shri_i64(carry_out
, cpu_T
[0], 32);
3903 /* Otherwise compute the carry-out in two steps. */
3904 zero
= tcg_const_tl(0);
3905 tcg_gen_add2_tl(cpu_T
[0], carry_out
,
3908 tcg_gen_add2_tl(cpu_regs
[reg
], carry_out
,
3909 cpu_regs
[reg
], carry_out
,
3911 tcg_temp_free(zero
);
3914 set_cc_op(s
, end_op
);
3918 case 0x1f7: /* shlx Gy, Ey, By */
3919 case 0x2f7: /* sarx Gy, Ey, By */
3920 case 0x3f7: /* shrx Gy, Ey, By */
3921 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3922 || !(s
->prefix
& PREFIX_VEX
)
3926 ot
= mo_64_32(s
->dflag
);
3927 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3929 tcg_gen_andi_tl(cpu_T
[1], cpu_regs
[s
->vex_v
], 63);
3931 tcg_gen_andi_tl(cpu_T
[1], cpu_regs
[s
->vex_v
], 31);
3934 tcg_gen_shl_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
3935 } else if (b
== 0x2f7) {
3937 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
3939 tcg_gen_sar_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
3942 tcg_gen_ext32u_tl(cpu_T
[0], cpu_T
[0]);
3944 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
3946 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3952 case 0x3f3: /* Group 17 */
3953 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3954 || !(s
->prefix
& PREFIX_VEX
)
3958 ot
= mo_64_32(s
->dflag
);
3959 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3962 case 1: /* blsr By,Ey */
3963 tcg_gen_neg_tl(cpu_T
[1], cpu_T
[0]);
3964 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
3965 gen_op_mov_reg_v(ot
, s
->vex_v
, cpu_T
[0]);
3966 gen_op_update2_cc();
3967 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
3970 case 2: /* blsmsk By,Ey */
3971 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
3972 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], 1);
3973 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_cc_src
);
3974 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
3975 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
3978 case 3: /* blsi By, Ey */
3979 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
3980 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], 1);
3981 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_cc_src
);
3982 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
3983 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
3999 modrm
= cpu_ldub_code(env
, s
->pc
++);
4001 reg
= ((modrm
>> 3) & 7) | rex_r
;
4002 mod
= (modrm
>> 6) & 3;
4007 sse_fn_eppi
= sse_op_table7
[b
].op
[b1
];
4011 if (!(s
->cpuid_ext_features
& sse_op_table7
[b
].ext_mask
))
4014 if (sse_fn_eppi
== SSE_SPECIAL
) {
4015 ot
= mo_64_32(s
->dflag
);
4016 rm
= (modrm
& 7) | REX_B(s
);
4018 gen_lea_modrm(env
, s
, modrm
);
4019 reg
= ((modrm
>> 3) & 7) | rex_r
;
4020 val
= cpu_ldub_code(env
, s
->pc
++);
4022 case 0x14: /* pextrb */
4023 tcg_gen_ld8u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4024 xmm_regs
[reg
].ZMM_B(val
& 15)));
4026 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4028 tcg_gen_qemu_st_tl(cpu_T
[0], cpu_A0
,
4029 s
->mem_index
, MO_UB
);
4032 case 0x15: /* pextrw */
4033 tcg_gen_ld16u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4034 xmm_regs
[reg
].ZMM_W(val
& 7)));
4036 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4038 tcg_gen_qemu_st_tl(cpu_T
[0], cpu_A0
,
4039 s
->mem_index
, MO_LEUW
);
4043 if (ot
== MO_32
) { /* pextrd */
4044 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4045 offsetof(CPUX86State
,
4046 xmm_regs
[reg
].ZMM_L(val
& 3)));
4048 tcg_gen_extu_i32_tl(cpu_regs
[rm
], cpu_tmp2_i32
);
4050 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
4051 s
->mem_index
, MO_LEUL
);
4053 } else { /* pextrq */
4054 #ifdef TARGET_X86_64
4055 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
4056 offsetof(CPUX86State
,
4057 xmm_regs
[reg
].ZMM_Q(val
& 1)));
4059 tcg_gen_mov_i64(cpu_regs
[rm
], cpu_tmp1_i64
);
4061 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
4062 s
->mem_index
, MO_LEQ
);
4069 case 0x17: /* extractps */
4070 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4071 xmm_regs
[reg
].ZMM_L(val
& 3)));
4073 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4075 tcg_gen_qemu_st_tl(cpu_T
[0], cpu_A0
,
4076 s
->mem_index
, MO_LEUL
);
4079 case 0x20: /* pinsrb */
4081 gen_op_mov_v_reg(MO_32
, cpu_T
[0], rm
);
4083 tcg_gen_qemu_ld_tl(cpu_T
[0], cpu_A0
,
4084 s
->mem_index
, MO_UB
);
4086 tcg_gen_st8_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4087 xmm_regs
[reg
].ZMM_B(val
& 15)));
4089 case 0x21: /* insertps */
4091 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4092 offsetof(CPUX86State
,xmm_regs
[rm
]
4093 .ZMM_L((val
>> 6) & 3)));
4095 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
4096 s
->mem_index
, MO_LEUL
);
4098 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4099 offsetof(CPUX86State
,xmm_regs
[reg
]
4100 .ZMM_L((val
>> 4) & 3)));
4102 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4103 cpu_env
, offsetof(CPUX86State
,
4104 xmm_regs
[reg
].ZMM_L(0)));
4106 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4107 cpu_env
, offsetof(CPUX86State
,
4108 xmm_regs
[reg
].ZMM_L(1)));
4110 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4111 cpu_env
, offsetof(CPUX86State
,
4112 xmm_regs
[reg
].ZMM_L(2)));
4114 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4115 cpu_env
, offsetof(CPUX86State
,
4116 xmm_regs
[reg
].ZMM_L(3)));
4119 if (ot
== MO_32
) { /* pinsrd */
4121 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[rm
]);
4123 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
4124 s
->mem_index
, MO_LEUL
);
4126 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4127 offsetof(CPUX86State
,
4128 xmm_regs
[reg
].ZMM_L(val
& 3)));
4129 } else { /* pinsrq */
4130 #ifdef TARGET_X86_64
4132 gen_op_mov_v_reg(ot
, cpu_tmp1_i64
, rm
);
4134 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
4135 s
->mem_index
, MO_LEQ
);
4137 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
4138 offsetof(CPUX86State
,
4139 xmm_regs
[reg
].ZMM_Q(val
& 1)));
4150 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4152 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
4154 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4155 gen_lea_modrm(env
, s
, modrm
);
4156 gen_ldo_env_A0(s
, op2_offset
);
4159 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4161 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4163 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4164 gen_lea_modrm(env
, s
, modrm
);
4165 gen_ldq_env_A0(s
, op2_offset
);
4168 val
= cpu_ldub_code(env
, s
->pc
++);
4170 if ((b
& 0xfc) == 0x60) { /* pcmpXstrX */
4171 set_cc_op(s
, CC_OP_EFLAGS
);
4173 if (s
->dflag
== MO_64
) {
4174 /* The helper must use entire 64-bit gp registers */
4179 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4180 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4181 sse_fn_eppi(cpu_env
, cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4185 /* Various integer extensions at 0f 3a f[0-f]. */
4186 b
= modrm
| (b1
<< 8);
4187 modrm
= cpu_ldub_code(env
, s
->pc
++);
4188 reg
= ((modrm
>> 3) & 7) | rex_r
;
4191 case 0x3f0: /* rorx Gy,Ey, Ib */
4192 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4193 || !(s
->prefix
& PREFIX_VEX
)
4197 ot
= mo_64_32(s
->dflag
);
4198 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4199 b
= cpu_ldub_code(env
, s
->pc
++);
4201 tcg_gen_rotri_tl(cpu_T
[0], cpu_T
[0], b
& 63);
4203 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4204 tcg_gen_rotri_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, b
& 31);
4205 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
4207 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
4219 /* generic MMX or SSE operation */
4221 case 0x70: /* pshufx insn */
4222 case 0xc6: /* pshufx insn */
4223 case 0xc2: /* compare insns */
4230 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4234 gen_lea_modrm(env
, s
, modrm
);
4235 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4241 /* Most sse scalar operations. */
4244 } else if (b1
== 3) {
4249 case 0x2e: /* ucomis[sd] */
4250 case 0x2f: /* comis[sd] */
4262 gen_op_ld_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
4263 tcg_gen_st32_tl(cpu_T
[0], cpu_env
,
4264 offsetof(CPUX86State
,xmm_t0
.ZMM_L(0)));
4268 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.ZMM_D(0)));
4271 /* 128 bit access */
4272 gen_ldo_env_A0(s
, op2_offset
);
4276 rm
= (modrm
& 7) | REX_B(s
);
4277 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
4280 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4282 gen_lea_modrm(env
, s
, modrm
);
4283 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4284 gen_ldq_env_A0(s
, op2_offset
);
4287 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4291 case 0x0f: /* 3DNow! data insns */
4292 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
))
4294 val
= cpu_ldub_code(env
, s
->pc
++);
4295 sse_fn_epp
= sse_op_table5
[val
];
4299 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4300 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4301 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4303 case 0x70: /* pshufx insn */
4304 case 0xc6: /* pshufx insn */
4305 val
= cpu_ldub_code(env
, s
->pc
++);
4306 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4307 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4308 /* XXX: introduce a new table? */
4309 sse_fn_ppi
= (SSEFunc_0_ppi
)sse_fn_epp
;
4310 sse_fn_ppi(cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4314 val
= cpu_ldub_code(env
, s
->pc
++);
4317 sse_fn_epp
= sse_op_table4
[val
][b1
];
4319 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4320 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4321 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4324 /* maskmov : we must prepare A0 */
4327 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EDI
]);
4328 gen_extu(s
->aflag
, cpu_A0
);
4329 gen_add_A0_ds_seg(s
);
4331 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4332 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4333 /* XXX: introduce a new table? */
4334 sse_fn_eppt
= (SSEFunc_0_eppt
)sse_fn_epp
;
4335 sse_fn_eppt(cpu_env
, cpu_ptr0
, cpu_ptr1
, cpu_A0
);
4338 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4339 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4340 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4343 if (b
== 0x2e || b
== 0x2f) {
4344 set_cc_op(s
, CC_OP_EFLAGS
);
4349 /* convert one instruction. s->is_jmp is set if the translation must
4350 be stopped. Return the next pc value */
4351 static target_ulong
disas_insn(CPUX86State
*env
, DisasContext
*s
,
4352 target_ulong pc_start
)
4356 TCGMemOp ot
, aflag
, dflag
;
4357 int modrm
, reg
, rm
, mod
, op
, opreg
, val
;
4358 target_ulong next_eip
, tval
;
4366 #ifdef TARGET_X86_64
4371 s
->rip_offset
= 0; /* for relative ip address */
4375 b
= cpu_ldub_code(env
, s
->pc
);
4377 /* Collect prefixes. */
4380 prefixes
|= PREFIX_REPZ
;
4383 prefixes
|= PREFIX_REPNZ
;
4386 prefixes
|= PREFIX_LOCK
;
4407 prefixes
|= PREFIX_DATA
;
4410 prefixes
|= PREFIX_ADR
;
4412 #ifdef TARGET_X86_64
4416 rex_w
= (b
>> 3) & 1;
4417 rex_r
= (b
& 0x4) << 1;
4418 s
->rex_x
= (b
& 0x2) << 2;
4419 REX_B(s
) = (b
& 0x1) << 3;
4420 x86_64_hregs
= 1; /* select uniform byte register addressing */
4425 case 0xc5: /* 2-byte VEX */
4426 case 0xc4: /* 3-byte VEX */
4427 /* VEX prefixes cannot be used except in 32-bit mode.
4428 Otherwise the instruction is LES or LDS. */
4429 if (s
->code32
&& !s
->vm86
) {
4430 static const int pp_prefix
[4] = {
4431 0, PREFIX_DATA
, PREFIX_REPZ
, PREFIX_REPNZ
4433 int vex3
, vex2
= cpu_ldub_code(env
, s
->pc
);
4435 if (!CODE64(s
) && (vex2
& 0xc0) != 0xc0) {
4436 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4437 otherwise the instruction is LES or LDS. */
4442 /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
4443 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
4444 | PREFIX_LOCK
| PREFIX_DATA
)) {
4447 #ifdef TARGET_X86_64
4452 rex_r
= (~vex2
>> 4) & 8;
4455 b
= cpu_ldub_code(env
, s
->pc
++);
4457 #ifdef TARGET_X86_64
4458 s
->rex_x
= (~vex2
>> 3) & 8;
4459 s
->rex_b
= (~vex2
>> 2) & 8;
4461 vex3
= cpu_ldub_code(env
, s
->pc
++);
4462 rex_w
= (vex3
>> 7) & 1;
4463 switch (vex2
& 0x1f) {
4464 case 0x01: /* Implied 0f leading opcode bytes. */
4465 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4467 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4470 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4473 default: /* Reserved for future use. */
4477 s
->vex_v
= (~vex3
>> 3) & 0xf;
4478 s
->vex_l
= (vex3
>> 2) & 1;
4479 prefixes
|= pp_prefix
[vex3
& 3] | PREFIX_VEX
;
4484 /* Post-process prefixes. */
4486 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit
4487 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4488 over 0x66 if both are present. */
4489 dflag
= (rex_w
> 0 ? MO_64
: prefixes
& PREFIX_DATA
? MO_16
: MO_32
);
4490 /* In 64-bit mode, 0x67 selects 32-bit addressing. */
4491 aflag
= (prefixes
& PREFIX_ADR
? MO_32
: MO_64
);
4493 /* In 16/32-bit mode, 0x66 selects the opposite data size. */
4494 if (s
->code32
^ ((prefixes
& PREFIX_DATA
) != 0)) {
4499 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */
4500 if (s
->code32
^ ((prefixes
& PREFIX_ADR
) != 0)) {
4507 s
->prefix
= prefixes
;
4511 /* lock generation */
4512 if (prefixes
& PREFIX_LOCK
)
4515 /* now check op code */
4519 /**************************/
4520 /* extended op code */
4521 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4524 /**************************/
4539 ot
= mo_b_d(b
, dflag
);
4542 case 0: /* OP Ev, Gv */
4543 modrm
= cpu_ldub_code(env
, s
->pc
++);
4544 reg
= ((modrm
>> 3) & 7) | rex_r
;
4545 mod
= (modrm
>> 6) & 3;
4546 rm
= (modrm
& 7) | REX_B(s
);
4548 gen_lea_modrm(env
, s
, modrm
);
4550 } else if (op
== OP_XORL
&& rm
== reg
) {
4552 /* xor reg, reg optimisation */
4553 set_cc_op(s
, CC_OP_CLR
);
4554 tcg_gen_movi_tl(cpu_T
[0], 0);
4555 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
4560 gen_op_mov_v_reg(ot
, cpu_T
[1], reg
);
4561 gen_op(s
, op
, ot
, opreg
);
4563 case 1: /* OP Gv, Ev */
4564 modrm
= cpu_ldub_code(env
, s
->pc
++);
4565 mod
= (modrm
>> 6) & 3;
4566 reg
= ((modrm
>> 3) & 7) | rex_r
;
4567 rm
= (modrm
& 7) | REX_B(s
);
4569 gen_lea_modrm(env
, s
, modrm
);
4570 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
4571 } else if (op
== OP_XORL
&& rm
== reg
) {
4574 gen_op_mov_v_reg(ot
, cpu_T
[1], rm
);
4576 gen_op(s
, op
, ot
, reg
);
4578 case 2: /* OP A, Iv */
4579 val
= insn_get(env
, s
, ot
);
4580 tcg_gen_movi_tl(cpu_T
[1], val
);
4581 gen_op(s
, op
, ot
, OR_EAX
);
4590 case 0x80: /* GRP1 */
4596 ot
= mo_b_d(b
, dflag
);
4598 modrm
= cpu_ldub_code(env
, s
->pc
++);
4599 mod
= (modrm
>> 6) & 3;
4600 rm
= (modrm
& 7) | REX_B(s
);
4601 op
= (modrm
>> 3) & 7;
4607 s
->rip_offset
= insn_const_size(ot
);
4608 gen_lea_modrm(env
, s
, modrm
);
4619 val
= insn_get(env
, s
, ot
);
4622 val
= (int8_t)insn_get(env
, s
, MO_8
);
4625 tcg_gen_movi_tl(cpu_T
[1], val
);
4626 gen_op(s
, op
, ot
, opreg
);
4630 /**************************/
4631 /* inc, dec, and other misc arith */
4632 case 0x40 ... 0x47: /* inc Gv */
4634 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), 1);
4636 case 0x48 ... 0x4f: /* dec Gv */
4638 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), -1);
4640 case 0xf6: /* GRP3 */
4642 ot
= mo_b_d(b
, dflag
);
4644 modrm
= cpu_ldub_code(env
, s
->pc
++);
4645 mod
= (modrm
>> 6) & 3;
4646 rm
= (modrm
& 7) | REX_B(s
);
4647 op
= (modrm
>> 3) & 7;
4650 s
->rip_offset
= insn_const_size(ot
);
4651 gen_lea_modrm(env
, s
, modrm
);
4652 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
4654 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
4659 val
= insn_get(env
, s
, ot
);
4660 tcg_gen_movi_tl(cpu_T
[1], val
);
4661 gen_op_testl_T0_T1_cc();
4662 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4665 tcg_gen_not_tl(cpu_T
[0], cpu_T
[0]);
4667 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
4669 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4673 tcg_gen_neg_tl(cpu_T
[0], cpu_T
[0]);
4675 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
4677 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4679 gen_op_update_neg_cc();
4680 set_cc_op(s
, CC_OP_SUBB
+ ot
);
4685 gen_op_mov_v_reg(MO_8
, cpu_T
[1], R_EAX
);
4686 tcg_gen_ext8u_tl(cpu_T
[0], cpu_T
[0]);
4687 tcg_gen_ext8u_tl(cpu_T
[1], cpu_T
[1]);
4688 /* XXX: use 32 bit mul which could be faster */
4689 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4690 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
4691 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4692 tcg_gen_andi_tl(cpu_cc_src
, cpu_T
[0], 0xff00);
4693 set_cc_op(s
, CC_OP_MULB
);
4696 gen_op_mov_v_reg(MO_16
, cpu_T
[1], R_EAX
);
4697 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
4698 tcg_gen_ext16u_tl(cpu_T
[1], cpu_T
[1]);
4699 /* XXX: use 32 bit mul which could be faster */
4700 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4701 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
4702 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4703 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], 16);
4704 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T
[0]);
4705 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
4706 set_cc_op(s
, CC_OP_MULW
);
4710 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4711 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
4712 tcg_gen_mulu2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4713 cpu_tmp2_i32
, cpu_tmp3_i32
);
4714 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
4715 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
4716 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4717 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4718 set_cc_op(s
, CC_OP_MULL
);
4720 #ifdef TARGET_X86_64
4722 tcg_gen_mulu2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4723 cpu_T
[0], cpu_regs
[R_EAX
]);
4724 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4725 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4726 set_cc_op(s
, CC_OP_MULQ
);
4734 gen_op_mov_v_reg(MO_8
, cpu_T
[1], R_EAX
);
4735 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
4736 tcg_gen_ext8s_tl(cpu_T
[1], cpu_T
[1]);
4737 /* XXX: use 32 bit mul which could be faster */
4738 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4739 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
4740 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4741 tcg_gen_ext8s_tl(cpu_tmp0
, cpu_T
[0]);
4742 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
4743 set_cc_op(s
, CC_OP_MULB
);
4746 gen_op_mov_v_reg(MO_16
, cpu_T
[1], R_EAX
);
4747 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
4748 tcg_gen_ext16s_tl(cpu_T
[1], cpu_T
[1]);
4749 /* XXX: use 32 bit mul which could be faster */
4750 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4751 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
4752 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4753 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T
[0]);
4754 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
4755 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], 16);
4756 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T
[0]);
4757 set_cc_op(s
, CC_OP_MULW
);
4761 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4762 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
4763 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4764 cpu_tmp2_i32
, cpu_tmp3_i32
);
4765 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
4766 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
4767 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
4768 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4769 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
4770 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
4771 set_cc_op(s
, CC_OP_MULL
);
4773 #ifdef TARGET_X86_64
4775 tcg_gen_muls2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4776 cpu_T
[0], cpu_regs
[R_EAX
]);
4777 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4778 tcg_gen_sari_tl(cpu_cc_src
, cpu_regs
[R_EAX
], 63);
4779 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_regs
[R_EDX
]);
4780 set_cc_op(s
, CC_OP_MULQ
);
4788 gen_helper_divb_AL(cpu_env
, cpu_T
[0]);
4791 gen_helper_divw_AX(cpu_env
, cpu_T
[0]);
4795 gen_helper_divl_EAX(cpu_env
, cpu_T
[0]);
4797 #ifdef TARGET_X86_64
4799 gen_helper_divq_EAX(cpu_env
, cpu_T
[0]);
4807 gen_helper_idivb_AL(cpu_env
, cpu_T
[0]);
4810 gen_helper_idivw_AX(cpu_env
, cpu_T
[0]);
4814 gen_helper_idivl_EAX(cpu_env
, cpu_T
[0]);
4816 #ifdef TARGET_X86_64
4818 gen_helper_idivq_EAX(cpu_env
, cpu_T
[0]);
4828 case 0xfe: /* GRP4 */
4829 case 0xff: /* GRP5 */
4830 ot
= mo_b_d(b
, dflag
);
4832 modrm
= cpu_ldub_code(env
, s
->pc
++);
4833 mod
= (modrm
>> 6) & 3;
4834 rm
= (modrm
& 7) | REX_B(s
);
4835 op
= (modrm
>> 3) & 7;
4836 if (op
>= 2 && b
== 0xfe) {
4840 if (op
== 2 || op
== 4) {
4841 /* operand size for jumps is 64 bit */
4843 } else if (op
== 3 || op
== 5) {
4844 ot
= dflag
!= MO_16
? MO_32
+ (rex_w
== 1) : MO_16
;
4845 } else if (op
== 6) {
4846 /* default push size is 64 bit */
4847 ot
= mo_pushpop(s
, dflag
);
4851 gen_lea_modrm(env
, s
, modrm
);
4852 if (op
>= 2 && op
!= 3 && op
!= 5)
4853 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
4855 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
4859 case 0: /* inc Ev */
4864 gen_inc(s
, ot
, opreg
, 1);
4866 case 1: /* dec Ev */
4871 gen_inc(s
, ot
, opreg
, -1);
4873 case 2: /* call Ev */
4874 /* XXX: optimize if memory (no 'and' is necessary) */
4875 if (dflag
== MO_16
) {
4876 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
4878 next_eip
= s
->pc
- s
->cs_base
;
4879 tcg_gen_movi_tl(cpu_T
[1], next_eip
);
4880 gen_push_v(s
, cpu_T
[1]);
4881 gen_op_jmp_v(cpu_T
[0]);
4884 case 3: /* lcall Ev */
4885 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
4886 gen_add_A0_im(s
, 1 << ot
);
4887 gen_op_ld_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
4889 if (s
->pe
&& !s
->vm86
) {
4890 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4891 gen_helper_lcall_protected(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
4892 tcg_const_i32(dflag
- 1),
4893 tcg_const_tl(s
->pc
- s
->cs_base
));
4895 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4896 gen_helper_lcall_real(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
4897 tcg_const_i32(dflag
- 1),
4898 tcg_const_i32(s
->pc
- s
->cs_base
));
4902 case 4: /* jmp Ev */
4903 if (dflag
== MO_16
) {
4904 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
4906 gen_op_jmp_v(cpu_T
[0]);
4909 case 5: /* ljmp Ev */
4910 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
4911 gen_add_A0_im(s
, 1 << ot
);
4912 gen_op_ld_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
4914 if (s
->pe
&& !s
->vm86
) {
4915 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4916 gen_helper_ljmp_protected(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
4917 tcg_const_tl(s
->pc
- s
->cs_base
));
4919 gen_op_movl_seg_T0_vm(R_CS
);
4920 gen_op_jmp_v(cpu_T
[1]);
4924 case 6: /* push Ev */
4925 gen_push_v(s
, cpu_T
[0]);
4932 case 0x84: /* test Ev, Gv */
4934 ot
= mo_b_d(b
, dflag
);
4936 modrm
= cpu_ldub_code(env
, s
->pc
++);
4937 reg
= ((modrm
>> 3) & 7) | rex_r
;
4939 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4940 gen_op_mov_v_reg(ot
, cpu_T
[1], reg
);
4941 gen_op_testl_T0_T1_cc();
4942 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4945 case 0xa8: /* test eAX, Iv */
4947 ot
= mo_b_d(b
, dflag
);
4948 val
= insn_get(env
, s
, ot
);
4950 gen_op_mov_v_reg(ot
, cpu_T
[0], OR_EAX
);
4951 tcg_gen_movi_tl(cpu_T
[1], val
);
4952 gen_op_testl_T0_T1_cc();
4953 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4956 case 0x98: /* CWDE/CBW */
4958 #ifdef TARGET_X86_64
4960 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EAX
);
4961 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
4962 gen_op_mov_reg_v(MO_64
, R_EAX
, cpu_T
[0]);
4966 gen_op_mov_v_reg(MO_16
, cpu_T
[0], R_EAX
);
4967 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
4968 gen_op_mov_reg_v(MO_32
, R_EAX
, cpu_T
[0]);
4971 gen_op_mov_v_reg(MO_8
, cpu_T
[0], R_EAX
);
4972 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
4973 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
4979 case 0x99: /* CDQ/CWD */
4981 #ifdef TARGET_X86_64
4983 gen_op_mov_v_reg(MO_64
, cpu_T
[0], R_EAX
);
4984 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 63);
4985 gen_op_mov_reg_v(MO_64
, R_EDX
, cpu_T
[0]);
4989 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EAX
);
4990 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
4991 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 31);
4992 gen_op_mov_reg_v(MO_32
, R_EDX
, cpu_T
[0]);
4995 gen_op_mov_v_reg(MO_16
, cpu_T
[0], R_EAX
);
4996 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
4997 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 15);
4998 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T
[0]);
5004 case 0x1af: /* imul Gv, Ev */
5005 case 0x69: /* imul Gv, Ev, I */
5008 modrm
= cpu_ldub_code(env
, s
->pc
++);
5009 reg
= ((modrm
>> 3) & 7) | rex_r
;
5011 s
->rip_offset
= insn_const_size(ot
);
5014 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5016 val
= insn_get(env
, s
, ot
);
5017 tcg_gen_movi_tl(cpu_T
[1], val
);
5018 } else if (b
== 0x6b) {
5019 val
= (int8_t)insn_get(env
, s
, MO_8
);
5020 tcg_gen_movi_tl(cpu_T
[1], val
);
5022 gen_op_mov_v_reg(ot
, cpu_T
[1], reg
);
5025 #ifdef TARGET_X86_64
5027 tcg_gen_muls2_i64(cpu_regs
[reg
], cpu_T
[1], cpu_T
[0], cpu_T
[1]);
5028 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5029 tcg_gen_sari_tl(cpu_cc_src
, cpu_cc_dst
, 63);
5030 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_T
[1]);
5034 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5035 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
5036 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
5037 cpu_tmp2_i32
, cpu_tmp3_i32
);
5038 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
5039 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
5040 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5041 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
5042 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
5045 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5046 tcg_gen_ext16s_tl(cpu_T
[1], cpu_T
[1]);
5047 /* XXX: use 32 bit mul which could be faster */
5048 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5049 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5050 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T
[0]);
5051 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
5052 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
5055 set_cc_op(s
, CC_OP_MULB
+ ot
);
5058 case 0x1c1: /* xadd Ev, Gv */
5059 ot
= mo_b_d(b
, dflag
);
5060 modrm
= cpu_ldub_code(env
, s
->pc
++);
5061 reg
= ((modrm
>> 3) & 7) | rex_r
;
5062 mod
= (modrm
>> 6) & 3;
5064 rm
= (modrm
& 7) | REX_B(s
);
5065 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
5066 gen_op_mov_v_reg(ot
, cpu_T
[1], rm
);
5067 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5068 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5069 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
5071 gen_lea_modrm(env
, s
, modrm
);
5072 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
5073 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
5074 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5075 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
5076 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5078 gen_op_update2_cc();
5079 set_cc_op(s
, CC_OP_ADDB
+ ot
);
5082 case 0x1b1: /* cmpxchg Ev, Gv */
5084 TCGLabel
*label1
, *label2
;
5085 TCGv t0
, t1
, t2
, a0
;
5087 ot
= mo_b_d(b
, dflag
);
5088 modrm
= cpu_ldub_code(env
, s
->pc
++);
5089 reg
= ((modrm
>> 3) & 7) | rex_r
;
5090 mod
= (modrm
>> 6) & 3;
5091 t0
= tcg_temp_local_new();
5092 t1
= tcg_temp_local_new();
5093 t2
= tcg_temp_local_new();
5094 a0
= tcg_temp_local_new();
5095 gen_op_mov_v_reg(ot
, t1
, reg
);
5097 rm
= (modrm
& 7) | REX_B(s
);
5098 gen_op_mov_v_reg(ot
, t0
, rm
);
5100 gen_lea_modrm(env
, s
, modrm
);
5101 tcg_gen_mov_tl(a0
, cpu_A0
);
5102 gen_op_ld_v(s
, ot
, t0
, a0
);
5103 rm
= 0; /* avoid warning */
5105 label1
= gen_new_label();
5106 tcg_gen_mov_tl(t2
, cpu_regs
[R_EAX
]);
5109 tcg_gen_brcond_tl(TCG_COND_EQ
, t2
, t0
, label1
);
5110 label2
= gen_new_label();
5112 gen_op_mov_reg_v(ot
, R_EAX
, t0
);
5114 gen_set_label(label1
);
5115 gen_op_mov_reg_v(ot
, rm
, t1
);
5117 /* perform no-op store cycle like physical cpu; must be
5118 before changing accumulator to ensure idempotency if
5119 the store faults and the instruction is restarted */
5120 gen_op_st_v(s
, ot
, t0
, a0
);
5121 gen_op_mov_reg_v(ot
, R_EAX
, t0
);
5123 gen_set_label(label1
);
5124 gen_op_st_v(s
, ot
, t1
, a0
);
5126 gen_set_label(label2
);
5127 tcg_gen_mov_tl(cpu_cc_src
, t0
);
5128 tcg_gen_mov_tl(cpu_cc_srcT
, t2
);
5129 tcg_gen_sub_tl(cpu_cc_dst
, t2
, t0
);
5130 set_cc_op(s
, CC_OP_SUBB
+ ot
);
5137 case 0x1c7: /* cmpxchg8b */
5138 modrm
= cpu_ldub_code(env
, s
->pc
++);
5139 mod
= (modrm
>> 6) & 3;
5140 if ((mod
== 3) || ((modrm
& 0x38) != 0x8))
5142 #ifdef TARGET_X86_64
5143 if (dflag
== MO_64
) {
5144 if (!(s
->cpuid_ext_features
& CPUID_EXT_CX16
))
5146 gen_lea_modrm(env
, s
, modrm
);
5147 gen_helper_cmpxchg16b(cpu_env
, cpu_A0
);
5151 if (!(s
->cpuid_features
& CPUID_CX8
))
5153 gen_lea_modrm(env
, s
, modrm
);
5154 gen_helper_cmpxchg8b(cpu_env
, cpu_A0
);
5156 set_cc_op(s
, CC_OP_EFLAGS
);
5159 /**************************/
5161 case 0x50 ... 0x57: /* push */
5162 gen_op_mov_v_reg(MO_32
, cpu_T
[0], (b
& 7) | REX_B(s
));
5163 gen_push_v(s
, cpu_T
[0]);
5165 case 0x58 ... 0x5f: /* pop */
5167 /* NOTE: order is important for pop %sp */
5168 gen_pop_update(s
, ot
);
5169 gen_op_mov_reg_v(ot
, (b
& 7) | REX_B(s
), cpu_T
[0]);
5171 case 0x60: /* pusha */
5176 case 0x61: /* popa */
5181 case 0x68: /* push Iv */
5183 ot
= mo_pushpop(s
, dflag
);
5185 val
= insn_get(env
, s
, ot
);
5187 val
= (int8_t)insn_get(env
, s
, MO_8
);
5188 tcg_gen_movi_tl(cpu_T
[0], val
);
5189 gen_push_v(s
, cpu_T
[0]);
5191 case 0x8f: /* pop Ev */
5192 modrm
= cpu_ldub_code(env
, s
->pc
++);
5193 mod
= (modrm
>> 6) & 3;
5196 /* NOTE: order is important for pop %sp */
5197 gen_pop_update(s
, ot
);
5198 rm
= (modrm
& 7) | REX_B(s
);
5199 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
5201 /* NOTE: order is important too for MMU exceptions */
5202 s
->popl_esp_hack
= 1 << ot
;
5203 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5204 s
->popl_esp_hack
= 0;
5205 gen_pop_update(s
, ot
);
5208 case 0xc8: /* enter */
5211 val
= cpu_lduw_code(env
, s
->pc
);
5213 level
= cpu_ldub_code(env
, s
->pc
++);
5214 gen_enter(s
, val
, level
);
5217 case 0xc9: /* leave */
5218 /* XXX: exception not precise (ESP is updated before potential exception) */
5220 gen_op_mov_v_reg(MO_64
, cpu_T
[0], R_EBP
);
5221 gen_op_mov_reg_v(MO_64
, R_ESP
, cpu_T
[0]);
5222 } else if (s
->ss32
) {
5223 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EBP
);
5224 gen_op_mov_reg_v(MO_32
, R_ESP
, cpu_T
[0]);
5226 gen_op_mov_v_reg(MO_16
, cpu_T
[0], R_EBP
);
5227 gen_op_mov_reg_v(MO_16
, R_ESP
, cpu_T
[0]);
5230 gen_op_mov_reg_v(ot
, R_EBP
, cpu_T
[0]);
5231 gen_pop_update(s
, ot
);
5233 case 0x06: /* push es */
5234 case 0x0e: /* push cs */
5235 case 0x16: /* push ss */
5236 case 0x1e: /* push ds */
5239 gen_op_movl_T0_seg(b
>> 3);
5240 gen_push_v(s
, cpu_T
[0]);
5242 case 0x1a0: /* push fs */
5243 case 0x1a8: /* push gs */
5244 gen_op_movl_T0_seg((b
>> 3) & 7);
5245 gen_push_v(s
, cpu_T
[0]);
5247 case 0x07: /* pop es */
5248 case 0x17: /* pop ss */
5249 case 0x1f: /* pop ds */
5254 gen_movl_seg_T0(s
, reg
);
5255 gen_pop_update(s
, ot
);
5257 /* if reg == SS, inhibit interrupts/trace. */
5258 /* If several instructions disable interrupts, only the
5260 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
5261 gen_helper_set_inhibit_irq(cpu_env
);
5265 gen_jmp_im(s
->pc
- s
->cs_base
);
5269 case 0x1a1: /* pop fs */
5270 case 0x1a9: /* pop gs */
5272 gen_movl_seg_T0(s
, (b
>> 3) & 7);
5273 gen_pop_update(s
, ot
);
5275 gen_jmp_im(s
->pc
- s
->cs_base
);
5280 /**************************/
5283 case 0x89: /* mov Gv, Ev */
5284 ot
= mo_b_d(b
, dflag
);
5285 modrm
= cpu_ldub_code(env
, s
->pc
++);
5286 reg
= ((modrm
>> 3) & 7) | rex_r
;
5288 /* generate a generic store */
5289 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
5292 case 0xc7: /* mov Ev, Iv */
5293 ot
= mo_b_d(b
, dflag
);
5294 modrm
= cpu_ldub_code(env
, s
->pc
++);
5295 mod
= (modrm
>> 6) & 3;
5297 s
->rip_offset
= insn_const_size(ot
);
5298 gen_lea_modrm(env
, s
, modrm
);
5300 val
= insn_get(env
, s
, ot
);
5301 tcg_gen_movi_tl(cpu_T
[0], val
);
5303 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
5305 gen_op_mov_reg_v(ot
, (modrm
& 7) | REX_B(s
), cpu_T
[0]);
5309 case 0x8b: /* mov Ev, Gv */
5310 ot
= mo_b_d(b
, dflag
);
5311 modrm
= cpu_ldub_code(env
, s
->pc
++);
5312 reg
= ((modrm
>> 3) & 7) | rex_r
;
5314 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5315 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
5317 case 0x8e: /* mov seg, Gv */
5318 modrm
= cpu_ldub_code(env
, s
->pc
++);
5319 reg
= (modrm
>> 3) & 7;
5320 if (reg
>= 6 || reg
== R_CS
)
5322 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
5323 gen_movl_seg_T0(s
, reg
);
5325 /* if reg == SS, inhibit interrupts/trace */
5326 /* If several instructions disable interrupts, only the
5328 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
5329 gen_helper_set_inhibit_irq(cpu_env
);
5333 gen_jmp_im(s
->pc
- s
->cs_base
);
5337 case 0x8c: /* mov Gv, seg */
5338 modrm
= cpu_ldub_code(env
, s
->pc
++);
5339 reg
= (modrm
>> 3) & 7;
5340 mod
= (modrm
>> 6) & 3;
5343 gen_op_movl_T0_seg(reg
);
5344 ot
= mod
== 3 ? dflag
: MO_16
;
5345 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5348 case 0x1b6: /* movzbS Gv, Eb */
5349 case 0x1b7: /* movzwS Gv, Eb */
5350 case 0x1be: /* movsbS Gv, Eb */
5351 case 0x1bf: /* movswS Gv, Eb */
5356 /* d_ot is the size of destination */
5358 /* ot is the size of source */
5359 ot
= (b
& 1) + MO_8
;
5360 /* s_ot is the sign+size of source */
5361 s_ot
= b
& 8 ? MO_SIGN
| ot
: ot
;
5363 modrm
= cpu_ldub_code(env
, s
->pc
++);
5364 reg
= ((modrm
>> 3) & 7) | rex_r
;
5365 mod
= (modrm
>> 6) & 3;
5366 rm
= (modrm
& 7) | REX_B(s
);
5369 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
5372 tcg_gen_ext8u_tl(cpu_T
[0], cpu_T
[0]);
5375 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
5378 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
5382 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5385 gen_op_mov_reg_v(d_ot
, reg
, cpu_T
[0]);
5387 gen_lea_modrm(env
, s
, modrm
);
5388 gen_op_ld_v(s
, s_ot
, cpu_T
[0], cpu_A0
);
5389 gen_op_mov_reg_v(d_ot
, reg
, cpu_T
[0]);
5394 case 0x8d: /* lea */
5396 modrm
= cpu_ldub_code(env
, s
->pc
++);
5397 mod
= (modrm
>> 6) & 3;
5400 reg
= ((modrm
>> 3) & 7) | rex_r
;
5401 /* we must ensure that no segment is added */
5405 gen_lea_modrm(env
, s
, modrm
);
5407 gen_op_mov_reg_v(ot
, reg
, cpu_A0
);
5410 case 0xa0: /* mov EAX, Ov */
5412 case 0xa2: /* mov Ov, EAX */
5415 target_ulong offset_addr
;
5417 ot
= mo_b_d(b
, dflag
);
5419 #ifdef TARGET_X86_64
5421 offset_addr
= cpu_ldq_code(env
, s
->pc
);
5426 offset_addr
= insn_get(env
, s
, s
->aflag
);
5429 tcg_gen_movi_tl(cpu_A0
, offset_addr
);
5430 gen_add_A0_ds_seg(s
);
5432 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
5433 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T
[0]);
5435 gen_op_mov_v_reg(ot
, cpu_T
[0], R_EAX
);
5436 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
5440 case 0xd7: /* xlat */
5441 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EBX
]);
5442 tcg_gen_ext8u_tl(cpu_T
[0], cpu_regs
[R_EAX
]);
5443 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_T
[0]);
5444 gen_extu(s
->aflag
, cpu_A0
);
5445 gen_add_A0_ds_seg(s
);
5446 gen_op_ld_v(s
, MO_8
, cpu_T
[0], cpu_A0
);
5447 gen_op_mov_reg_v(MO_8
, R_EAX
, cpu_T
[0]);
5449 case 0xb0 ... 0xb7: /* mov R, Ib */
5450 val
= insn_get(env
, s
, MO_8
);
5451 tcg_gen_movi_tl(cpu_T
[0], val
);
5452 gen_op_mov_reg_v(MO_8
, (b
& 7) | REX_B(s
), cpu_T
[0]);
5454 case 0xb8 ... 0xbf: /* mov R, Iv */
5455 #ifdef TARGET_X86_64
5456 if (dflag
== MO_64
) {
5459 tmp
= cpu_ldq_code(env
, s
->pc
);
5461 reg
= (b
& 7) | REX_B(s
);
5462 tcg_gen_movi_tl(cpu_T
[0], tmp
);
5463 gen_op_mov_reg_v(MO_64
, reg
, cpu_T
[0]);
5468 val
= insn_get(env
, s
, ot
);
5469 reg
= (b
& 7) | REX_B(s
);
5470 tcg_gen_movi_tl(cpu_T
[0], val
);
5471 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
5475 case 0x91 ... 0x97: /* xchg R, EAX */
5478 reg
= (b
& 7) | REX_B(s
);
5482 case 0x87: /* xchg Ev, Gv */
5483 ot
= mo_b_d(b
, dflag
);
5484 modrm
= cpu_ldub_code(env
, s
->pc
++);
5485 reg
= ((modrm
>> 3) & 7) | rex_r
;
5486 mod
= (modrm
>> 6) & 3;
5488 rm
= (modrm
& 7) | REX_B(s
);
5490 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
5491 gen_op_mov_v_reg(ot
, cpu_T
[1], rm
);
5492 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
5493 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5495 gen_lea_modrm(env
, s
, modrm
);
5496 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
5497 /* for xchg, lock is implicit */
5498 if (!(prefixes
& PREFIX_LOCK
))
5500 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
5501 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
5502 if (!(prefixes
& PREFIX_LOCK
))
5503 gen_helper_unlock();
5504 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5507 case 0xc4: /* les Gv */
5508 /* In CODE64 this is VEX3; see above. */
5511 case 0xc5: /* lds Gv */
5512 /* In CODE64 this is VEX2; see above. */
5515 case 0x1b2: /* lss Gv */
5518 case 0x1b4: /* lfs Gv */
5521 case 0x1b5: /* lgs Gv */
5524 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
5525 modrm
= cpu_ldub_code(env
, s
->pc
++);
5526 reg
= ((modrm
>> 3) & 7) | rex_r
;
5527 mod
= (modrm
>> 6) & 3;
5530 gen_lea_modrm(env
, s
, modrm
);
5531 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
5532 gen_add_A0_im(s
, 1 << ot
);
5533 /* load the segment first to handle exceptions properly */
5534 gen_op_ld_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
5535 gen_movl_seg_T0(s
, op
);
5536 /* then put the data */
5537 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5539 gen_jmp_im(s
->pc
- s
->cs_base
);
5544 /************************/
5552 ot
= mo_b_d(b
, dflag
);
5553 modrm
= cpu_ldub_code(env
, s
->pc
++);
5554 mod
= (modrm
>> 6) & 3;
5555 op
= (modrm
>> 3) & 7;
5561 gen_lea_modrm(env
, s
, modrm
);
5564 opreg
= (modrm
& 7) | REX_B(s
);
5569 gen_shift(s
, op
, ot
, opreg
, OR_ECX
);
5572 shift
= cpu_ldub_code(env
, s
->pc
++);
5574 gen_shifti(s
, op
, ot
, opreg
, shift
);
5589 case 0x1a4: /* shld imm */
5593 case 0x1a5: /* shld cl */
5597 case 0x1ac: /* shrd imm */
5601 case 0x1ad: /* shrd cl */
5606 modrm
= cpu_ldub_code(env
, s
->pc
++);
5607 mod
= (modrm
>> 6) & 3;
5608 rm
= (modrm
& 7) | REX_B(s
);
5609 reg
= ((modrm
>> 3) & 7) | rex_r
;
5611 gen_lea_modrm(env
, s
, modrm
);
5616 gen_op_mov_v_reg(ot
, cpu_T
[1], reg
);
5619 TCGv imm
= tcg_const_tl(cpu_ldub_code(env
, s
->pc
++));
5620 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, imm
);
5623 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, cpu_regs
[R_ECX
]);
5627 /************************/
5630 if (s
->flags
& (HF_EM_MASK
| HF_TS_MASK
)) {
5631 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5632 /* XXX: what to do if illegal op ? */
5633 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
5636 modrm
= cpu_ldub_code(env
, s
->pc
++);
5637 mod
= (modrm
>> 6) & 3;
5639 op
= ((b
& 7) << 3) | ((modrm
>> 3) & 7);
5642 gen_lea_modrm(env
, s
, modrm
);
5644 case 0x00 ... 0x07: /* fxxxs */
5645 case 0x10 ... 0x17: /* fixxxl */
5646 case 0x20 ... 0x27: /* fxxxl */
5647 case 0x30 ... 0x37: /* fixxx */
5654 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5655 s
->mem_index
, MO_LEUL
);
5656 gen_helper_flds_FT0(cpu_env
, cpu_tmp2_i32
);
5659 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5660 s
->mem_index
, MO_LEUL
);
5661 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
5664 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
5665 s
->mem_index
, MO_LEQ
);
5666 gen_helper_fldl_FT0(cpu_env
, cpu_tmp1_i64
);
5670 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5671 s
->mem_index
, MO_LESW
);
5672 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
5676 gen_helper_fp_arith_ST0_FT0(op1
);
5678 /* fcomp needs pop */
5679 gen_helper_fpop(cpu_env
);
5683 case 0x08: /* flds */
5684 case 0x0a: /* fsts */
5685 case 0x0b: /* fstps */
5686 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5687 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5688 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5693 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5694 s
->mem_index
, MO_LEUL
);
5695 gen_helper_flds_ST0(cpu_env
, cpu_tmp2_i32
);
5698 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5699 s
->mem_index
, MO_LEUL
);
5700 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
5703 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
5704 s
->mem_index
, MO_LEQ
);
5705 gen_helper_fldl_ST0(cpu_env
, cpu_tmp1_i64
);
5709 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5710 s
->mem_index
, MO_LESW
);
5711 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
5716 /* XXX: the corresponding CPUID bit must be tested ! */
5719 gen_helper_fisttl_ST0(cpu_tmp2_i32
, cpu_env
);
5720 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5721 s
->mem_index
, MO_LEUL
);
5724 gen_helper_fisttll_ST0(cpu_tmp1_i64
, cpu_env
);
5725 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
5726 s
->mem_index
, MO_LEQ
);
5730 gen_helper_fistt_ST0(cpu_tmp2_i32
, cpu_env
);
5731 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5732 s
->mem_index
, MO_LEUW
);
5735 gen_helper_fpop(cpu_env
);
5740 gen_helper_fsts_ST0(cpu_tmp2_i32
, cpu_env
);
5741 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5742 s
->mem_index
, MO_LEUL
);
5745 gen_helper_fistl_ST0(cpu_tmp2_i32
, cpu_env
);
5746 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5747 s
->mem_index
, MO_LEUL
);
5750 gen_helper_fstl_ST0(cpu_tmp1_i64
, cpu_env
);
5751 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
5752 s
->mem_index
, MO_LEQ
);
5756 gen_helper_fist_ST0(cpu_tmp2_i32
, cpu_env
);
5757 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5758 s
->mem_index
, MO_LEUW
);
5762 gen_helper_fpop(cpu_env
);
5766 case 0x0c: /* fldenv mem */
5767 gen_helper_fldenv(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5769 case 0x0d: /* fldcw mem */
5770 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5771 s
->mem_index
, MO_LEUW
);
5772 gen_helper_fldcw(cpu_env
, cpu_tmp2_i32
);
5774 case 0x0e: /* fnstenv mem */
5775 gen_helper_fstenv(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5777 case 0x0f: /* fnstcw mem */
5778 gen_helper_fnstcw(cpu_tmp2_i32
, cpu_env
);
5779 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5780 s
->mem_index
, MO_LEUW
);
5782 case 0x1d: /* fldt mem */
5783 gen_helper_fldt_ST0(cpu_env
, cpu_A0
);
5785 case 0x1f: /* fstpt mem */
5786 gen_helper_fstt_ST0(cpu_env
, cpu_A0
);
5787 gen_helper_fpop(cpu_env
);
5789 case 0x2c: /* frstor mem */
5790 gen_helper_frstor(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5792 case 0x2e: /* fnsave mem */
5793 gen_helper_fsave(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5795 case 0x2f: /* fnstsw mem */
5796 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
5797 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5798 s
->mem_index
, MO_LEUW
);
5800 case 0x3c: /* fbld */
5801 gen_helper_fbld_ST0(cpu_env
, cpu_A0
);
5803 case 0x3e: /* fbstp */
5804 gen_helper_fbst_ST0(cpu_env
, cpu_A0
);
5805 gen_helper_fpop(cpu_env
);
5807 case 0x3d: /* fildll */
5808 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
5809 gen_helper_fildll_ST0(cpu_env
, cpu_tmp1_i64
);
5811 case 0x3f: /* fistpll */
5812 gen_helper_fistll_ST0(cpu_tmp1_i64
, cpu_env
);
5813 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
5814 gen_helper_fpop(cpu_env
);
5820 /* register float ops */
5824 case 0x08: /* fld sti */
5825 gen_helper_fpush(cpu_env
);
5826 gen_helper_fmov_ST0_STN(cpu_env
,
5827 tcg_const_i32((opreg
+ 1) & 7));
5829 case 0x09: /* fxchg sti */
5830 case 0x29: /* fxchg4 sti, undocumented op */
5831 case 0x39: /* fxchg7 sti, undocumented op */
5832 gen_helper_fxchg_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
5834 case 0x0a: /* grp d9/2 */
5837 /* check exceptions (FreeBSD FPU probe) */
5838 gen_helper_fwait(cpu_env
);
5844 case 0x0c: /* grp d9/4 */
5847 gen_helper_fchs_ST0(cpu_env
);
5850 gen_helper_fabs_ST0(cpu_env
);
5853 gen_helper_fldz_FT0(cpu_env
);
5854 gen_helper_fcom_ST0_FT0(cpu_env
);
5857 gen_helper_fxam_ST0(cpu_env
);
5863 case 0x0d: /* grp d9/5 */
5867 gen_helper_fpush(cpu_env
);
5868 gen_helper_fld1_ST0(cpu_env
);
5871 gen_helper_fpush(cpu_env
);
5872 gen_helper_fldl2t_ST0(cpu_env
);
5875 gen_helper_fpush(cpu_env
);
5876 gen_helper_fldl2e_ST0(cpu_env
);
5879 gen_helper_fpush(cpu_env
);
5880 gen_helper_fldpi_ST0(cpu_env
);
5883 gen_helper_fpush(cpu_env
);
5884 gen_helper_fldlg2_ST0(cpu_env
);
5887 gen_helper_fpush(cpu_env
);
5888 gen_helper_fldln2_ST0(cpu_env
);
5891 gen_helper_fpush(cpu_env
);
5892 gen_helper_fldz_ST0(cpu_env
);
5899 case 0x0e: /* grp d9/6 */
5902 gen_helper_f2xm1(cpu_env
);
5905 gen_helper_fyl2x(cpu_env
);
5908 gen_helper_fptan(cpu_env
);
5910 case 3: /* fpatan */
5911 gen_helper_fpatan(cpu_env
);
5913 case 4: /* fxtract */
5914 gen_helper_fxtract(cpu_env
);
5916 case 5: /* fprem1 */
5917 gen_helper_fprem1(cpu_env
);
5919 case 6: /* fdecstp */
5920 gen_helper_fdecstp(cpu_env
);
5923 case 7: /* fincstp */
5924 gen_helper_fincstp(cpu_env
);
5928 case 0x0f: /* grp d9/7 */
5931 gen_helper_fprem(cpu_env
);
5933 case 1: /* fyl2xp1 */
5934 gen_helper_fyl2xp1(cpu_env
);
5937 gen_helper_fsqrt(cpu_env
);
5939 case 3: /* fsincos */
5940 gen_helper_fsincos(cpu_env
);
5942 case 5: /* fscale */
5943 gen_helper_fscale(cpu_env
);
5945 case 4: /* frndint */
5946 gen_helper_frndint(cpu_env
);
5949 gen_helper_fsin(cpu_env
);
5953 gen_helper_fcos(cpu_env
);
5957 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
5958 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
5959 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
5965 gen_helper_fp_arith_STN_ST0(op1
, opreg
);
5967 gen_helper_fpop(cpu_env
);
5969 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
5970 gen_helper_fp_arith_ST0_FT0(op1
);
5974 case 0x02: /* fcom */
5975 case 0x22: /* fcom2, undocumented op */
5976 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
5977 gen_helper_fcom_ST0_FT0(cpu_env
);
5979 case 0x03: /* fcomp */
5980 case 0x23: /* fcomp3, undocumented op */
5981 case 0x32: /* fcomp5, undocumented op */
5982 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
5983 gen_helper_fcom_ST0_FT0(cpu_env
);
5984 gen_helper_fpop(cpu_env
);
5986 case 0x15: /* da/5 */
5988 case 1: /* fucompp */
5989 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
5990 gen_helper_fucom_ST0_FT0(cpu_env
);
5991 gen_helper_fpop(cpu_env
);
5992 gen_helper_fpop(cpu_env
);
6000 case 0: /* feni (287 only, just do nop here) */
6002 case 1: /* fdisi (287 only, just do nop here) */
6005 gen_helper_fclex(cpu_env
);
6007 case 3: /* fninit */
6008 gen_helper_fninit(cpu_env
);
6010 case 4: /* fsetpm (287 only, just do nop here) */
6016 case 0x1d: /* fucomi */
6017 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6020 gen_update_cc_op(s
);
6021 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6022 gen_helper_fucomi_ST0_FT0(cpu_env
);
6023 set_cc_op(s
, CC_OP_EFLAGS
);
6025 case 0x1e: /* fcomi */
6026 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6029 gen_update_cc_op(s
);
6030 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6031 gen_helper_fcomi_ST0_FT0(cpu_env
);
6032 set_cc_op(s
, CC_OP_EFLAGS
);
6034 case 0x28: /* ffree sti */
6035 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6037 case 0x2a: /* fst sti */
6038 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6040 case 0x2b: /* fstp sti */
6041 case 0x0b: /* fstp1 sti, undocumented op */
6042 case 0x3a: /* fstp8 sti, undocumented op */
6043 case 0x3b: /* fstp9 sti, undocumented op */
6044 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6045 gen_helper_fpop(cpu_env
);
6047 case 0x2c: /* fucom st(i) */
6048 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6049 gen_helper_fucom_ST0_FT0(cpu_env
);
6051 case 0x2d: /* fucomp st(i) */
6052 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6053 gen_helper_fucom_ST0_FT0(cpu_env
);
6054 gen_helper_fpop(cpu_env
);
6056 case 0x33: /* de/3 */
6058 case 1: /* fcompp */
6059 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6060 gen_helper_fcom_ST0_FT0(cpu_env
);
6061 gen_helper_fpop(cpu_env
);
6062 gen_helper_fpop(cpu_env
);
6068 case 0x38: /* ffreep sti, undocumented op */
6069 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6070 gen_helper_fpop(cpu_env
);
6072 case 0x3c: /* df/4 */
6075 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
6076 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6077 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
6083 case 0x3d: /* fucomip */
6084 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6087 gen_update_cc_op(s
);
6088 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6089 gen_helper_fucomi_ST0_FT0(cpu_env
);
6090 gen_helper_fpop(cpu_env
);
6091 set_cc_op(s
, CC_OP_EFLAGS
);
6093 case 0x3e: /* fcomip */
6094 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6097 gen_update_cc_op(s
);
6098 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6099 gen_helper_fcomi_ST0_FT0(cpu_env
);
6100 gen_helper_fpop(cpu_env
);
6101 set_cc_op(s
, CC_OP_EFLAGS
);
6103 case 0x10 ... 0x13: /* fcmovxx */
6108 static const uint8_t fcmov_cc
[8] = {
6115 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6118 op1
= fcmov_cc
[op
& 3] | (((op
>> 3) & 1) ^ 1);
6119 l1
= gen_new_label();
6120 gen_jcc1_noeob(s
, op1
, l1
);
6121 gen_helper_fmov_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6130 /************************/
6133 case 0xa4: /* movsS */
6135 ot
= mo_b_d(b
, dflag
);
6136 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6137 gen_repz_movs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6143 case 0xaa: /* stosS */
6145 ot
= mo_b_d(b
, dflag
);
6146 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6147 gen_repz_stos(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6152 case 0xac: /* lodsS */
6154 ot
= mo_b_d(b
, dflag
);
6155 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6156 gen_repz_lods(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6161 case 0xae: /* scasS */
6163 ot
= mo_b_d(b
, dflag
);
6164 if (prefixes
& PREFIX_REPNZ
) {
6165 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6166 } else if (prefixes
& PREFIX_REPZ
) {
6167 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6173 case 0xa6: /* cmpsS */
6175 ot
= mo_b_d(b
, dflag
);
6176 if (prefixes
& PREFIX_REPNZ
) {
6177 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6178 } else if (prefixes
& PREFIX_REPZ
) {
6179 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6184 case 0x6c: /* insS */
6186 ot
= mo_b_d32(b
, dflag
);
6187 tcg_gen_ext16u_tl(cpu_T
[0], cpu_regs
[R_EDX
]);
6188 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6189 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
) | 4);
6190 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6191 gen_repz_ins(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6194 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6195 gen_jmp(s
, s
->pc
- s
->cs_base
);
6199 case 0x6e: /* outsS */
6201 ot
= mo_b_d32(b
, dflag
);
6202 tcg_gen_ext16u_tl(cpu_T
[0], cpu_regs
[R_EDX
]);
6203 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6204 svm_is_rep(prefixes
) | 4);
6205 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6206 gen_repz_outs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6209 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6210 gen_jmp(s
, s
->pc
- s
->cs_base
);
6215 /************************/
6220 ot
= mo_b_d32(b
, dflag
);
6221 val
= cpu_ldub_code(env
, s
->pc
++);
6222 tcg_gen_movi_tl(cpu_T
[0], val
);
6223 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6224 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6225 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6228 tcg_gen_movi_i32(cpu_tmp2_i32
, val
);
6229 gen_helper_in_func(ot
, cpu_T
[1], cpu_tmp2_i32
);
6230 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T
[1]);
6231 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6232 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6234 gen_jmp(s
, s
->pc
- s
->cs_base
);
6239 ot
= mo_b_d32(b
, dflag
);
6240 val
= cpu_ldub_code(env
, s
->pc
++);
6241 tcg_gen_movi_tl(cpu_T
[0], val
);
6242 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6243 svm_is_rep(prefixes
));
6244 gen_op_mov_v_reg(ot
, cpu_T
[1], R_EAX
);
6246 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6249 tcg_gen_movi_i32(cpu_tmp2_i32
, val
);
6250 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
6251 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6252 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6253 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6255 gen_jmp(s
, s
->pc
- s
->cs_base
);
6260 ot
= mo_b_d32(b
, dflag
);
6261 tcg_gen_ext16u_tl(cpu_T
[0], cpu_regs
[R_EDX
]);
6262 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6263 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6264 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6267 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6268 gen_helper_in_func(ot
, cpu_T
[1], cpu_tmp2_i32
);
6269 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T
[1]);
6270 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6271 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6273 gen_jmp(s
, s
->pc
- s
->cs_base
);
6278 ot
= mo_b_d32(b
, dflag
);
6279 tcg_gen_ext16u_tl(cpu_T
[0], cpu_regs
[R_EDX
]);
6280 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6281 svm_is_rep(prefixes
));
6282 gen_op_mov_v_reg(ot
, cpu_T
[1], R_EAX
);
6284 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6287 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6288 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
6289 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6290 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6291 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6293 gen_jmp(s
, s
->pc
- s
->cs_base
);
6297 /************************/
6299 case 0xc2: /* ret im */
6300 val
= cpu_ldsw_code(env
, s
->pc
);
6303 gen_stack_update(s
, val
+ (1 << ot
));
6304 /* Note that gen_pop_T0 uses a zero-extending load. */
6305 gen_op_jmp_v(cpu_T
[0]);
6308 case 0xc3: /* ret */
6310 gen_pop_update(s
, ot
);
6311 /* Note that gen_pop_T0 uses a zero-extending load. */
6312 gen_op_jmp_v(cpu_T
[0]);
6315 case 0xca: /* lret im */
6316 val
= cpu_ldsw_code(env
, s
->pc
);
6319 if (s
->pe
&& !s
->vm86
) {
6320 gen_update_cc_op(s
);
6321 gen_jmp_im(pc_start
- s
->cs_base
);
6322 gen_helper_lret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6323 tcg_const_i32(val
));
6327 gen_op_ld_v(s
, dflag
, cpu_T
[0], cpu_A0
);
6328 /* NOTE: keeping EIP updated is not a problem in case of
6330 gen_op_jmp_v(cpu_T
[0]);
6332 gen_op_addl_A0_im(1 << dflag
);
6333 gen_op_ld_v(s
, dflag
, cpu_T
[0], cpu_A0
);
6334 gen_op_movl_seg_T0_vm(R_CS
);
6335 /* add stack offset */
6336 gen_stack_update(s
, val
+ (2 << dflag
));
6340 case 0xcb: /* lret */
6343 case 0xcf: /* iret */
6344 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IRET
);
6347 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6348 set_cc_op(s
, CC_OP_EFLAGS
);
6349 } else if (s
->vm86
) {
6351 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6353 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6354 set_cc_op(s
, CC_OP_EFLAGS
);
6357 gen_helper_iret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6358 tcg_const_i32(s
->pc
- s
->cs_base
));
6359 set_cc_op(s
, CC_OP_EFLAGS
);
6363 case 0xe8: /* call im */
6365 if (dflag
!= MO_16
) {
6366 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6368 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6370 next_eip
= s
->pc
- s
->cs_base
;
6372 if (dflag
== MO_16
) {
6374 } else if (!CODE64(s
)) {
6377 tcg_gen_movi_tl(cpu_T
[0], next_eip
);
6378 gen_push_v(s
, cpu_T
[0]);
6382 case 0x9a: /* lcall im */
6384 unsigned int selector
, offset
;
6389 offset
= insn_get(env
, s
, ot
);
6390 selector
= insn_get(env
, s
, MO_16
);
6392 tcg_gen_movi_tl(cpu_T
[0], selector
);
6393 tcg_gen_movi_tl(cpu_T
[1], offset
);
6396 case 0xe9: /* jmp im */
6397 if (dflag
!= MO_16
) {
6398 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6400 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6402 tval
+= s
->pc
- s
->cs_base
;
6403 if (dflag
== MO_16
) {
6405 } else if (!CODE64(s
)) {
6410 case 0xea: /* ljmp im */
6412 unsigned int selector
, offset
;
6417 offset
= insn_get(env
, s
, ot
);
6418 selector
= insn_get(env
, s
, MO_16
);
6420 tcg_gen_movi_tl(cpu_T
[0], selector
);
6421 tcg_gen_movi_tl(cpu_T
[1], offset
);
6424 case 0xeb: /* jmp Jb */
6425 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6426 tval
+= s
->pc
- s
->cs_base
;
6427 if (dflag
== MO_16
) {
6432 case 0x70 ... 0x7f: /* jcc Jb */
6433 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6435 case 0x180 ... 0x18f: /* jcc Jv */
6436 if (dflag
!= MO_16
) {
6437 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6439 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6442 next_eip
= s
->pc
- s
->cs_base
;
6444 if (dflag
== MO_16
) {
6447 gen_jcc(s
, b
, tval
, next_eip
);
6450 case 0x190 ... 0x19f: /* setcc Gv */
6451 modrm
= cpu_ldub_code(env
, s
->pc
++);
6452 gen_setcc1(s
, b
, cpu_T
[0]);
6453 gen_ldst_modrm(env
, s
, modrm
, MO_8
, OR_TMP0
, 1);
6455 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6456 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6460 modrm
= cpu_ldub_code(env
, s
->pc
++);
6461 reg
= ((modrm
>> 3) & 7) | rex_r
;
6462 gen_cmovcc1(env
, s
, ot
, b
, modrm
, reg
);
6465 /************************/
6467 case 0x9c: /* pushf */
6468 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_PUSHF
);
6469 if (s
->vm86
&& s
->iopl
!= 3) {
6470 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6472 gen_update_cc_op(s
);
6473 gen_helper_read_eflags(cpu_T
[0], cpu_env
);
6474 gen_push_v(s
, cpu_T
[0]);
6477 case 0x9d: /* popf */
6478 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_POPF
);
6479 if (s
->vm86
&& s
->iopl
!= 3) {
6480 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6484 if (dflag
!= MO_16
) {
6485 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6486 tcg_const_i32((TF_MASK
| AC_MASK
|
6491 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6492 tcg_const_i32((TF_MASK
| AC_MASK
|
6494 IF_MASK
| IOPL_MASK
)
6498 if (s
->cpl
<= s
->iopl
) {
6499 if (dflag
!= MO_16
) {
6500 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6501 tcg_const_i32((TF_MASK
|
6507 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6508 tcg_const_i32((TF_MASK
|
6516 if (dflag
!= MO_16
) {
6517 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6518 tcg_const_i32((TF_MASK
| AC_MASK
|
6519 ID_MASK
| NT_MASK
)));
6521 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6522 tcg_const_i32((TF_MASK
| AC_MASK
|
6528 gen_pop_update(s
, ot
);
6529 set_cc_op(s
, CC_OP_EFLAGS
);
6530 /* abort translation because TF/AC flag may change */
6531 gen_jmp_im(s
->pc
- s
->cs_base
);
6535 case 0x9e: /* sahf */
6536 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6538 gen_op_mov_v_reg(MO_8
, cpu_T
[0], R_AH
);
6539 gen_compute_eflags(s
);
6540 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, CC_O
);
6541 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], CC_S
| CC_Z
| CC_A
| CC_P
| CC_C
);
6542 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, cpu_T
[0]);
6544 case 0x9f: /* lahf */
6545 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6547 gen_compute_eflags(s
);
6548 /* Note: gen_compute_eflags() only gives the condition codes */
6549 tcg_gen_ori_tl(cpu_T
[0], cpu_cc_src
, 0x02);
6550 gen_op_mov_reg_v(MO_8
, R_AH
, cpu_T
[0]);
6552 case 0xf5: /* cmc */
6553 gen_compute_eflags(s
);
6554 tcg_gen_xori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6556 case 0xf8: /* clc */
6557 gen_compute_eflags(s
);
6558 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_C
);
6560 case 0xf9: /* stc */
6561 gen_compute_eflags(s
);
6562 tcg_gen_ori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6564 case 0xfc: /* cld */
6565 tcg_gen_movi_i32(cpu_tmp2_i32
, 1);
6566 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6568 case 0xfd: /* std */
6569 tcg_gen_movi_i32(cpu_tmp2_i32
, -1);
6570 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6573 /************************/
6574 /* bit operations */
6575 case 0x1ba: /* bt/bts/btr/btc Gv, im */
6577 modrm
= cpu_ldub_code(env
, s
->pc
++);
6578 op
= (modrm
>> 3) & 7;
6579 mod
= (modrm
>> 6) & 3;
6580 rm
= (modrm
& 7) | REX_B(s
);
6583 gen_lea_modrm(env
, s
, modrm
);
6584 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
6586 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
6589 val
= cpu_ldub_code(env
, s
->pc
++);
6590 tcg_gen_movi_tl(cpu_T
[1], val
);
6595 case 0x1a3: /* bt Gv, Ev */
6598 case 0x1ab: /* bts */
6601 case 0x1b3: /* btr */
6604 case 0x1bb: /* btc */
6608 modrm
= cpu_ldub_code(env
, s
->pc
++);
6609 reg
= ((modrm
>> 3) & 7) | rex_r
;
6610 mod
= (modrm
>> 6) & 3;
6611 rm
= (modrm
& 7) | REX_B(s
);
6612 gen_op_mov_v_reg(MO_32
, cpu_T
[1], reg
);
6614 gen_lea_modrm(env
, s
, modrm
);
6615 /* specific case: we need to add a displacement */
6616 gen_exts(ot
, cpu_T
[1]);
6617 tcg_gen_sari_tl(cpu_tmp0
, cpu_T
[1], 3 + ot
);
6618 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, ot
);
6619 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
6620 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
6622 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
6625 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], (1 << (3 + ot
)) - 1);
6626 tcg_gen_shr_tl(cpu_tmp4
, cpu_T
[0], cpu_T
[1]);
6631 tcg_gen_movi_tl(cpu_tmp0
, 1);
6632 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
6633 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
6636 tcg_gen_movi_tl(cpu_tmp0
, 1);
6637 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
6638 tcg_gen_andc_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
6642 tcg_gen_movi_tl(cpu_tmp0
, 1);
6643 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
6644 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
6649 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
6651 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
6655 /* Delay all CC updates until after the store above. Note that
6656 C is the result of the test, Z is unchanged, and the others
6657 are all undefined. */
6659 case CC_OP_MULB
... CC_OP_MULQ
:
6660 case CC_OP_ADDB
... CC_OP_ADDQ
:
6661 case CC_OP_ADCB
... CC_OP_ADCQ
:
6662 case CC_OP_SUBB
... CC_OP_SUBQ
:
6663 case CC_OP_SBBB
... CC_OP_SBBQ
:
6664 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
6665 case CC_OP_INCB
... CC_OP_INCQ
:
6666 case CC_OP_DECB
... CC_OP_DECQ
:
6667 case CC_OP_SHLB
... CC_OP_SHLQ
:
6668 case CC_OP_SARB
... CC_OP_SARQ
:
6669 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
6670 /* Z was going to be computed from the non-zero status of CC_DST.
6671 We can get that same Z value (and the new C value) by leaving
6672 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
6674 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
6675 set_cc_op(s
, ((s
->cc_op
- CC_OP_MULB
) & 3) + CC_OP_SARB
);
6678 /* Otherwise, generate EFLAGS and replace the C bit. */
6679 gen_compute_eflags(s
);
6680 tcg_gen_deposit_tl(cpu_cc_src
, cpu_cc_src
, cpu_tmp4
,
6685 case 0x1bc: /* bsf / tzcnt */
6686 case 0x1bd: /* bsr / lzcnt */
6688 modrm
= cpu_ldub_code(env
, s
->pc
++);
6689 reg
= ((modrm
>> 3) & 7) | rex_r
;
6690 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
6691 gen_extu(ot
, cpu_T
[0]);
6693 /* Note that lzcnt and tzcnt are in different extensions. */
6694 if ((prefixes
& PREFIX_REPZ
)
6696 ? s
->cpuid_ext3_features
& CPUID_EXT3_ABM
6697 : s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)) {
6699 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
6701 /* For lzcnt, reduce the target_ulong result by the
6702 number of zeros that we expect to find at the top. */
6703 gen_helper_clz(cpu_T
[0], cpu_T
[0]);
6704 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], TARGET_LONG_BITS
- size
);
6706 /* For tzcnt, a zero input must return the operand size:
6707 force all bits outside the operand size to 1. */
6708 target_ulong mask
= (target_ulong
)-2 << (size
- 1);
6709 tcg_gen_ori_tl(cpu_T
[0], cpu_T
[0], mask
);
6710 gen_helper_ctz(cpu_T
[0], cpu_T
[0]);
6712 /* For lzcnt/tzcnt, C and Z bits are defined and are
6713 related to the result. */
6714 gen_op_update1_cc();
6715 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
6717 /* For bsr/bsf, only the Z bit is defined and it is related
6718 to the input and not the result. */
6719 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
6720 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
6722 /* For bsr, return the bit index of the first 1 bit,
6723 not the count of leading zeros. */
6724 gen_helper_clz(cpu_T
[0], cpu_T
[0]);
6725 tcg_gen_xori_tl(cpu_T
[0], cpu_T
[0], TARGET_LONG_BITS
- 1);
6727 gen_helper_ctz(cpu_T
[0], cpu_T
[0]);
6729 /* ??? The manual says that the output is undefined when the
6730 input is zero, but real hardware leaves it unchanged, and
6731 real programs appear to depend on that. */
6732 tcg_gen_movi_tl(cpu_tmp0
, 0);
6733 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_T
[0], cpu_cc_dst
, cpu_tmp0
,
6734 cpu_regs
[reg
], cpu_T
[0]);
6736 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
6738 /************************/
6740 case 0x27: /* daa */
6743 gen_update_cc_op(s
);
6744 gen_helper_daa(cpu_env
);
6745 set_cc_op(s
, CC_OP_EFLAGS
);
6747 case 0x2f: /* das */
6750 gen_update_cc_op(s
);
6751 gen_helper_das(cpu_env
);
6752 set_cc_op(s
, CC_OP_EFLAGS
);
6754 case 0x37: /* aaa */
6757 gen_update_cc_op(s
);
6758 gen_helper_aaa(cpu_env
);
6759 set_cc_op(s
, CC_OP_EFLAGS
);
6761 case 0x3f: /* aas */
6764 gen_update_cc_op(s
);
6765 gen_helper_aas(cpu_env
);
6766 set_cc_op(s
, CC_OP_EFLAGS
);
6768 case 0xd4: /* aam */
6771 val
= cpu_ldub_code(env
, s
->pc
++);
6773 gen_exception(s
, EXCP00_DIVZ
, pc_start
- s
->cs_base
);
6775 gen_helper_aam(cpu_env
, tcg_const_i32(val
));
6776 set_cc_op(s
, CC_OP_LOGICB
);
6779 case 0xd5: /* aad */
6782 val
= cpu_ldub_code(env
, s
->pc
++);
6783 gen_helper_aad(cpu_env
, tcg_const_i32(val
));
6784 set_cc_op(s
, CC_OP_LOGICB
);
6786 /************************/
6788 case 0x90: /* nop */
6789 /* XXX: correct lock test for all insn */
6790 if (prefixes
& PREFIX_LOCK
) {
6793 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
6795 goto do_xchg_reg_eax
;
6797 if (prefixes
& PREFIX_REPZ
) {
6798 gen_update_cc_op(s
);
6799 gen_jmp_im(pc_start
- s
->cs_base
);
6800 gen_helper_pause(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
6801 s
->is_jmp
= DISAS_TB_JUMP
;
6804 case 0x9b: /* fwait */
6805 if ((s
->flags
& (HF_MP_MASK
| HF_TS_MASK
)) ==
6806 (HF_MP_MASK
| HF_TS_MASK
)) {
6807 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
6809 gen_helper_fwait(cpu_env
);
6812 case 0xcc: /* int3 */
6813 gen_interrupt(s
, EXCP03_INT3
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6815 case 0xcd: /* int N */
6816 val
= cpu_ldub_code(env
, s
->pc
++);
6817 if (s
->vm86
&& s
->iopl
!= 3) {
6818 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6820 gen_interrupt(s
, val
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6823 case 0xce: /* into */
6826 gen_update_cc_op(s
);
6827 gen_jmp_im(pc_start
- s
->cs_base
);
6828 gen_helper_into(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
6831 case 0xf1: /* icebp (undocumented, exits to external debugger) */
6832 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_ICEBP
);
6834 gen_debug(s
, pc_start
- s
->cs_base
);
6837 tb_flush(CPU(x86_env_get_cpu(env
)));
6838 qemu_set_log(CPU_LOG_INT
| CPU_LOG_TB_IN_ASM
);
6842 case 0xfa: /* cli */
6844 if (s
->cpl
<= s
->iopl
) {
6845 gen_helper_cli(cpu_env
);
6847 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6851 gen_helper_cli(cpu_env
);
6853 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6857 case 0xfb: /* sti */
6859 if (s
->cpl
<= s
->iopl
) {
6861 gen_helper_sti(cpu_env
);
6862 /* interruptions are enabled only the first insn after sti */
6863 /* If several instructions disable interrupts, only the
6865 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
6866 gen_helper_set_inhibit_irq(cpu_env
);
6867 /* give a chance to handle pending irqs */
6868 gen_jmp_im(s
->pc
- s
->cs_base
);
6871 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6877 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6881 case 0x62: /* bound */
6885 modrm
= cpu_ldub_code(env
, s
->pc
++);
6886 reg
= (modrm
>> 3) & 7;
6887 mod
= (modrm
>> 6) & 3;
6890 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
6891 gen_lea_modrm(env
, s
, modrm
);
6892 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6894 gen_helper_boundw(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
6896 gen_helper_boundl(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
6899 case 0x1c8 ... 0x1cf: /* bswap reg */
6900 reg
= (b
& 7) | REX_B(s
);
6901 #ifdef TARGET_X86_64
6902 if (dflag
== MO_64
) {
6903 gen_op_mov_v_reg(MO_64
, cpu_T
[0], reg
);
6904 tcg_gen_bswap64_i64(cpu_T
[0], cpu_T
[0]);
6905 gen_op_mov_reg_v(MO_64
, reg
, cpu_T
[0]);
6909 gen_op_mov_v_reg(MO_32
, cpu_T
[0], reg
);
6910 tcg_gen_ext32u_tl(cpu_T
[0], cpu_T
[0]);
6911 tcg_gen_bswap32_tl(cpu_T
[0], cpu_T
[0]);
6912 gen_op_mov_reg_v(MO_32
, reg
, cpu_T
[0]);
6915 case 0xd6: /* salc */
6918 gen_compute_eflags_c(s
, cpu_T
[0]);
6919 tcg_gen_neg_tl(cpu_T
[0], cpu_T
[0]);
6920 gen_op_mov_reg_v(MO_8
, R_EAX
, cpu_T
[0]);
6922 case 0xe0: /* loopnz */
6923 case 0xe1: /* loopz */
6924 case 0xe2: /* loop */
6925 case 0xe3: /* jecxz */
6927 TCGLabel
*l1
, *l2
, *l3
;
6929 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6930 next_eip
= s
->pc
- s
->cs_base
;
6932 if (dflag
== MO_16
) {
6936 l1
= gen_new_label();
6937 l2
= gen_new_label();
6938 l3
= gen_new_label();
6941 case 0: /* loopnz */
6943 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
6944 gen_op_jz_ecx(s
->aflag
, l3
);
6945 gen_jcc1(s
, (JCC_Z
<< 1) | (b
^ 1), l1
);
6948 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
6949 gen_op_jnz_ecx(s
->aflag
, l1
);
6953 gen_op_jz_ecx(s
->aflag
, l1
);
6958 gen_jmp_im(next_eip
);
6967 case 0x130: /* wrmsr */
6968 case 0x132: /* rdmsr */
6970 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6972 gen_update_cc_op(s
);
6973 gen_jmp_im(pc_start
- s
->cs_base
);
6975 gen_helper_rdmsr(cpu_env
);
6977 gen_helper_wrmsr(cpu_env
);
6981 case 0x131: /* rdtsc */
6982 gen_update_cc_op(s
);
6983 gen_jmp_im(pc_start
- s
->cs_base
);
6984 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6987 gen_helper_rdtsc(cpu_env
);
6988 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6990 gen_jmp(s
, s
->pc
- s
->cs_base
);
6993 case 0x133: /* rdpmc */
6994 gen_update_cc_op(s
);
6995 gen_jmp_im(pc_start
- s
->cs_base
);
6996 gen_helper_rdpmc(cpu_env
);
6998 case 0x134: /* sysenter */
6999 /* For Intel SYSENTER is valid on 64-bit */
7000 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7003 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7005 gen_helper_sysenter(cpu_env
);
7009 case 0x135: /* sysexit */
7010 /* For Intel SYSEXIT is valid on 64-bit */
7011 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7014 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7016 gen_helper_sysexit(cpu_env
, tcg_const_i32(dflag
- 1));
7020 #ifdef TARGET_X86_64
7021 case 0x105: /* syscall */
7022 /* XXX: is it usable in real mode ? */
7023 gen_update_cc_op(s
);
7024 gen_jmp_im(pc_start
- s
->cs_base
);
7025 gen_helper_syscall(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7028 case 0x107: /* sysret */
7030 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7032 gen_helper_sysret(cpu_env
, tcg_const_i32(dflag
- 1));
7033 /* condition codes are modified only in long mode */
7035 set_cc_op(s
, CC_OP_EFLAGS
);
7041 case 0x1a2: /* cpuid */
7042 gen_update_cc_op(s
);
7043 gen_jmp_im(pc_start
- s
->cs_base
);
7044 gen_helper_cpuid(cpu_env
);
7046 case 0xf4: /* hlt */
7048 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7050 gen_update_cc_op(s
);
7051 gen_jmp_im(pc_start
- s
->cs_base
);
7052 gen_helper_hlt(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7053 s
->is_jmp
= DISAS_TB_JUMP
;
7057 modrm
= cpu_ldub_code(env
, s
->pc
++);
7058 mod
= (modrm
>> 6) & 3;
7059 op
= (modrm
>> 3) & 7;
7062 if (!s
->pe
|| s
->vm86
)
7064 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_READ
);
7065 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,ldt
.selector
));
7066 ot
= mod
== 3 ? dflag
: MO_16
;
7067 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7070 if (!s
->pe
|| s
->vm86
)
7073 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7075 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_WRITE
);
7076 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7077 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
7078 gen_helper_lldt(cpu_env
, cpu_tmp2_i32
);
7082 if (!s
->pe
|| s
->vm86
)
7084 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_READ
);
7085 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,tr
.selector
));
7086 ot
= mod
== 3 ? dflag
: MO_16
;
7087 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7090 if (!s
->pe
|| s
->vm86
)
7093 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7095 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_WRITE
);
7096 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7097 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
7098 gen_helper_ltr(cpu_env
, cpu_tmp2_i32
);
7103 if (!s
->pe
|| s
->vm86
)
7105 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7106 gen_update_cc_op(s
);
7108 gen_helper_verr(cpu_env
, cpu_T
[0]);
7110 gen_helper_verw(cpu_env
, cpu_T
[0]);
7112 set_cc_op(s
, CC_OP_EFLAGS
);
7119 modrm
= cpu_ldub_code(env
, s
->pc
++);
7120 mod
= (modrm
>> 6) & 3;
7121 op
= (modrm
>> 3) & 7;
7127 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_READ
);
7128 gen_lea_modrm(env
, s
, modrm
);
7129 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7130 gen_op_st_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
7131 gen_add_A0_im(s
, 2);
7132 tcg_gen_ld_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7133 if (dflag
== MO_16
) {
7134 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffffff);
7136 gen_op_st_v(s
, CODE64(s
) + MO_32
, cpu_T
[0], cpu_A0
);
7141 case 0: /* monitor */
7142 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) ||
7145 gen_update_cc_op(s
);
7146 gen_jmp_im(pc_start
- s
->cs_base
);
7147 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EAX
]);
7148 gen_extu(s
->aflag
, cpu_A0
);
7149 gen_add_A0_ds_seg(s
);
7150 gen_helper_monitor(cpu_env
, cpu_A0
);
7153 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) ||
7156 gen_update_cc_op(s
);
7157 gen_jmp_im(pc_start
- s
->cs_base
);
7158 gen_helper_mwait(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7162 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
) ||
7166 gen_helper_clac(cpu_env
);
7167 gen_jmp_im(s
->pc
- s
->cs_base
);
7171 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
) ||
7175 gen_helper_stac(cpu_env
);
7176 gen_jmp_im(s
->pc
- s
->cs_base
);
7183 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_READ
);
7184 gen_lea_modrm(env
, s
, modrm
);
7185 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7186 gen_op_st_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
7187 gen_add_A0_im(s
, 2);
7188 tcg_gen_ld_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, idt
.base
));
7189 if (dflag
== MO_16
) {
7190 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffffff);
7192 gen_op_st_v(s
, CODE64(s
) + MO_32
, cpu_T
[0], cpu_A0
);
7198 gen_update_cc_op(s
);
7199 gen_jmp_im(pc_start
- s
->cs_base
);
7202 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7205 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7208 gen_helper_vmrun(cpu_env
, tcg_const_i32(s
->aflag
- 1),
7209 tcg_const_i32(s
->pc
- pc_start
));
7211 s
->is_jmp
= DISAS_TB_JUMP
;
7214 case 1: /* VMMCALL */
7215 if (!(s
->flags
& HF_SVME_MASK
))
7217 gen_helper_vmmcall(cpu_env
);
7219 case 2: /* VMLOAD */
7220 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7223 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7226 gen_helper_vmload(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7229 case 3: /* VMSAVE */
7230 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7233 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7236 gen_helper_vmsave(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7240 if ((!(s
->flags
& HF_SVME_MASK
) &&
7241 !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
)) ||
7245 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7248 gen_helper_stgi(cpu_env
);
7252 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7255 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7258 gen_helper_clgi(cpu_env
);
7261 case 6: /* SKINIT */
7262 if ((!(s
->flags
& HF_SVME_MASK
) &&
7263 !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
)) ||
7266 gen_helper_skinit(cpu_env
);
7268 case 7: /* INVLPGA */
7269 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7272 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7275 gen_helper_invlpga(cpu_env
,
7276 tcg_const_i32(s
->aflag
- 1));
7282 } else if (s
->cpl
!= 0) {
7283 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7285 gen_svm_check_intercept(s
, pc_start
,
7286 op
==2 ? SVM_EXIT_GDTR_WRITE
: SVM_EXIT_IDTR_WRITE
);
7287 gen_lea_modrm(env
, s
, modrm
);
7288 gen_op_ld_v(s
, MO_16
, cpu_T
[1], cpu_A0
);
7289 gen_add_A0_im(s
, 2);
7290 gen_op_ld_v(s
, CODE64(s
) + MO_32
, cpu_T
[0], cpu_A0
);
7291 if (dflag
== MO_16
) {
7292 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffffff);
7295 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,gdt
.base
));
7296 tcg_gen_st32_tl(cpu_T
[1], cpu_env
, offsetof(CPUX86State
,gdt
.limit
));
7298 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,idt
.base
));
7299 tcg_gen_st32_tl(cpu_T
[1], cpu_env
, offsetof(CPUX86State
,idt
.limit
));
7304 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_CR0
);
7305 #if defined TARGET_X86_64 && defined HOST_WORDS_BIGENDIAN
7306 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,cr
[0]) + 4);
7308 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,cr
[0]));
7310 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 1);
7314 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7316 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7317 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7318 gen_helper_lmsw(cpu_env
, cpu_T
[0]);
7319 gen_jmp_im(s
->pc
- s
->cs_base
);
7324 if (mod
!= 3) { /* invlpg */
7326 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7328 gen_update_cc_op(s
);
7329 gen_jmp_im(pc_start
- s
->cs_base
);
7330 gen_lea_modrm(env
, s
, modrm
);
7331 gen_helper_invlpg(cpu_env
, cpu_A0
);
7332 gen_jmp_im(s
->pc
- s
->cs_base
);
7337 case 0: /* swapgs */
7338 #ifdef TARGET_X86_64
7341 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7343 tcg_gen_ld_tl(cpu_T
[0], cpu_env
,
7344 offsetof(CPUX86State
,segs
[R_GS
].base
));
7345 tcg_gen_ld_tl(cpu_T
[1], cpu_env
,
7346 offsetof(CPUX86State
,kernelgsbase
));
7347 tcg_gen_st_tl(cpu_T
[1], cpu_env
,
7348 offsetof(CPUX86State
,segs
[R_GS
].base
));
7349 tcg_gen_st_tl(cpu_T
[0], cpu_env
,
7350 offsetof(CPUX86State
,kernelgsbase
));
7358 case 1: /* rdtscp */
7359 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_RDTSCP
))
7361 gen_update_cc_op(s
);
7362 gen_jmp_im(pc_start
- s
->cs_base
);
7363 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7366 gen_helper_rdtscp(cpu_env
);
7367 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7369 gen_jmp(s
, s
->pc
- s
->cs_base
);
7381 case 0x108: /* invd */
7382 case 0x109: /* wbinvd */
7384 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7386 gen_svm_check_intercept(s
, pc_start
, (b
& 2) ? SVM_EXIT_INVD
: SVM_EXIT_WBINVD
);
7390 case 0x63: /* arpl or movslS (x86_64) */
7391 #ifdef TARGET_X86_64
7394 /* d_ot is the size of destination */
7397 modrm
= cpu_ldub_code(env
, s
->pc
++);
7398 reg
= ((modrm
>> 3) & 7) | rex_r
;
7399 mod
= (modrm
>> 6) & 3;
7400 rm
= (modrm
& 7) | REX_B(s
);
7403 gen_op_mov_v_reg(MO_32
, cpu_T
[0], rm
);
7405 if (d_ot
== MO_64
) {
7406 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
7408 gen_op_mov_reg_v(d_ot
, reg
, cpu_T
[0]);
7410 gen_lea_modrm(env
, s
, modrm
);
7411 gen_op_ld_v(s
, MO_32
| MO_SIGN
, cpu_T
[0], cpu_A0
);
7412 gen_op_mov_reg_v(d_ot
, reg
, cpu_T
[0]);
7418 TCGv t0
, t1
, t2
, a0
;
7420 if (!s
->pe
|| s
->vm86
)
7422 t0
= tcg_temp_local_new();
7423 t1
= tcg_temp_local_new();
7424 t2
= tcg_temp_local_new();
7426 modrm
= cpu_ldub_code(env
, s
->pc
++);
7427 reg
= (modrm
>> 3) & 7;
7428 mod
= (modrm
>> 6) & 3;
7431 gen_lea_modrm(env
, s
, modrm
);
7432 gen_op_ld_v(s
, ot
, t0
, cpu_A0
);
7433 a0
= tcg_temp_local_new();
7434 tcg_gen_mov_tl(a0
, cpu_A0
);
7436 gen_op_mov_v_reg(ot
, t0
, rm
);
7439 gen_op_mov_v_reg(ot
, t1
, reg
);
7440 tcg_gen_andi_tl(cpu_tmp0
, t0
, 3);
7441 tcg_gen_andi_tl(t1
, t1
, 3);
7442 tcg_gen_movi_tl(t2
, 0);
7443 label1
= gen_new_label();
7444 tcg_gen_brcond_tl(TCG_COND_GE
, cpu_tmp0
, t1
, label1
);
7445 tcg_gen_andi_tl(t0
, t0
, ~3);
7446 tcg_gen_or_tl(t0
, t0
, t1
);
7447 tcg_gen_movi_tl(t2
, CC_Z
);
7448 gen_set_label(label1
);
7450 gen_op_st_v(s
, ot
, t0
, a0
);
7453 gen_op_mov_reg_v(ot
, rm
, t0
);
7455 gen_compute_eflags(s
);
7456 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_Z
);
7457 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, t2
);
7463 case 0x102: /* lar */
7464 case 0x103: /* lsl */
7468 if (!s
->pe
|| s
->vm86
)
7470 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
7471 modrm
= cpu_ldub_code(env
, s
->pc
++);
7472 reg
= ((modrm
>> 3) & 7) | rex_r
;
7473 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7474 t0
= tcg_temp_local_new();
7475 gen_update_cc_op(s
);
7477 gen_helper_lar(t0
, cpu_env
, cpu_T
[0]);
7479 gen_helper_lsl(t0
, cpu_env
, cpu_T
[0]);
7481 tcg_gen_andi_tl(cpu_tmp0
, cpu_cc_src
, CC_Z
);
7482 label1
= gen_new_label();
7483 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
7484 gen_op_mov_reg_v(ot
, reg
, t0
);
7485 gen_set_label(label1
);
7486 set_cc_op(s
, CC_OP_EFLAGS
);
7491 modrm
= cpu_ldub_code(env
, s
->pc
++);
7492 mod
= (modrm
>> 6) & 3;
7493 op
= (modrm
>> 3) & 7;
7495 case 0: /* prefetchnta */
7496 case 1: /* prefetchnt0 */
7497 case 2: /* prefetchnt0 */
7498 case 3: /* prefetchnt0 */
7501 gen_lea_modrm(env
, s
, modrm
);
7502 /* nothing more to do */
7504 default: /* nop (multi byte) */
7505 gen_nop_modrm(env
, s
, modrm
);
7509 case 0x119 ... 0x11f: /* nop (multi byte) */
7510 modrm
= cpu_ldub_code(env
, s
->pc
++);
7511 gen_nop_modrm(env
, s
, modrm
);
7513 case 0x120: /* mov reg, crN */
7514 case 0x122: /* mov crN, reg */
7516 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7518 modrm
= cpu_ldub_code(env
, s
->pc
++);
7519 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7520 * AMD documentation (24594.pdf) and testing of
7521 * intel 386 and 486 processors all show that the mod bits
7522 * are assumed to be 1's, regardless of actual values.
7524 rm
= (modrm
& 7) | REX_B(s
);
7525 reg
= ((modrm
>> 3) & 7) | rex_r
;
7530 if ((prefixes
& PREFIX_LOCK
) && (reg
== 0) &&
7531 (s
->cpuid_ext3_features
& CPUID_EXT3_CR8LEG
)) {
7540 gen_update_cc_op(s
);
7541 gen_jmp_im(pc_start
- s
->cs_base
);
7543 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
7544 gen_helper_write_crN(cpu_env
, tcg_const_i32(reg
),
7546 gen_jmp_im(s
->pc
- s
->cs_base
);
7549 gen_helper_read_crN(cpu_T
[0], cpu_env
, tcg_const_i32(reg
));
7550 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
7558 case 0x121: /* mov reg, drN */
7559 case 0x123: /* mov drN, reg */
7561 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7563 modrm
= cpu_ldub_code(env
, s
->pc
++);
7564 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7565 * AMD documentation (24594.pdf) and testing of
7566 * intel 386 and 486 processors all show that the mod bits
7567 * are assumed to be 1's, regardless of actual values.
7569 rm
= (modrm
& 7) | REX_B(s
);
7570 reg
= ((modrm
>> 3) & 7) | rex_r
;
7579 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_DR0
+ reg
);
7580 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
7581 tcg_gen_movi_i32(cpu_tmp2_i32
, reg
);
7582 gen_helper_set_dr(cpu_env
, cpu_tmp2_i32
, cpu_T
[0]);
7583 gen_jmp_im(s
->pc
- s
->cs_base
);
7586 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_DR0
+ reg
);
7587 tcg_gen_movi_i32(cpu_tmp2_i32
, reg
);
7588 gen_helper_get_dr(cpu_T
[0], cpu_env
, cpu_tmp2_i32
);
7589 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
7593 case 0x106: /* clts */
7595 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7597 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7598 gen_helper_clts(cpu_env
);
7599 /* abort block because static cpu state changed */
7600 gen_jmp_im(s
->pc
- s
->cs_base
);
7604 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
7605 case 0x1c3: /* MOVNTI reg, mem */
7606 if (!(s
->cpuid_features
& CPUID_SSE2
))
7608 ot
= mo_64_32(dflag
);
7609 modrm
= cpu_ldub_code(env
, s
->pc
++);
7610 mod
= (modrm
>> 6) & 3;
7613 reg
= ((modrm
>> 3) & 7) | rex_r
;
7614 /* generate a generic store */
7615 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
7618 modrm
= cpu_ldub_code(env
, s
->pc
++);
7619 mod
= (modrm
>> 6) & 3;
7620 op
= (modrm
>> 3) & 7;
7622 case 0: /* fxsave */
7623 if (mod
== 3 || !(s
->cpuid_features
& CPUID_FXSR
) ||
7624 (s
->prefix
& PREFIX_LOCK
))
7626 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
7627 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7630 gen_lea_modrm(env
, s
, modrm
);
7631 gen_helper_fxsave(cpu_env
, cpu_A0
, tcg_const_i32(dflag
== MO_64
));
7633 case 1: /* fxrstor */
7634 if (mod
== 3 || !(s
->cpuid_features
& CPUID_FXSR
) ||
7635 (s
->prefix
& PREFIX_LOCK
))
7637 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
7638 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7641 gen_lea_modrm(env
, s
, modrm
);
7642 gen_helper_fxrstor(cpu_env
, cpu_A0
, tcg_const_i32(dflag
== MO_64
));
7644 case 2: /* ldmxcsr */
7645 case 3: /* stmxcsr */
7646 if (s
->flags
& HF_TS_MASK
) {
7647 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7650 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
) ||
7653 gen_lea_modrm(env
, s
, modrm
);
7655 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
7656 s
->mem_index
, MO_LEUL
);
7657 gen_helper_ldmxcsr(cpu_env
, cpu_tmp2_i32
);
7659 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, mxcsr
));
7660 gen_op_st_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
7663 case 5: /* lfence */
7664 if ((modrm
& 0xc7) != 0xc0 || !(s
->cpuid_features
& CPUID_SSE2
))
7667 case 6: /* mfence/clwb */
7668 if (s
->prefix
& PREFIX_DATA
) {
7670 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLWB
))
7672 gen_nop_modrm(env
, s
, modrm
);
7675 if ((modrm
& 0xc7) != 0xc0 || !(s
->cpuid_features
& CPUID_SSE2
))
7679 case 7: /* sfence / clflush / clflushopt / pcommit */
7680 if ((modrm
& 0xc7) == 0xc0) {
7681 if (s
->prefix
& PREFIX_DATA
) {
7683 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_PCOMMIT
))
7687 /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX */
7688 if (!(s
->cpuid_features
& CPUID_SSE
))
7692 if (s
->prefix
& PREFIX_DATA
) {
7694 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLFLUSHOPT
))
7698 if (!(s
->cpuid_features
& CPUID_CLFLUSH
))
7701 gen_lea_modrm(env
, s
, modrm
);
7708 case 0x10d: /* 3DNow! prefetch(w) */
7709 modrm
= cpu_ldub_code(env
, s
->pc
++);
7710 mod
= (modrm
>> 6) & 3;
7713 gen_lea_modrm(env
, s
, modrm
);
7714 /* ignore for now */
7716 case 0x1aa: /* rsm */
7717 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_RSM
);
7718 if (!(s
->flags
& HF_SMM_MASK
))
7720 gen_update_cc_op(s
);
7721 gen_jmp_im(s
->pc
- s
->cs_base
);
7722 gen_helper_rsm(cpu_env
);
7725 case 0x1b8: /* SSE4.2 popcnt */
7726 if ((prefixes
& (PREFIX_REPZ
| PREFIX_LOCK
| PREFIX_REPNZ
)) !=
7729 if (!(s
->cpuid_ext_features
& CPUID_EXT_POPCNT
))
7732 modrm
= cpu_ldub_code(env
, s
->pc
++);
7733 reg
= ((modrm
>> 3) & 7) | rex_r
;
7735 if (s
->prefix
& PREFIX_DATA
) {
7738 ot
= mo_64_32(dflag
);
7741 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
7742 gen_helper_popcnt(cpu_T
[0], cpu_env
, cpu_T
[0], tcg_const_i32(ot
));
7743 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
7745 set_cc_op(s
, CC_OP_EFLAGS
);
7747 case 0x10e ... 0x10f:
7748 /* 3DNow! instructions, ignore prefixes */
7749 s
->prefix
&= ~(PREFIX_REPZ
| PREFIX_REPNZ
| PREFIX_DATA
);
7750 case 0x110 ... 0x117:
7751 case 0x128 ... 0x12f:
7752 case 0x138 ... 0x13a:
7753 case 0x150 ... 0x179:
7754 case 0x17c ... 0x17f:
7756 case 0x1c4 ... 0x1c6:
7757 case 0x1d0 ... 0x1fe:
7758 gen_sse(env
, s
, b
, pc_start
, rex_r
);
7763 /* lock generation */
7764 if (s
->prefix
& PREFIX_LOCK
)
7765 gen_helper_unlock();
7768 if (s
->prefix
& PREFIX_LOCK
)
7769 gen_helper_unlock();
7770 /* XXX: ensure that no lock was generated */
7771 gen_exception(s
, EXCP06_ILLOP
, pc_start
- s
->cs_base
);
7775 void tcg_x86_init(void)
7777 static const char reg_names
[CPU_NB_REGS
][4] = {
7778 #ifdef TARGET_X86_64
7808 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
7809 cpu_cc_op
= tcg_global_mem_new_i32(cpu_env
,
7810 offsetof(CPUX86State
, cc_op
), "cc_op");
7811 cpu_cc_dst
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_dst
),
7813 cpu_cc_src
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_src
),
7815 cpu_cc_src2
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_src2
),
7818 for (i
= 0; i
< CPU_NB_REGS
; ++i
) {
7819 cpu_regs
[i
] = tcg_global_mem_new(cpu_env
,
7820 offsetof(CPUX86State
, regs
[i
]),
7827 /* generate intermediate code for basic block 'tb'. */
7828 void gen_intermediate_code(CPUX86State
*env
, TranslationBlock
*tb
)
7830 X86CPU
*cpu
= x86_env_get_cpu(env
);
7831 CPUState
*cs
= CPU(cpu
);
7832 DisasContext dc1
, *dc
= &dc1
;
7833 target_ulong pc_ptr
;
7835 target_ulong pc_start
;
7836 target_ulong cs_base
;
7840 /* generate intermediate code */
7842 cs_base
= tb
->cs_base
;
7845 dc
->pe
= (flags
>> HF_PE_SHIFT
) & 1;
7846 dc
->code32
= (flags
>> HF_CS32_SHIFT
) & 1;
7847 dc
->ss32
= (flags
>> HF_SS32_SHIFT
) & 1;
7848 dc
->addseg
= (flags
>> HF_ADDSEG_SHIFT
) & 1;
7850 dc
->vm86
= (flags
>> VM_SHIFT
) & 1;
7851 dc
->cpl
= (flags
>> HF_CPL_SHIFT
) & 3;
7852 dc
->iopl
= (flags
>> IOPL_SHIFT
) & 3;
7853 dc
->tf
= (flags
>> TF_SHIFT
) & 1;
7854 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
7855 dc
->cc_op
= CC_OP_DYNAMIC
;
7856 dc
->cc_op_dirty
= false;
7857 dc
->cs_base
= cs_base
;
7859 dc
->popl_esp_hack
= 0;
7860 /* select memory access functions */
7862 if (flags
& HF_SOFTMMU_MASK
) {
7863 dc
->mem_index
= cpu_mmu_index(env
, false);
7865 dc
->cpuid_features
= env
->features
[FEAT_1_EDX
];
7866 dc
->cpuid_ext_features
= env
->features
[FEAT_1_ECX
];
7867 dc
->cpuid_ext2_features
= env
->features
[FEAT_8000_0001_EDX
];
7868 dc
->cpuid_ext3_features
= env
->features
[FEAT_8000_0001_ECX
];
7869 dc
->cpuid_7_0_ebx_features
= env
->features
[FEAT_7_0_EBX
];
7870 #ifdef TARGET_X86_64
7871 dc
->lma
= (flags
>> HF_LMA_SHIFT
) & 1;
7872 dc
->code64
= (flags
>> HF_CS64_SHIFT
) & 1;
7875 dc
->jmp_opt
= !(dc
->tf
|| cs
->singlestep_enabled
||
7876 (flags
& HF_INHIBIT_IRQ_MASK
)
7877 #ifndef CONFIG_SOFTMMU
7878 || (flags
& HF_SOFTMMU_MASK
)
7881 /* Do not optimize repz jumps at all in icount mode, because
7882 rep movsS instructions are execured with different paths
7883 in !repz_opt and repz_opt modes. The first one was used
7884 always except single step mode. And this setting
7885 disables jumps optimization and control paths become
7886 equivalent in run and single step modes.
7887 Now there will be no jump optimization for repz in
7888 record/replay modes and there will always be an
7889 additional step for ecx=0 when icount is enabled.
7891 dc
->repz_opt
= !dc
->jmp_opt
&& !(tb
->cflags
& CF_USE_ICOUNT
);
7893 /* check addseg logic */
7894 if (!dc
->addseg
&& (dc
->vm86
|| !dc
->pe
|| !dc
->code32
))
7895 printf("ERROR addseg\n");
7898 cpu_T
[0] = tcg_temp_new();
7899 cpu_T
[1] = tcg_temp_new();
7900 cpu_A0
= tcg_temp_new();
7902 cpu_tmp0
= tcg_temp_new();
7903 cpu_tmp1_i64
= tcg_temp_new_i64();
7904 cpu_tmp2_i32
= tcg_temp_new_i32();
7905 cpu_tmp3_i32
= tcg_temp_new_i32();
7906 cpu_tmp4
= tcg_temp_new();
7907 cpu_ptr0
= tcg_temp_new_ptr();
7908 cpu_ptr1
= tcg_temp_new_ptr();
7909 cpu_cc_srcT
= tcg_temp_local_new();
7911 dc
->is_jmp
= DISAS_NEXT
;
7914 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
7915 if (max_insns
== 0) {
7916 max_insns
= CF_COUNT_MASK
;
7918 if (max_insns
> TCG_MAX_INSNS
) {
7919 max_insns
= TCG_MAX_INSNS
;
7924 tcg_gen_insn_start(pc_ptr
, dc
->cc_op
);
7927 /* If RF is set, suppress an internally generated breakpoint. */
7928 if (unlikely(cpu_breakpoint_test(cs
, pc_ptr
,
7929 tb
->flags
& HF_RF_MASK
7930 ? BP_GDB
: BP_ANY
))) {
7931 gen_debug(dc
, pc_ptr
- dc
->cs_base
);
7932 /* The address covered by the breakpoint must be included in
7933 [tb->pc, tb->pc + tb->size) in order to for it to be
7934 properly cleared -- thus we increment the PC here so that
7935 the logic setting tb->size below does the right thing. */
7937 goto done_generating
;
7939 if (num_insns
== max_insns
&& (tb
->cflags
& CF_LAST_IO
)) {
7943 pc_ptr
= disas_insn(env
, dc
, pc_ptr
);
7944 /* stop translation if indicated */
7947 /* if single step mode, we generate only one instruction and
7948 generate an exception */
7949 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
7950 the flag and abort the translation to give the irqs a
7951 change to be happen */
7952 if (dc
->tf
|| dc
->singlestep_enabled
||
7953 (flags
& HF_INHIBIT_IRQ_MASK
)) {
7954 gen_jmp_im(pc_ptr
- dc
->cs_base
);
7958 /* Do not cross the boundary of the pages in icount mode,
7959 it can cause an exception. Do it only when boundary is
7960 crossed by the first instruction in the block.
7961 If current instruction already crossed the bound - it's ok,
7962 because an exception hasn't stopped this code.
7964 if ((tb
->cflags
& CF_USE_ICOUNT
)
7965 && ((pc_ptr
& TARGET_PAGE_MASK
)
7966 != ((pc_ptr
+ TARGET_MAX_INSN_SIZE
- 1) & TARGET_PAGE_MASK
)
7967 || (pc_ptr
& ~TARGET_PAGE_MASK
) == 0)) {
7968 gen_jmp_im(pc_ptr
- dc
->cs_base
);
7972 /* if too long translation, stop generation too */
7973 if (tcg_op_buf_full() ||
7974 (pc_ptr
- pc_start
) >= (TARGET_PAGE_SIZE
- 32) ||
7975 num_insns
>= max_insns
) {
7976 gen_jmp_im(pc_ptr
- dc
->cs_base
);
7981 gen_jmp_im(pc_ptr
- dc
->cs_base
);
7986 if (tb
->cflags
& CF_LAST_IO
)
7989 gen_tb_end(tb
, num_insns
);
7992 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
7994 qemu_log("----------------\n");
7995 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
7996 #ifdef TARGET_X86_64
8001 disas_flags
= !dc
->code32
;
8002 log_target_disas(cs
, pc_start
, pc_ptr
- pc_start
, disas_flags
);
8007 tb
->size
= pc_ptr
- pc_start
;
8008 tb
->icount
= num_insns
;
8011 void restore_state_to_opc(CPUX86State
*env
, TranslationBlock
*tb
,
8014 int cc_op
= data
[1];
8015 env
->eip
= data
[0] - tb
->cs_base
;
8016 if (cc_op
!= CC_OP_DYNAMIC
) {