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/>.
25 #include "qemu/host-utils.h"
27 #include "disas/disas.h"
29 #include "exec/cpu_ldst.h"
31 #include "exec/helper-proto.h"
32 #include "exec/helper-gen.h"
34 #include "trace-tcg.h"
37 #define PREFIX_REPZ 0x01
38 #define PREFIX_REPNZ 0x02
39 #define PREFIX_LOCK 0x04
40 #define PREFIX_DATA 0x08
41 #define PREFIX_ADR 0x10
42 #define PREFIX_VEX 0x20
45 #define CODE64(s) ((s)->code64)
46 #define REX_X(s) ((s)->rex_x)
47 #define REX_B(s) ((s)->rex_b)
62 //#define MACRO_TEST 1
64 /* global register indexes */
65 static TCGv_ptr cpu_env
;
67 static TCGv cpu_cc_dst
, cpu_cc_src
, cpu_cc_src2
, cpu_cc_srcT
;
68 static TCGv_i32 cpu_cc_op
;
69 static TCGv cpu_regs
[CPU_NB_REGS
];
72 /* local register indexes (only used inside old micro ops) */
73 static TCGv cpu_tmp0
, cpu_tmp4
;
74 static TCGv_ptr cpu_ptr0
, cpu_ptr1
;
75 static TCGv_i32 cpu_tmp2_i32
, cpu_tmp3_i32
;
76 static TCGv_i64 cpu_tmp1_i64
;
78 static uint8_t gen_opc_cc_op
[OPC_BUF_SIZE
];
80 #include "exec/gen-icount.h"
83 static int x86_64_hregs
;
86 typedef struct DisasContext
{
87 /* current insn context */
88 int override
; /* -1 if no override */
92 target_ulong pc
; /* pc = eip + cs_base */
93 int is_jmp
; /* 1 = means jump (stop translation), 2 means CPU
94 static state change (stop translation) */
95 /* current block context */
96 target_ulong cs_base
; /* base of CS segment */
97 int pe
; /* protected mode */
98 int code32
; /* 32 bit code segment */
100 int lma
; /* long mode active */
101 int code64
; /* 64 bit code segment */
104 int vex_l
; /* vex vector length */
105 int vex_v
; /* vex vvvv register, without 1's compliment. */
106 int ss32
; /* 32 bit stack segment */
107 CCOp cc_op
; /* current CC operation */
109 int addseg
; /* non zero if either DS/ES/SS have a non zero base */
110 int f_st
; /* currently unused */
111 int vm86
; /* vm86 mode */
114 int tf
; /* TF cpu flag */
115 int singlestep_enabled
; /* "hardware" single step enabled */
116 int jmp_opt
; /* use direct block chaining for direct jumps */
117 int repz_opt
; /* optimize jumps within repz instructions */
118 int mem_index
; /* select memory access functions */
119 uint64_t flags
; /* all execution flags */
120 struct TranslationBlock
*tb
;
121 int popl_esp_hack
; /* for correct popl with esp base handling */
122 int rip_offset
; /* only used in x86_64, but left for simplicity */
124 int cpuid_ext_features
;
125 int cpuid_ext2_features
;
126 int cpuid_ext3_features
;
127 int cpuid_7_0_ebx_features
;
130 static void gen_eob(DisasContext
*s
);
131 static void gen_jmp(DisasContext
*s
, target_ulong eip
);
132 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
);
133 static void gen_op(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
);
135 /* i386 arith/logic operations */
155 OP_SHL1
, /* undocumented */
171 /* I386 int registers */
172 OR_EAX
, /* MUST be even numbered */
181 OR_TMP0
= 16, /* temporary operand register */
183 OR_A0
, /* temporary register used when doing address evaluation */
193 /* Bit set if the global variable is live after setting CC_OP to X. */
194 static const uint8_t cc_op_live
[CC_OP_NB
] = {
195 [CC_OP_DYNAMIC
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
196 [CC_OP_EFLAGS
] = USES_CC_SRC
,
197 [CC_OP_MULB
... CC_OP_MULQ
] = USES_CC_DST
| USES_CC_SRC
,
198 [CC_OP_ADDB
... CC_OP_ADDQ
] = USES_CC_DST
| USES_CC_SRC
,
199 [CC_OP_ADCB
... CC_OP_ADCQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
200 [CC_OP_SUBB
... CC_OP_SUBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRCT
,
201 [CC_OP_SBBB
... CC_OP_SBBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
202 [CC_OP_LOGICB
... CC_OP_LOGICQ
] = USES_CC_DST
,
203 [CC_OP_INCB
... CC_OP_INCQ
] = USES_CC_DST
| USES_CC_SRC
,
204 [CC_OP_DECB
... CC_OP_DECQ
] = USES_CC_DST
| USES_CC_SRC
,
205 [CC_OP_SHLB
... CC_OP_SHLQ
] = USES_CC_DST
| USES_CC_SRC
,
206 [CC_OP_SARB
... CC_OP_SARQ
] = USES_CC_DST
| USES_CC_SRC
,
207 [CC_OP_BMILGB
... CC_OP_BMILGQ
] = USES_CC_DST
| USES_CC_SRC
,
208 [CC_OP_ADCX
] = USES_CC_DST
| USES_CC_SRC
,
209 [CC_OP_ADOX
] = USES_CC_SRC
| USES_CC_SRC2
,
210 [CC_OP_ADCOX
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
214 static void set_cc_op(DisasContext
*s
, CCOp op
)
218 if (s
->cc_op
== op
) {
222 /* Discard CC computation that will no longer be used. */
223 dead
= cc_op_live
[s
->cc_op
] & ~cc_op_live
[op
];
224 if (dead
& USES_CC_DST
) {
225 tcg_gen_discard_tl(cpu_cc_dst
);
227 if (dead
& USES_CC_SRC
) {
228 tcg_gen_discard_tl(cpu_cc_src
);
230 if (dead
& USES_CC_SRC2
) {
231 tcg_gen_discard_tl(cpu_cc_src2
);
233 if (dead
& USES_CC_SRCT
) {
234 tcg_gen_discard_tl(cpu_cc_srcT
);
237 if (op
== CC_OP_DYNAMIC
) {
238 /* The DYNAMIC setting is translator only, and should never be
239 stored. Thus we always consider it clean. */
240 s
->cc_op_dirty
= false;
242 /* Discard any computed CC_OP value (see shifts). */
243 if (s
->cc_op
== CC_OP_DYNAMIC
) {
244 tcg_gen_discard_i32(cpu_cc_op
);
246 s
->cc_op_dirty
= true;
251 static void gen_update_cc_op(DisasContext
*s
)
253 if (s
->cc_op_dirty
) {
254 tcg_gen_movi_i32(cpu_cc_op
, s
->cc_op
);
255 s
->cc_op_dirty
= false;
261 #define NB_OP_SIZES 4
263 #else /* !TARGET_X86_64 */
265 #define NB_OP_SIZES 3
267 #endif /* !TARGET_X86_64 */
269 #if defined(HOST_WORDS_BIGENDIAN)
270 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
271 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
272 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
273 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
274 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
276 #define REG_B_OFFSET 0
277 #define REG_H_OFFSET 1
278 #define REG_W_OFFSET 0
279 #define REG_L_OFFSET 0
280 #define REG_LH_OFFSET 4
283 /* In instruction encodings for byte register accesses the
284 * register number usually indicates "low 8 bits of register N";
285 * however there are some special cases where N 4..7 indicates
286 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
287 * true for this special case, false otherwise.
289 static inline bool byte_reg_is_xH(int reg
)
295 if (reg
>= 8 || x86_64_hregs
) {
302 /* Select the size of a push/pop operation. */
303 static inline TCGMemOp
mo_pushpop(DisasContext
*s
, TCGMemOp ot
)
306 return ot
== MO_16
? MO_16
: MO_64
;
312 /* Select only size 64 else 32. Used for SSE operand sizes. */
313 static inline TCGMemOp
mo_64_32(TCGMemOp ot
)
316 return ot
== MO_64
? MO_64
: MO_32
;
322 /* Select size 8 if lsb of B is clear, else OT. Used for decoding
323 byte vs word opcodes. */
324 static inline TCGMemOp
mo_b_d(int b
, TCGMemOp ot
)
326 return b
& 1 ? ot
: MO_8
;
329 /* Select size 8 if lsb of B is clear, else OT capped at 32.
330 Used for decoding operand size of port opcodes. */
331 static inline TCGMemOp
mo_b_d32(int b
, TCGMemOp ot
)
333 return b
& 1 ? (ot
== MO_16
? MO_16
: MO_32
) : MO_8
;
336 static void gen_op_mov_reg_v(TCGMemOp ot
, int reg
, TCGv t0
)
340 if (!byte_reg_is_xH(reg
)) {
341 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 8);
343 tcg_gen_deposit_tl(cpu_regs
[reg
- 4], cpu_regs
[reg
- 4], t0
, 8, 8);
347 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 16);
350 /* For x86_64, this sets the higher half of register to zero.
351 For i386, this is equivalent to a mov. */
352 tcg_gen_ext32u_tl(cpu_regs
[reg
], t0
);
356 tcg_gen_mov_tl(cpu_regs
[reg
], t0
);
364 static inline void gen_op_mov_v_reg(TCGMemOp ot
, TCGv t0
, int reg
)
366 if (ot
== MO_8
&& byte_reg_is_xH(reg
)) {
367 tcg_gen_shri_tl(t0
, cpu_regs
[reg
- 4], 8);
368 tcg_gen_ext8u_tl(t0
, t0
);
370 tcg_gen_mov_tl(t0
, cpu_regs
[reg
]);
374 static inline void gen_op_movl_A0_reg(int reg
)
376 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[reg
]);
379 static inline void gen_op_addl_A0_im(int32_t val
)
381 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, val
);
383 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffffffff);
388 static inline void gen_op_addq_A0_im(int64_t val
)
390 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, val
);
394 static void gen_add_A0_im(DisasContext
*s
, int val
)
398 gen_op_addq_A0_im(val
);
401 gen_op_addl_A0_im(val
);
404 static inline void gen_op_jmp_v(TCGv dest
)
406 tcg_gen_st_tl(dest
, cpu_env
, offsetof(CPUX86State
, eip
));
409 static inline void gen_op_add_reg_im(TCGMemOp size
, int reg
, int32_t val
)
411 tcg_gen_addi_tl(cpu_tmp0
, cpu_regs
[reg
], val
);
412 gen_op_mov_reg_v(size
, reg
, cpu_tmp0
);
415 static inline void gen_op_add_reg_T0(TCGMemOp size
, int reg
)
417 tcg_gen_add_tl(cpu_tmp0
, cpu_regs
[reg
], cpu_T
[0]);
418 gen_op_mov_reg_v(size
, reg
, cpu_tmp0
);
421 static inline void gen_op_addl_A0_reg_sN(int shift
, int reg
)
423 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[reg
]);
425 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, shift
);
426 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
427 /* For x86_64, this sets the higher half of register to zero.
428 For i386, this is equivalent to a nop. */
429 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
432 static inline void gen_op_movl_A0_seg(int reg
)
434 tcg_gen_ld32u_tl(cpu_A0
, cpu_env
, offsetof(CPUX86State
, segs
[reg
].base
) + REG_L_OFFSET
);
437 static inline void gen_op_addl_A0_seg(DisasContext
*s
, int reg
)
439 tcg_gen_ld_tl(cpu_tmp0
, cpu_env
, offsetof(CPUX86State
, segs
[reg
].base
));
442 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffffffff);
443 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
445 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
446 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffffffff);
449 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
454 static inline void gen_op_movq_A0_seg(int reg
)
456 tcg_gen_ld_tl(cpu_A0
, cpu_env
, offsetof(CPUX86State
, segs
[reg
].base
));
459 static inline void gen_op_addq_A0_seg(int reg
)
461 tcg_gen_ld_tl(cpu_tmp0
, cpu_env
, offsetof(CPUX86State
, segs
[reg
].base
));
462 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
465 static inline void gen_op_movq_A0_reg(int reg
)
467 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[reg
]);
470 static inline void gen_op_addq_A0_reg_sN(int shift
, int reg
)
472 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[reg
]);
474 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, shift
);
475 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
479 static inline void gen_op_ld_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
481 tcg_gen_qemu_ld_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
484 static inline void gen_op_st_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
486 tcg_gen_qemu_st_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
489 static inline void gen_op_st_rm_T0_A0(DisasContext
*s
, int idx
, int d
)
492 gen_op_st_v(s
, idx
, cpu_T
[0], cpu_A0
);
494 gen_op_mov_reg_v(idx
, d
, cpu_T
[0]);
498 static inline void gen_jmp_im(target_ulong pc
)
500 tcg_gen_movi_tl(cpu_tmp0
, pc
);
501 gen_op_jmp_v(cpu_tmp0
);
504 static inline void gen_string_movl_A0_ESI(DisasContext
*s
)
508 override
= s
->override
;
513 gen_op_movq_A0_seg(override
);
514 gen_op_addq_A0_reg_sN(0, R_ESI
);
516 gen_op_movq_A0_reg(R_ESI
);
522 if (s
->addseg
&& override
< 0)
525 gen_op_movl_A0_seg(override
);
526 gen_op_addl_A0_reg_sN(0, R_ESI
);
528 gen_op_movl_A0_reg(R_ESI
);
532 /* 16 address, always override */
535 tcg_gen_ext16u_tl(cpu_A0
, cpu_regs
[R_ESI
]);
536 gen_op_addl_A0_seg(s
, override
);
543 static inline void gen_string_movl_A0_EDI(DisasContext
*s
)
548 gen_op_movq_A0_reg(R_EDI
);
553 gen_op_movl_A0_seg(R_ES
);
554 gen_op_addl_A0_reg_sN(0, R_EDI
);
556 gen_op_movl_A0_reg(R_EDI
);
560 tcg_gen_ext16u_tl(cpu_A0
, cpu_regs
[R_EDI
]);
561 gen_op_addl_A0_seg(s
, R_ES
);
568 static inline void gen_op_movl_T0_Dshift(TCGMemOp ot
)
570 tcg_gen_ld32s_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, df
));
571 tcg_gen_shli_tl(cpu_T
[0], cpu_T
[0], ot
);
574 static TCGv
gen_ext_tl(TCGv dst
, TCGv src
, TCGMemOp size
, bool sign
)
579 tcg_gen_ext8s_tl(dst
, src
);
581 tcg_gen_ext8u_tl(dst
, src
);
586 tcg_gen_ext16s_tl(dst
, src
);
588 tcg_gen_ext16u_tl(dst
, src
);
594 tcg_gen_ext32s_tl(dst
, src
);
596 tcg_gen_ext32u_tl(dst
, src
);
605 static void gen_extu(TCGMemOp ot
, TCGv reg
)
607 gen_ext_tl(reg
, reg
, ot
, false);
610 static void gen_exts(TCGMemOp ot
, TCGv reg
)
612 gen_ext_tl(reg
, reg
, ot
, true);
615 static inline void gen_op_jnz_ecx(TCGMemOp size
, TCGLabel
*label1
)
617 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[R_ECX
]);
618 gen_extu(size
, cpu_tmp0
);
619 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_tmp0
, 0, label1
);
622 static inline void gen_op_jz_ecx(TCGMemOp size
, TCGLabel
*label1
)
624 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[R_ECX
]);
625 gen_extu(size
, cpu_tmp0
);
626 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
629 static void gen_helper_in_func(TCGMemOp ot
, TCGv v
, TCGv_i32 n
)
633 gen_helper_inb(v
, cpu_env
, n
);
636 gen_helper_inw(v
, cpu_env
, n
);
639 gen_helper_inl(v
, cpu_env
, n
);
646 static void gen_helper_out_func(TCGMemOp ot
, TCGv_i32 v
, TCGv_i32 n
)
650 gen_helper_outb(cpu_env
, v
, n
);
653 gen_helper_outw(cpu_env
, v
, n
);
656 gen_helper_outl(cpu_env
, v
, n
);
663 static void gen_check_io(DisasContext
*s
, TCGMemOp ot
, target_ulong cur_eip
,
666 target_ulong next_eip
;
668 if (s
->pe
&& (s
->cpl
> s
->iopl
|| s
->vm86
)) {
669 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
672 gen_helper_check_iob(cpu_env
, cpu_tmp2_i32
);
675 gen_helper_check_iow(cpu_env
, cpu_tmp2_i32
);
678 gen_helper_check_iol(cpu_env
, cpu_tmp2_i32
);
684 if(s
->flags
& HF_SVMI_MASK
) {
687 svm_flags
|= (1 << (4 + ot
));
688 next_eip
= s
->pc
- s
->cs_base
;
689 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
690 gen_helper_svm_check_io(cpu_env
, cpu_tmp2_i32
,
691 tcg_const_i32(svm_flags
),
692 tcg_const_i32(next_eip
- cur_eip
));
696 static inline void gen_movs(DisasContext
*s
, TCGMemOp ot
)
698 gen_string_movl_A0_ESI(s
);
699 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
700 gen_string_movl_A0_EDI(s
);
701 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
702 gen_op_movl_T0_Dshift(ot
);
703 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
704 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
707 static void gen_op_update1_cc(void)
709 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
712 static void gen_op_update2_cc(void)
714 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
715 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
718 static void gen_op_update3_cc(TCGv reg
)
720 tcg_gen_mov_tl(cpu_cc_src2
, reg
);
721 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
722 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
725 static inline void gen_op_testl_T0_T1_cc(void)
727 tcg_gen_and_tl(cpu_cc_dst
, cpu_T
[0], cpu_T
[1]);
730 static void gen_op_update_neg_cc(void)
732 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
733 tcg_gen_neg_tl(cpu_cc_src
, cpu_T
[0]);
734 tcg_gen_movi_tl(cpu_cc_srcT
, 0);
737 /* compute all eflags to cc_src */
738 static void gen_compute_eflags(DisasContext
*s
)
740 TCGv zero
, dst
, src1
, src2
;
743 if (s
->cc_op
== CC_OP_EFLAGS
) {
746 if (s
->cc_op
== CC_OP_CLR
) {
747 tcg_gen_movi_tl(cpu_cc_src
, CC_Z
| CC_P
);
748 set_cc_op(s
, CC_OP_EFLAGS
);
757 /* Take care to not read values that are not live. */
758 live
= cc_op_live
[s
->cc_op
] & ~USES_CC_SRCT
;
759 dead
= live
^ (USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
);
761 zero
= tcg_const_tl(0);
762 if (dead
& USES_CC_DST
) {
765 if (dead
& USES_CC_SRC
) {
768 if (dead
& USES_CC_SRC2
) {
774 gen_helper_cc_compute_all(cpu_cc_src
, dst
, src1
, src2
, cpu_cc_op
);
775 set_cc_op(s
, CC_OP_EFLAGS
);
782 typedef struct CCPrepare
{
792 /* compute eflags.C to reg */
793 static CCPrepare
gen_prepare_eflags_c(DisasContext
*s
, TCGv reg
)
799 case CC_OP_SUBB
... CC_OP_SUBQ
:
800 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
801 size
= s
->cc_op
- CC_OP_SUBB
;
802 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
803 /* If no temporary was used, be careful not to alias t1 and t0. */
804 t0
= TCGV_EQUAL(t1
, cpu_cc_src
) ? cpu_tmp0
: reg
;
805 tcg_gen_mov_tl(t0
, cpu_cc_srcT
);
809 case CC_OP_ADDB
... CC_OP_ADDQ
:
810 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
811 size
= s
->cc_op
- CC_OP_ADDB
;
812 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
813 t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
815 return (CCPrepare
) { .cond
= TCG_COND_LTU
, .reg
= t0
,
816 .reg2
= t1
, .mask
= -1, .use_reg2
= true };
818 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
820 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
822 case CC_OP_INCB
... CC_OP_INCQ
:
823 case CC_OP_DECB
... CC_OP_DECQ
:
824 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
825 .mask
= -1, .no_setcond
= true };
827 case CC_OP_SHLB
... CC_OP_SHLQ
:
828 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
829 size
= s
->cc_op
- CC_OP_SHLB
;
830 shift
= (8 << size
) - 1;
831 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
832 .mask
= (target_ulong
)1 << shift
};
834 case CC_OP_MULB
... CC_OP_MULQ
:
835 return (CCPrepare
) { .cond
= TCG_COND_NE
,
836 .reg
= cpu_cc_src
, .mask
= -1 };
838 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
839 size
= s
->cc_op
- CC_OP_BMILGB
;
840 t0
= gen_ext_tl(reg
, cpu_cc_src
, size
, false);
841 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
845 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_dst
,
846 .mask
= -1, .no_setcond
= true };
849 case CC_OP_SARB
... CC_OP_SARQ
:
851 return (CCPrepare
) { .cond
= TCG_COND_NE
,
852 .reg
= cpu_cc_src
, .mask
= CC_C
};
855 /* The need to compute only C from CC_OP_DYNAMIC is important
856 in efficiently implementing e.g. INC at the start of a TB. */
858 gen_helper_cc_compute_c(reg
, cpu_cc_dst
, cpu_cc_src
,
859 cpu_cc_src2
, cpu_cc_op
);
860 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
861 .mask
= -1, .no_setcond
= true };
865 /* compute eflags.P to reg */
866 static CCPrepare
gen_prepare_eflags_p(DisasContext
*s
, TCGv reg
)
868 gen_compute_eflags(s
);
869 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
873 /* compute eflags.S to reg */
874 static CCPrepare
gen_prepare_eflags_s(DisasContext
*s
, TCGv reg
)
878 gen_compute_eflags(s
);
884 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
887 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
890 TCGMemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
891 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, true);
892 return (CCPrepare
) { .cond
= TCG_COND_LT
, .reg
= t0
, .mask
= -1 };
897 /* compute eflags.O to reg */
898 static CCPrepare
gen_prepare_eflags_o(DisasContext
*s
, TCGv reg
)
903 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src2
,
904 .mask
= -1, .no_setcond
= true };
906 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
908 gen_compute_eflags(s
);
909 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
914 /* compute eflags.Z to reg */
915 static CCPrepare
gen_prepare_eflags_z(DisasContext
*s
, TCGv reg
)
919 gen_compute_eflags(s
);
925 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
928 return (CCPrepare
) { .cond
= TCG_COND_ALWAYS
, .mask
= -1 };
931 TCGMemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
932 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
933 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
938 /* perform a conditional store into register 'reg' according to jump opcode
939 value 'b'. In the fast case, T0 is guaranted not to be used. */
940 static CCPrepare
gen_prepare_cc(DisasContext
*s
, int b
, TCGv reg
)
942 int inv
, jcc_op
, cond
;
948 jcc_op
= (b
>> 1) & 7;
951 case CC_OP_SUBB
... CC_OP_SUBQ
:
952 /* We optimize relational operators for the cmp/jcc case. */
953 size
= s
->cc_op
- CC_OP_SUBB
;
956 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
957 gen_extu(size
, cpu_tmp4
);
958 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
959 cc
= (CCPrepare
) { .cond
= TCG_COND_LEU
, .reg
= cpu_tmp4
,
960 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
969 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
970 gen_exts(size
, cpu_tmp4
);
971 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, true);
972 cc
= (CCPrepare
) { .cond
= cond
, .reg
= cpu_tmp4
,
973 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
983 /* This actually generates good code for JC, JZ and JS. */
986 cc
= gen_prepare_eflags_o(s
, reg
);
989 cc
= gen_prepare_eflags_c(s
, reg
);
992 cc
= gen_prepare_eflags_z(s
, reg
);
995 gen_compute_eflags(s
);
996 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
997 .mask
= CC_Z
| CC_C
};
1000 cc
= gen_prepare_eflags_s(s
, reg
);
1003 cc
= gen_prepare_eflags_p(s
, reg
);
1006 gen_compute_eflags(s
);
1007 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
1010 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
1011 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
1012 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
1017 gen_compute_eflags(s
);
1018 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
1021 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
1022 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
1023 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
1024 .mask
= CC_S
| CC_Z
};
1031 cc
.cond
= tcg_invert_cond(cc
.cond
);
1036 static void gen_setcc1(DisasContext
*s
, int b
, TCGv reg
)
1038 CCPrepare cc
= gen_prepare_cc(s
, b
, reg
);
1040 if (cc
.no_setcond
) {
1041 if (cc
.cond
== TCG_COND_EQ
) {
1042 tcg_gen_xori_tl(reg
, cc
.reg
, 1);
1044 tcg_gen_mov_tl(reg
, cc
.reg
);
1049 if (cc
.cond
== TCG_COND_NE
&& !cc
.use_reg2
&& cc
.imm
== 0 &&
1050 cc
.mask
!= 0 && (cc
.mask
& (cc
.mask
- 1)) == 0) {
1051 tcg_gen_shri_tl(reg
, cc
.reg
, ctztl(cc
.mask
));
1052 tcg_gen_andi_tl(reg
, reg
, 1);
1055 if (cc
.mask
!= -1) {
1056 tcg_gen_andi_tl(reg
, cc
.reg
, cc
.mask
);
1060 tcg_gen_setcond_tl(cc
.cond
, reg
, cc
.reg
, cc
.reg2
);
1062 tcg_gen_setcondi_tl(cc
.cond
, reg
, cc
.reg
, cc
.imm
);
1066 static inline void gen_compute_eflags_c(DisasContext
*s
, TCGv reg
)
1068 gen_setcc1(s
, JCC_B
<< 1, reg
);
1071 /* generate a conditional jump to label 'l1' according to jump opcode
1072 value 'b'. In the fast case, T0 is guaranted not to be used. */
1073 static inline void gen_jcc1_noeob(DisasContext
*s
, int b
, TCGLabel
*l1
)
1075 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T
[0]);
1077 if (cc
.mask
!= -1) {
1078 tcg_gen_andi_tl(cpu_T
[0], cc
.reg
, cc
.mask
);
1082 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1084 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1088 /* Generate a conditional jump to label 'l1' according to jump opcode
1089 value 'b'. In the fast case, T0 is guaranted not to be used.
1090 A translation block must end soon. */
1091 static inline void gen_jcc1(DisasContext
*s
, int b
, TCGLabel
*l1
)
1093 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T
[0]);
1095 gen_update_cc_op(s
);
1096 if (cc
.mask
!= -1) {
1097 tcg_gen_andi_tl(cpu_T
[0], cc
.reg
, cc
.mask
);
1100 set_cc_op(s
, CC_OP_DYNAMIC
);
1102 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1104 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1108 /* XXX: does not work with gdbstub "ice" single step - not a
1110 static TCGLabel
*gen_jz_ecx_string(DisasContext
*s
, target_ulong next_eip
)
1112 TCGLabel
*l1
= gen_new_label();
1113 TCGLabel
*l2
= gen_new_label();
1114 gen_op_jnz_ecx(s
->aflag
, l1
);
1116 gen_jmp_tb(s
, next_eip
, 1);
1121 static inline void gen_stos(DisasContext
*s
, TCGMemOp ot
)
1123 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EAX
);
1124 gen_string_movl_A0_EDI(s
);
1125 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
1126 gen_op_movl_T0_Dshift(ot
);
1127 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1130 static inline void gen_lods(DisasContext
*s
, TCGMemOp ot
)
1132 gen_string_movl_A0_ESI(s
);
1133 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1134 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T
[0]);
1135 gen_op_movl_T0_Dshift(ot
);
1136 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1139 static inline void gen_scas(DisasContext
*s
, TCGMemOp ot
)
1141 gen_string_movl_A0_EDI(s
);
1142 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
1143 gen_op(s
, OP_CMPL
, ot
, R_EAX
);
1144 gen_op_movl_T0_Dshift(ot
);
1145 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1148 static inline void gen_cmps(DisasContext
*s
, TCGMemOp ot
)
1150 gen_string_movl_A0_EDI(s
);
1151 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
1152 gen_string_movl_A0_ESI(s
);
1153 gen_op(s
, OP_CMPL
, ot
, OR_TMP0
);
1154 gen_op_movl_T0_Dshift(ot
);
1155 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1156 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1159 static inline void gen_ins(DisasContext
*s
, TCGMemOp ot
)
1161 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1164 gen_string_movl_A0_EDI(s
);
1165 /* Note: we must do this dummy write first to be restartable in
1166 case of page fault. */
1167 tcg_gen_movi_tl(cpu_T
[0], 0);
1168 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
1169 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_EDX
]);
1170 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1171 gen_helper_in_func(ot
, cpu_T
[0], cpu_tmp2_i32
);
1172 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
1173 gen_op_movl_T0_Dshift(ot
);
1174 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1175 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1180 static inline void gen_outs(DisasContext
*s
, TCGMemOp ot
)
1182 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1185 gen_string_movl_A0_ESI(s
);
1186 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1188 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_EDX
]);
1189 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1190 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[0]);
1191 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1193 gen_op_movl_T0_Dshift(ot
);
1194 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1195 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1200 /* same method as Valgrind : we generate jumps to current or next
1202 #define GEN_REPZ(op) \
1203 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1204 target_ulong cur_eip, target_ulong next_eip) \
1207 gen_update_cc_op(s); \
1208 l2 = gen_jz_ecx_string(s, next_eip); \
1209 gen_ ## op(s, ot); \
1210 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1211 /* a loop would cause two single step exceptions if ECX = 1 \
1212 before rep string_insn */ \
1214 gen_op_jz_ecx(s->aflag, l2); \
1215 gen_jmp(s, cur_eip); \
1218 #define GEN_REPZ2(op) \
1219 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1220 target_ulong cur_eip, \
1221 target_ulong next_eip, \
1225 gen_update_cc_op(s); \
1226 l2 = gen_jz_ecx_string(s, next_eip); \
1227 gen_ ## op(s, ot); \
1228 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1229 gen_update_cc_op(s); \
1230 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
1232 gen_op_jz_ecx(s->aflag, l2); \
1233 gen_jmp(s, cur_eip); \
1244 static void gen_helper_fp_arith_ST0_FT0(int op
)
1248 gen_helper_fadd_ST0_FT0(cpu_env
);
1251 gen_helper_fmul_ST0_FT0(cpu_env
);
1254 gen_helper_fcom_ST0_FT0(cpu_env
);
1257 gen_helper_fcom_ST0_FT0(cpu_env
);
1260 gen_helper_fsub_ST0_FT0(cpu_env
);
1263 gen_helper_fsubr_ST0_FT0(cpu_env
);
1266 gen_helper_fdiv_ST0_FT0(cpu_env
);
1269 gen_helper_fdivr_ST0_FT0(cpu_env
);
1274 /* NOTE the exception in "r" op ordering */
1275 static void gen_helper_fp_arith_STN_ST0(int op
, int opreg
)
1277 TCGv_i32 tmp
= tcg_const_i32(opreg
);
1280 gen_helper_fadd_STN_ST0(cpu_env
, tmp
);
1283 gen_helper_fmul_STN_ST0(cpu_env
, tmp
);
1286 gen_helper_fsubr_STN_ST0(cpu_env
, tmp
);
1289 gen_helper_fsub_STN_ST0(cpu_env
, tmp
);
1292 gen_helper_fdivr_STN_ST0(cpu_env
, tmp
);
1295 gen_helper_fdiv_STN_ST0(cpu_env
, tmp
);
1300 /* if d == OR_TMP0, it means memory operand (address in A0) */
1301 static void gen_op(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
)
1304 gen_op_mov_v_reg(ot
, cpu_T
[0], d
);
1306 gen_op_ld_v(s1
, ot
, cpu_T
[0], cpu_A0
);
1310 gen_compute_eflags_c(s1
, cpu_tmp4
);
1311 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1312 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_tmp4
);
1313 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1314 gen_op_update3_cc(cpu_tmp4
);
1315 set_cc_op(s1
, CC_OP_ADCB
+ ot
);
1318 gen_compute_eflags_c(s1
, cpu_tmp4
);
1319 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1320 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_tmp4
);
1321 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1322 gen_op_update3_cc(cpu_tmp4
);
1323 set_cc_op(s1
, CC_OP_SBBB
+ ot
);
1326 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1327 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1328 gen_op_update2_cc();
1329 set_cc_op(s1
, CC_OP_ADDB
+ ot
);
1332 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T
[0]);
1333 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1334 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1335 gen_op_update2_cc();
1336 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1340 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1341 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1342 gen_op_update1_cc();
1343 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1346 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1347 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1348 gen_op_update1_cc();
1349 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1352 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1353 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1354 gen_op_update1_cc();
1355 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1358 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
1359 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T
[0]);
1360 tcg_gen_sub_tl(cpu_cc_dst
, cpu_T
[0], cpu_T
[1]);
1361 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1366 /* if d == OR_TMP0, it means memory operand (address in A0) */
1367 static void gen_inc(DisasContext
*s1
, TCGMemOp ot
, int d
, int c
)
1370 gen_op_mov_v_reg(ot
, cpu_T
[0], d
);
1372 gen_op_ld_v(s1
, ot
, cpu_T
[0], cpu_A0
);
1374 gen_compute_eflags_c(s1
, cpu_cc_src
);
1376 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], 1);
1377 set_cc_op(s1
, CC_OP_INCB
+ ot
);
1379 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], -1);
1380 set_cc_op(s1
, CC_OP_DECB
+ ot
);
1382 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1383 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
1386 static void gen_shift_flags(DisasContext
*s
, TCGMemOp ot
, TCGv result
,
1387 TCGv shm1
, TCGv count
, bool is_right
)
1389 TCGv_i32 z32
, s32
, oldop
;
1392 /* Store the results into the CC variables. If we know that the
1393 variable must be dead, store unconditionally. Otherwise we'll
1394 need to not disrupt the current contents. */
1395 z_tl
= tcg_const_tl(0);
1396 if (cc_op_live
[s
->cc_op
] & USES_CC_DST
) {
1397 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_dst
, count
, z_tl
,
1398 result
, cpu_cc_dst
);
1400 tcg_gen_mov_tl(cpu_cc_dst
, result
);
1402 if (cc_op_live
[s
->cc_op
] & USES_CC_SRC
) {
1403 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_src
, count
, z_tl
,
1406 tcg_gen_mov_tl(cpu_cc_src
, shm1
);
1408 tcg_temp_free(z_tl
);
1410 /* Get the two potential CC_OP values into temporaries. */
1411 tcg_gen_movi_i32(cpu_tmp2_i32
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1412 if (s
->cc_op
== CC_OP_DYNAMIC
) {
1415 tcg_gen_movi_i32(cpu_tmp3_i32
, s
->cc_op
);
1416 oldop
= cpu_tmp3_i32
;
1419 /* Conditionally store the CC_OP value. */
1420 z32
= tcg_const_i32(0);
1421 s32
= tcg_temp_new_i32();
1422 tcg_gen_trunc_tl_i32(s32
, count
);
1423 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, s32
, z32
, cpu_tmp2_i32
, oldop
);
1424 tcg_temp_free_i32(z32
);
1425 tcg_temp_free_i32(s32
);
1427 /* The CC_OP value is no longer predictable. */
1428 set_cc_op(s
, CC_OP_DYNAMIC
);
1431 static void gen_shift_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1432 int is_right
, int is_arith
)
1434 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1437 if (op1
== OR_TMP0
) {
1438 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1440 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1443 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], mask
);
1444 tcg_gen_subi_tl(cpu_tmp0
, cpu_T
[1], 1);
1448 gen_exts(ot
, cpu_T
[0]);
1449 tcg_gen_sar_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1450 tcg_gen_sar_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1452 gen_extu(ot
, cpu_T
[0]);
1453 tcg_gen_shr_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1454 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1457 tcg_gen_shl_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1458 tcg_gen_shl_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1462 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1464 gen_shift_flags(s
, ot
, cpu_T
[0], cpu_tmp0
, cpu_T
[1], is_right
);
1467 static void gen_shift_rm_im(DisasContext
*s
, TCGMemOp ot
, int op1
, int op2
,
1468 int is_right
, int is_arith
)
1470 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1474 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1476 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1482 gen_exts(ot
, cpu_T
[0]);
1483 tcg_gen_sari_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1484 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], op2
);
1486 gen_extu(ot
, cpu_T
[0]);
1487 tcg_gen_shri_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1488 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], op2
);
1491 tcg_gen_shli_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1492 tcg_gen_shli_tl(cpu_T
[0], cpu_T
[0], op2
);
1497 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1499 /* update eflags if non zero shift */
1501 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
1502 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
1503 set_cc_op(s
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1507 static void gen_rot_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
, int is_right
)
1509 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1513 if (op1
== OR_TMP0
) {
1514 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1516 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1519 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], mask
);
1523 /* Replicate the 8-bit input so that a 32-bit rotate works. */
1524 tcg_gen_ext8u_tl(cpu_T
[0], cpu_T
[0]);
1525 tcg_gen_muli_tl(cpu_T
[0], cpu_T
[0], 0x01010101);
1528 /* Replicate the 16-bit input so that a 32-bit rotate works. */
1529 tcg_gen_deposit_tl(cpu_T
[0], cpu_T
[0], cpu_T
[0], 16, 16);
1532 #ifdef TARGET_X86_64
1534 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
1535 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
1537 tcg_gen_rotr_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1539 tcg_gen_rotl_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1541 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
1546 tcg_gen_rotr_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1548 tcg_gen_rotl_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1554 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1556 /* We'll need the flags computed into CC_SRC. */
1557 gen_compute_eflags(s
);
1559 /* The value that was "rotated out" is now present at the other end
1560 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1561 since we've computed the flags into CC_SRC, these variables are
1564 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T
[0], mask
- 1);
1565 tcg_gen_shri_tl(cpu_cc_dst
, cpu_T
[0], mask
);
1566 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1568 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T
[0], mask
);
1569 tcg_gen_andi_tl(cpu_cc_dst
, cpu_T
[0], 1);
1571 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1572 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1574 /* Now conditionally store the new CC_OP value. If the shift count
1575 is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1576 Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1577 exactly as we computed above. */
1578 t0
= tcg_const_i32(0);
1579 t1
= tcg_temp_new_i32();
1580 tcg_gen_trunc_tl_i32(t1
, cpu_T
[1]);
1581 tcg_gen_movi_i32(cpu_tmp2_i32
, CC_OP_ADCOX
);
1582 tcg_gen_movi_i32(cpu_tmp3_i32
, CC_OP_EFLAGS
);
1583 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, t1
, t0
,
1584 cpu_tmp2_i32
, cpu_tmp3_i32
);
1585 tcg_temp_free_i32(t0
);
1586 tcg_temp_free_i32(t1
);
1588 /* The CC_OP value is no longer predictable. */
1589 set_cc_op(s
, CC_OP_DYNAMIC
);
1592 static void gen_rot_rm_im(DisasContext
*s
, TCGMemOp ot
, int op1
, int op2
,
1595 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1599 if (op1
== OR_TMP0
) {
1600 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1602 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1608 #ifdef TARGET_X86_64
1610 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
1612 tcg_gen_rotri_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, op2
);
1614 tcg_gen_rotli_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, op2
);
1616 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
1621 tcg_gen_rotri_tl(cpu_T
[0], cpu_T
[0], op2
);
1623 tcg_gen_rotli_tl(cpu_T
[0], cpu_T
[0], op2
);
1634 shift
= mask
+ 1 - shift
;
1636 gen_extu(ot
, cpu_T
[0]);
1637 tcg_gen_shli_tl(cpu_tmp0
, cpu_T
[0], shift
);
1638 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], mask
+ 1 - shift
);
1639 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
1645 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1648 /* Compute the flags into CC_SRC. */
1649 gen_compute_eflags(s
);
1651 /* The value that was "rotated out" is now present at the other end
1652 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1653 since we've computed the flags into CC_SRC, these variables are
1656 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T
[0], mask
- 1);
1657 tcg_gen_shri_tl(cpu_cc_dst
, cpu_T
[0], mask
);
1658 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1660 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T
[0], mask
);
1661 tcg_gen_andi_tl(cpu_cc_dst
, cpu_T
[0], 1);
1663 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1664 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1665 set_cc_op(s
, CC_OP_ADCOX
);
1669 /* XXX: add faster immediate = 1 case */
1670 static void gen_rotc_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1673 gen_compute_eflags(s
);
1674 assert(s
->cc_op
== CC_OP_EFLAGS
);
1678 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1680 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1685 gen_helper_rcrb(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1688 gen_helper_rcrw(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1691 gen_helper_rcrl(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1693 #ifdef TARGET_X86_64
1695 gen_helper_rcrq(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1704 gen_helper_rclb(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1707 gen_helper_rclw(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1710 gen_helper_rcll(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1712 #ifdef TARGET_X86_64
1714 gen_helper_rclq(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1722 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1725 /* XXX: add faster immediate case */
1726 static void gen_shiftd_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1727 bool is_right
, TCGv count_in
)
1729 target_ulong mask
= (ot
== MO_64
? 63 : 31);
1733 if (op1
== OR_TMP0
) {
1734 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1736 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1739 count
= tcg_temp_new();
1740 tcg_gen_andi_tl(count
, count_in
, mask
);
1744 /* Note: we implement the Intel behaviour for shift count > 16.
1745 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A
1746 portion by constructing it as a 32-bit value. */
1748 tcg_gen_deposit_tl(cpu_tmp0
, cpu_T
[0], cpu_T
[1], 16, 16);
1749 tcg_gen_mov_tl(cpu_T
[1], cpu_T
[0]);
1750 tcg_gen_mov_tl(cpu_T
[0], cpu_tmp0
);
1752 tcg_gen_deposit_tl(cpu_T
[1], cpu_T
[0], cpu_T
[1], 16, 16);
1755 #ifdef TARGET_X86_64
1757 /* Concatenate the two 32-bit values and use a 64-bit shift. */
1758 tcg_gen_subi_tl(cpu_tmp0
, count
, 1);
1760 tcg_gen_concat_tl_i64(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1761 tcg_gen_shr_i64(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1762 tcg_gen_shr_i64(cpu_T
[0], cpu_T
[0], count
);
1764 tcg_gen_concat_tl_i64(cpu_T
[0], cpu_T
[1], cpu_T
[0]);
1765 tcg_gen_shl_i64(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1766 tcg_gen_shl_i64(cpu_T
[0], cpu_T
[0], count
);
1767 tcg_gen_shri_i64(cpu_tmp0
, cpu_tmp0
, 32);
1768 tcg_gen_shri_i64(cpu_T
[0], cpu_T
[0], 32);
1773 tcg_gen_subi_tl(cpu_tmp0
, count
, 1);
1775 tcg_gen_shr_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1777 tcg_gen_subfi_tl(cpu_tmp4
, mask
+ 1, count
);
1778 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], count
);
1779 tcg_gen_shl_tl(cpu_T
[1], cpu_T
[1], cpu_tmp4
);
1781 tcg_gen_shl_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1783 /* Only needed if count > 16, for Intel behaviour. */
1784 tcg_gen_subfi_tl(cpu_tmp4
, 33, count
);
1785 tcg_gen_shr_tl(cpu_tmp4
, cpu_T
[1], cpu_tmp4
);
1786 tcg_gen_or_tl(cpu_tmp0
, cpu_tmp0
, cpu_tmp4
);
1789 tcg_gen_subfi_tl(cpu_tmp4
, mask
+ 1, count
);
1790 tcg_gen_shl_tl(cpu_T
[0], cpu_T
[0], count
);
1791 tcg_gen_shr_tl(cpu_T
[1], cpu_T
[1], cpu_tmp4
);
1793 tcg_gen_movi_tl(cpu_tmp4
, 0);
1794 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_T
[1], count
, cpu_tmp4
,
1795 cpu_tmp4
, cpu_T
[1]);
1796 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1801 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1803 gen_shift_flags(s
, ot
, cpu_T
[0], cpu_tmp0
, count
, is_right
);
1804 tcg_temp_free(count
);
1807 static void gen_shift(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
, int s
)
1810 gen_op_mov_v_reg(ot
, cpu_T
[1], s
);
1813 gen_rot_rm_T1(s1
, ot
, d
, 0);
1816 gen_rot_rm_T1(s1
, ot
, d
, 1);
1820 gen_shift_rm_T1(s1
, ot
, d
, 0, 0);
1823 gen_shift_rm_T1(s1
, ot
, d
, 1, 0);
1826 gen_shift_rm_T1(s1
, ot
, d
, 1, 1);
1829 gen_rotc_rm_T1(s1
, ot
, d
, 0);
1832 gen_rotc_rm_T1(s1
, ot
, d
, 1);
1837 static void gen_shifti(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
, int c
)
1841 gen_rot_rm_im(s1
, ot
, d
, c
, 0);
1844 gen_rot_rm_im(s1
, ot
, d
, c
, 1);
1848 gen_shift_rm_im(s1
, ot
, d
, c
, 0, 0);
1851 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 0);
1854 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 1);
1857 /* currently not optimized */
1858 tcg_gen_movi_tl(cpu_T
[1], c
);
1859 gen_shift(s1
, op
, ot
, d
, OR_TMP1
);
1864 static void gen_lea_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
1871 int mod
, rm
, code
, override
, must_add_seg
;
1874 override
= s
->override
;
1875 must_add_seg
= s
->addseg
;
1878 mod
= (modrm
>> 6) & 3;
1891 code
= cpu_ldub_code(env
, s
->pc
++);
1892 scale
= (code
>> 6) & 3;
1893 index
= ((code
>> 3) & 7) | REX_X(s
);
1895 index
= -1; /* no index */
1903 if ((base
& 7) == 5) {
1905 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
1907 if (CODE64(s
) && !havesib
) {
1908 disp
+= s
->pc
+ s
->rip_offset
;
1915 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
1919 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
1924 /* For correct popl handling with esp. */
1925 if (base
== R_ESP
&& s
->popl_esp_hack
) {
1926 disp
+= s
->popl_esp_hack
;
1929 /* Compute the address, with a minimum number of TCG ops. */
1933 sum
= cpu_regs
[index
];
1935 tcg_gen_shli_tl(cpu_A0
, cpu_regs
[index
], scale
);
1939 tcg_gen_add_tl(cpu_A0
, sum
, cpu_regs
[base
]);
1942 } else if (base
>= 0) {
1943 sum
= cpu_regs
[base
];
1945 if (TCGV_IS_UNUSED(sum
)) {
1946 tcg_gen_movi_tl(cpu_A0
, disp
);
1948 tcg_gen_addi_tl(cpu_A0
, sum
, disp
);
1953 if (base
== R_EBP
|| base
== R_ESP
) {
1960 tcg_gen_ld_tl(cpu_tmp0
, cpu_env
,
1961 offsetof(CPUX86State
, segs
[override
].base
));
1963 if (s
->aflag
== MO_32
) {
1964 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
1966 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
1970 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
1973 if (s
->aflag
== MO_32
) {
1974 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
1982 disp
= cpu_lduw_code(env
, s
->pc
);
1984 tcg_gen_movi_tl(cpu_A0
, disp
);
1985 rm
= 0; /* avoid SS override */
1992 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
1996 disp
= (int16_t)cpu_lduw_code(env
, s
->pc
);
2004 tcg_gen_add_tl(cpu_A0
, cpu_regs
[R_EBX
], cpu_regs
[R_ESI
]);
2007 tcg_gen_add_tl(cpu_A0
, cpu_regs
[R_EBX
], cpu_regs
[R_EDI
]);
2010 tcg_gen_add_tl(cpu_A0
, cpu_regs
[R_EBP
], cpu_regs
[R_ESI
]);
2013 tcg_gen_add_tl(cpu_A0
, cpu_regs
[R_EBP
], cpu_regs
[R_EDI
]);
2016 sum
= cpu_regs
[R_ESI
];
2019 sum
= cpu_regs
[R_EDI
];
2022 sum
= cpu_regs
[R_EBP
];
2026 sum
= cpu_regs
[R_EBX
];
2029 tcg_gen_addi_tl(cpu_A0
, sum
, disp
);
2030 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2034 if (rm
== 2 || rm
== 3 || rm
== 6) {
2040 gen_op_addl_A0_seg(s
, override
);
2049 static void gen_nop_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2051 int mod
, rm
, base
, code
;
2053 mod
= (modrm
>> 6) & 3;
2064 code
= cpu_ldub_code(env
, s
->pc
++);
2106 /* used for LEA and MOV AX, mem */
2107 static void gen_add_A0_ds_seg(DisasContext
*s
)
2109 int override
, must_add_seg
;
2110 must_add_seg
= s
->addseg
;
2112 if (s
->override
>= 0) {
2113 override
= s
->override
;
2117 #ifdef TARGET_X86_64
2119 gen_op_addq_A0_seg(override
);
2123 gen_op_addl_A0_seg(s
, override
);
2128 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2130 static void gen_ldst_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2131 TCGMemOp ot
, int reg
, int is_store
)
2135 mod
= (modrm
>> 6) & 3;
2136 rm
= (modrm
& 7) | REX_B(s
);
2140 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
2141 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
2143 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
2145 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
2148 gen_lea_modrm(env
, s
, modrm
);
2151 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
2152 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
2154 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
2156 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
2161 static inline uint32_t insn_get(CPUX86State
*env
, DisasContext
*s
, TCGMemOp ot
)
2167 ret
= cpu_ldub_code(env
, s
->pc
);
2171 ret
= cpu_lduw_code(env
, s
->pc
);
2175 #ifdef TARGET_X86_64
2178 ret
= cpu_ldl_code(env
, s
->pc
);
2187 static inline int insn_const_size(TCGMemOp ot
)
2196 static inline void gen_goto_tb(DisasContext
*s
, int tb_num
, target_ulong eip
)
2198 TranslationBlock
*tb
;
2201 pc
= s
->cs_base
+ eip
;
2203 /* NOTE: we handle the case where the TB spans two pages here */
2204 if ((pc
& TARGET_PAGE_MASK
) == (tb
->pc
& TARGET_PAGE_MASK
) ||
2205 (pc
& TARGET_PAGE_MASK
) == ((s
->pc
- 1) & TARGET_PAGE_MASK
)) {
2206 /* jump to same page: we can use a direct jump */
2207 tcg_gen_goto_tb(tb_num
);
2209 tcg_gen_exit_tb((uintptr_t)tb
+ tb_num
);
2211 /* jump to another page: currently not optimized */
2217 static inline void gen_jcc(DisasContext
*s
, int b
,
2218 target_ulong val
, target_ulong next_eip
)
2223 l1
= gen_new_label();
2226 gen_goto_tb(s
, 0, next_eip
);
2229 gen_goto_tb(s
, 1, val
);
2230 s
->is_jmp
= DISAS_TB_JUMP
;
2232 l1
= gen_new_label();
2233 l2
= gen_new_label();
2236 gen_jmp_im(next_eip
);
2246 static void gen_cmovcc1(CPUX86State
*env
, DisasContext
*s
, TCGMemOp ot
, int b
,
2251 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
2253 cc
= gen_prepare_cc(s
, b
, cpu_T
[1]);
2254 if (cc
.mask
!= -1) {
2255 TCGv t0
= tcg_temp_new();
2256 tcg_gen_andi_tl(t0
, cc
.reg
, cc
.mask
);
2260 cc
.reg2
= tcg_const_tl(cc
.imm
);
2263 tcg_gen_movcond_tl(cc
.cond
, cpu_T
[0], cc
.reg
, cc
.reg2
,
2264 cpu_T
[0], cpu_regs
[reg
]);
2265 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
2267 if (cc
.mask
!= -1) {
2268 tcg_temp_free(cc
.reg
);
2271 tcg_temp_free(cc
.reg2
);
2275 static inline void gen_op_movl_T0_seg(int seg_reg
)
2277 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
,
2278 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2281 static inline void gen_op_movl_seg_T0_vm(int seg_reg
)
2283 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffff);
2284 tcg_gen_st32_tl(cpu_T
[0], cpu_env
,
2285 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2286 tcg_gen_shli_tl(cpu_T
[0], cpu_T
[0], 4);
2287 tcg_gen_st_tl(cpu_T
[0], cpu_env
,
2288 offsetof(CPUX86State
,segs
[seg_reg
].base
));
2291 /* move T0 to seg_reg and compute if the CPU state may change. Never
2292 call this function with seg_reg == R_CS */
2293 static void gen_movl_seg_T0(DisasContext
*s
, int seg_reg
)
2295 if (s
->pe
&& !s
->vm86
) {
2296 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
2297 gen_helper_load_seg(cpu_env
, tcg_const_i32(seg_reg
), cpu_tmp2_i32
);
2298 /* abort translation because the addseg value may change or
2299 because ss32 may change. For R_SS, translation must always
2300 stop as a special handling must be done to disable hardware
2301 interrupts for the next instruction */
2302 if (seg_reg
== R_SS
|| (s
->code32
&& seg_reg
< R_FS
))
2303 s
->is_jmp
= DISAS_TB_JUMP
;
2305 gen_op_movl_seg_T0_vm(seg_reg
);
2306 if (seg_reg
== R_SS
)
2307 s
->is_jmp
= DISAS_TB_JUMP
;
2311 static inline int svm_is_rep(int prefixes
)
2313 return ((prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) ? 8 : 0);
2317 gen_svm_check_intercept_param(DisasContext
*s
, target_ulong pc_start
,
2318 uint32_t type
, uint64_t param
)
2320 /* no SVM activated; fast case */
2321 if (likely(!(s
->flags
& HF_SVMI_MASK
)))
2323 gen_update_cc_op(s
);
2324 gen_jmp_im(pc_start
- s
->cs_base
);
2325 gen_helper_svm_check_intercept_param(cpu_env
, tcg_const_i32(type
),
2326 tcg_const_i64(param
));
2330 gen_svm_check_intercept(DisasContext
*s
, target_ulong pc_start
, uint64_t type
)
2332 gen_svm_check_intercept_param(s
, pc_start
, type
, 0);
2335 static inline void gen_stack_update(DisasContext
*s
, int addend
)
2337 #ifdef TARGET_X86_64
2339 gen_op_add_reg_im(MO_64
, R_ESP
, addend
);
2343 gen_op_add_reg_im(MO_32
, R_ESP
, addend
);
2345 gen_op_add_reg_im(MO_16
, R_ESP
, addend
);
2349 /* Generate a push. It depends on ss32, addseg and dflag. */
2350 static void gen_push_v(DisasContext
*s
, TCGv val
)
2352 TCGMemOp a_ot
, d_ot
= mo_pushpop(s
, s
->dflag
);
2353 int size
= 1 << d_ot
;
2354 TCGv new_esp
= cpu_A0
;
2356 tcg_gen_subi_tl(cpu_A0
, cpu_regs
[R_ESP
], size
);
2360 } else if (s
->ss32
) {
2364 tcg_gen_mov_tl(new_esp
, cpu_A0
);
2365 gen_op_addl_A0_seg(s
, R_SS
);
2367 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
2372 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2373 tcg_gen_mov_tl(new_esp
, cpu_A0
);
2374 gen_op_addl_A0_seg(s
, R_SS
);
2377 gen_op_st_v(s
, d_ot
, val
, cpu_A0
);
2378 gen_op_mov_reg_v(a_ot
, R_ESP
, new_esp
);
2381 /* two step pop is necessary for precise exceptions */
2382 static TCGMemOp
gen_pop_T0(DisasContext
*s
)
2384 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2388 addr
= cpu_regs
[R_ESP
];
2389 } else if (!s
->ss32
) {
2390 tcg_gen_ext16u_tl(cpu_A0
, cpu_regs
[R_ESP
]);
2391 gen_op_addl_A0_seg(s
, R_SS
);
2392 } else if (s
->addseg
) {
2393 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_ESP
]);
2394 gen_op_addl_A0_seg(s
, R_SS
);
2396 tcg_gen_ext32u_tl(cpu_A0
, cpu_regs
[R_ESP
]);
2399 gen_op_ld_v(s
, d_ot
, cpu_T
[0], addr
);
2403 static void gen_pop_update(DisasContext
*s
, TCGMemOp ot
)
2405 gen_stack_update(s
, 1 << ot
);
2408 static void gen_stack_A0(DisasContext
*s
)
2410 gen_op_movl_A0_reg(R_ESP
);
2412 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2413 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2415 gen_op_addl_A0_seg(s
, R_SS
);
2418 /* NOTE: wrap around in 16 bit not fully handled */
2419 static void gen_pusha(DisasContext
*s
)
2422 gen_op_movl_A0_reg(R_ESP
);
2423 gen_op_addl_A0_im(-8 << s
->dflag
);
2425 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2426 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2428 gen_op_addl_A0_seg(s
, R_SS
);
2429 for(i
= 0;i
< 8; i
++) {
2430 gen_op_mov_v_reg(MO_32
, cpu_T
[0], 7 - i
);
2431 gen_op_st_v(s
, s
->dflag
, cpu_T
[0], cpu_A0
);
2432 gen_op_addl_A0_im(1 << s
->dflag
);
2434 gen_op_mov_reg_v(MO_16
+ s
->ss32
, R_ESP
, cpu_T
[1]);
2437 /* NOTE: wrap around in 16 bit not fully handled */
2438 static void gen_popa(DisasContext
*s
)
2441 gen_op_movl_A0_reg(R_ESP
);
2443 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2444 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2445 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], 8 << s
->dflag
);
2447 gen_op_addl_A0_seg(s
, R_SS
);
2448 for(i
= 0;i
< 8; i
++) {
2449 /* ESP is not reloaded */
2451 gen_op_ld_v(s
, s
->dflag
, cpu_T
[0], cpu_A0
);
2452 gen_op_mov_reg_v(s
->dflag
, 7 - i
, cpu_T
[0]);
2454 gen_op_addl_A0_im(1 << s
->dflag
);
2456 gen_op_mov_reg_v(MO_16
+ s
->ss32
, R_ESP
, cpu_T
[1]);
2459 static void gen_enter(DisasContext
*s
, int esp_addend
, int level
)
2461 TCGMemOp ot
= mo_pushpop(s
, s
->dflag
);
2462 int opsize
= 1 << ot
;
2465 #ifdef TARGET_X86_64
2467 gen_op_movl_A0_reg(R_ESP
);
2468 gen_op_addq_A0_im(-opsize
);
2469 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2472 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EBP
);
2473 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
2475 /* XXX: must save state */
2476 gen_helper_enter64_level(cpu_env
, tcg_const_i32(level
),
2477 tcg_const_i32((ot
== MO_64
)),
2480 gen_op_mov_reg_v(ot
, R_EBP
, cpu_T
[1]);
2481 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], -esp_addend
+ (-opsize
* level
));
2482 gen_op_mov_reg_v(MO_64
, R_ESP
, cpu_T
[1]);
2486 gen_op_movl_A0_reg(R_ESP
);
2487 gen_op_addl_A0_im(-opsize
);
2489 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2490 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2492 gen_op_addl_A0_seg(s
, R_SS
);
2494 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EBP
);
2495 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
2497 /* XXX: must save state */
2498 gen_helper_enter_level(cpu_env
, tcg_const_i32(level
),
2499 tcg_const_i32(s
->dflag
- 1),
2502 gen_op_mov_reg_v(ot
, R_EBP
, cpu_T
[1]);
2503 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], -esp_addend
+ (-opsize
* level
));
2504 gen_op_mov_reg_v(MO_16
+ s
->ss32
, R_ESP
, cpu_T
[1]);
2508 static void gen_exception(DisasContext
*s
, int trapno
, target_ulong cur_eip
)
2510 gen_update_cc_op(s
);
2511 gen_jmp_im(cur_eip
);
2512 gen_helper_raise_exception(cpu_env
, tcg_const_i32(trapno
));
2513 s
->is_jmp
= DISAS_TB_JUMP
;
2516 /* an interrupt is different from an exception because of the
2518 static void gen_interrupt(DisasContext
*s
, int intno
,
2519 target_ulong cur_eip
, target_ulong next_eip
)
2521 gen_update_cc_op(s
);
2522 gen_jmp_im(cur_eip
);
2523 gen_helper_raise_interrupt(cpu_env
, tcg_const_i32(intno
),
2524 tcg_const_i32(next_eip
- cur_eip
));
2525 s
->is_jmp
= DISAS_TB_JUMP
;
2528 static void gen_debug(DisasContext
*s
, target_ulong cur_eip
)
2530 gen_update_cc_op(s
);
2531 gen_jmp_im(cur_eip
);
2532 gen_helper_debug(cpu_env
);
2533 s
->is_jmp
= DISAS_TB_JUMP
;
2536 /* generate a generic end of block. Trace exception is also generated
2538 static void gen_eob(DisasContext
*s
)
2540 gen_update_cc_op(s
);
2541 if (s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
) {
2542 gen_helper_reset_inhibit_irq(cpu_env
);
2544 if (s
->tb
->flags
& HF_RF_MASK
) {
2545 gen_helper_reset_rf(cpu_env
);
2547 if (s
->singlestep_enabled
) {
2548 gen_helper_debug(cpu_env
);
2550 gen_helper_single_step(cpu_env
);
2554 s
->is_jmp
= DISAS_TB_JUMP
;
2557 /* generate a jump to eip. No segment change must happen before as a
2558 direct call to the next block may occur */
2559 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
)
2561 gen_update_cc_op(s
);
2562 set_cc_op(s
, CC_OP_DYNAMIC
);
2564 gen_goto_tb(s
, tb_num
, eip
);
2565 s
->is_jmp
= DISAS_TB_JUMP
;
2572 static void gen_jmp(DisasContext
*s
, target_ulong eip
)
2574 gen_jmp_tb(s
, eip
, 0);
2577 static inline void gen_ldq_env_A0(DisasContext
*s
, int offset
)
2579 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
2580 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2583 static inline void gen_stq_env_A0(DisasContext
*s
, int offset
)
2585 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2586 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
2589 static inline void gen_ldo_env_A0(DisasContext
*s
, int offset
)
2591 int mem_index
= s
->mem_index
;
2592 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, mem_index
, MO_LEQ
);
2593 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(0)));
2594 tcg_gen_addi_tl(cpu_tmp0
, cpu_A0
, 8);
2595 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
, MO_LEQ
);
2596 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(1)));
2599 static inline void gen_sto_env_A0(DisasContext
*s
, int offset
)
2601 int mem_index
= s
->mem_index
;
2602 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(0)));
2603 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, mem_index
, MO_LEQ
);
2604 tcg_gen_addi_tl(cpu_tmp0
, cpu_A0
, 8);
2605 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(1)));
2606 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
, MO_LEQ
);
2609 static inline void gen_op_movo(int d_offset
, int s_offset
)
2611 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
+ offsetof(XMMReg
, XMM_Q(0)));
2612 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
+ offsetof(XMMReg
, XMM_Q(0)));
2613 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
+ offsetof(XMMReg
, XMM_Q(1)));
2614 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
+ offsetof(XMMReg
, XMM_Q(1)));
2617 static inline void gen_op_movq(int d_offset
, int s_offset
)
2619 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
);
2620 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2623 static inline void gen_op_movl(int d_offset
, int s_offset
)
2625 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
, s_offset
);
2626 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, d_offset
);
2629 static inline void gen_op_movq_env_0(int d_offset
)
2631 tcg_gen_movi_i64(cpu_tmp1_i64
, 0);
2632 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2635 typedef void (*SSEFunc_i_ep
)(TCGv_i32 val
, TCGv_ptr env
, TCGv_ptr reg
);
2636 typedef void (*SSEFunc_l_ep
)(TCGv_i64 val
, TCGv_ptr env
, TCGv_ptr reg
);
2637 typedef void (*SSEFunc_0_epi
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i32 val
);
2638 typedef void (*SSEFunc_0_epl
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i64 val
);
2639 typedef void (*SSEFunc_0_epp
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
);
2640 typedef void (*SSEFunc_0_eppi
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2642 typedef void (*SSEFunc_0_ppi
)(TCGv_ptr reg_a
, TCGv_ptr reg_b
, TCGv_i32 val
);
2643 typedef void (*SSEFunc_0_eppt
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2646 #define SSE_SPECIAL ((void *)1)
2647 #define SSE_DUMMY ((void *)2)
2649 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2650 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2651 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2653 static const SSEFunc_0_epp sse_op_table1
[256][4] = {
2654 /* 3DNow! extensions */
2655 [0x0e] = { SSE_DUMMY
}, /* femms */
2656 [0x0f] = { SSE_DUMMY
}, /* pf... */
2657 /* pure SSE operations */
2658 [0x10] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2659 [0x11] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2660 [0x12] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd, movsldup, movddup */
2661 [0x13] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd */
2662 [0x14] = { gen_helper_punpckldq_xmm
, gen_helper_punpcklqdq_xmm
},
2663 [0x15] = { gen_helper_punpckhdq_xmm
, gen_helper_punpckhqdq_xmm
},
2664 [0x16] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd, movshdup */
2665 [0x17] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd */
2667 [0x28] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2668 [0x29] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2669 [0x2a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2670 [0x2b] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movntps, movntpd, movntss, movntsd */
2671 [0x2c] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2672 [0x2d] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2673 [0x2e] = { gen_helper_ucomiss
, gen_helper_ucomisd
},
2674 [0x2f] = { gen_helper_comiss
, gen_helper_comisd
},
2675 [0x50] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movmskps, movmskpd */
2676 [0x51] = SSE_FOP(sqrt
),
2677 [0x52] = { gen_helper_rsqrtps
, NULL
, gen_helper_rsqrtss
, NULL
},
2678 [0x53] = { gen_helper_rcpps
, NULL
, gen_helper_rcpss
, NULL
},
2679 [0x54] = { gen_helper_pand_xmm
, gen_helper_pand_xmm
}, /* andps, andpd */
2680 [0x55] = { gen_helper_pandn_xmm
, gen_helper_pandn_xmm
}, /* andnps, andnpd */
2681 [0x56] = { gen_helper_por_xmm
, gen_helper_por_xmm
}, /* orps, orpd */
2682 [0x57] = { gen_helper_pxor_xmm
, gen_helper_pxor_xmm
}, /* xorps, xorpd */
2683 [0x58] = SSE_FOP(add
),
2684 [0x59] = SSE_FOP(mul
),
2685 [0x5a] = { gen_helper_cvtps2pd
, gen_helper_cvtpd2ps
,
2686 gen_helper_cvtss2sd
, gen_helper_cvtsd2ss
},
2687 [0x5b] = { gen_helper_cvtdq2ps
, gen_helper_cvtps2dq
, gen_helper_cvttps2dq
},
2688 [0x5c] = SSE_FOP(sub
),
2689 [0x5d] = SSE_FOP(min
),
2690 [0x5e] = SSE_FOP(div
),
2691 [0x5f] = SSE_FOP(max
),
2693 [0xc2] = SSE_FOP(cmpeq
),
2694 [0xc6] = { (SSEFunc_0_epp
)gen_helper_shufps
,
2695 (SSEFunc_0_epp
)gen_helper_shufpd
}, /* XXX: casts */
2697 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */
2698 [0x38] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2699 [0x3a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2701 /* MMX ops and their SSE extensions */
2702 [0x60] = MMX_OP2(punpcklbw
),
2703 [0x61] = MMX_OP2(punpcklwd
),
2704 [0x62] = MMX_OP2(punpckldq
),
2705 [0x63] = MMX_OP2(packsswb
),
2706 [0x64] = MMX_OP2(pcmpgtb
),
2707 [0x65] = MMX_OP2(pcmpgtw
),
2708 [0x66] = MMX_OP2(pcmpgtl
),
2709 [0x67] = MMX_OP2(packuswb
),
2710 [0x68] = MMX_OP2(punpckhbw
),
2711 [0x69] = MMX_OP2(punpckhwd
),
2712 [0x6a] = MMX_OP2(punpckhdq
),
2713 [0x6b] = MMX_OP2(packssdw
),
2714 [0x6c] = { NULL
, gen_helper_punpcklqdq_xmm
},
2715 [0x6d] = { NULL
, gen_helper_punpckhqdq_xmm
},
2716 [0x6e] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movd mm, ea */
2717 [0x6f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, , movqdu */
2718 [0x70] = { (SSEFunc_0_epp
)gen_helper_pshufw_mmx
,
2719 (SSEFunc_0_epp
)gen_helper_pshufd_xmm
,
2720 (SSEFunc_0_epp
)gen_helper_pshufhw_xmm
,
2721 (SSEFunc_0_epp
)gen_helper_pshuflw_xmm
}, /* XXX: casts */
2722 [0x71] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftw */
2723 [0x72] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftd */
2724 [0x73] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftq */
2725 [0x74] = MMX_OP2(pcmpeqb
),
2726 [0x75] = MMX_OP2(pcmpeqw
),
2727 [0x76] = MMX_OP2(pcmpeql
),
2728 [0x77] = { SSE_DUMMY
}, /* emms */
2729 [0x78] = { NULL
, SSE_SPECIAL
, NULL
, SSE_SPECIAL
}, /* extrq_i, insertq_i */
2730 [0x79] = { NULL
, gen_helper_extrq_r
, NULL
, gen_helper_insertq_r
},
2731 [0x7c] = { NULL
, gen_helper_haddpd
, NULL
, gen_helper_haddps
},
2732 [0x7d] = { NULL
, gen_helper_hsubpd
, NULL
, gen_helper_hsubps
},
2733 [0x7e] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movd, movd, , movq */
2734 [0x7f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, movdqu */
2735 [0xc4] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pinsrw */
2736 [0xc5] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pextrw */
2737 [0xd0] = { NULL
, gen_helper_addsubpd
, NULL
, gen_helper_addsubps
},
2738 [0xd1] = MMX_OP2(psrlw
),
2739 [0xd2] = MMX_OP2(psrld
),
2740 [0xd3] = MMX_OP2(psrlq
),
2741 [0xd4] = MMX_OP2(paddq
),
2742 [0xd5] = MMX_OP2(pmullw
),
2743 [0xd6] = { NULL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2744 [0xd7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pmovmskb */
2745 [0xd8] = MMX_OP2(psubusb
),
2746 [0xd9] = MMX_OP2(psubusw
),
2747 [0xda] = MMX_OP2(pminub
),
2748 [0xdb] = MMX_OP2(pand
),
2749 [0xdc] = MMX_OP2(paddusb
),
2750 [0xdd] = MMX_OP2(paddusw
),
2751 [0xde] = MMX_OP2(pmaxub
),
2752 [0xdf] = MMX_OP2(pandn
),
2753 [0xe0] = MMX_OP2(pavgb
),
2754 [0xe1] = MMX_OP2(psraw
),
2755 [0xe2] = MMX_OP2(psrad
),
2756 [0xe3] = MMX_OP2(pavgw
),
2757 [0xe4] = MMX_OP2(pmulhuw
),
2758 [0xe5] = MMX_OP2(pmulhw
),
2759 [0xe6] = { NULL
, gen_helper_cvttpd2dq
, gen_helper_cvtdq2pd
, gen_helper_cvtpd2dq
},
2760 [0xe7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movntq, movntq */
2761 [0xe8] = MMX_OP2(psubsb
),
2762 [0xe9] = MMX_OP2(psubsw
),
2763 [0xea] = MMX_OP2(pminsw
),
2764 [0xeb] = MMX_OP2(por
),
2765 [0xec] = MMX_OP2(paddsb
),
2766 [0xed] = MMX_OP2(paddsw
),
2767 [0xee] = MMX_OP2(pmaxsw
),
2768 [0xef] = MMX_OP2(pxor
),
2769 [0xf0] = { NULL
, NULL
, NULL
, SSE_SPECIAL
}, /* lddqu */
2770 [0xf1] = MMX_OP2(psllw
),
2771 [0xf2] = MMX_OP2(pslld
),
2772 [0xf3] = MMX_OP2(psllq
),
2773 [0xf4] = MMX_OP2(pmuludq
),
2774 [0xf5] = MMX_OP2(pmaddwd
),
2775 [0xf6] = MMX_OP2(psadbw
),
2776 [0xf7] = { (SSEFunc_0_epp
)gen_helper_maskmov_mmx
,
2777 (SSEFunc_0_epp
)gen_helper_maskmov_xmm
}, /* XXX: casts */
2778 [0xf8] = MMX_OP2(psubb
),
2779 [0xf9] = MMX_OP2(psubw
),
2780 [0xfa] = MMX_OP2(psubl
),
2781 [0xfb] = MMX_OP2(psubq
),
2782 [0xfc] = MMX_OP2(paddb
),
2783 [0xfd] = MMX_OP2(paddw
),
2784 [0xfe] = MMX_OP2(paddl
),
2787 static const SSEFunc_0_epp sse_op_table2
[3 * 8][2] = {
2788 [0 + 2] = MMX_OP2(psrlw
),
2789 [0 + 4] = MMX_OP2(psraw
),
2790 [0 + 6] = MMX_OP2(psllw
),
2791 [8 + 2] = MMX_OP2(psrld
),
2792 [8 + 4] = MMX_OP2(psrad
),
2793 [8 + 6] = MMX_OP2(pslld
),
2794 [16 + 2] = MMX_OP2(psrlq
),
2795 [16 + 3] = { NULL
, gen_helper_psrldq_xmm
},
2796 [16 + 6] = MMX_OP2(psllq
),
2797 [16 + 7] = { NULL
, gen_helper_pslldq_xmm
},
2800 static const SSEFunc_0_epi sse_op_table3ai
[] = {
2801 gen_helper_cvtsi2ss
,
2805 #ifdef TARGET_X86_64
2806 static const SSEFunc_0_epl sse_op_table3aq
[] = {
2807 gen_helper_cvtsq2ss
,
2812 static const SSEFunc_i_ep sse_op_table3bi
[] = {
2813 gen_helper_cvttss2si
,
2814 gen_helper_cvtss2si
,
2815 gen_helper_cvttsd2si
,
2819 #ifdef TARGET_X86_64
2820 static const SSEFunc_l_ep sse_op_table3bq
[] = {
2821 gen_helper_cvttss2sq
,
2822 gen_helper_cvtss2sq
,
2823 gen_helper_cvttsd2sq
,
2828 static const SSEFunc_0_epp sse_op_table4
[8][4] = {
2839 static const SSEFunc_0_epp sse_op_table5
[256] = {
2840 [0x0c] = gen_helper_pi2fw
,
2841 [0x0d] = gen_helper_pi2fd
,
2842 [0x1c] = gen_helper_pf2iw
,
2843 [0x1d] = gen_helper_pf2id
,
2844 [0x8a] = gen_helper_pfnacc
,
2845 [0x8e] = gen_helper_pfpnacc
,
2846 [0x90] = gen_helper_pfcmpge
,
2847 [0x94] = gen_helper_pfmin
,
2848 [0x96] = gen_helper_pfrcp
,
2849 [0x97] = gen_helper_pfrsqrt
,
2850 [0x9a] = gen_helper_pfsub
,
2851 [0x9e] = gen_helper_pfadd
,
2852 [0xa0] = gen_helper_pfcmpgt
,
2853 [0xa4] = gen_helper_pfmax
,
2854 [0xa6] = gen_helper_movq
, /* pfrcpit1; no need to actually increase precision */
2855 [0xa7] = gen_helper_movq
, /* pfrsqit1 */
2856 [0xaa] = gen_helper_pfsubr
,
2857 [0xae] = gen_helper_pfacc
,
2858 [0xb0] = gen_helper_pfcmpeq
,
2859 [0xb4] = gen_helper_pfmul
,
2860 [0xb6] = gen_helper_movq
, /* pfrcpit2 */
2861 [0xb7] = gen_helper_pmulhrw_mmx
,
2862 [0xbb] = gen_helper_pswapd
,
2863 [0xbf] = gen_helper_pavgb_mmx
/* pavgusb */
2866 struct SSEOpHelper_epp
{
2867 SSEFunc_0_epp op
[2];
2871 struct SSEOpHelper_eppi
{
2872 SSEFunc_0_eppi op
[2];
2876 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
2877 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
2878 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
2879 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
2880 #define PCLMULQDQ_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, \
2881 CPUID_EXT_PCLMULQDQ }
2882 #define AESNI_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_AES }
2884 static const struct SSEOpHelper_epp sse_op_table6
[256] = {
2885 [0x00] = SSSE3_OP(pshufb
),
2886 [0x01] = SSSE3_OP(phaddw
),
2887 [0x02] = SSSE3_OP(phaddd
),
2888 [0x03] = SSSE3_OP(phaddsw
),
2889 [0x04] = SSSE3_OP(pmaddubsw
),
2890 [0x05] = SSSE3_OP(phsubw
),
2891 [0x06] = SSSE3_OP(phsubd
),
2892 [0x07] = SSSE3_OP(phsubsw
),
2893 [0x08] = SSSE3_OP(psignb
),
2894 [0x09] = SSSE3_OP(psignw
),
2895 [0x0a] = SSSE3_OP(psignd
),
2896 [0x0b] = SSSE3_OP(pmulhrsw
),
2897 [0x10] = SSE41_OP(pblendvb
),
2898 [0x14] = SSE41_OP(blendvps
),
2899 [0x15] = SSE41_OP(blendvpd
),
2900 [0x17] = SSE41_OP(ptest
),
2901 [0x1c] = SSSE3_OP(pabsb
),
2902 [0x1d] = SSSE3_OP(pabsw
),
2903 [0x1e] = SSSE3_OP(pabsd
),
2904 [0x20] = SSE41_OP(pmovsxbw
),
2905 [0x21] = SSE41_OP(pmovsxbd
),
2906 [0x22] = SSE41_OP(pmovsxbq
),
2907 [0x23] = SSE41_OP(pmovsxwd
),
2908 [0x24] = SSE41_OP(pmovsxwq
),
2909 [0x25] = SSE41_OP(pmovsxdq
),
2910 [0x28] = SSE41_OP(pmuldq
),
2911 [0x29] = SSE41_OP(pcmpeqq
),
2912 [0x2a] = SSE41_SPECIAL
, /* movntqda */
2913 [0x2b] = SSE41_OP(packusdw
),
2914 [0x30] = SSE41_OP(pmovzxbw
),
2915 [0x31] = SSE41_OP(pmovzxbd
),
2916 [0x32] = SSE41_OP(pmovzxbq
),
2917 [0x33] = SSE41_OP(pmovzxwd
),
2918 [0x34] = SSE41_OP(pmovzxwq
),
2919 [0x35] = SSE41_OP(pmovzxdq
),
2920 [0x37] = SSE42_OP(pcmpgtq
),
2921 [0x38] = SSE41_OP(pminsb
),
2922 [0x39] = SSE41_OP(pminsd
),
2923 [0x3a] = SSE41_OP(pminuw
),
2924 [0x3b] = SSE41_OP(pminud
),
2925 [0x3c] = SSE41_OP(pmaxsb
),
2926 [0x3d] = SSE41_OP(pmaxsd
),
2927 [0x3e] = SSE41_OP(pmaxuw
),
2928 [0x3f] = SSE41_OP(pmaxud
),
2929 [0x40] = SSE41_OP(pmulld
),
2930 [0x41] = SSE41_OP(phminposuw
),
2931 [0xdb] = AESNI_OP(aesimc
),
2932 [0xdc] = AESNI_OP(aesenc
),
2933 [0xdd] = AESNI_OP(aesenclast
),
2934 [0xde] = AESNI_OP(aesdec
),
2935 [0xdf] = AESNI_OP(aesdeclast
),
2938 static const struct SSEOpHelper_eppi sse_op_table7
[256] = {
2939 [0x08] = SSE41_OP(roundps
),
2940 [0x09] = SSE41_OP(roundpd
),
2941 [0x0a] = SSE41_OP(roundss
),
2942 [0x0b] = SSE41_OP(roundsd
),
2943 [0x0c] = SSE41_OP(blendps
),
2944 [0x0d] = SSE41_OP(blendpd
),
2945 [0x0e] = SSE41_OP(pblendw
),
2946 [0x0f] = SSSE3_OP(palignr
),
2947 [0x14] = SSE41_SPECIAL
, /* pextrb */
2948 [0x15] = SSE41_SPECIAL
, /* pextrw */
2949 [0x16] = SSE41_SPECIAL
, /* pextrd/pextrq */
2950 [0x17] = SSE41_SPECIAL
, /* extractps */
2951 [0x20] = SSE41_SPECIAL
, /* pinsrb */
2952 [0x21] = SSE41_SPECIAL
, /* insertps */
2953 [0x22] = SSE41_SPECIAL
, /* pinsrd/pinsrq */
2954 [0x40] = SSE41_OP(dpps
),
2955 [0x41] = SSE41_OP(dppd
),
2956 [0x42] = SSE41_OP(mpsadbw
),
2957 [0x44] = PCLMULQDQ_OP(pclmulqdq
),
2958 [0x60] = SSE42_OP(pcmpestrm
),
2959 [0x61] = SSE42_OP(pcmpestri
),
2960 [0x62] = SSE42_OP(pcmpistrm
),
2961 [0x63] = SSE42_OP(pcmpistri
),
2962 [0xdf] = AESNI_OP(aeskeygenassist
),
2965 static void gen_sse(CPUX86State
*env
, DisasContext
*s
, int b
,
2966 target_ulong pc_start
, int rex_r
)
2968 int b1
, op1_offset
, op2_offset
, is_xmm
, val
;
2969 int modrm
, mod
, rm
, reg
;
2970 SSEFunc_0_epp sse_fn_epp
;
2971 SSEFunc_0_eppi sse_fn_eppi
;
2972 SSEFunc_0_ppi sse_fn_ppi
;
2973 SSEFunc_0_eppt sse_fn_eppt
;
2977 if (s
->prefix
& PREFIX_DATA
)
2979 else if (s
->prefix
& PREFIX_REPZ
)
2981 else if (s
->prefix
& PREFIX_REPNZ
)
2985 sse_fn_epp
= sse_op_table1
[b
][b1
];
2989 if ((b
<= 0x5f && b
>= 0x10) || b
== 0xc6 || b
== 0xc2) {
2999 /* simple MMX/SSE operation */
3000 if (s
->flags
& HF_TS_MASK
) {
3001 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
3004 if (s
->flags
& HF_EM_MASK
) {
3006 gen_exception(s
, EXCP06_ILLOP
, pc_start
- s
->cs_base
);
3009 if (is_xmm
&& !(s
->flags
& HF_OSFXSR_MASK
))
3010 if ((b
!= 0x38 && b
!= 0x3a) || (s
->prefix
& PREFIX_DATA
))
3013 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
))
3016 gen_helper_emms(cpu_env
);
3021 gen_helper_emms(cpu_env
);
3024 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3025 the static cpu state) */
3027 gen_helper_enter_mmx(cpu_env
);
3030 modrm
= cpu_ldub_code(env
, s
->pc
++);
3031 reg
= ((modrm
>> 3) & 7);
3034 mod
= (modrm
>> 6) & 3;
3035 if (sse_fn_epp
== SSE_SPECIAL
) {
3038 case 0x0e7: /* movntq */
3041 gen_lea_modrm(env
, s
, modrm
);
3042 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3044 case 0x1e7: /* movntdq */
3045 case 0x02b: /* movntps */
3046 case 0x12b: /* movntps */
3049 gen_lea_modrm(env
, s
, modrm
);
3050 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3052 case 0x3f0: /* lddqu */
3055 gen_lea_modrm(env
, s
, modrm
);
3056 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3058 case 0x22b: /* movntss */
3059 case 0x32b: /* movntsd */
3062 gen_lea_modrm(env
, s
, modrm
);
3064 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3065 xmm_regs
[reg
].XMM_Q(0)));
3067 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
3068 xmm_regs
[reg
].XMM_L(0)));
3069 gen_op_st_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
3072 case 0x6e: /* movd mm, ea */
3073 #ifdef TARGET_X86_64
3074 if (s
->dflag
== MO_64
) {
3075 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3076 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3080 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3081 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3082 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3083 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3084 gen_helper_movl_mm_T0_mmx(cpu_ptr0
, cpu_tmp2_i32
);
3087 case 0x16e: /* movd xmm, ea */
3088 #ifdef TARGET_X86_64
3089 if (s
->dflag
== MO_64
) {
3090 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3091 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3092 offsetof(CPUX86State
,xmm_regs
[reg
]));
3093 gen_helper_movq_mm_T0_xmm(cpu_ptr0
, cpu_T
[0]);
3097 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3098 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3099 offsetof(CPUX86State
,xmm_regs
[reg
]));
3100 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3101 gen_helper_movl_mm_T0_xmm(cpu_ptr0
, cpu_tmp2_i32
);
3104 case 0x6f: /* movq mm, ea */
3106 gen_lea_modrm(env
, s
, modrm
);
3107 gen_ldq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3110 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
3111 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3112 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
3113 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3116 case 0x010: /* movups */
3117 case 0x110: /* movupd */
3118 case 0x028: /* movaps */
3119 case 0x128: /* movapd */
3120 case 0x16f: /* movdqa xmm, ea */
3121 case 0x26f: /* movdqu xmm, ea */
3123 gen_lea_modrm(env
, s
, modrm
);
3124 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3126 rm
= (modrm
& 7) | REX_B(s
);
3127 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[reg
]),
3128 offsetof(CPUX86State
,xmm_regs
[rm
]));
3131 case 0x210: /* movss xmm, ea */
3133 gen_lea_modrm(env
, s
, modrm
);
3134 gen_op_ld_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
3135 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3136 tcg_gen_movi_tl(cpu_T
[0], 0);
3137 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(1)));
3138 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)));
3139 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)));
3141 rm
= (modrm
& 7) | REX_B(s
);
3142 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)),
3143 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(0)));
3146 case 0x310: /* movsd xmm, ea */
3148 gen_lea_modrm(env
, s
, modrm
);
3149 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3150 xmm_regs
[reg
].XMM_Q(0)));
3151 tcg_gen_movi_tl(cpu_T
[0], 0);
3152 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)));
3153 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)));
3155 rm
= (modrm
& 7) | REX_B(s
);
3156 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3157 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3160 case 0x012: /* movlps */
3161 case 0x112: /* movlpd */
3163 gen_lea_modrm(env
, s
, modrm
);
3164 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3165 xmm_regs
[reg
].XMM_Q(0)));
3168 rm
= (modrm
& 7) | REX_B(s
);
3169 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3170 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(1)));
3173 case 0x212: /* movsldup */
3175 gen_lea_modrm(env
, s
, modrm
);
3176 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3178 rm
= (modrm
& 7) | REX_B(s
);
3179 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)),
3180 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(0)));
3181 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)),
3182 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(2)));
3184 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(1)),
3185 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3186 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)),
3187 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)));
3189 case 0x312: /* movddup */
3191 gen_lea_modrm(env
, s
, modrm
);
3192 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3193 xmm_regs
[reg
].XMM_Q(0)));
3195 rm
= (modrm
& 7) | REX_B(s
);
3196 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3197 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3199 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)),
3200 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3202 case 0x016: /* movhps */
3203 case 0x116: /* movhpd */
3205 gen_lea_modrm(env
, s
, modrm
);
3206 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3207 xmm_regs
[reg
].XMM_Q(1)));
3210 rm
= (modrm
& 7) | REX_B(s
);
3211 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)),
3212 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3215 case 0x216: /* movshdup */
3217 gen_lea_modrm(env
, s
, modrm
);
3218 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3220 rm
= (modrm
& 7) | REX_B(s
);
3221 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(1)),
3222 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(1)));
3223 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)),
3224 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(3)));
3226 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)),
3227 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(1)));
3228 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)),
3229 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)));
3234 int bit_index
, field_length
;
3236 if (b1
== 1 && reg
!= 0)
3238 field_length
= cpu_ldub_code(env
, s
->pc
++) & 0x3F;
3239 bit_index
= cpu_ldub_code(env
, s
->pc
++) & 0x3F;
3240 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3241 offsetof(CPUX86State
,xmm_regs
[reg
]));
3243 gen_helper_extrq_i(cpu_env
, cpu_ptr0
,
3244 tcg_const_i32(bit_index
),
3245 tcg_const_i32(field_length
));
3247 gen_helper_insertq_i(cpu_env
, cpu_ptr0
,
3248 tcg_const_i32(bit_index
),
3249 tcg_const_i32(field_length
));
3252 case 0x7e: /* movd ea, mm */
3253 #ifdef TARGET_X86_64
3254 if (s
->dflag
== MO_64
) {
3255 tcg_gen_ld_i64(cpu_T
[0], cpu_env
,
3256 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3257 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3261 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
,
3262 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_L(0)));
3263 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3266 case 0x17e: /* movd ea, xmm */
3267 #ifdef TARGET_X86_64
3268 if (s
->dflag
== MO_64
) {
3269 tcg_gen_ld_i64(cpu_T
[0], cpu_env
,
3270 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3271 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3275 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
,
3276 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3277 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3280 case 0x27e: /* movq xmm, ea */
3282 gen_lea_modrm(env
, s
, modrm
);
3283 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3284 xmm_regs
[reg
].XMM_Q(0)));
3286 rm
= (modrm
& 7) | REX_B(s
);
3287 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3288 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3290 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)));
3292 case 0x7f: /* movq ea, mm */
3294 gen_lea_modrm(env
, s
, modrm
);
3295 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3298 gen_op_movq(offsetof(CPUX86State
,fpregs
[rm
].mmx
),
3299 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3302 case 0x011: /* movups */
3303 case 0x111: /* movupd */
3304 case 0x029: /* movaps */
3305 case 0x129: /* movapd */
3306 case 0x17f: /* movdqa ea, xmm */
3307 case 0x27f: /* movdqu ea, xmm */
3309 gen_lea_modrm(env
, s
, modrm
);
3310 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3312 rm
= (modrm
& 7) | REX_B(s
);
3313 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[rm
]),
3314 offsetof(CPUX86State
,xmm_regs
[reg
]));
3317 case 0x211: /* movss ea, xmm */
3319 gen_lea_modrm(env
, s
, modrm
);
3320 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3321 gen_op_st_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
3323 rm
= (modrm
& 7) | REX_B(s
);
3324 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(0)),
3325 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3328 case 0x311: /* movsd ea, xmm */
3330 gen_lea_modrm(env
, s
, modrm
);
3331 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3332 xmm_regs
[reg
].XMM_Q(0)));
3334 rm
= (modrm
& 7) | REX_B(s
);
3335 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)),
3336 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3339 case 0x013: /* movlps */
3340 case 0x113: /* movlpd */
3342 gen_lea_modrm(env
, s
, modrm
);
3343 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3344 xmm_regs
[reg
].XMM_Q(0)));
3349 case 0x017: /* movhps */
3350 case 0x117: /* movhpd */
3352 gen_lea_modrm(env
, s
, modrm
);
3353 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3354 xmm_regs
[reg
].XMM_Q(1)));
3359 case 0x71: /* shift mm, im */
3362 case 0x171: /* shift xmm, im */
3368 val
= cpu_ldub_code(env
, s
->pc
++);
3370 tcg_gen_movi_tl(cpu_T
[0], val
);
3371 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.XMM_L(0)));
3372 tcg_gen_movi_tl(cpu_T
[0], 0);
3373 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.XMM_L(1)));
3374 op1_offset
= offsetof(CPUX86State
,xmm_t0
);
3376 tcg_gen_movi_tl(cpu_T
[0], val
);
3377 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,mmx_t0
.MMX_L(0)));
3378 tcg_gen_movi_tl(cpu_T
[0], 0);
3379 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,mmx_t0
.MMX_L(1)));
3380 op1_offset
= offsetof(CPUX86State
,mmx_t0
);
3382 sse_fn_epp
= sse_op_table2
[((b
- 1) & 3) * 8 +
3383 (((modrm
>> 3)) & 7)][b1
];
3388 rm
= (modrm
& 7) | REX_B(s
);
3389 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3392 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3394 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3395 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op1_offset
);
3396 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3398 case 0x050: /* movmskps */
3399 rm
= (modrm
& 7) | REX_B(s
);
3400 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3401 offsetof(CPUX86State
,xmm_regs
[rm
]));
3402 gen_helper_movmskps(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3403 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3405 case 0x150: /* movmskpd */
3406 rm
= (modrm
& 7) | REX_B(s
);
3407 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3408 offsetof(CPUX86State
,xmm_regs
[rm
]));
3409 gen_helper_movmskpd(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3410 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3412 case 0x02a: /* cvtpi2ps */
3413 case 0x12a: /* cvtpi2pd */
3414 gen_helper_enter_mmx(cpu_env
);
3416 gen_lea_modrm(env
, s
, modrm
);
3417 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3418 gen_ldq_env_A0(s
, op2_offset
);
3421 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3423 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
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_cvtpi2ps(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3432 gen_helper_cvtpi2pd(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3436 case 0x22a: /* cvtsi2ss */
3437 case 0x32a: /* cvtsi2sd */
3438 ot
= mo_64_32(s
->dflag
);
3439 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3440 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3441 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3443 SSEFunc_0_epi sse_fn_epi
= sse_op_table3ai
[(b
>> 8) & 1];
3444 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3445 sse_fn_epi(cpu_env
, cpu_ptr0
, cpu_tmp2_i32
);
3447 #ifdef TARGET_X86_64
3448 SSEFunc_0_epl sse_fn_epl
= sse_op_table3aq
[(b
>> 8) & 1];
3449 sse_fn_epl(cpu_env
, cpu_ptr0
, cpu_T
[0]);
3455 case 0x02c: /* cvttps2pi */
3456 case 0x12c: /* cvttpd2pi */
3457 case 0x02d: /* cvtps2pi */
3458 case 0x12d: /* cvtpd2pi */
3459 gen_helper_enter_mmx(cpu_env
);
3461 gen_lea_modrm(env
, s
, modrm
);
3462 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3463 gen_ldo_env_A0(s
, op2_offset
);
3465 rm
= (modrm
& 7) | REX_B(s
);
3466 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3468 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
);
3469 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3470 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3473 gen_helper_cvttps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3476 gen_helper_cvttpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3479 gen_helper_cvtps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3482 gen_helper_cvtpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3486 case 0x22c: /* cvttss2si */
3487 case 0x32c: /* cvttsd2si */
3488 case 0x22d: /* cvtss2si */
3489 case 0x32d: /* cvtsd2si */
3490 ot
= mo_64_32(s
->dflag
);
3492 gen_lea_modrm(env
, s
, modrm
);
3494 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.XMM_Q(0)));
3496 gen_op_ld_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
3497 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.XMM_L(0)));
3499 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3501 rm
= (modrm
& 7) | REX_B(s
);
3502 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3504 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3506 SSEFunc_i_ep sse_fn_i_ep
=
3507 sse_op_table3bi
[((b
>> 7) & 2) | (b
& 1)];
3508 sse_fn_i_ep(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3509 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
3511 #ifdef TARGET_X86_64
3512 SSEFunc_l_ep sse_fn_l_ep
=
3513 sse_op_table3bq
[((b
>> 7) & 2) | (b
& 1)];
3514 sse_fn_l_ep(cpu_T
[0], cpu_env
, cpu_ptr0
);
3519 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3521 case 0xc4: /* pinsrw */
3524 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
3525 val
= cpu_ldub_code(env
, s
->pc
++);
3528 tcg_gen_st16_tl(cpu_T
[0], cpu_env
,
3529 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_W(val
)));
3532 tcg_gen_st16_tl(cpu_T
[0], cpu_env
,
3533 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_W(val
)));
3536 case 0xc5: /* pextrw */
3540 ot
= mo_64_32(s
->dflag
);
3541 val
= cpu_ldub_code(env
, s
->pc
++);
3544 rm
= (modrm
& 7) | REX_B(s
);
3545 tcg_gen_ld16u_tl(cpu_T
[0], cpu_env
,
3546 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_W(val
)));
3550 tcg_gen_ld16u_tl(cpu_T
[0], cpu_env
,
3551 offsetof(CPUX86State
,fpregs
[rm
].mmx
.MMX_W(val
)));
3553 reg
= ((modrm
>> 3) & 7) | rex_r
;
3554 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3556 case 0x1d6: /* movq ea, xmm */
3558 gen_lea_modrm(env
, s
, modrm
);
3559 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3560 xmm_regs
[reg
].XMM_Q(0)));
3562 rm
= (modrm
& 7) | REX_B(s
);
3563 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)),
3564 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3565 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(1)));
3568 case 0x2d6: /* movq2dq */
3569 gen_helper_enter_mmx(cpu_env
);
3571 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3572 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3573 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)));
3575 case 0x3d6: /* movdq2q */
3576 gen_helper_enter_mmx(cpu_env
);
3577 rm
= (modrm
& 7) | REX_B(s
);
3578 gen_op_movq(offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
),
3579 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3581 case 0xd7: /* pmovmskb */
3586 rm
= (modrm
& 7) | REX_B(s
);
3587 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[rm
]));
3588 gen_helper_pmovmskb_xmm(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3591 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3592 gen_helper_pmovmskb_mmx(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3594 reg
= ((modrm
>> 3) & 7) | rex_r
;
3595 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3601 if ((b
& 0xf0) == 0xf0) {
3604 modrm
= cpu_ldub_code(env
, s
->pc
++);
3606 reg
= ((modrm
>> 3) & 7) | rex_r
;
3607 mod
= (modrm
>> 6) & 3;
3612 sse_fn_epp
= sse_op_table6
[b
].op
[b1
];
3616 if (!(s
->cpuid_ext_features
& sse_op_table6
[b
].ext_mask
))
3620 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3622 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
3624 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3625 gen_lea_modrm(env
, s
, modrm
);
3627 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3628 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3629 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3630 gen_ldq_env_A0(s
, op2_offset
+
3631 offsetof(XMMReg
, XMM_Q(0)));
3633 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3634 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3635 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
3636 s
->mem_index
, MO_LEUL
);
3637 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, op2_offset
+
3638 offsetof(XMMReg
, XMM_L(0)));
3640 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3641 tcg_gen_qemu_ld_tl(cpu_tmp0
, cpu_A0
,
3642 s
->mem_index
, MO_LEUW
);
3643 tcg_gen_st16_tl(cpu_tmp0
, cpu_env
, op2_offset
+
3644 offsetof(XMMReg
, XMM_W(0)));
3646 case 0x2a: /* movntqda */
3647 gen_ldo_env_A0(s
, op1_offset
);
3650 gen_ldo_env_A0(s
, op2_offset
);
3654 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
3656 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3658 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3659 gen_lea_modrm(env
, s
, modrm
);
3660 gen_ldq_env_A0(s
, op2_offset
);
3663 if (sse_fn_epp
== SSE_SPECIAL
) {
3667 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3668 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3669 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3672 set_cc_op(s
, CC_OP_EFLAGS
);
3679 /* Various integer extensions at 0f 38 f[0-f]. */
3680 b
= modrm
| (b1
<< 8);
3681 modrm
= cpu_ldub_code(env
, s
->pc
++);
3682 reg
= ((modrm
>> 3) & 7) | rex_r
;
3685 case 0x3f0: /* crc32 Gd,Eb */
3686 case 0x3f1: /* crc32 Gd,Ey */
3688 if (!(s
->cpuid_ext_features
& CPUID_EXT_SSE42
)) {
3691 if ((b
& 0xff) == 0xf0) {
3693 } else if (s
->dflag
!= MO_64
) {
3694 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3699 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[reg
]);
3700 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3701 gen_helper_crc32(cpu_T
[0], cpu_tmp2_i32
,
3702 cpu_T
[0], tcg_const_i32(8 << ot
));
3704 ot
= mo_64_32(s
->dflag
);
3705 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3708 case 0x1f0: /* crc32 or movbe */
3710 /* For these insns, the f3 prefix is supposed to have priority
3711 over the 66 prefix, but that's not what we implement above
3713 if (s
->prefix
& PREFIX_REPNZ
) {
3717 case 0x0f0: /* movbe Gy,My */
3718 case 0x0f1: /* movbe My,Gy */
3719 if (!(s
->cpuid_ext_features
& CPUID_EXT_MOVBE
)) {
3722 if (s
->dflag
!= MO_64
) {
3723 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3728 gen_lea_modrm(env
, s
, modrm
);
3730 tcg_gen_qemu_ld_tl(cpu_T
[0], cpu_A0
,
3731 s
->mem_index
, ot
| MO_BE
);
3732 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3734 tcg_gen_qemu_st_tl(cpu_regs
[reg
], cpu_A0
,
3735 s
->mem_index
, ot
| MO_BE
);
3739 case 0x0f2: /* andn Gy, By, Ey */
3740 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3741 || !(s
->prefix
& PREFIX_VEX
)
3745 ot
= mo_64_32(s
->dflag
);
3746 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3747 tcg_gen_andc_tl(cpu_T
[0], cpu_regs
[s
->vex_v
], cpu_T
[0]);
3748 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3749 gen_op_update1_cc();
3750 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3753 case 0x0f7: /* bextr Gy, Ey, By */
3754 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3755 || !(s
->prefix
& PREFIX_VEX
)
3759 ot
= mo_64_32(s
->dflag
);
3763 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3764 /* Extract START, and shift the operand.
3765 Shifts larger than operand size get zeros. */
3766 tcg_gen_ext8u_tl(cpu_A0
, cpu_regs
[s
->vex_v
]);
3767 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], cpu_A0
);
3769 bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3770 zero
= tcg_const_tl(0);
3771 tcg_gen_movcond_tl(TCG_COND_LEU
, cpu_T
[0], cpu_A0
, bound
,
3773 tcg_temp_free(zero
);
3775 /* Extract the LEN into a mask. Lengths larger than
3776 operand size get all ones. */
3777 tcg_gen_shri_tl(cpu_A0
, cpu_regs
[s
->vex_v
], 8);
3778 tcg_gen_ext8u_tl(cpu_A0
, cpu_A0
);
3779 tcg_gen_movcond_tl(TCG_COND_LEU
, cpu_A0
, cpu_A0
, bound
,
3781 tcg_temp_free(bound
);
3782 tcg_gen_movi_tl(cpu_T
[1], 1);
3783 tcg_gen_shl_tl(cpu_T
[1], cpu_T
[1], cpu_A0
);
3784 tcg_gen_subi_tl(cpu_T
[1], cpu_T
[1], 1);
3785 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
3787 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3788 gen_op_update1_cc();
3789 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3793 case 0x0f5: /* bzhi Gy, Ey, By */
3794 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3795 || !(s
->prefix
& PREFIX_VEX
)
3799 ot
= mo_64_32(s
->dflag
);
3800 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3801 tcg_gen_ext8u_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
3803 TCGv bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3804 /* Note that since we're using BMILG (in order to get O
3805 cleared) we need to store the inverse into C. */
3806 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_cc_src
,
3808 tcg_gen_movcond_tl(TCG_COND_GT
, cpu_T
[1], cpu_T
[1],
3809 bound
, bound
, cpu_T
[1]);
3810 tcg_temp_free(bound
);
3812 tcg_gen_movi_tl(cpu_A0
, -1);
3813 tcg_gen_shl_tl(cpu_A0
, cpu_A0
, cpu_T
[1]);
3814 tcg_gen_andc_tl(cpu_T
[0], cpu_T
[0], cpu_A0
);
3815 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3816 gen_op_update1_cc();
3817 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
3820 case 0x3f6: /* mulx By, Gy, rdx, Ey */
3821 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3822 || !(s
->prefix
& PREFIX_VEX
)
3826 ot
= mo_64_32(s
->dflag
);
3827 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3830 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3831 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EDX
]);
3832 tcg_gen_mulu2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
3833 cpu_tmp2_i32
, cpu_tmp3_i32
);
3834 tcg_gen_extu_i32_tl(cpu_regs
[s
->vex_v
], cpu_tmp2_i32
);
3835 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp3_i32
);
3837 #ifdef TARGET_X86_64
3839 tcg_gen_mulu2_i64(cpu_regs
[s
->vex_v
], cpu_regs
[reg
],
3840 cpu_T
[0], cpu_regs
[R_EDX
]);
3846 case 0x3f5: /* pdep Gy, By, Ey */
3847 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3848 || !(s
->prefix
& PREFIX_VEX
)
3852 ot
= mo_64_32(s
->dflag
);
3853 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3854 /* Note that by zero-extending the mask operand, we
3855 automatically handle zero-extending the result. */
3857 tcg_gen_mov_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
3859 tcg_gen_ext32u_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
3861 gen_helper_pdep(cpu_regs
[reg
], cpu_T
[0], cpu_T
[1]);
3864 case 0x2f5: /* pext Gy, By, Ey */
3865 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3866 || !(s
->prefix
& PREFIX_VEX
)
3870 ot
= mo_64_32(s
->dflag
);
3871 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3872 /* Note that by zero-extending the mask operand, we
3873 automatically handle zero-extending the result. */
3875 tcg_gen_mov_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
3877 tcg_gen_ext32u_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
3879 gen_helper_pext(cpu_regs
[reg
], cpu_T
[0], cpu_T
[1]);
3882 case 0x1f6: /* adcx Gy, Ey */
3883 case 0x2f6: /* adox Gy, Ey */
3884 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_ADX
)) {
3887 TCGv carry_in
, carry_out
, zero
;
3890 ot
= mo_64_32(s
->dflag
);
3891 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3893 /* Re-use the carry-out from a previous round. */
3894 TCGV_UNUSED(carry_in
);
3895 carry_out
= (b
== 0x1f6 ? cpu_cc_dst
: cpu_cc_src2
);
3899 carry_in
= cpu_cc_dst
;
3900 end_op
= CC_OP_ADCX
;
3902 end_op
= CC_OP_ADCOX
;
3907 end_op
= CC_OP_ADCOX
;
3909 carry_in
= cpu_cc_src2
;
3910 end_op
= CC_OP_ADOX
;
3914 end_op
= CC_OP_ADCOX
;
3915 carry_in
= carry_out
;
3918 end_op
= (b
== 0x1f6 ? CC_OP_ADCX
: CC_OP_ADOX
);
3921 /* If we can't reuse carry-out, get it out of EFLAGS. */
3922 if (TCGV_IS_UNUSED(carry_in
)) {
3923 if (s
->cc_op
!= CC_OP_ADCX
&& s
->cc_op
!= CC_OP_ADOX
) {
3924 gen_compute_eflags(s
);
3926 carry_in
= cpu_tmp0
;
3927 tcg_gen_shri_tl(carry_in
, cpu_cc_src
,
3928 ctz32(b
== 0x1f6 ? CC_C
: CC_O
));
3929 tcg_gen_andi_tl(carry_in
, carry_in
, 1);
3933 #ifdef TARGET_X86_64
3935 /* If we know TL is 64-bit, and we want a 32-bit
3936 result, just do everything in 64-bit arithmetic. */
3937 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_regs
[reg
]);
3938 tcg_gen_ext32u_i64(cpu_T
[0], cpu_T
[0]);
3939 tcg_gen_add_i64(cpu_T
[0], cpu_T
[0], cpu_regs
[reg
]);
3940 tcg_gen_add_i64(cpu_T
[0], cpu_T
[0], carry_in
);
3941 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_T
[0]);
3942 tcg_gen_shri_i64(carry_out
, cpu_T
[0], 32);
3946 /* Otherwise compute the carry-out in two steps. */
3947 zero
= tcg_const_tl(0);
3948 tcg_gen_add2_tl(cpu_T
[0], carry_out
,
3951 tcg_gen_add2_tl(cpu_regs
[reg
], carry_out
,
3952 cpu_regs
[reg
], carry_out
,
3954 tcg_temp_free(zero
);
3957 set_cc_op(s
, end_op
);
3961 case 0x1f7: /* shlx Gy, Ey, By */
3962 case 0x2f7: /* sarx Gy, Ey, By */
3963 case 0x3f7: /* shrx Gy, Ey, By */
3964 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3965 || !(s
->prefix
& PREFIX_VEX
)
3969 ot
= mo_64_32(s
->dflag
);
3970 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3972 tcg_gen_andi_tl(cpu_T
[1], cpu_regs
[s
->vex_v
], 63);
3974 tcg_gen_andi_tl(cpu_T
[1], cpu_regs
[s
->vex_v
], 31);
3977 tcg_gen_shl_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
3978 } else if (b
== 0x2f7) {
3980 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
3982 tcg_gen_sar_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
3985 tcg_gen_ext32u_tl(cpu_T
[0], cpu_T
[0]);
3987 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
3989 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3995 case 0x3f3: /* Group 17 */
3996 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3997 || !(s
->prefix
& PREFIX_VEX
)
4001 ot
= mo_64_32(s
->dflag
);
4002 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4005 case 1: /* blsr By,Ey */
4006 tcg_gen_neg_tl(cpu_T
[1], cpu_T
[0]);
4007 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4008 gen_op_mov_reg_v(ot
, s
->vex_v
, cpu_T
[0]);
4009 gen_op_update2_cc();
4010 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4013 case 2: /* blsmsk By,Ey */
4014 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
4015 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], 1);
4016 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_cc_src
);
4017 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4018 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4021 case 3: /* blsi By, Ey */
4022 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
4023 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], 1);
4024 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_cc_src
);
4025 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4026 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4042 modrm
= cpu_ldub_code(env
, s
->pc
++);
4044 reg
= ((modrm
>> 3) & 7) | rex_r
;
4045 mod
= (modrm
>> 6) & 3;
4050 sse_fn_eppi
= sse_op_table7
[b
].op
[b1
];
4054 if (!(s
->cpuid_ext_features
& sse_op_table7
[b
].ext_mask
))
4057 if (sse_fn_eppi
== SSE_SPECIAL
) {
4058 ot
= mo_64_32(s
->dflag
);
4059 rm
= (modrm
& 7) | REX_B(s
);
4061 gen_lea_modrm(env
, s
, modrm
);
4062 reg
= ((modrm
>> 3) & 7) | rex_r
;
4063 val
= cpu_ldub_code(env
, s
->pc
++);
4065 case 0x14: /* pextrb */
4066 tcg_gen_ld8u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4067 xmm_regs
[reg
].XMM_B(val
& 15)));
4069 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4071 tcg_gen_qemu_st_tl(cpu_T
[0], cpu_A0
,
4072 s
->mem_index
, MO_UB
);
4075 case 0x15: /* pextrw */
4076 tcg_gen_ld16u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4077 xmm_regs
[reg
].XMM_W(val
& 7)));
4079 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4081 tcg_gen_qemu_st_tl(cpu_T
[0], cpu_A0
,
4082 s
->mem_index
, MO_LEUW
);
4086 if (ot
== MO_32
) { /* pextrd */
4087 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4088 offsetof(CPUX86State
,
4089 xmm_regs
[reg
].XMM_L(val
& 3)));
4091 tcg_gen_extu_i32_tl(cpu_regs
[rm
], cpu_tmp2_i32
);
4093 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
4094 s
->mem_index
, MO_LEUL
);
4096 } else { /* pextrq */
4097 #ifdef TARGET_X86_64
4098 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
4099 offsetof(CPUX86State
,
4100 xmm_regs
[reg
].XMM_Q(val
& 1)));
4102 tcg_gen_mov_i64(cpu_regs
[rm
], cpu_tmp1_i64
);
4104 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
4105 s
->mem_index
, MO_LEQ
);
4112 case 0x17: /* extractps */
4113 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4114 xmm_regs
[reg
].XMM_L(val
& 3)));
4116 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4118 tcg_gen_qemu_st_tl(cpu_T
[0], cpu_A0
,
4119 s
->mem_index
, MO_LEUL
);
4122 case 0x20: /* pinsrb */
4124 gen_op_mov_v_reg(MO_32
, cpu_T
[0], rm
);
4126 tcg_gen_qemu_ld_tl(cpu_T
[0], cpu_A0
,
4127 s
->mem_index
, MO_UB
);
4129 tcg_gen_st8_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4130 xmm_regs
[reg
].XMM_B(val
& 15)));
4132 case 0x21: /* insertps */
4134 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4135 offsetof(CPUX86State
,xmm_regs
[rm
]
4136 .XMM_L((val
>> 6) & 3)));
4138 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
4139 s
->mem_index
, MO_LEUL
);
4141 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4142 offsetof(CPUX86State
,xmm_regs
[reg
]
4143 .XMM_L((val
>> 4) & 3)));
4145 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4146 cpu_env
, offsetof(CPUX86State
,
4147 xmm_regs
[reg
].XMM_L(0)));
4149 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4150 cpu_env
, offsetof(CPUX86State
,
4151 xmm_regs
[reg
].XMM_L(1)));
4153 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4154 cpu_env
, offsetof(CPUX86State
,
4155 xmm_regs
[reg
].XMM_L(2)));
4157 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4158 cpu_env
, offsetof(CPUX86State
,
4159 xmm_regs
[reg
].XMM_L(3)));
4162 if (ot
== MO_32
) { /* pinsrd */
4164 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[rm
]);
4166 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
4167 s
->mem_index
, MO_LEUL
);
4169 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4170 offsetof(CPUX86State
,
4171 xmm_regs
[reg
].XMM_L(val
& 3)));
4172 } else { /* pinsrq */
4173 #ifdef TARGET_X86_64
4175 gen_op_mov_v_reg(ot
, cpu_tmp1_i64
, rm
);
4177 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
4178 s
->mem_index
, MO_LEQ
);
4180 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
4181 offsetof(CPUX86State
,
4182 xmm_regs
[reg
].XMM_Q(val
& 1)));
4193 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4195 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
4197 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4198 gen_lea_modrm(env
, s
, modrm
);
4199 gen_ldo_env_A0(s
, op2_offset
);
4202 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4204 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4206 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4207 gen_lea_modrm(env
, s
, modrm
);
4208 gen_ldq_env_A0(s
, op2_offset
);
4211 val
= cpu_ldub_code(env
, s
->pc
++);
4213 if ((b
& 0xfc) == 0x60) { /* pcmpXstrX */
4214 set_cc_op(s
, CC_OP_EFLAGS
);
4216 if (s
->dflag
== MO_64
) {
4217 /* The helper must use entire 64-bit gp registers */
4222 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4223 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4224 sse_fn_eppi(cpu_env
, cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4228 /* Various integer extensions at 0f 3a f[0-f]. */
4229 b
= modrm
| (b1
<< 8);
4230 modrm
= cpu_ldub_code(env
, s
->pc
++);
4231 reg
= ((modrm
>> 3) & 7) | rex_r
;
4234 case 0x3f0: /* rorx Gy,Ey, Ib */
4235 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4236 || !(s
->prefix
& PREFIX_VEX
)
4240 ot
= mo_64_32(s
->dflag
);
4241 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4242 b
= cpu_ldub_code(env
, s
->pc
++);
4244 tcg_gen_rotri_tl(cpu_T
[0], cpu_T
[0], b
& 63);
4246 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4247 tcg_gen_rotri_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, b
& 31);
4248 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
4250 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
4262 /* generic MMX or SSE operation */
4264 case 0x70: /* pshufx insn */
4265 case 0xc6: /* pshufx insn */
4266 case 0xc2: /* compare insns */
4273 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4277 gen_lea_modrm(env
, s
, modrm
);
4278 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4284 /* Most sse scalar operations. */
4287 } else if (b1
== 3) {
4292 case 0x2e: /* ucomis[sd] */
4293 case 0x2f: /* comis[sd] */
4305 gen_op_ld_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
4306 tcg_gen_st32_tl(cpu_T
[0], cpu_env
,
4307 offsetof(CPUX86State
,xmm_t0
.XMM_L(0)));
4311 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.XMM_D(0)));
4314 /* 128 bit access */
4315 gen_ldo_env_A0(s
, op2_offset
);
4319 rm
= (modrm
& 7) | REX_B(s
);
4320 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
4323 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4325 gen_lea_modrm(env
, s
, modrm
);
4326 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4327 gen_ldq_env_A0(s
, op2_offset
);
4330 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4334 case 0x0f: /* 3DNow! data insns */
4335 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
))
4337 val
= cpu_ldub_code(env
, s
->pc
++);
4338 sse_fn_epp
= sse_op_table5
[val
];
4342 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4343 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4344 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4346 case 0x70: /* pshufx insn */
4347 case 0xc6: /* pshufx insn */
4348 val
= cpu_ldub_code(env
, s
->pc
++);
4349 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4350 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4351 /* XXX: introduce a new table? */
4352 sse_fn_ppi
= (SSEFunc_0_ppi
)sse_fn_epp
;
4353 sse_fn_ppi(cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4357 val
= cpu_ldub_code(env
, s
->pc
++);
4360 sse_fn_epp
= sse_op_table4
[val
][b1
];
4362 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4363 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4364 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4367 /* maskmov : we must prepare A0 */
4370 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EDI
]);
4371 gen_extu(s
->aflag
, cpu_A0
);
4372 gen_add_A0_ds_seg(s
);
4374 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4375 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4376 /* XXX: introduce a new table? */
4377 sse_fn_eppt
= (SSEFunc_0_eppt
)sse_fn_epp
;
4378 sse_fn_eppt(cpu_env
, cpu_ptr0
, cpu_ptr1
, cpu_A0
);
4381 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4382 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4383 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4386 if (b
== 0x2e || b
== 0x2f) {
4387 set_cc_op(s
, CC_OP_EFLAGS
);
4392 /* convert one instruction. s->is_jmp is set if the translation must
4393 be stopped. Return the next pc value */
4394 static target_ulong
disas_insn(CPUX86State
*env
, DisasContext
*s
,
4395 target_ulong pc_start
)
4399 TCGMemOp ot
, aflag
, dflag
;
4400 int modrm
, reg
, rm
, mod
, op
, opreg
, val
;
4401 target_ulong next_eip
, tval
;
4404 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
4405 tcg_gen_debug_insn_start(pc_start
);
4412 #ifdef TARGET_X86_64
4417 s
->rip_offset
= 0; /* for relative ip address */
4421 b
= cpu_ldub_code(env
, s
->pc
);
4423 /* Collect prefixes. */
4426 prefixes
|= PREFIX_REPZ
;
4429 prefixes
|= PREFIX_REPNZ
;
4432 prefixes
|= PREFIX_LOCK
;
4453 prefixes
|= PREFIX_DATA
;
4456 prefixes
|= PREFIX_ADR
;
4458 #ifdef TARGET_X86_64
4462 rex_w
= (b
>> 3) & 1;
4463 rex_r
= (b
& 0x4) << 1;
4464 s
->rex_x
= (b
& 0x2) << 2;
4465 REX_B(s
) = (b
& 0x1) << 3;
4466 x86_64_hregs
= 1; /* select uniform byte register addressing */
4471 case 0xc5: /* 2-byte VEX */
4472 case 0xc4: /* 3-byte VEX */
4473 /* VEX prefixes cannot be used except in 32-bit mode.
4474 Otherwise the instruction is LES or LDS. */
4475 if (s
->code32
&& !s
->vm86
) {
4476 static const int pp_prefix
[4] = {
4477 0, PREFIX_DATA
, PREFIX_REPZ
, PREFIX_REPNZ
4479 int vex3
, vex2
= cpu_ldub_code(env
, s
->pc
);
4481 if (!CODE64(s
) && (vex2
& 0xc0) != 0xc0) {
4482 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4483 otherwise the instruction is LES or LDS. */
4488 /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
4489 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
4490 | PREFIX_LOCK
| PREFIX_DATA
)) {
4493 #ifdef TARGET_X86_64
4498 rex_r
= (~vex2
>> 4) & 8;
4501 b
= cpu_ldub_code(env
, s
->pc
++);
4503 #ifdef TARGET_X86_64
4504 s
->rex_x
= (~vex2
>> 3) & 8;
4505 s
->rex_b
= (~vex2
>> 2) & 8;
4507 vex3
= cpu_ldub_code(env
, s
->pc
++);
4508 rex_w
= (vex3
>> 7) & 1;
4509 switch (vex2
& 0x1f) {
4510 case 0x01: /* Implied 0f leading opcode bytes. */
4511 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4513 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4516 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4519 default: /* Reserved for future use. */
4523 s
->vex_v
= (~vex3
>> 3) & 0xf;
4524 s
->vex_l
= (vex3
>> 2) & 1;
4525 prefixes
|= pp_prefix
[vex3
& 3] | PREFIX_VEX
;
4530 /* Post-process prefixes. */
4532 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit
4533 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4534 over 0x66 if both are present. */
4535 dflag
= (rex_w
> 0 ? MO_64
: prefixes
& PREFIX_DATA
? MO_16
: MO_32
);
4536 /* In 64-bit mode, 0x67 selects 32-bit addressing. */
4537 aflag
= (prefixes
& PREFIX_ADR
? MO_32
: MO_64
);
4539 /* In 16/32-bit mode, 0x66 selects the opposite data size. */
4540 if (s
->code32
^ ((prefixes
& PREFIX_DATA
) != 0)) {
4545 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */
4546 if (s
->code32
^ ((prefixes
& PREFIX_ADR
) != 0)) {
4553 s
->prefix
= prefixes
;
4557 /* lock generation */
4558 if (prefixes
& PREFIX_LOCK
)
4561 /* now check op code */
4565 /**************************/
4566 /* extended op code */
4567 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4570 /**************************/
4585 ot
= mo_b_d(b
, dflag
);
4588 case 0: /* OP Ev, Gv */
4589 modrm
= cpu_ldub_code(env
, s
->pc
++);
4590 reg
= ((modrm
>> 3) & 7) | rex_r
;
4591 mod
= (modrm
>> 6) & 3;
4592 rm
= (modrm
& 7) | REX_B(s
);
4594 gen_lea_modrm(env
, s
, modrm
);
4596 } else if (op
== OP_XORL
&& rm
== reg
) {
4598 /* xor reg, reg optimisation */
4599 set_cc_op(s
, CC_OP_CLR
);
4600 tcg_gen_movi_tl(cpu_T
[0], 0);
4601 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
4606 gen_op_mov_v_reg(ot
, cpu_T
[1], reg
);
4607 gen_op(s
, op
, ot
, opreg
);
4609 case 1: /* OP Gv, Ev */
4610 modrm
= cpu_ldub_code(env
, s
->pc
++);
4611 mod
= (modrm
>> 6) & 3;
4612 reg
= ((modrm
>> 3) & 7) | rex_r
;
4613 rm
= (modrm
& 7) | REX_B(s
);
4615 gen_lea_modrm(env
, s
, modrm
);
4616 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
4617 } else if (op
== OP_XORL
&& rm
== reg
) {
4620 gen_op_mov_v_reg(ot
, cpu_T
[1], rm
);
4622 gen_op(s
, op
, ot
, reg
);
4624 case 2: /* OP A, Iv */
4625 val
= insn_get(env
, s
, ot
);
4626 tcg_gen_movi_tl(cpu_T
[1], val
);
4627 gen_op(s
, op
, ot
, OR_EAX
);
4636 case 0x80: /* GRP1 */
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;
4653 s
->rip_offset
= insn_const_size(ot
);
4654 gen_lea_modrm(env
, s
, modrm
);
4665 val
= insn_get(env
, s
, ot
);
4668 val
= (int8_t)insn_get(env
, s
, MO_8
);
4671 tcg_gen_movi_tl(cpu_T
[1], val
);
4672 gen_op(s
, op
, ot
, opreg
);
4676 /**************************/
4677 /* inc, dec, and other misc arith */
4678 case 0x40 ... 0x47: /* inc Gv */
4680 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), 1);
4682 case 0x48 ... 0x4f: /* dec Gv */
4684 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), -1);
4686 case 0xf6: /* GRP3 */
4688 ot
= mo_b_d(b
, dflag
);
4690 modrm
= cpu_ldub_code(env
, s
->pc
++);
4691 mod
= (modrm
>> 6) & 3;
4692 rm
= (modrm
& 7) | REX_B(s
);
4693 op
= (modrm
>> 3) & 7;
4696 s
->rip_offset
= insn_const_size(ot
);
4697 gen_lea_modrm(env
, s
, modrm
);
4698 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
4700 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
4705 val
= insn_get(env
, s
, ot
);
4706 tcg_gen_movi_tl(cpu_T
[1], val
);
4707 gen_op_testl_T0_T1_cc();
4708 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4711 tcg_gen_not_tl(cpu_T
[0], cpu_T
[0]);
4713 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
4715 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4719 tcg_gen_neg_tl(cpu_T
[0], cpu_T
[0]);
4721 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
4723 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4725 gen_op_update_neg_cc();
4726 set_cc_op(s
, CC_OP_SUBB
+ ot
);
4731 gen_op_mov_v_reg(MO_8
, cpu_T
[1], R_EAX
);
4732 tcg_gen_ext8u_tl(cpu_T
[0], cpu_T
[0]);
4733 tcg_gen_ext8u_tl(cpu_T
[1], cpu_T
[1]);
4734 /* XXX: use 32 bit mul which could be faster */
4735 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4736 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
4737 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4738 tcg_gen_andi_tl(cpu_cc_src
, cpu_T
[0], 0xff00);
4739 set_cc_op(s
, CC_OP_MULB
);
4742 gen_op_mov_v_reg(MO_16
, cpu_T
[1], R_EAX
);
4743 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
4744 tcg_gen_ext16u_tl(cpu_T
[1], cpu_T
[1]);
4745 /* XXX: use 32 bit mul which could be faster */
4746 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4747 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
4748 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4749 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], 16);
4750 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T
[0]);
4751 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
4752 set_cc_op(s
, CC_OP_MULW
);
4756 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4757 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
4758 tcg_gen_mulu2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4759 cpu_tmp2_i32
, cpu_tmp3_i32
);
4760 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
4761 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
4762 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4763 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4764 set_cc_op(s
, CC_OP_MULL
);
4766 #ifdef TARGET_X86_64
4768 tcg_gen_mulu2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4769 cpu_T
[0], cpu_regs
[R_EAX
]);
4770 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4771 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4772 set_cc_op(s
, CC_OP_MULQ
);
4780 gen_op_mov_v_reg(MO_8
, cpu_T
[1], R_EAX
);
4781 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
4782 tcg_gen_ext8s_tl(cpu_T
[1], cpu_T
[1]);
4783 /* XXX: use 32 bit mul which could be faster */
4784 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4785 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
4786 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4787 tcg_gen_ext8s_tl(cpu_tmp0
, cpu_T
[0]);
4788 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
4789 set_cc_op(s
, CC_OP_MULB
);
4792 gen_op_mov_v_reg(MO_16
, cpu_T
[1], R_EAX
);
4793 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
4794 tcg_gen_ext16s_tl(cpu_T
[1], cpu_T
[1]);
4795 /* XXX: use 32 bit mul which could be faster */
4796 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4797 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
4798 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4799 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T
[0]);
4800 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
4801 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], 16);
4802 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T
[0]);
4803 set_cc_op(s
, CC_OP_MULW
);
4807 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4808 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
4809 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4810 cpu_tmp2_i32
, cpu_tmp3_i32
);
4811 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
4812 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
4813 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
4814 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4815 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
4816 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
4817 set_cc_op(s
, CC_OP_MULL
);
4819 #ifdef TARGET_X86_64
4821 tcg_gen_muls2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4822 cpu_T
[0], cpu_regs
[R_EAX
]);
4823 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4824 tcg_gen_sari_tl(cpu_cc_src
, cpu_regs
[R_EAX
], 63);
4825 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_regs
[R_EDX
]);
4826 set_cc_op(s
, CC_OP_MULQ
);
4834 gen_helper_divb_AL(cpu_env
, cpu_T
[0]);
4837 gen_helper_divw_AX(cpu_env
, cpu_T
[0]);
4841 gen_helper_divl_EAX(cpu_env
, cpu_T
[0]);
4843 #ifdef TARGET_X86_64
4845 gen_helper_divq_EAX(cpu_env
, cpu_T
[0]);
4853 gen_helper_idivb_AL(cpu_env
, cpu_T
[0]);
4856 gen_helper_idivw_AX(cpu_env
, cpu_T
[0]);
4860 gen_helper_idivl_EAX(cpu_env
, cpu_T
[0]);
4862 #ifdef TARGET_X86_64
4864 gen_helper_idivq_EAX(cpu_env
, cpu_T
[0]);
4874 case 0xfe: /* GRP4 */
4875 case 0xff: /* GRP5 */
4876 ot
= mo_b_d(b
, dflag
);
4878 modrm
= cpu_ldub_code(env
, s
->pc
++);
4879 mod
= (modrm
>> 6) & 3;
4880 rm
= (modrm
& 7) | REX_B(s
);
4881 op
= (modrm
>> 3) & 7;
4882 if (op
>= 2 && b
== 0xfe) {
4886 if (op
== 2 || op
== 4) {
4887 /* operand size for jumps is 64 bit */
4889 } else if (op
== 3 || op
== 5) {
4890 ot
= dflag
!= MO_16
? MO_32
+ (rex_w
== 1) : MO_16
;
4891 } else if (op
== 6) {
4892 /* default push size is 64 bit */
4893 ot
= mo_pushpop(s
, dflag
);
4897 gen_lea_modrm(env
, s
, modrm
);
4898 if (op
>= 2 && op
!= 3 && op
!= 5)
4899 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
4901 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
4905 case 0: /* inc Ev */
4910 gen_inc(s
, ot
, opreg
, 1);
4912 case 1: /* dec Ev */
4917 gen_inc(s
, ot
, opreg
, -1);
4919 case 2: /* call Ev */
4920 /* XXX: optimize if memory (no 'and' is necessary) */
4921 if (dflag
== MO_16
) {
4922 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
4924 next_eip
= s
->pc
- s
->cs_base
;
4925 tcg_gen_movi_tl(cpu_T
[1], next_eip
);
4926 gen_push_v(s
, cpu_T
[1]);
4927 gen_op_jmp_v(cpu_T
[0]);
4930 case 3: /* lcall Ev */
4931 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
4932 gen_add_A0_im(s
, 1 << ot
);
4933 gen_op_ld_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
4935 if (s
->pe
&& !s
->vm86
) {
4936 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4937 gen_helper_lcall_protected(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
4938 tcg_const_i32(dflag
- 1),
4939 tcg_const_tl(s
->pc
- s
->cs_base
));
4941 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4942 gen_helper_lcall_real(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
4943 tcg_const_i32(dflag
- 1),
4944 tcg_const_i32(s
->pc
- s
->cs_base
));
4948 case 4: /* jmp Ev */
4949 if (dflag
== MO_16
) {
4950 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
4952 gen_op_jmp_v(cpu_T
[0]);
4955 case 5: /* ljmp Ev */
4956 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
4957 gen_add_A0_im(s
, 1 << ot
);
4958 gen_op_ld_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
4960 if (s
->pe
&& !s
->vm86
) {
4961 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4962 gen_helper_ljmp_protected(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
4963 tcg_const_tl(s
->pc
- s
->cs_base
));
4965 gen_op_movl_seg_T0_vm(R_CS
);
4966 gen_op_jmp_v(cpu_T
[1]);
4970 case 6: /* push Ev */
4971 gen_push_v(s
, cpu_T
[0]);
4978 case 0x84: /* test Ev, Gv */
4980 ot
= mo_b_d(b
, dflag
);
4982 modrm
= cpu_ldub_code(env
, s
->pc
++);
4983 reg
= ((modrm
>> 3) & 7) | rex_r
;
4985 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4986 gen_op_mov_v_reg(ot
, cpu_T
[1], reg
);
4987 gen_op_testl_T0_T1_cc();
4988 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4991 case 0xa8: /* test eAX, Iv */
4993 ot
= mo_b_d(b
, dflag
);
4994 val
= insn_get(env
, s
, ot
);
4996 gen_op_mov_v_reg(ot
, cpu_T
[0], OR_EAX
);
4997 tcg_gen_movi_tl(cpu_T
[1], val
);
4998 gen_op_testl_T0_T1_cc();
4999 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5002 case 0x98: /* CWDE/CBW */
5004 #ifdef TARGET_X86_64
5006 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EAX
);
5007 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
5008 gen_op_mov_reg_v(MO_64
, R_EAX
, cpu_T
[0]);
5012 gen_op_mov_v_reg(MO_16
, cpu_T
[0], R_EAX
);
5013 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5014 gen_op_mov_reg_v(MO_32
, R_EAX
, cpu_T
[0]);
5017 gen_op_mov_v_reg(MO_8
, cpu_T
[0], R_EAX
);
5018 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
5019 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
5025 case 0x99: /* CDQ/CWD */
5027 #ifdef TARGET_X86_64
5029 gen_op_mov_v_reg(MO_64
, cpu_T
[0], R_EAX
);
5030 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 63);
5031 gen_op_mov_reg_v(MO_64
, R_EDX
, cpu_T
[0]);
5035 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EAX
);
5036 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
5037 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 31);
5038 gen_op_mov_reg_v(MO_32
, R_EDX
, cpu_T
[0]);
5041 gen_op_mov_v_reg(MO_16
, cpu_T
[0], R_EAX
);
5042 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5043 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 15);
5044 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T
[0]);
5050 case 0x1af: /* imul Gv, Ev */
5051 case 0x69: /* imul Gv, Ev, I */
5054 modrm
= cpu_ldub_code(env
, s
->pc
++);
5055 reg
= ((modrm
>> 3) & 7) | rex_r
;
5057 s
->rip_offset
= insn_const_size(ot
);
5060 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5062 val
= insn_get(env
, s
, ot
);
5063 tcg_gen_movi_tl(cpu_T
[1], val
);
5064 } else if (b
== 0x6b) {
5065 val
= (int8_t)insn_get(env
, s
, MO_8
);
5066 tcg_gen_movi_tl(cpu_T
[1], val
);
5068 gen_op_mov_v_reg(ot
, cpu_T
[1], reg
);
5071 #ifdef TARGET_X86_64
5073 tcg_gen_muls2_i64(cpu_regs
[reg
], cpu_T
[1], cpu_T
[0], cpu_T
[1]);
5074 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5075 tcg_gen_sari_tl(cpu_cc_src
, cpu_cc_dst
, 63);
5076 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_T
[1]);
5080 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5081 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
5082 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
5083 cpu_tmp2_i32
, cpu_tmp3_i32
);
5084 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
5085 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
5086 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5087 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
5088 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
5091 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5092 tcg_gen_ext16s_tl(cpu_T
[1], cpu_T
[1]);
5093 /* XXX: use 32 bit mul which could be faster */
5094 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5095 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5096 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T
[0]);
5097 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
5098 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
5101 set_cc_op(s
, CC_OP_MULB
+ ot
);
5104 case 0x1c1: /* xadd Ev, Gv */
5105 ot
= mo_b_d(b
, dflag
);
5106 modrm
= cpu_ldub_code(env
, s
->pc
++);
5107 reg
= ((modrm
>> 3) & 7) | rex_r
;
5108 mod
= (modrm
>> 6) & 3;
5110 rm
= (modrm
& 7) | REX_B(s
);
5111 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
5112 gen_op_mov_v_reg(ot
, cpu_T
[1], rm
);
5113 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5114 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5115 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
5117 gen_lea_modrm(env
, s
, modrm
);
5118 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
5119 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
5120 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5121 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
5122 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5124 gen_op_update2_cc();
5125 set_cc_op(s
, CC_OP_ADDB
+ ot
);
5128 case 0x1b1: /* cmpxchg Ev, Gv */
5130 TCGLabel
*label1
, *label2
;
5131 TCGv t0
, t1
, t2
, a0
;
5133 ot
= mo_b_d(b
, dflag
);
5134 modrm
= cpu_ldub_code(env
, s
->pc
++);
5135 reg
= ((modrm
>> 3) & 7) | rex_r
;
5136 mod
= (modrm
>> 6) & 3;
5137 t0
= tcg_temp_local_new();
5138 t1
= tcg_temp_local_new();
5139 t2
= tcg_temp_local_new();
5140 a0
= tcg_temp_local_new();
5141 gen_op_mov_v_reg(ot
, t1
, reg
);
5143 rm
= (modrm
& 7) | REX_B(s
);
5144 gen_op_mov_v_reg(ot
, t0
, rm
);
5146 gen_lea_modrm(env
, s
, modrm
);
5147 tcg_gen_mov_tl(a0
, cpu_A0
);
5148 gen_op_ld_v(s
, ot
, t0
, a0
);
5149 rm
= 0; /* avoid warning */
5151 label1
= gen_new_label();
5152 tcg_gen_mov_tl(t2
, cpu_regs
[R_EAX
]);
5155 tcg_gen_brcond_tl(TCG_COND_EQ
, t2
, t0
, label1
);
5156 label2
= gen_new_label();
5158 gen_op_mov_reg_v(ot
, R_EAX
, t0
);
5160 gen_set_label(label1
);
5161 gen_op_mov_reg_v(ot
, rm
, t1
);
5163 /* perform no-op store cycle like physical cpu; must be
5164 before changing accumulator to ensure idempotency if
5165 the store faults and the instruction is restarted */
5166 gen_op_st_v(s
, ot
, t0
, a0
);
5167 gen_op_mov_reg_v(ot
, R_EAX
, t0
);
5169 gen_set_label(label1
);
5170 gen_op_st_v(s
, ot
, t1
, a0
);
5172 gen_set_label(label2
);
5173 tcg_gen_mov_tl(cpu_cc_src
, t0
);
5174 tcg_gen_mov_tl(cpu_cc_srcT
, t2
);
5175 tcg_gen_sub_tl(cpu_cc_dst
, t2
, t0
);
5176 set_cc_op(s
, CC_OP_SUBB
+ ot
);
5183 case 0x1c7: /* cmpxchg8b */
5184 modrm
= cpu_ldub_code(env
, s
->pc
++);
5185 mod
= (modrm
>> 6) & 3;
5186 if ((mod
== 3) || ((modrm
& 0x38) != 0x8))
5188 #ifdef TARGET_X86_64
5189 if (dflag
== MO_64
) {
5190 if (!(s
->cpuid_ext_features
& CPUID_EXT_CX16
))
5192 gen_lea_modrm(env
, s
, modrm
);
5193 gen_helper_cmpxchg16b(cpu_env
, cpu_A0
);
5197 if (!(s
->cpuid_features
& CPUID_CX8
))
5199 gen_lea_modrm(env
, s
, modrm
);
5200 gen_helper_cmpxchg8b(cpu_env
, cpu_A0
);
5202 set_cc_op(s
, CC_OP_EFLAGS
);
5205 /**************************/
5207 case 0x50 ... 0x57: /* push */
5208 gen_op_mov_v_reg(MO_32
, cpu_T
[0], (b
& 7) | REX_B(s
));
5209 gen_push_v(s
, cpu_T
[0]);
5211 case 0x58 ... 0x5f: /* pop */
5213 /* NOTE: order is important for pop %sp */
5214 gen_pop_update(s
, ot
);
5215 gen_op_mov_reg_v(ot
, (b
& 7) | REX_B(s
), cpu_T
[0]);
5217 case 0x60: /* pusha */
5222 case 0x61: /* popa */
5227 case 0x68: /* push Iv */
5229 ot
= mo_pushpop(s
, dflag
);
5231 val
= insn_get(env
, s
, ot
);
5233 val
= (int8_t)insn_get(env
, s
, MO_8
);
5234 tcg_gen_movi_tl(cpu_T
[0], val
);
5235 gen_push_v(s
, cpu_T
[0]);
5237 case 0x8f: /* pop Ev */
5238 modrm
= cpu_ldub_code(env
, s
->pc
++);
5239 mod
= (modrm
>> 6) & 3;
5242 /* NOTE: order is important for pop %sp */
5243 gen_pop_update(s
, ot
);
5244 rm
= (modrm
& 7) | REX_B(s
);
5245 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
5247 /* NOTE: order is important too for MMU exceptions */
5248 s
->popl_esp_hack
= 1 << ot
;
5249 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5250 s
->popl_esp_hack
= 0;
5251 gen_pop_update(s
, ot
);
5254 case 0xc8: /* enter */
5257 val
= cpu_lduw_code(env
, s
->pc
);
5259 level
= cpu_ldub_code(env
, s
->pc
++);
5260 gen_enter(s
, val
, level
);
5263 case 0xc9: /* leave */
5264 /* XXX: exception not precise (ESP is updated before potential exception) */
5266 gen_op_mov_v_reg(MO_64
, cpu_T
[0], R_EBP
);
5267 gen_op_mov_reg_v(MO_64
, R_ESP
, cpu_T
[0]);
5268 } else if (s
->ss32
) {
5269 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EBP
);
5270 gen_op_mov_reg_v(MO_32
, R_ESP
, cpu_T
[0]);
5272 gen_op_mov_v_reg(MO_16
, cpu_T
[0], R_EBP
);
5273 gen_op_mov_reg_v(MO_16
, R_ESP
, cpu_T
[0]);
5276 gen_op_mov_reg_v(ot
, R_EBP
, cpu_T
[0]);
5277 gen_pop_update(s
, ot
);
5279 case 0x06: /* push es */
5280 case 0x0e: /* push cs */
5281 case 0x16: /* push ss */
5282 case 0x1e: /* push ds */
5285 gen_op_movl_T0_seg(b
>> 3);
5286 gen_push_v(s
, cpu_T
[0]);
5288 case 0x1a0: /* push fs */
5289 case 0x1a8: /* push gs */
5290 gen_op_movl_T0_seg((b
>> 3) & 7);
5291 gen_push_v(s
, cpu_T
[0]);
5293 case 0x07: /* pop es */
5294 case 0x17: /* pop ss */
5295 case 0x1f: /* pop ds */
5300 gen_movl_seg_T0(s
, reg
);
5301 gen_pop_update(s
, ot
);
5303 /* if reg == SS, inhibit interrupts/trace. */
5304 /* If several instructions disable interrupts, only the
5306 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
5307 gen_helper_set_inhibit_irq(cpu_env
);
5311 gen_jmp_im(s
->pc
- s
->cs_base
);
5315 case 0x1a1: /* pop fs */
5316 case 0x1a9: /* pop gs */
5318 gen_movl_seg_T0(s
, (b
>> 3) & 7);
5319 gen_pop_update(s
, ot
);
5321 gen_jmp_im(s
->pc
- s
->cs_base
);
5326 /**************************/
5329 case 0x89: /* mov Gv, Ev */
5330 ot
= mo_b_d(b
, dflag
);
5331 modrm
= cpu_ldub_code(env
, s
->pc
++);
5332 reg
= ((modrm
>> 3) & 7) | rex_r
;
5334 /* generate a generic store */
5335 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
5338 case 0xc7: /* mov Ev, Iv */
5339 ot
= mo_b_d(b
, dflag
);
5340 modrm
= cpu_ldub_code(env
, s
->pc
++);
5341 mod
= (modrm
>> 6) & 3;
5343 s
->rip_offset
= insn_const_size(ot
);
5344 gen_lea_modrm(env
, s
, modrm
);
5346 val
= insn_get(env
, s
, ot
);
5347 tcg_gen_movi_tl(cpu_T
[0], val
);
5349 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
5351 gen_op_mov_reg_v(ot
, (modrm
& 7) | REX_B(s
), cpu_T
[0]);
5355 case 0x8b: /* mov Ev, Gv */
5356 ot
= mo_b_d(b
, dflag
);
5357 modrm
= cpu_ldub_code(env
, s
->pc
++);
5358 reg
= ((modrm
>> 3) & 7) | rex_r
;
5360 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5361 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
5363 case 0x8e: /* mov seg, Gv */
5364 modrm
= cpu_ldub_code(env
, s
->pc
++);
5365 reg
= (modrm
>> 3) & 7;
5366 if (reg
>= 6 || reg
== R_CS
)
5368 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
5369 gen_movl_seg_T0(s
, reg
);
5371 /* if reg == SS, inhibit interrupts/trace */
5372 /* If several instructions disable interrupts, only the
5374 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
5375 gen_helper_set_inhibit_irq(cpu_env
);
5379 gen_jmp_im(s
->pc
- s
->cs_base
);
5383 case 0x8c: /* mov Gv, seg */
5384 modrm
= cpu_ldub_code(env
, s
->pc
++);
5385 reg
= (modrm
>> 3) & 7;
5386 mod
= (modrm
>> 6) & 3;
5389 gen_op_movl_T0_seg(reg
);
5390 ot
= mod
== 3 ? dflag
: MO_16
;
5391 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5394 case 0x1b6: /* movzbS Gv, Eb */
5395 case 0x1b7: /* movzwS Gv, Eb */
5396 case 0x1be: /* movsbS Gv, Eb */
5397 case 0x1bf: /* movswS Gv, Eb */
5402 /* d_ot is the size of destination */
5404 /* ot is the size of source */
5405 ot
= (b
& 1) + MO_8
;
5406 /* s_ot is the sign+size of source */
5407 s_ot
= b
& 8 ? MO_SIGN
| ot
: ot
;
5409 modrm
= cpu_ldub_code(env
, s
->pc
++);
5410 reg
= ((modrm
>> 3) & 7) | rex_r
;
5411 mod
= (modrm
>> 6) & 3;
5412 rm
= (modrm
& 7) | REX_B(s
);
5415 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
5418 tcg_gen_ext8u_tl(cpu_T
[0], cpu_T
[0]);
5421 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
5424 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
5428 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5431 gen_op_mov_reg_v(d_ot
, reg
, cpu_T
[0]);
5433 gen_lea_modrm(env
, s
, modrm
);
5434 gen_op_ld_v(s
, s_ot
, cpu_T
[0], cpu_A0
);
5435 gen_op_mov_reg_v(d_ot
, reg
, cpu_T
[0]);
5440 case 0x8d: /* lea */
5442 modrm
= cpu_ldub_code(env
, s
->pc
++);
5443 mod
= (modrm
>> 6) & 3;
5446 reg
= ((modrm
>> 3) & 7) | rex_r
;
5447 /* we must ensure that no segment is added */
5451 gen_lea_modrm(env
, s
, modrm
);
5453 gen_op_mov_reg_v(ot
, reg
, cpu_A0
);
5456 case 0xa0: /* mov EAX, Ov */
5458 case 0xa2: /* mov Ov, EAX */
5461 target_ulong offset_addr
;
5463 ot
= mo_b_d(b
, dflag
);
5465 #ifdef TARGET_X86_64
5467 offset_addr
= cpu_ldq_code(env
, s
->pc
);
5472 offset_addr
= insn_get(env
, s
, s
->aflag
);
5475 tcg_gen_movi_tl(cpu_A0
, offset_addr
);
5476 gen_add_A0_ds_seg(s
);
5478 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
5479 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T
[0]);
5481 gen_op_mov_v_reg(ot
, cpu_T
[0], R_EAX
);
5482 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
5486 case 0xd7: /* xlat */
5487 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EBX
]);
5488 tcg_gen_ext8u_tl(cpu_T
[0], cpu_regs
[R_EAX
]);
5489 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_T
[0]);
5490 gen_extu(s
->aflag
, cpu_A0
);
5491 gen_add_A0_ds_seg(s
);
5492 gen_op_ld_v(s
, MO_8
, cpu_T
[0], cpu_A0
);
5493 gen_op_mov_reg_v(MO_8
, R_EAX
, cpu_T
[0]);
5495 case 0xb0 ... 0xb7: /* mov R, Ib */
5496 val
= insn_get(env
, s
, MO_8
);
5497 tcg_gen_movi_tl(cpu_T
[0], val
);
5498 gen_op_mov_reg_v(MO_8
, (b
& 7) | REX_B(s
), cpu_T
[0]);
5500 case 0xb8 ... 0xbf: /* mov R, Iv */
5501 #ifdef TARGET_X86_64
5502 if (dflag
== MO_64
) {
5505 tmp
= cpu_ldq_code(env
, s
->pc
);
5507 reg
= (b
& 7) | REX_B(s
);
5508 tcg_gen_movi_tl(cpu_T
[0], tmp
);
5509 gen_op_mov_reg_v(MO_64
, reg
, cpu_T
[0]);
5514 val
= insn_get(env
, s
, ot
);
5515 reg
= (b
& 7) | REX_B(s
);
5516 tcg_gen_movi_tl(cpu_T
[0], val
);
5517 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
5521 case 0x91 ... 0x97: /* xchg R, EAX */
5524 reg
= (b
& 7) | REX_B(s
);
5528 case 0x87: /* xchg Ev, Gv */
5529 ot
= mo_b_d(b
, dflag
);
5530 modrm
= cpu_ldub_code(env
, s
->pc
++);
5531 reg
= ((modrm
>> 3) & 7) | rex_r
;
5532 mod
= (modrm
>> 6) & 3;
5534 rm
= (modrm
& 7) | REX_B(s
);
5536 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
5537 gen_op_mov_v_reg(ot
, cpu_T
[1], rm
);
5538 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
5539 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5541 gen_lea_modrm(env
, s
, modrm
);
5542 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
5543 /* for xchg, lock is implicit */
5544 if (!(prefixes
& PREFIX_LOCK
))
5546 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
5547 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
5548 if (!(prefixes
& PREFIX_LOCK
))
5549 gen_helper_unlock();
5550 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5553 case 0xc4: /* les Gv */
5554 /* In CODE64 this is VEX3; see above. */
5557 case 0xc5: /* lds Gv */
5558 /* In CODE64 this is VEX2; see above. */
5561 case 0x1b2: /* lss Gv */
5564 case 0x1b4: /* lfs Gv */
5567 case 0x1b5: /* lgs Gv */
5570 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
5571 modrm
= cpu_ldub_code(env
, s
->pc
++);
5572 reg
= ((modrm
>> 3) & 7) | rex_r
;
5573 mod
= (modrm
>> 6) & 3;
5576 gen_lea_modrm(env
, s
, modrm
);
5577 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
5578 gen_add_A0_im(s
, 1 << ot
);
5579 /* load the segment first to handle exceptions properly */
5580 gen_op_ld_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
5581 gen_movl_seg_T0(s
, op
);
5582 /* then put the data */
5583 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5585 gen_jmp_im(s
->pc
- s
->cs_base
);
5590 /************************/
5598 ot
= mo_b_d(b
, dflag
);
5599 modrm
= cpu_ldub_code(env
, s
->pc
++);
5600 mod
= (modrm
>> 6) & 3;
5601 op
= (modrm
>> 3) & 7;
5607 gen_lea_modrm(env
, s
, modrm
);
5610 opreg
= (modrm
& 7) | REX_B(s
);
5615 gen_shift(s
, op
, ot
, opreg
, OR_ECX
);
5618 shift
= cpu_ldub_code(env
, s
->pc
++);
5620 gen_shifti(s
, op
, ot
, opreg
, shift
);
5635 case 0x1a4: /* shld imm */
5639 case 0x1a5: /* shld cl */
5643 case 0x1ac: /* shrd imm */
5647 case 0x1ad: /* shrd cl */
5652 modrm
= cpu_ldub_code(env
, s
->pc
++);
5653 mod
= (modrm
>> 6) & 3;
5654 rm
= (modrm
& 7) | REX_B(s
);
5655 reg
= ((modrm
>> 3) & 7) | rex_r
;
5657 gen_lea_modrm(env
, s
, modrm
);
5662 gen_op_mov_v_reg(ot
, cpu_T
[1], reg
);
5665 TCGv imm
= tcg_const_tl(cpu_ldub_code(env
, s
->pc
++));
5666 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, imm
);
5669 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, cpu_regs
[R_ECX
]);
5673 /************************/
5676 if (s
->flags
& (HF_EM_MASK
| HF_TS_MASK
)) {
5677 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5678 /* XXX: what to do if illegal op ? */
5679 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
5682 modrm
= cpu_ldub_code(env
, s
->pc
++);
5683 mod
= (modrm
>> 6) & 3;
5685 op
= ((b
& 7) << 3) | ((modrm
>> 3) & 7);
5688 gen_lea_modrm(env
, s
, modrm
);
5690 case 0x00 ... 0x07: /* fxxxs */
5691 case 0x10 ... 0x17: /* fixxxl */
5692 case 0x20 ... 0x27: /* fxxxl */
5693 case 0x30 ... 0x37: /* fixxx */
5700 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5701 s
->mem_index
, MO_LEUL
);
5702 gen_helper_flds_FT0(cpu_env
, cpu_tmp2_i32
);
5705 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5706 s
->mem_index
, MO_LEUL
);
5707 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
5710 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
5711 s
->mem_index
, MO_LEQ
);
5712 gen_helper_fldl_FT0(cpu_env
, cpu_tmp1_i64
);
5716 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5717 s
->mem_index
, MO_LESW
);
5718 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
5722 gen_helper_fp_arith_ST0_FT0(op1
);
5724 /* fcomp needs pop */
5725 gen_helper_fpop(cpu_env
);
5729 case 0x08: /* flds */
5730 case 0x0a: /* fsts */
5731 case 0x0b: /* fstps */
5732 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5733 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5734 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5739 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5740 s
->mem_index
, MO_LEUL
);
5741 gen_helper_flds_ST0(cpu_env
, cpu_tmp2_i32
);
5744 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5745 s
->mem_index
, MO_LEUL
);
5746 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
5749 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
5750 s
->mem_index
, MO_LEQ
);
5751 gen_helper_fldl_ST0(cpu_env
, cpu_tmp1_i64
);
5755 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5756 s
->mem_index
, MO_LESW
);
5757 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
5762 /* XXX: the corresponding CPUID bit must be tested ! */
5765 gen_helper_fisttl_ST0(cpu_tmp2_i32
, cpu_env
);
5766 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5767 s
->mem_index
, MO_LEUL
);
5770 gen_helper_fisttll_ST0(cpu_tmp1_i64
, cpu_env
);
5771 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
5772 s
->mem_index
, MO_LEQ
);
5776 gen_helper_fistt_ST0(cpu_tmp2_i32
, cpu_env
);
5777 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5778 s
->mem_index
, MO_LEUW
);
5781 gen_helper_fpop(cpu_env
);
5786 gen_helper_fsts_ST0(cpu_tmp2_i32
, cpu_env
);
5787 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5788 s
->mem_index
, MO_LEUL
);
5791 gen_helper_fistl_ST0(cpu_tmp2_i32
, cpu_env
);
5792 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5793 s
->mem_index
, MO_LEUL
);
5796 gen_helper_fstl_ST0(cpu_tmp1_i64
, cpu_env
);
5797 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
5798 s
->mem_index
, MO_LEQ
);
5802 gen_helper_fist_ST0(cpu_tmp2_i32
, cpu_env
);
5803 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5804 s
->mem_index
, MO_LEUW
);
5808 gen_helper_fpop(cpu_env
);
5812 case 0x0c: /* fldenv mem */
5813 gen_helper_fldenv(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5815 case 0x0d: /* fldcw mem */
5816 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5817 s
->mem_index
, MO_LEUW
);
5818 gen_helper_fldcw(cpu_env
, cpu_tmp2_i32
);
5820 case 0x0e: /* fnstenv mem */
5821 gen_helper_fstenv(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5823 case 0x0f: /* fnstcw mem */
5824 gen_helper_fnstcw(cpu_tmp2_i32
, cpu_env
);
5825 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5826 s
->mem_index
, MO_LEUW
);
5828 case 0x1d: /* fldt mem */
5829 gen_helper_fldt_ST0(cpu_env
, cpu_A0
);
5831 case 0x1f: /* fstpt mem */
5832 gen_helper_fstt_ST0(cpu_env
, cpu_A0
);
5833 gen_helper_fpop(cpu_env
);
5835 case 0x2c: /* frstor mem */
5836 gen_helper_frstor(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5838 case 0x2e: /* fnsave mem */
5839 gen_helper_fsave(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5841 case 0x2f: /* fnstsw mem */
5842 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
5843 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5844 s
->mem_index
, MO_LEUW
);
5846 case 0x3c: /* fbld */
5847 gen_helper_fbld_ST0(cpu_env
, cpu_A0
);
5849 case 0x3e: /* fbstp */
5850 gen_helper_fbst_ST0(cpu_env
, cpu_A0
);
5851 gen_helper_fpop(cpu_env
);
5853 case 0x3d: /* fildll */
5854 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
5855 gen_helper_fildll_ST0(cpu_env
, cpu_tmp1_i64
);
5857 case 0x3f: /* fistpll */
5858 gen_helper_fistll_ST0(cpu_tmp1_i64
, cpu_env
);
5859 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
5860 gen_helper_fpop(cpu_env
);
5866 /* register float ops */
5870 case 0x08: /* fld sti */
5871 gen_helper_fpush(cpu_env
);
5872 gen_helper_fmov_ST0_STN(cpu_env
,
5873 tcg_const_i32((opreg
+ 1) & 7));
5875 case 0x09: /* fxchg sti */
5876 case 0x29: /* fxchg4 sti, undocumented op */
5877 case 0x39: /* fxchg7 sti, undocumented op */
5878 gen_helper_fxchg_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
5880 case 0x0a: /* grp d9/2 */
5883 /* check exceptions (FreeBSD FPU probe) */
5884 gen_helper_fwait(cpu_env
);
5890 case 0x0c: /* grp d9/4 */
5893 gen_helper_fchs_ST0(cpu_env
);
5896 gen_helper_fabs_ST0(cpu_env
);
5899 gen_helper_fldz_FT0(cpu_env
);
5900 gen_helper_fcom_ST0_FT0(cpu_env
);
5903 gen_helper_fxam_ST0(cpu_env
);
5909 case 0x0d: /* grp d9/5 */
5913 gen_helper_fpush(cpu_env
);
5914 gen_helper_fld1_ST0(cpu_env
);
5917 gen_helper_fpush(cpu_env
);
5918 gen_helper_fldl2t_ST0(cpu_env
);
5921 gen_helper_fpush(cpu_env
);
5922 gen_helper_fldl2e_ST0(cpu_env
);
5925 gen_helper_fpush(cpu_env
);
5926 gen_helper_fldpi_ST0(cpu_env
);
5929 gen_helper_fpush(cpu_env
);
5930 gen_helper_fldlg2_ST0(cpu_env
);
5933 gen_helper_fpush(cpu_env
);
5934 gen_helper_fldln2_ST0(cpu_env
);
5937 gen_helper_fpush(cpu_env
);
5938 gen_helper_fldz_ST0(cpu_env
);
5945 case 0x0e: /* grp d9/6 */
5948 gen_helper_f2xm1(cpu_env
);
5951 gen_helper_fyl2x(cpu_env
);
5954 gen_helper_fptan(cpu_env
);
5956 case 3: /* fpatan */
5957 gen_helper_fpatan(cpu_env
);
5959 case 4: /* fxtract */
5960 gen_helper_fxtract(cpu_env
);
5962 case 5: /* fprem1 */
5963 gen_helper_fprem1(cpu_env
);
5965 case 6: /* fdecstp */
5966 gen_helper_fdecstp(cpu_env
);
5969 case 7: /* fincstp */
5970 gen_helper_fincstp(cpu_env
);
5974 case 0x0f: /* grp d9/7 */
5977 gen_helper_fprem(cpu_env
);
5979 case 1: /* fyl2xp1 */
5980 gen_helper_fyl2xp1(cpu_env
);
5983 gen_helper_fsqrt(cpu_env
);
5985 case 3: /* fsincos */
5986 gen_helper_fsincos(cpu_env
);
5988 case 5: /* fscale */
5989 gen_helper_fscale(cpu_env
);
5991 case 4: /* frndint */
5992 gen_helper_frndint(cpu_env
);
5995 gen_helper_fsin(cpu_env
);
5999 gen_helper_fcos(cpu_env
);
6003 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6004 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6005 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6011 gen_helper_fp_arith_STN_ST0(op1
, opreg
);
6013 gen_helper_fpop(cpu_env
);
6015 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6016 gen_helper_fp_arith_ST0_FT0(op1
);
6020 case 0x02: /* fcom */
6021 case 0x22: /* fcom2, undocumented op */
6022 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6023 gen_helper_fcom_ST0_FT0(cpu_env
);
6025 case 0x03: /* fcomp */
6026 case 0x23: /* fcomp3, undocumented op */
6027 case 0x32: /* fcomp5, undocumented op */
6028 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6029 gen_helper_fcom_ST0_FT0(cpu_env
);
6030 gen_helper_fpop(cpu_env
);
6032 case 0x15: /* da/5 */
6034 case 1: /* fucompp */
6035 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6036 gen_helper_fucom_ST0_FT0(cpu_env
);
6037 gen_helper_fpop(cpu_env
);
6038 gen_helper_fpop(cpu_env
);
6046 case 0: /* feni (287 only, just do nop here) */
6048 case 1: /* fdisi (287 only, just do nop here) */
6051 gen_helper_fclex(cpu_env
);
6053 case 3: /* fninit */
6054 gen_helper_fninit(cpu_env
);
6056 case 4: /* fsetpm (287 only, just do nop here) */
6062 case 0x1d: /* fucomi */
6063 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6066 gen_update_cc_op(s
);
6067 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6068 gen_helper_fucomi_ST0_FT0(cpu_env
);
6069 set_cc_op(s
, CC_OP_EFLAGS
);
6071 case 0x1e: /* fcomi */
6072 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6075 gen_update_cc_op(s
);
6076 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6077 gen_helper_fcomi_ST0_FT0(cpu_env
);
6078 set_cc_op(s
, CC_OP_EFLAGS
);
6080 case 0x28: /* ffree sti */
6081 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6083 case 0x2a: /* fst sti */
6084 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6086 case 0x2b: /* fstp sti */
6087 case 0x0b: /* fstp1 sti, undocumented op */
6088 case 0x3a: /* fstp8 sti, undocumented op */
6089 case 0x3b: /* fstp9 sti, undocumented op */
6090 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6091 gen_helper_fpop(cpu_env
);
6093 case 0x2c: /* fucom st(i) */
6094 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6095 gen_helper_fucom_ST0_FT0(cpu_env
);
6097 case 0x2d: /* fucomp st(i) */
6098 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6099 gen_helper_fucom_ST0_FT0(cpu_env
);
6100 gen_helper_fpop(cpu_env
);
6102 case 0x33: /* de/3 */
6104 case 1: /* fcompp */
6105 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6106 gen_helper_fcom_ST0_FT0(cpu_env
);
6107 gen_helper_fpop(cpu_env
);
6108 gen_helper_fpop(cpu_env
);
6114 case 0x38: /* ffreep sti, undocumented op */
6115 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6116 gen_helper_fpop(cpu_env
);
6118 case 0x3c: /* df/4 */
6121 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
6122 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6123 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
6129 case 0x3d: /* fucomip */
6130 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6133 gen_update_cc_op(s
);
6134 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6135 gen_helper_fucomi_ST0_FT0(cpu_env
);
6136 gen_helper_fpop(cpu_env
);
6137 set_cc_op(s
, CC_OP_EFLAGS
);
6139 case 0x3e: /* fcomip */
6140 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6143 gen_update_cc_op(s
);
6144 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6145 gen_helper_fcomi_ST0_FT0(cpu_env
);
6146 gen_helper_fpop(cpu_env
);
6147 set_cc_op(s
, CC_OP_EFLAGS
);
6149 case 0x10 ... 0x13: /* fcmovxx */
6154 static const uint8_t fcmov_cc
[8] = {
6161 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6164 op1
= fcmov_cc
[op
& 3] | (((op
>> 3) & 1) ^ 1);
6165 l1
= gen_new_label();
6166 gen_jcc1_noeob(s
, op1
, l1
);
6167 gen_helper_fmov_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6176 /************************/
6179 case 0xa4: /* movsS */
6181 ot
= mo_b_d(b
, dflag
);
6182 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6183 gen_repz_movs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6189 case 0xaa: /* stosS */
6191 ot
= mo_b_d(b
, dflag
);
6192 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6193 gen_repz_stos(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6198 case 0xac: /* lodsS */
6200 ot
= mo_b_d(b
, dflag
);
6201 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6202 gen_repz_lods(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6207 case 0xae: /* scasS */
6209 ot
= mo_b_d(b
, dflag
);
6210 if (prefixes
& PREFIX_REPNZ
) {
6211 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6212 } else if (prefixes
& PREFIX_REPZ
) {
6213 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6219 case 0xa6: /* cmpsS */
6221 ot
= mo_b_d(b
, dflag
);
6222 if (prefixes
& PREFIX_REPNZ
) {
6223 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6224 } else if (prefixes
& PREFIX_REPZ
) {
6225 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6230 case 0x6c: /* insS */
6232 ot
= mo_b_d32(b
, dflag
);
6233 tcg_gen_ext16u_tl(cpu_T
[0], cpu_regs
[R_EDX
]);
6234 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6235 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
) | 4);
6236 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6237 gen_repz_ins(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6240 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6241 gen_jmp(s
, s
->pc
- s
->cs_base
);
6245 case 0x6e: /* outsS */
6247 ot
= mo_b_d32(b
, dflag
);
6248 tcg_gen_ext16u_tl(cpu_T
[0], cpu_regs
[R_EDX
]);
6249 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6250 svm_is_rep(prefixes
) | 4);
6251 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6252 gen_repz_outs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6255 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6256 gen_jmp(s
, s
->pc
- s
->cs_base
);
6261 /************************/
6266 ot
= mo_b_d32(b
, dflag
);
6267 val
= cpu_ldub_code(env
, s
->pc
++);
6268 tcg_gen_movi_tl(cpu_T
[0], val
);
6269 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6270 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6271 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6274 tcg_gen_movi_i32(cpu_tmp2_i32
, val
);
6275 gen_helper_in_func(ot
, cpu_T
[1], cpu_tmp2_i32
);
6276 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T
[1]);
6277 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6279 gen_jmp(s
, s
->pc
- s
->cs_base
);
6284 ot
= mo_b_d32(b
, dflag
);
6285 val
= cpu_ldub_code(env
, s
->pc
++);
6286 tcg_gen_movi_tl(cpu_T
[0], val
);
6287 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6288 svm_is_rep(prefixes
));
6289 gen_op_mov_v_reg(ot
, cpu_T
[1], R_EAX
);
6291 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6294 tcg_gen_movi_i32(cpu_tmp2_i32
, val
);
6295 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
6296 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6297 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6299 gen_jmp(s
, s
->pc
- s
->cs_base
);
6304 ot
= mo_b_d32(b
, dflag
);
6305 tcg_gen_ext16u_tl(cpu_T
[0], cpu_regs
[R_EDX
]);
6306 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6307 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6308 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6311 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6312 gen_helper_in_func(ot
, cpu_T
[1], cpu_tmp2_i32
);
6313 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T
[1]);
6314 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6316 gen_jmp(s
, s
->pc
- s
->cs_base
);
6321 ot
= mo_b_d32(b
, dflag
);
6322 tcg_gen_ext16u_tl(cpu_T
[0], cpu_regs
[R_EDX
]);
6323 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6324 svm_is_rep(prefixes
));
6325 gen_op_mov_v_reg(ot
, cpu_T
[1], R_EAX
);
6327 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6330 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6331 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
6332 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6333 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6335 gen_jmp(s
, s
->pc
- s
->cs_base
);
6339 /************************/
6341 case 0xc2: /* ret im */
6342 val
= cpu_ldsw_code(env
, s
->pc
);
6345 gen_stack_update(s
, val
+ (1 << ot
));
6346 /* Note that gen_pop_T0 uses a zero-extending load. */
6347 gen_op_jmp_v(cpu_T
[0]);
6350 case 0xc3: /* ret */
6352 gen_pop_update(s
, ot
);
6353 /* Note that gen_pop_T0 uses a zero-extending load. */
6354 gen_op_jmp_v(cpu_T
[0]);
6357 case 0xca: /* lret im */
6358 val
= cpu_ldsw_code(env
, s
->pc
);
6361 if (s
->pe
&& !s
->vm86
) {
6362 gen_update_cc_op(s
);
6363 gen_jmp_im(pc_start
- s
->cs_base
);
6364 gen_helper_lret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6365 tcg_const_i32(val
));
6369 gen_op_ld_v(s
, dflag
, cpu_T
[0], cpu_A0
);
6370 /* NOTE: keeping EIP updated is not a problem in case of
6372 gen_op_jmp_v(cpu_T
[0]);
6374 gen_op_addl_A0_im(1 << dflag
);
6375 gen_op_ld_v(s
, dflag
, cpu_T
[0], cpu_A0
);
6376 gen_op_movl_seg_T0_vm(R_CS
);
6377 /* add stack offset */
6378 gen_stack_update(s
, val
+ (2 << dflag
));
6382 case 0xcb: /* lret */
6385 case 0xcf: /* iret */
6386 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IRET
);
6389 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6390 set_cc_op(s
, CC_OP_EFLAGS
);
6391 } else if (s
->vm86
) {
6393 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6395 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6396 set_cc_op(s
, CC_OP_EFLAGS
);
6399 gen_helper_iret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6400 tcg_const_i32(s
->pc
- s
->cs_base
));
6401 set_cc_op(s
, CC_OP_EFLAGS
);
6405 case 0xe8: /* call im */
6407 if (dflag
!= MO_16
) {
6408 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6410 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6412 next_eip
= s
->pc
- s
->cs_base
;
6414 if (dflag
== MO_16
) {
6416 } else if (!CODE64(s
)) {
6419 tcg_gen_movi_tl(cpu_T
[0], next_eip
);
6420 gen_push_v(s
, cpu_T
[0]);
6424 case 0x9a: /* lcall im */
6426 unsigned int selector
, offset
;
6431 offset
= insn_get(env
, s
, ot
);
6432 selector
= insn_get(env
, s
, MO_16
);
6434 tcg_gen_movi_tl(cpu_T
[0], selector
);
6435 tcg_gen_movi_tl(cpu_T
[1], offset
);
6438 case 0xe9: /* jmp im */
6439 if (dflag
!= MO_16
) {
6440 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6442 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6444 tval
+= s
->pc
- s
->cs_base
;
6445 if (dflag
== MO_16
) {
6447 } else if (!CODE64(s
)) {
6452 case 0xea: /* ljmp im */
6454 unsigned int selector
, offset
;
6459 offset
= insn_get(env
, s
, ot
);
6460 selector
= insn_get(env
, s
, MO_16
);
6462 tcg_gen_movi_tl(cpu_T
[0], selector
);
6463 tcg_gen_movi_tl(cpu_T
[1], offset
);
6466 case 0xeb: /* jmp Jb */
6467 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6468 tval
+= s
->pc
- s
->cs_base
;
6469 if (dflag
== MO_16
) {
6474 case 0x70 ... 0x7f: /* jcc Jb */
6475 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6477 case 0x180 ... 0x18f: /* jcc Jv */
6478 if (dflag
!= MO_16
) {
6479 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6481 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6484 next_eip
= s
->pc
- s
->cs_base
;
6486 if (dflag
== MO_16
) {
6489 gen_jcc(s
, b
, tval
, next_eip
);
6492 case 0x190 ... 0x19f: /* setcc Gv */
6493 modrm
= cpu_ldub_code(env
, s
->pc
++);
6494 gen_setcc1(s
, b
, cpu_T
[0]);
6495 gen_ldst_modrm(env
, s
, modrm
, MO_8
, OR_TMP0
, 1);
6497 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6498 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6502 modrm
= cpu_ldub_code(env
, s
->pc
++);
6503 reg
= ((modrm
>> 3) & 7) | rex_r
;
6504 gen_cmovcc1(env
, s
, ot
, b
, modrm
, reg
);
6507 /************************/
6509 case 0x9c: /* pushf */
6510 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_PUSHF
);
6511 if (s
->vm86
&& s
->iopl
!= 3) {
6512 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6514 gen_update_cc_op(s
);
6515 gen_helper_read_eflags(cpu_T
[0], cpu_env
);
6516 gen_push_v(s
, cpu_T
[0]);
6519 case 0x9d: /* popf */
6520 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_POPF
);
6521 if (s
->vm86
&& s
->iopl
!= 3) {
6522 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6526 if (dflag
!= MO_16
) {
6527 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6528 tcg_const_i32((TF_MASK
| AC_MASK
|
6533 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6534 tcg_const_i32((TF_MASK
| AC_MASK
|
6536 IF_MASK
| IOPL_MASK
)
6540 if (s
->cpl
<= s
->iopl
) {
6541 if (dflag
!= MO_16
) {
6542 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6543 tcg_const_i32((TF_MASK
|
6549 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6550 tcg_const_i32((TF_MASK
|
6558 if (dflag
!= MO_16
) {
6559 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6560 tcg_const_i32((TF_MASK
| AC_MASK
|
6561 ID_MASK
| NT_MASK
)));
6563 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6564 tcg_const_i32((TF_MASK
| AC_MASK
|
6570 gen_pop_update(s
, ot
);
6571 set_cc_op(s
, CC_OP_EFLAGS
);
6572 /* abort translation because TF/AC flag may change */
6573 gen_jmp_im(s
->pc
- s
->cs_base
);
6577 case 0x9e: /* sahf */
6578 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6580 gen_op_mov_v_reg(MO_8
, cpu_T
[0], R_AH
);
6581 gen_compute_eflags(s
);
6582 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, CC_O
);
6583 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], CC_S
| CC_Z
| CC_A
| CC_P
| CC_C
);
6584 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, cpu_T
[0]);
6586 case 0x9f: /* lahf */
6587 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6589 gen_compute_eflags(s
);
6590 /* Note: gen_compute_eflags() only gives the condition codes */
6591 tcg_gen_ori_tl(cpu_T
[0], cpu_cc_src
, 0x02);
6592 gen_op_mov_reg_v(MO_8
, R_AH
, cpu_T
[0]);
6594 case 0xf5: /* cmc */
6595 gen_compute_eflags(s
);
6596 tcg_gen_xori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6598 case 0xf8: /* clc */
6599 gen_compute_eflags(s
);
6600 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_C
);
6602 case 0xf9: /* stc */
6603 gen_compute_eflags(s
);
6604 tcg_gen_ori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6606 case 0xfc: /* cld */
6607 tcg_gen_movi_i32(cpu_tmp2_i32
, 1);
6608 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6610 case 0xfd: /* std */
6611 tcg_gen_movi_i32(cpu_tmp2_i32
, -1);
6612 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6615 /************************/
6616 /* bit operations */
6617 case 0x1ba: /* bt/bts/btr/btc Gv, im */
6619 modrm
= cpu_ldub_code(env
, s
->pc
++);
6620 op
= (modrm
>> 3) & 7;
6621 mod
= (modrm
>> 6) & 3;
6622 rm
= (modrm
& 7) | REX_B(s
);
6625 gen_lea_modrm(env
, s
, modrm
);
6626 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
6628 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
6631 val
= cpu_ldub_code(env
, s
->pc
++);
6632 tcg_gen_movi_tl(cpu_T
[1], val
);
6637 case 0x1a3: /* bt Gv, Ev */
6640 case 0x1ab: /* bts */
6643 case 0x1b3: /* btr */
6646 case 0x1bb: /* btc */
6650 modrm
= cpu_ldub_code(env
, s
->pc
++);
6651 reg
= ((modrm
>> 3) & 7) | rex_r
;
6652 mod
= (modrm
>> 6) & 3;
6653 rm
= (modrm
& 7) | REX_B(s
);
6654 gen_op_mov_v_reg(MO_32
, cpu_T
[1], reg
);
6656 gen_lea_modrm(env
, s
, modrm
);
6657 /* specific case: we need to add a displacement */
6658 gen_exts(ot
, cpu_T
[1]);
6659 tcg_gen_sari_tl(cpu_tmp0
, cpu_T
[1], 3 + ot
);
6660 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, ot
);
6661 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
6662 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
6664 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
6667 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], (1 << (3 + ot
)) - 1);
6668 tcg_gen_shr_tl(cpu_tmp4
, cpu_T
[0], cpu_T
[1]);
6673 tcg_gen_movi_tl(cpu_tmp0
, 1);
6674 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
6675 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
6678 tcg_gen_movi_tl(cpu_tmp0
, 1);
6679 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
6680 tcg_gen_andc_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
6684 tcg_gen_movi_tl(cpu_tmp0
, 1);
6685 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
6686 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
6691 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
6693 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
6697 /* Delay all CC updates until after the store above. Note that
6698 C is the result of the test, Z is unchanged, and the others
6699 are all undefined. */
6701 case CC_OP_MULB
... CC_OP_MULQ
:
6702 case CC_OP_ADDB
... CC_OP_ADDQ
:
6703 case CC_OP_ADCB
... CC_OP_ADCQ
:
6704 case CC_OP_SUBB
... CC_OP_SUBQ
:
6705 case CC_OP_SBBB
... CC_OP_SBBQ
:
6706 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
6707 case CC_OP_INCB
... CC_OP_INCQ
:
6708 case CC_OP_DECB
... CC_OP_DECQ
:
6709 case CC_OP_SHLB
... CC_OP_SHLQ
:
6710 case CC_OP_SARB
... CC_OP_SARQ
:
6711 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
6712 /* Z was going to be computed from the non-zero status of CC_DST.
6713 We can get that same Z value (and the new C value) by leaving
6714 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
6716 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
6717 set_cc_op(s
, ((s
->cc_op
- CC_OP_MULB
) & 3) + CC_OP_SARB
);
6720 /* Otherwise, generate EFLAGS and replace the C bit. */
6721 gen_compute_eflags(s
);
6722 tcg_gen_deposit_tl(cpu_cc_src
, cpu_cc_src
, cpu_tmp4
,
6727 case 0x1bc: /* bsf / tzcnt */
6728 case 0x1bd: /* bsr / lzcnt */
6730 modrm
= cpu_ldub_code(env
, s
->pc
++);
6731 reg
= ((modrm
>> 3) & 7) | rex_r
;
6732 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
6733 gen_extu(ot
, cpu_T
[0]);
6735 /* Note that lzcnt and tzcnt are in different extensions. */
6736 if ((prefixes
& PREFIX_REPZ
)
6738 ? s
->cpuid_ext3_features
& CPUID_EXT3_ABM
6739 : s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)) {
6741 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
6743 /* For lzcnt, reduce the target_ulong result by the
6744 number of zeros that we expect to find at the top. */
6745 gen_helper_clz(cpu_T
[0], cpu_T
[0]);
6746 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], TARGET_LONG_BITS
- size
);
6748 /* For tzcnt, a zero input must return the operand size:
6749 force all bits outside the operand size to 1. */
6750 target_ulong mask
= (target_ulong
)-2 << (size
- 1);
6751 tcg_gen_ori_tl(cpu_T
[0], cpu_T
[0], mask
);
6752 gen_helper_ctz(cpu_T
[0], cpu_T
[0]);
6754 /* For lzcnt/tzcnt, C and Z bits are defined and are
6755 related to the result. */
6756 gen_op_update1_cc();
6757 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
6759 /* For bsr/bsf, only the Z bit is defined and it is related
6760 to the input and not the result. */
6761 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
6762 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
6764 /* For bsr, return the bit index of the first 1 bit,
6765 not the count of leading zeros. */
6766 gen_helper_clz(cpu_T
[0], cpu_T
[0]);
6767 tcg_gen_xori_tl(cpu_T
[0], cpu_T
[0], TARGET_LONG_BITS
- 1);
6769 gen_helper_ctz(cpu_T
[0], cpu_T
[0]);
6771 /* ??? The manual says that the output is undefined when the
6772 input is zero, but real hardware leaves it unchanged, and
6773 real programs appear to depend on that. */
6774 tcg_gen_movi_tl(cpu_tmp0
, 0);
6775 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_T
[0], cpu_cc_dst
, cpu_tmp0
,
6776 cpu_regs
[reg
], cpu_T
[0]);
6778 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
6780 /************************/
6782 case 0x27: /* daa */
6785 gen_update_cc_op(s
);
6786 gen_helper_daa(cpu_env
);
6787 set_cc_op(s
, CC_OP_EFLAGS
);
6789 case 0x2f: /* das */
6792 gen_update_cc_op(s
);
6793 gen_helper_das(cpu_env
);
6794 set_cc_op(s
, CC_OP_EFLAGS
);
6796 case 0x37: /* aaa */
6799 gen_update_cc_op(s
);
6800 gen_helper_aaa(cpu_env
);
6801 set_cc_op(s
, CC_OP_EFLAGS
);
6803 case 0x3f: /* aas */
6806 gen_update_cc_op(s
);
6807 gen_helper_aas(cpu_env
);
6808 set_cc_op(s
, CC_OP_EFLAGS
);
6810 case 0xd4: /* aam */
6813 val
= cpu_ldub_code(env
, s
->pc
++);
6815 gen_exception(s
, EXCP00_DIVZ
, pc_start
- s
->cs_base
);
6817 gen_helper_aam(cpu_env
, tcg_const_i32(val
));
6818 set_cc_op(s
, CC_OP_LOGICB
);
6821 case 0xd5: /* aad */
6824 val
= cpu_ldub_code(env
, s
->pc
++);
6825 gen_helper_aad(cpu_env
, tcg_const_i32(val
));
6826 set_cc_op(s
, CC_OP_LOGICB
);
6828 /************************/
6830 case 0x90: /* nop */
6831 /* XXX: correct lock test for all insn */
6832 if (prefixes
& PREFIX_LOCK
) {
6835 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
6837 goto do_xchg_reg_eax
;
6839 if (prefixes
& PREFIX_REPZ
) {
6840 gen_update_cc_op(s
);
6841 gen_jmp_im(pc_start
- s
->cs_base
);
6842 gen_helper_pause(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
6843 s
->is_jmp
= DISAS_TB_JUMP
;
6846 case 0x9b: /* fwait */
6847 if ((s
->flags
& (HF_MP_MASK
| HF_TS_MASK
)) ==
6848 (HF_MP_MASK
| HF_TS_MASK
)) {
6849 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
6851 gen_helper_fwait(cpu_env
);
6854 case 0xcc: /* int3 */
6855 gen_interrupt(s
, EXCP03_INT3
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6857 case 0xcd: /* int N */
6858 val
= cpu_ldub_code(env
, s
->pc
++);
6859 if (s
->vm86
&& s
->iopl
!= 3) {
6860 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6862 gen_interrupt(s
, val
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6865 case 0xce: /* into */
6868 gen_update_cc_op(s
);
6869 gen_jmp_im(pc_start
- s
->cs_base
);
6870 gen_helper_into(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
6873 case 0xf1: /* icebp (undocumented, exits to external debugger) */
6874 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_ICEBP
);
6876 gen_debug(s
, pc_start
- s
->cs_base
);
6879 tb_flush(CPU(x86_env_get_cpu(env
)));
6880 qemu_set_log(CPU_LOG_INT
| CPU_LOG_TB_IN_ASM
);
6884 case 0xfa: /* cli */
6886 if (s
->cpl
<= s
->iopl
) {
6887 gen_helper_cli(cpu_env
);
6889 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6893 gen_helper_cli(cpu_env
);
6895 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6899 case 0xfb: /* sti */
6901 if (s
->cpl
<= s
->iopl
) {
6903 gen_helper_sti(cpu_env
);
6904 /* interruptions are enabled only the first insn after sti */
6905 /* If several instructions disable interrupts, only the
6907 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
6908 gen_helper_set_inhibit_irq(cpu_env
);
6909 /* give a chance to handle pending irqs */
6910 gen_jmp_im(s
->pc
- s
->cs_base
);
6913 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6919 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6923 case 0x62: /* bound */
6927 modrm
= cpu_ldub_code(env
, s
->pc
++);
6928 reg
= (modrm
>> 3) & 7;
6929 mod
= (modrm
>> 6) & 3;
6932 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
6933 gen_lea_modrm(env
, s
, modrm
);
6934 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6936 gen_helper_boundw(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
6938 gen_helper_boundl(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
6941 case 0x1c8 ... 0x1cf: /* bswap reg */
6942 reg
= (b
& 7) | REX_B(s
);
6943 #ifdef TARGET_X86_64
6944 if (dflag
== MO_64
) {
6945 gen_op_mov_v_reg(MO_64
, cpu_T
[0], reg
);
6946 tcg_gen_bswap64_i64(cpu_T
[0], cpu_T
[0]);
6947 gen_op_mov_reg_v(MO_64
, reg
, cpu_T
[0]);
6951 gen_op_mov_v_reg(MO_32
, cpu_T
[0], reg
);
6952 tcg_gen_ext32u_tl(cpu_T
[0], cpu_T
[0]);
6953 tcg_gen_bswap32_tl(cpu_T
[0], cpu_T
[0]);
6954 gen_op_mov_reg_v(MO_32
, reg
, cpu_T
[0]);
6957 case 0xd6: /* salc */
6960 gen_compute_eflags_c(s
, cpu_T
[0]);
6961 tcg_gen_neg_tl(cpu_T
[0], cpu_T
[0]);
6962 gen_op_mov_reg_v(MO_8
, R_EAX
, cpu_T
[0]);
6964 case 0xe0: /* loopnz */
6965 case 0xe1: /* loopz */
6966 case 0xe2: /* loop */
6967 case 0xe3: /* jecxz */
6969 TCGLabel
*l1
, *l2
, *l3
;
6971 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6972 next_eip
= s
->pc
- s
->cs_base
;
6974 if (dflag
== MO_16
) {
6978 l1
= gen_new_label();
6979 l2
= gen_new_label();
6980 l3
= gen_new_label();
6983 case 0: /* loopnz */
6985 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
6986 gen_op_jz_ecx(s
->aflag
, l3
);
6987 gen_jcc1(s
, (JCC_Z
<< 1) | (b
^ 1), l1
);
6990 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
6991 gen_op_jnz_ecx(s
->aflag
, l1
);
6995 gen_op_jz_ecx(s
->aflag
, l1
);
7000 gen_jmp_im(next_eip
);
7009 case 0x130: /* wrmsr */
7010 case 0x132: /* rdmsr */
7012 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7014 gen_update_cc_op(s
);
7015 gen_jmp_im(pc_start
- s
->cs_base
);
7017 gen_helper_rdmsr(cpu_env
);
7019 gen_helper_wrmsr(cpu_env
);
7023 case 0x131: /* rdtsc */
7024 gen_update_cc_op(s
);
7025 gen_jmp_im(pc_start
- s
->cs_base
);
7026 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7029 gen_helper_rdtsc(cpu_env
);
7030 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7032 gen_jmp(s
, s
->pc
- s
->cs_base
);
7035 case 0x133: /* rdpmc */
7036 gen_update_cc_op(s
);
7037 gen_jmp_im(pc_start
- s
->cs_base
);
7038 gen_helper_rdpmc(cpu_env
);
7040 case 0x134: /* sysenter */
7041 /* For Intel SYSENTER is valid on 64-bit */
7042 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7045 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7047 gen_helper_sysenter(cpu_env
);
7051 case 0x135: /* sysexit */
7052 /* For Intel SYSEXIT is valid on 64-bit */
7053 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7056 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7058 gen_helper_sysexit(cpu_env
, tcg_const_i32(dflag
- 1));
7062 #ifdef TARGET_X86_64
7063 case 0x105: /* syscall */
7064 /* XXX: is it usable in real mode ? */
7065 gen_update_cc_op(s
);
7066 gen_jmp_im(pc_start
- s
->cs_base
);
7067 gen_helper_syscall(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7070 case 0x107: /* sysret */
7072 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7074 gen_helper_sysret(cpu_env
, tcg_const_i32(dflag
- 1));
7075 /* condition codes are modified only in long mode */
7077 set_cc_op(s
, CC_OP_EFLAGS
);
7083 case 0x1a2: /* cpuid */
7084 gen_update_cc_op(s
);
7085 gen_jmp_im(pc_start
- s
->cs_base
);
7086 gen_helper_cpuid(cpu_env
);
7088 case 0xf4: /* hlt */
7090 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7092 gen_update_cc_op(s
);
7093 gen_jmp_im(pc_start
- s
->cs_base
);
7094 gen_helper_hlt(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7095 s
->is_jmp
= DISAS_TB_JUMP
;
7099 modrm
= cpu_ldub_code(env
, s
->pc
++);
7100 mod
= (modrm
>> 6) & 3;
7101 op
= (modrm
>> 3) & 7;
7104 if (!s
->pe
|| s
->vm86
)
7106 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_READ
);
7107 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,ldt
.selector
));
7108 ot
= mod
== 3 ? dflag
: MO_16
;
7109 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7112 if (!s
->pe
|| s
->vm86
)
7115 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7117 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_WRITE
);
7118 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7119 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
7120 gen_helper_lldt(cpu_env
, cpu_tmp2_i32
);
7124 if (!s
->pe
|| s
->vm86
)
7126 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_READ
);
7127 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,tr
.selector
));
7128 ot
= mod
== 3 ? dflag
: MO_16
;
7129 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7132 if (!s
->pe
|| s
->vm86
)
7135 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7137 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_WRITE
);
7138 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7139 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
7140 gen_helper_ltr(cpu_env
, cpu_tmp2_i32
);
7145 if (!s
->pe
|| s
->vm86
)
7147 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7148 gen_update_cc_op(s
);
7150 gen_helper_verr(cpu_env
, cpu_T
[0]);
7152 gen_helper_verw(cpu_env
, cpu_T
[0]);
7154 set_cc_op(s
, CC_OP_EFLAGS
);
7161 modrm
= cpu_ldub_code(env
, s
->pc
++);
7162 mod
= (modrm
>> 6) & 3;
7163 op
= (modrm
>> 3) & 7;
7169 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_READ
);
7170 gen_lea_modrm(env
, s
, modrm
);
7171 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7172 gen_op_st_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
7173 gen_add_A0_im(s
, 2);
7174 tcg_gen_ld_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7175 if (dflag
== MO_16
) {
7176 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffffff);
7178 gen_op_st_v(s
, CODE64(s
) + MO_32
, cpu_T
[0], cpu_A0
);
7183 case 0: /* monitor */
7184 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) ||
7187 gen_update_cc_op(s
);
7188 gen_jmp_im(pc_start
- s
->cs_base
);
7189 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EAX
]);
7190 gen_extu(s
->aflag
, cpu_A0
);
7191 gen_add_A0_ds_seg(s
);
7192 gen_helper_monitor(cpu_env
, cpu_A0
);
7195 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) ||
7198 gen_update_cc_op(s
);
7199 gen_jmp_im(pc_start
- s
->cs_base
);
7200 gen_helper_mwait(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7204 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
) ||
7208 gen_helper_clac(cpu_env
);
7209 gen_jmp_im(s
->pc
- s
->cs_base
);
7213 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
) ||
7217 gen_helper_stac(cpu_env
);
7218 gen_jmp_im(s
->pc
- s
->cs_base
);
7225 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_READ
);
7226 gen_lea_modrm(env
, s
, modrm
);
7227 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7228 gen_op_st_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
7229 gen_add_A0_im(s
, 2);
7230 tcg_gen_ld_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, idt
.base
));
7231 if (dflag
== MO_16
) {
7232 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffffff);
7234 gen_op_st_v(s
, CODE64(s
) + MO_32
, cpu_T
[0], cpu_A0
);
7240 gen_update_cc_op(s
);
7241 gen_jmp_im(pc_start
- s
->cs_base
);
7244 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7247 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7250 gen_helper_vmrun(cpu_env
, tcg_const_i32(s
->aflag
- 1),
7251 tcg_const_i32(s
->pc
- pc_start
));
7253 s
->is_jmp
= DISAS_TB_JUMP
;
7256 case 1: /* VMMCALL */
7257 if (!(s
->flags
& HF_SVME_MASK
))
7259 gen_helper_vmmcall(cpu_env
);
7261 case 2: /* VMLOAD */
7262 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7265 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7268 gen_helper_vmload(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7271 case 3: /* VMSAVE */
7272 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7275 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7278 gen_helper_vmsave(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7282 if ((!(s
->flags
& HF_SVME_MASK
) &&
7283 !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
)) ||
7287 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7290 gen_helper_stgi(cpu_env
);
7294 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7297 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7300 gen_helper_clgi(cpu_env
);
7303 case 6: /* SKINIT */
7304 if ((!(s
->flags
& HF_SVME_MASK
) &&
7305 !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
)) ||
7308 gen_helper_skinit(cpu_env
);
7310 case 7: /* INVLPGA */
7311 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7314 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7317 gen_helper_invlpga(cpu_env
,
7318 tcg_const_i32(s
->aflag
- 1));
7324 } else if (s
->cpl
!= 0) {
7325 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7327 gen_svm_check_intercept(s
, pc_start
,
7328 op
==2 ? SVM_EXIT_GDTR_WRITE
: SVM_EXIT_IDTR_WRITE
);
7329 gen_lea_modrm(env
, s
, modrm
);
7330 gen_op_ld_v(s
, MO_16
, cpu_T
[1], cpu_A0
);
7331 gen_add_A0_im(s
, 2);
7332 gen_op_ld_v(s
, CODE64(s
) + MO_32
, cpu_T
[0], cpu_A0
);
7333 if (dflag
== MO_16
) {
7334 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffffff);
7337 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,gdt
.base
));
7338 tcg_gen_st32_tl(cpu_T
[1], cpu_env
, offsetof(CPUX86State
,gdt
.limit
));
7340 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,idt
.base
));
7341 tcg_gen_st32_tl(cpu_T
[1], cpu_env
, offsetof(CPUX86State
,idt
.limit
));
7346 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_CR0
);
7347 #if defined TARGET_X86_64 && defined HOST_WORDS_BIGENDIAN
7348 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,cr
[0]) + 4);
7350 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,cr
[0]));
7352 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 1);
7356 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7358 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7359 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7360 gen_helper_lmsw(cpu_env
, cpu_T
[0]);
7361 gen_jmp_im(s
->pc
- s
->cs_base
);
7366 if (mod
!= 3) { /* invlpg */
7368 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7370 gen_update_cc_op(s
);
7371 gen_jmp_im(pc_start
- s
->cs_base
);
7372 gen_lea_modrm(env
, s
, modrm
);
7373 gen_helper_invlpg(cpu_env
, cpu_A0
);
7374 gen_jmp_im(s
->pc
- s
->cs_base
);
7379 case 0: /* swapgs */
7380 #ifdef TARGET_X86_64
7383 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7385 tcg_gen_ld_tl(cpu_T
[0], cpu_env
,
7386 offsetof(CPUX86State
,segs
[R_GS
].base
));
7387 tcg_gen_ld_tl(cpu_T
[1], cpu_env
,
7388 offsetof(CPUX86State
,kernelgsbase
));
7389 tcg_gen_st_tl(cpu_T
[1], cpu_env
,
7390 offsetof(CPUX86State
,segs
[R_GS
].base
));
7391 tcg_gen_st_tl(cpu_T
[0], cpu_env
,
7392 offsetof(CPUX86State
,kernelgsbase
));
7400 case 1: /* rdtscp */
7401 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_RDTSCP
))
7403 gen_update_cc_op(s
);
7404 gen_jmp_im(pc_start
- s
->cs_base
);
7405 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7408 gen_helper_rdtscp(cpu_env
);
7409 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7411 gen_jmp(s
, s
->pc
- s
->cs_base
);
7423 case 0x108: /* invd */
7424 case 0x109: /* wbinvd */
7426 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7428 gen_svm_check_intercept(s
, pc_start
, (b
& 2) ? SVM_EXIT_INVD
: SVM_EXIT_WBINVD
);
7432 case 0x63: /* arpl or movslS (x86_64) */
7433 #ifdef TARGET_X86_64
7436 /* d_ot is the size of destination */
7439 modrm
= cpu_ldub_code(env
, s
->pc
++);
7440 reg
= ((modrm
>> 3) & 7) | rex_r
;
7441 mod
= (modrm
>> 6) & 3;
7442 rm
= (modrm
& 7) | REX_B(s
);
7445 gen_op_mov_v_reg(MO_32
, cpu_T
[0], rm
);
7447 if (d_ot
== MO_64
) {
7448 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
7450 gen_op_mov_reg_v(d_ot
, reg
, cpu_T
[0]);
7452 gen_lea_modrm(env
, s
, modrm
);
7453 gen_op_ld_v(s
, MO_32
| MO_SIGN
, cpu_T
[0], cpu_A0
);
7454 gen_op_mov_reg_v(d_ot
, reg
, cpu_T
[0]);
7460 TCGv t0
, t1
, t2
, a0
;
7462 if (!s
->pe
|| s
->vm86
)
7464 t0
= tcg_temp_local_new();
7465 t1
= tcg_temp_local_new();
7466 t2
= tcg_temp_local_new();
7468 modrm
= cpu_ldub_code(env
, s
->pc
++);
7469 reg
= (modrm
>> 3) & 7;
7470 mod
= (modrm
>> 6) & 3;
7473 gen_lea_modrm(env
, s
, modrm
);
7474 gen_op_ld_v(s
, ot
, t0
, cpu_A0
);
7475 a0
= tcg_temp_local_new();
7476 tcg_gen_mov_tl(a0
, cpu_A0
);
7478 gen_op_mov_v_reg(ot
, t0
, rm
);
7481 gen_op_mov_v_reg(ot
, t1
, reg
);
7482 tcg_gen_andi_tl(cpu_tmp0
, t0
, 3);
7483 tcg_gen_andi_tl(t1
, t1
, 3);
7484 tcg_gen_movi_tl(t2
, 0);
7485 label1
= gen_new_label();
7486 tcg_gen_brcond_tl(TCG_COND_GE
, cpu_tmp0
, t1
, label1
);
7487 tcg_gen_andi_tl(t0
, t0
, ~3);
7488 tcg_gen_or_tl(t0
, t0
, t1
);
7489 tcg_gen_movi_tl(t2
, CC_Z
);
7490 gen_set_label(label1
);
7492 gen_op_st_v(s
, ot
, t0
, a0
);
7495 gen_op_mov_reg_v(ot
, rm
, t0
);
7497 gen_compute_eflags(s
);
7498 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_Z
);
7499 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, t2
);
7505 case 0x102: /* lar */
7506 case 0x103: /* lsl */
7510 if (!s
->pe
|| s
->vm86
)
7512 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
7513 modrm
= cpu_ldub_code(env
, s
->pc
++);
7514 reg
= ((modrm
>> 3) & 7) | rex_r
;
7515 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7516 t0
= tcg_temp_local_new();
7517 gen_update_cc_op(s
);
7519 gen_helper_lar(t0
, cpu_env
, cpu_T
[0]);
7521 gen_helper_lsl(t0
, cpu_env
, cpu_T
[0]);
7523 tcg_gen_andi_tl(cpu_tmp0
, cpu_cc_src
, CC_Z
);
7524 label1
= gen_new_label();
7525 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
7526 gen_op_mov_reg_v(ot
, reg
, t0
);
7527 gen_set_label(label1
);
7528 set_cc_op(s
, CC_OP_EFLAGS
);
7533 modrm
= cpu_ldub_code(env
, s
->pc
++);
7534 mod
= (modrm
>> 6) & 3;
7535 op
= (modrm
>> 3) & 7;
7537 case 0: /* prefetchnta */
7538 case 1: /* prefetchnt0 */
7539 case 2: /* prefetchnt0 */
7540 case 3: /* prefetchnt0 */
7543 gen_lea_modrm(env
, s
, modrm
);
7544 /* nothing more to do */
7546 default: /* nop (multi byte) */
7547 gen_nop_modrm(env
, s
, modrm
);
7551 case 0x119 ... 0x11f: /* nop (multi byte) */
7552 modrm
= cpu_ldub_code(env
, s
->pc
++);
7553 gen_nop_modrm(env
, s
, modrm
);
7555 case 0x120: /* mov reg, crN */
7556 case 0x122: /* mov crN, reg */
7558 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7560 modrm
= cpu_ldub_code(env
, s
->pc
++);
7561 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7562 * AMD documentation (24594.pdf) and testing of
7563 * intel 386 and 486 processors all show that the mod bits
7564 * are assumed to be 1's, regardless of actual values.
7566 rm
= (modrm
& 7) | REX_B(s
);
7567 reg
= ((modrm
>> 3) & 7) | rex_r
;
7572 if ((prefixes
& PREFIX_LOCK
) && (reg
== 0) &&
7573 (s
->cpuid_ext3_features
& CPUID_EXT3_CR8LEG
)) {
7582 gen_update_cc_op(s
);
7583 gen_jmp_im(pc_start
- s
->cs_base
);
7585 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
7586 gen_helper_write_crN(cpu_env
, tcg_const_i32(reg
),
7588 gen_jmp_im(s
->pc
- s
->cs_base
);
7591 gen_helper_read_crN(cpu_T
[0], cpu_env
, tcg_const_i32(reg
));
7592 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
7600 case 0x121: /* mov reg, drN */
7601 case 0x123: /* mov drN, reg */
7603 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7605 modrm
= cpu_ldub_code(env
, s
->pc
++);
7606 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7607 * AMD documentation (24594.pdf) and testing of
7608 * intel 386 and 486 processors all show that the mod bits
7609 * are assumed to be 1's, regardless of actual values.
7611 rm
= (modrm
& 7) | REX_B(s
);
7612 reg
= ((modrm
>> 3) & 7) | rex_r
;
7617 /* XXX: do it dynamically with CR4.DE bit */
7618 if (reg
== 4 || reg
== 5 || reg
>= 8)
7621 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_DR0
+ reg
);
7622 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
7623 gen_helper_movl_drN_T0(cpu_env
, tcg_const_i32(reg
), cpu_T
[0]);
7624 gen_jmp_im(s
->pc
- s
->cs_base
);
7627 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_DR0
+ reg
);
7628 tcg_gen_ld_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,dr
[reg
]));
7629 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
7633 case 0x106: /* clts */
7635 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7637 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7638 gen_helper_clts(cpu_env
);
7639 /* abort block because static cpu state changed */
7640 gen_jmp_im(s
->pc
- s
->cs_base
);
7644 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
7645 case 0x1c3: /* MOVNTI reg, mem */
7646 if (!(s
->cpuid_features
& CPUID_SSE2
))
7648 ot
= mo_64_32(dflag
);
7649 modrm
= cpu_ldub_code(env
, s
->pc
++);
7650 mod
= (modrm
>> 6) & 3;
7653 reg
= ((modrm
>> 3) & 7) | rex_r
;
7654 /* generate a generic store */
7655 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
7658 modrm
= cpu_ldub_code(env
, s
->pc
++);
7659 mod
= (modrm
>> 6) & 3;
7660 op
= (modrm
>> 3) & 7;
7662 case 0: /* fxsave */
7663 if (mod
== 3 || !(s
->cpuid_features
& CPUID_FXSR
) ||
7664 (s
->prefix
& PREFIX_LOCK
))
7666 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
7667 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7670 gen_lea_modrm(env
, s
, modrm
);
7671 gen_helper_fxsave(cpu_env
, cpu_A0
, tcg_const_i32(dflag
== MO_64
));
7673 case 1: /* fxrstor */
7674 if (mod
== 3 || !(s
->cpuid_features
& CPUID_FXSR
) ||
7675 (s
->prefix
& PREFIX_LOCK
))
7677 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
7678 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7681 gen_lea_modrm(env
, s
, modrm
);
7682 gen_helper_fxrstor(cpu_env
, cpu_A0
, tcg_const_i32(dflag
== MO_64
));
7684 case 2: /* ldmxcsr */
7685 case 3: /* stmxcsr */
7686 if (s
->flags
& HF_TS_MASK
) {
7687 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7690 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
) ||
7693 gen_lea_modrm(env
, s
, modrm
);
7695 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
7696 s
->mem_index
, MO_LEUL
);
7697 gen_helper_ldmxcsr(cpu_env
, cpu_tmp2_i32
);
7699 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, mxcsr
));
7700 gen_op_st_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
7703 case 5: /* lfence */
7704 case 6: /* mfence */
7705 if ((modrm
& 0xc7) != 0xc0 || !(s
->cpuid_features
& CPUID_SSE2
))
7708 case 7: /* sfence / clflush */
7709 if ((modrm
& 0xc7) == 0xc0) {
7711 /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX */
7712 if (!(s
->cpuid_features
& CPUID_SSE
))
7716 if (!(s
->cpuid_features
& CPUID_CLFLUSH
))
7718 gen_lea_modrm(env
, s
, modrm
);
7725 case 0x10d: /* 3DNow! prefetch(w) */
7726 modrm
= cpu_ldub_code(env
, s
->pc
++);
7727 mod
= (modrm
>> 6) & 3;
7730 gen_lea_modrm(env
, s
, modrm
);
7731 /* ignore for now */
7733 case 0x1aa: /* rsm */
7734 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_RSM
);
7735 if (!(s
->flags
& HF_SMM_MASK
))
7737 gen_update_cc_op(s
);
7738 gen_jmp_im(s
->pc
- s
->cs_base
);
7739 gen_helper_rsm(cpu_env
);
7742 case 0x1b8: /* SSE4.2 popcnt */
7743 if ((prefixes
& (PREFIX_REPZ
| PREFIX_LOCK
| PREFIX_REPNZ
)) !=
7746 if (!(s
->cpuid_ext_features
& CPUID_EXT_POPCNT
))
7749 modrm
= cpu_ldub_code(env
, s
->pc
++);
7750 reg
= ((modrm
>> 3) & 7) | rex_r
;
7752 if (s
->prefix
& PREFIX_DATA
) {
7755 ot
= mo_64_32(dflag
);
7758 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
7759 gen_helper_popcnt(cpu_T
[0], cpu_env
, cpu_T
[0], tcg_const_i32(ot
));
7760 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
7762 set_cc_op(s
, CC_OP_EFLAGS
);
7764 case 0x10e ... 0x10f:
7765 /* 3DNow! instructions, ignore prefixes */
7766 s
->prefix
&= ~(PREFIX_REPZ
| PREFIX_REPNZ
| PREFIX_DATA
);
7767 case 0x110 ... 0x117:
7768 case 0x128 ... 0x12f:
7769 case 0x138 ... 0x13a:
7770 case 0x150 ... 0x179:
7771 case 0x17c ... 0x17f:
7773 case 0x1c4 ... 0x1c6:
7774 case 0x1d0 ... 0x1fe:
7775 gen_sse(env
, s
, b
, pc_start
, rex_r
);
7780 /* lock generation */
7781 if (s
->prefix
& PREFIX_LOCK
)
7782 gen_helper_unlock();
7785 if (s
->prefix
& PREFIX_LOCK
)
7786 gen_helper_unlock();
7787 /* XXX: ensure that no lock was generated */
7788 gen_exception(s
, EXCP06_ILLOP
, pc_start
- s
->cs_base
);
7792 void optimize_flags_init(void)
7794 static const char reg_names
[CPU_NB_REGS
][4] = {
7795 #ifdef TARGET_X86_64
7825 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
7826 cpu_cc_op
= tcg_global_mem_new_i32(TCG_AREG0
,
7827 offsetof(CPUX86State
, cc_op
), "cc_op");
7828 cpu_cc_dst
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_dst
),
7830 cpu_cc_src
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_src
),
7832 cpu_cc_src2
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_src2
),
7835 for (i
= 0; i
< CPU_NB_REGS
; ++i
) {
7836 cpu_regs
[i
] = tcg_global_mem_new(TCG_AREG0
,
7837 offsetof(CPUX86State
, regs
[i
]),
7844 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
7845 basic block 'tb'. If search_pc is TRUE, also generate PC
7846 information for each intermediate instruction. */
7847 static inline void gen_intermediate_code_internal(X86CPU
*cpu
,
7848 TranslationBlock
*tb
,
7851 CPUState
*cs
= CPU(cpu
);
7852 CPUX86State
*env
= &cpu
->env
;
7853 DisasContext dc1
, *dc
= &dc1
;
7854 target_ulong pc_ptr
;
7858 target_ulong pc_start
;
7859 target_ulong cs_base
;
7863 /* generate intermediate code */
7865 cs_base
= tb
->cs_base
;
7868 dc
->pe
= (flags
>> HF_PE_SHIFT
) & 1;
7869 dc
->code32
= (flags
>> HF_CS32_SHIFT
) & 1;
7870 dc
->ss32
= (flags
>> HF_SS32_SHIFT
) & 1;
7871 dc
->addseg
= (flags
>> HF_ADDSEG_SHIFT
) & 1;
7873 dc
->vm86
= (flags
>> VM_SHIFT
) & 1;
7874 dc
->cpl
= (flags
>> HF_CPL_SHIFT
) & 3;
7875 dc
->iopl
= (flags
>> IOPL_SHIFT
) & 3;
7876 dc
->tf
= (flags
>> TF_SHIFT
) & 1;
7877 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
7878 dc
->cc_op
= CC_OP_DYNAMIC
;
7879 dc
->cc_op_dirty
= false;
7880 dc
->cs_base
= cs_base
;
7882 dc
->popl_esp_hack
= 0;
7883 /* select memory access functions */
7885 if (flags
& HF_SOFTMMU_MASK
) {
7886 dc
->mem_index
= cpu_mmu_index(env
, false);
7888 dc
->cpuid_features
= env
->features
[FEAT_1_EDX
];
7889 dc
->cpuid_ext_features
= env
->features
[FEAT_1_ECX
];
7890 dc
->cpuid_ext2_features
= env
->features
[FEAT_8000_0001_EDX
];
7891 dc
->cpuid_ext3_features
= env
->features
[FEAT_8000_0001_ECX
];
7892 dc
->cpuid_7_0_ebx_features
= env
->features
[FEAT_7_0_EBX
];
7893 #ifdef TARGET_X86_64
7894 dc
->lma
= (flags
>> HF_LMA_SHIFT
) & 1;
7895 dc
->code64
= (flags
>> HF_CS64_SHIFT
) & 1;
7898 dc
->jmp_opt
= !(dc
->tf
|| cs
->singlestep_enabled
||
7899 (flags
& HF_INHIBIT_IRQ_MASK
)
7900 #ifndef CONFIG_SOFTMMU
7901 || (flags
& HF_SOFTMMU_MASK
)
7904 /* Do not optimize repz jumps at all in icount mode, because
7905 rep movsS instructions are execured with different paths
7906 in !repz_opt and repz_opt modes. The first one was used
7907 always except single step mode. And this setting
7908 disables jumps optimization and control paths become
7909 equivalent in run and single step modes.
7910 Now there will be no jump optimization for repz in
7911 record/replay modes and there will always be an
7912 additional step for ecx=0 when icount is enabled.
7914 dc
->repz_opt
= !dc
->jmp_opt
&& !(tb
->cflags
& CF_USE_ICOUNT
);
7916 /* check addseg logic */
7917 if (!dc
->addseg
&& (dc
->vm86
|| !dc
->pe
|| !dc
->code32
))
7918 printf("ERROR addseg\n");
7921 cpu_T
[0] = tcg_temp_new();
7922 cpu_T
[1] = tcg_temp_new();
7923 cpu_A0
= tcg_temp_new();
7925 cpu_tmp0
= tcg_temp_new();
7926 cpu_tmp1_i64
= tcg_temp_new_i64();
7927 cpu_tmp2_i32
= tcg_temp_new_i32();
7928 cpu_tmp3_i32
= tcg_temp_new_i32();
7929 cpu_tmp4
= tcg_temp_new();
7930 cpu_ptr0
= tcg_temp_new_ptr();
7931 cpu_ptr1
= tcg_temp_new_ptr();
7932 cpu_cc_srcT
= tcg_temp_local_new();
7934 dc
->is_jmp
= DISAS_NEXT
;
7938 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
7940 max_insns
= CF_COUNT_MASK
;
7944 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
7945 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
7946 if (bp
->pc
== pc_ptr
&&
7947 !((bp
->flags
& BP_CPU
) && (tb
->flags
& HF_RF_MASK
))) {
7948 gen_debug(dc
, pc_ptr
- dc
->cs_base
);
7949 goto done_generating
;
7954 j
= tcg_op_buf_count();
7958 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
7960 tcg_ctx
.gen_opc_pc
[lj
] = pc_ptr
;
7961 gen_opc_cc_op
[lj
] = dc
->cc_op
;
7962 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
7963 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
7965 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
7968 pc_ptr
= disas_insn(env
, dc
, pc_ptr
);
7970 /* stop translation if indicated */
7973 /* if single step mode, we generate only one instruction and
7974 generate an exception */
7975 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
7976 the flag and abort the translation to give the irqs a
7977 change to be happen */
7978 if (dc
->tf
|| dc
->singlestep_enabled
||
7979 (flags
& HF_INHIBIT_IRQ_MASK
)) {
7980 gen_jmp_im(pc_ptr
- dc
->cs_base
);
7984 /* Do not cross the boundary of the pages in icount mode,
7985 it can cause an exception. Do it only when boundary is
7986 crossed by the first instruction in the block.
7987 If current instruction already crossed the bound - it's ok,
7988 because an exception hasn't stopped this code.
7990 if ((tb
->cflags
& CF_USE_ICOUNT
)
7991 && ((pc_ptr
& TARGET_PAGE_MASK
)
7992 != ((pc_ptr
+ TARGET_MAX_INSN_SIZE
- 1) & TARGET_PAGE_MASK
)
7993 || (pc_ptr
& ~TARGET_PAGE_MASK
) == 0)) {
7994 gen_jmp_im(pc_ptr
- dc
->cs_base
);
7998 /* if too long translation, stop generation too */
7999 if (tcg_op_buf_full() ||
8000 (pc_ptr
- pc_start
) >= (TARGET_PAGE_SIZE
- 32) ||
8001 num_insns
>= max_insns
) {
8002 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8007 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8012 if (tb
->cflags
& CF_LAST_IO
)
8015 gen_tb_end(tb
, num_insns
);
8017 /* we don't forget to fill the last values */
8019 j
= tcg_op_buf_count();
8022 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
8026 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
8028 qemu_log("----------------\n");
8029 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
8030 #ifdef TARGET_X86_64
8035 disas_flags
= !dc
->code32
;
8036 log_target_disas(cs
, pc_start
, pc_ptr
- pc_start
, disas_flags
);
8042 tb
->size
= pc_ptr
- pc_start
;
8043 tb
->icount
= num_insns
;
8047 void gen_intermediate_code(CPUX86State
*env
, TranslationBlock
*tb
)
8049 gen_intermediate_code_internal(x86_env_get_cpu(env
), tb
, false);
8052 void gen_intermediate_code_pc(CPUX86State
*env
, TranslationBlock
*tb
)
8054 gen_intermediate_code_internal(x86_env_get_cpu(env
), tb
, true);
8057 void restore_state_to_opc(CPUX86State
*env
, TranslationBlock
*tb
, int pc_pos
)
8061 if (qemu_loglevel_mask(CPU_LOG_TB_OP
)) {
8063 qemu_log("RESTORE:\n");
8064 for(i
= 0;i
<= pc_pos
; i
++) {
8065 if (tcg_ctx
.gen_opc_instr_start
[i
]) {
8066 qemu_log("0x%04x: " TARGET_FMT_lx
"\n", i
,
8067 tcg_ctx
.gen_opc_pc
[i
]);
8070 qemu_log("pc_pos=0x%x eip=" TARGET_FMT_lx
" cs_base=%x\n",
8071 pc_pos
, tcg_ctx
.gen_opc_pc
[pc_pos
] - tb
->cs_base
,
8072 (uint32_t)tb
->cs_base
);
8075 env
->eip
= tcg_ctx
.gen_opc_pc
[pc_pos
] - tb
->cs_base
;
8076 cc_op
= gen_opc_cc_op
[pc_pos
];
8077 if (cc_op
!= CC_OP_DYNAMIC
)