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
,
667 target_ulong next_eip
;
670 if (s
->pe
&& (s
->cpl
> s
->iopl
|| s
->vm86
)) {
674 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
677 gen_helper_check_iob(cpu_env
, cpu_tmp2_i32
);
680 gen_helper_check_iow(cpu_env
, cpu_tmp2_i32
);
683 gen_helper_check_iol(cpu_env
, cpu_tmp2_i32
);
689 if(s
->flags
& HF_SVMI_MASK
) {
694 svm_flags
|= (1 << (4 + ot
));
695 next_eip
= s
->pc
- s
->cs_base
;
696 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
697 gen_helper_svm_check_io(cpu_env
, cpu_tmp2_i32
,
698 tcg_const_i32(svm_flags
),
699 tcg_const_i32(next_eip
- cur_eip
));
703 static inline void gen_movs(DisasContext
*s
, TCGMemOp ot
)
705 gen_string_movl_A0_ESI(s
);
706 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
707 gen_string_movl_A0_EDI(s
);
708 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
709 gen_op_movl_T0_Dshift(ot
);
710 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
711 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
714 static void gen_op_update1_cc(void)
716 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
719 static void gen_op_update2_cc(void)
721 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
722 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
725 static void gen_op_update3_cc(TCGv reg
)
727 tcg_gen_mov_tl(cpu_cc_src2
, reg
);
728 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
729 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
732 static inline void gen_op_testl_T0_T1_cc(void)
734 tcg_gen_and_tl(cpu_cc_dst
, cpu_T
[0], cpu_T
[1]);
737 static void gen_op_update_neg_cc(void)
739 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
740 tcg_gen_neg_tl(cpu_cc_src
, cpu_T
[0]);
741 tcg_gen_movi_tl(cpu_cc_srcT
, 0);
744 /* compute all eflags to cc_src */
745 static void gen_compute_eflags(DisasContext
*s
)
747 TCGv zero
, dst
, src1
, src2
;
750 if (s
->cc_op
== CC_OP_EFLAGS
) {
753 if (s
->cc_op
== CC_OP_CLR
) {
754 tcg_gen_movi_tl(cpu_cc_src
, CC_Z
| CC_P
);
755 set_cc_op(s
, CC_OP_EFLAGS
);
764 /* Take care to not read values that are not live. */
765 live
= cc_op_live
[s
->cc_op
] & ~USES_CC_SRCT
;
766 dead
= live
^ (USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
);
768 zero
= tcg_const_tl(0);
769 if (dead
& USES_CC_DST
) {
772 if (dead
& USES_CC_SRC
) {
775 if (dead
& USES_CC_SRC2
) {
781 gen_helper_cc_compute_all(cpu_cc_src
, dst
, src1
, src2
, cpu_cc_op
);
782 set_cc_op(s
, CC_OP_EFLAGS
);
789 typedef struct CCPrepare
{
799 /* compute eflags.C to reg */
800 static CCPrepare
gen_prepare_eflags_c(DisasContext
*s
, TCGv reg
)
806 case CC_OP_SUBB
... CC_OP_SUBQ
:
807 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
808 size
= s
->cc_op
- CC_OP_SUBB
;
809 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
810 /* If no temporary was used, be careful not to alias t1 and t0. */
811 t0
= TCGV_EQUAL(t1
, cpu_cc_src
) ? cpu_tmp0
: reg
;
812 tcg_gen_mov_tl(t0
, cpu_cc_srcT
);
816 case CC_OP_ADDB
... CC_OP_ADDQ
:
817 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
818 size
= s
->cc_op
- CC_OP_ADDB
;
819 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
820 t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
822 return (CCPrepare
) { .cond
= TCG_COND_LTU
, .reg
= t0
,
823 .reg2
= t1
, .mask
= -1, .use_reg2
= true };
825 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
827 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
829 case CC_OP_INCB
... CC_OP_INCQ
:
830 case CC_OP_DECB
... CC_OP_DECQ
:
831 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
832 .mask
= -1, .no_setcond
= true };
834 case CC_OP_SHLB
... CC_OP_SHLQ
:
835 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
836 size
= s
->cc_op
- CC_OP_SHLB
;
837 shift
= (8 << size
) - 1;
838 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
839 .mask
= (target_ulong
)1 << shift
};
841 case CC_OP_MULB
... CC_OP_MULQ
:
842 return (CCPrepare
) { .cond
= TCG_COND_NE
,
843 .reg
= cpu_cc_src
, .mask
= -1 };
845 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
846 size
= s
->cc_op
- CC_OP_BMILGB
;
847 t0
= gen_ext_tl(reg
, cpu_cc_src
, size
, false);
848 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
852 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_dst
,
853 .mask
= -1, .no_setcond
= true };
856 case CC_OP_SARB
... CC_OP_SARQ
:
858 return (CCPrepare
) { .cond
= TCG_COND_NE
,
859 .reg
= cpu_cc_src
, .mask
= CC_C
};
862 /* The need to compute only C from CC_OP_DYNAMIC is important
863 in efficiently implementing e.g. INC at the start of a TB. */
865 gen_helper_cc_compute_c(reg
, cpu_cc_dst
, cpu_cc_src
,
866 cpu_cc_src2
, cpu_cc_op
);
867 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
868 .mask
= -1, .no_setcond
= true };
872 /* compute eflags.P to reg */
873 static CCPrepare
gen_prepare_eflags_p(DisasContext
*s
, TCGv reg
)
875 gen_compute_eflags(s
);
876 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
880 /* compute eflags.S to reg */
881 static CCPrepare
gen_prepare_eflags_s(DisasContext
*s
, TCGv reg
)
885 gen_compute_eflags(s
);
891 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
894 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
897 TCGMemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
898 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, true);
899 return (CCPrepare
) { .cond
= TCG_COND_LT
, .reg
= t0
, .mask
= -1 };
904 /* compute eflags.O to reg */
905 static CCPrepare
gen_prepare_eflags_o(DisasContext
*s
, TCGv reg
)
910 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src2
,
911 .mask
= -1, .no_setcond
= true };
913 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
915 gen_compute_eflags(s
);
916 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
921 /* compute eflags.Z to reg */
922 static CCPrepare
gen_prepare_eflags_z(DisasContext
*s
, TCGv reg
)
926 gen_compute_eflags(s
);
932 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
935 return (CCPrepare
) { .cond
= TCG_COND_ALWAYS
, .mask
= -1 };
938 TCGMemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
939 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
940 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
945 /* perform a conditional store into register 'reg' according to jump opcode
946 value 'b'. In the fast case, T0 is guaranted not to be used. */
947 static CCPrepare
gen_prepare_cc(DisasContext
*s
, int b
, TCGv reg
)
949 int inv
, jcc_op
, cond
;
955 jcc_op
= (b
>> 1) & 7;
958 case CC_OP_SUBB
... CC_OP_SUBQ
:
959 /* We optimize relational operators for the cmp/jcc case. */
960 size
= s
->cc_op
- CC_OP_SUBB
;
963 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
964 gen_extu(size
, cpu_tmp4
);
965 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
966 cc
= (CCPrepare
) { .cond
= TCG_COND_LEU
, .reg
= cpu_tmp4
,
967 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
976 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
977 gen_exts(size
, cpu_tmp4
);
978 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, true);
979 cc
= (CCPrepare
) { .cond
= cond
, .reg
= cpu_tmp4
,
980 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
990 /* This actually generates good code for JC, JZ and JS. */
993 cc
= gen_prepare_eflags_o(s
, reg
);
996 cc
= gen_prepare_eflags_c(s
, reg
);
999 cc
= gen_prepare_eflags_z(s
, reg
);
1002 gen_compute_eflags(s
);
1003 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
1004 .mask
= CC_Z
| CC_C
};
1007 cc
= gen_prepare_eflags_s(s
, reg
);
1010 cc
= gen_prepare_eflags_p(s
, reg
);
1013 gen_compute_eflags(s
);
1014 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
1017 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
1018 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
1019 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
1024 gen_compute_eflags(s
);
1025 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
1028 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
1029 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
1030 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
1031 .mask
= CC_S
| CC_Z
};
1038 cc
.cond
= tcg_invert_cond(cc
.cond
);
1043 static void gen_setcc1(DisasContext
*s
, int b
, TCGv reg
)
1045 CCPrepare cc
= gen_prepare_cc(s
, b
, reg
);
1047 if (cc
.no_setcond
) {
1048 if (cc
.cond
== TCG_COND_EQ
) {
1049 tcg_gen_xori_tl(reg
, cc
.reg
, 1);
1051 tcg_gen_mov_tl(reg
, cc
.reg
);
1056 if (cc
.cond
== TCG_COND_NE
&& !cc
.use_reg2
&& cc
.imm
== 0 &&
1057 cc
.mask
!= 0 && (cc
.mask
& (cc
.mask
- 1)) == 0) {
1058 tcg_gen_shri_tl(reg
, cc
.reg
, ctztl(cc
.mask
));
1059 tcg_gen_andi_tl(reg
, reg
, 1);
1062 if (cc
.mask
!= -1) {
1063 tcg_gen_andi_tl(reg
, cc
.reg
, cc
.mask
);
1067 tcg_gen_setcond_tl(cc
.cond
, reg
, cc
.reg
, cc
.reg2
);
1069 tcg_gen_setcondi_tl(cc
.cond
, reg
, cc
.reg
, cc
.imm
);
1073 static inline void gen_compute_eflags_c(DisasContext
*s
, TCGv reg
)
1075 gen_setcc1(s
, JCC_B
<< 1, reg
);
1078 /* generate a conditional jump to label 'l1' according to jump opcode
1079 value 'b'. In the fast case, T0 is guaranted not to be used. */
1080 static inline void gen_jcc1_noeob(DisasContext
*s
, int b
, TCGLabel
*l1
)
1082 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T
[0]);
1084 if (cc
.mask
!= -1) {
1085 tcg_gen_andi_tl(cpu_T
[0], cc
.reg
, cc
.mask
);
1089 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1091 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1095 /* Generate a conditional jump to label 'l1' according to jump opcode
1096 value 'b'. In the fast case, T0 is guaranted not to be used.
1097 A translation block must end soon. */
1098 static inline void gen_jcc1(DisasContext
*s
, int b
, TCGLabel
*l1
)
1100 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T
[0]);
1102 gen_update_cc_op(s
);
1103 if (cc
.mask
!= -1) {
1104 tcg_gen_andi_tl(cpu_T
[0], cc
.reg
, cc
.mask
);
1107 set_cc_op(s
, CC_OP_DYNAMIC
);
1109 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1111 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1115 /* XXX: does not work with gdbstub "ice" single step - not a
1117 static TCGLabel
*gen_jz_ecx_string(DisasContext
*s
, target_ulong next_eip
)
1119 TCGLabel
*l1
= gen_new_label();
1120 TCGLabel
*l2
= gen_new_label();
1121 gen_op_jnz_ecx(s
->aflag
, l1
);
1123 gen_jmp_tb(s
, next_eip
, 1);
1128 static inline void gen_stos(DisasContext
*s
, TCGMemOp ot
)
1130 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EAX
);
1131 gen_string_movl_A0_EDI(s
);
1132 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
1133 gen_op_movl_T0_Dshift(ot
);
1134 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1137 static inline void gen_lods(DisasContext
*s
, TCGMemOp ot
)
1139 gen_string_movl_A0_ESI(s
);
1140 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1141 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T
[0]);
1142 gen_op_movl_T0_Dshift(ot
);
1143 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1146 static inline void gen_scas(DisasContext
*s
, TCGMemOp ot
)
1148 gen_string_movl_A0_EDI(s
);
1149 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
1150 gen_op(s
, OP_CMPL
, ot
, R_EAX
);
1151 gen_op_movl_T0_Dshift(ot
);
1152 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1155 static inline void gen_cmps(DisasContext
*s
, TCGMemOp ot
)
1157 gen_string_movl_A0_EDI(s
);
1158 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
1159 gen_string_movl_A0_ESI(s
);
1160 gen_op(s
, OP_CMPL
, ot
, OR_TMP0
);
1161 gen_op_movl_T0_Dshift(ot
);
1162 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1163 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1166 static inline void gen_ins(DisasContext
*s
, TCGMemOp ot
)
1168 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1171 gen_string_movl_A0_EDI(s
);
1172 /* Note: we must do this dummy write first to be restartable in
1173 case of page fault. */
1174 tcg_gen_movi_tl(cpu_T
[0], 0);
1175 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
1176 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_EDX
]);
1177 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1178 gen_helper_in_func(ot
, cpu_T
[0], cpu_tmp2_i32
);
1179 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
1180 gen_op_movl_T0_Dshift(ot
);
1181 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1182 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1187 static inline void gen_outs(DisasContext
*s
, TCGMemOp ot
)
1189 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1192 gen_string_movl_A0_ESI(s
);
1193 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1195 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_EDX
]);
1196 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1197 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[0]);
1198 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1200 gen_op_movl_T0_Dshift(ot
);
1201 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1202 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
1207 /* same method as Valgrind : we generate jumps to current or next
1209 #define GEN_REPZ(op) \
1210 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1211 target_ulong cur_eip, target_ulong next_eip) \
1214 gen_update_cc_op(s); \
1215 l2 = gen_jz_ecx_string(s, next_eip); \
1216 gen_ ## op(s, ot); \
1217 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1218 /* a loop would cause two single step exceptions if ECX = 1 \
1219 before rep string_insn */ \
1221 gen_op_jz_ecx(s->aflag, l2); \
1222 gen_jmp(s, cur_eip); \
1225 #define GEN_REPZ2(op) \
1226 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1227 target_ulong cur_eip, \
1228 target_ulong next_eip, \
1232 gen_update_cc_op(s); \
1233 l2 = gen_jz_ecx_string(s, next_eip); \
1234 gen_ ## op(s, ot); \
1235 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1236 gen_update_cc_op(s); \
1237 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
1239 gen_op_jz_ecx(s->aflag, l2); \
1240 gen_jmp(s, cur_eip); \
1251 static void gen_helper_fp_arith_ST0_FT0(int op
)
1255 gen_helper_fadd_ST0_FT0(cpu_env
);
1258 gen_helper_fmul_ST0_FT0(cpu_env
);
1261 gen_helper_fcom_ST0_FT0(cpu_env
);
1264 gen_helper_fcom_ST0_FT0(cpu_env
);
1267 gen_helper_fsub_ST0_FT0(cpu_env
);
1270 gen_helper_fsubr_ST0_FT0(cpu_env
);
1273 gen_helper_fdiv_ST0_FT0(cpu_env
);
1276 gen_helper_fdivr_ST0_FT0(cpu_env
);
1281 /* NOTE the exception in "r" op ordering */
1282 static void gen_helper_fp_arith_STN_ST0(int op
, int opreg
)
1284 TCGv_i32 tmp
= tcg_const_i32(opreg
);
1287 gen_helper_fadd_STN_ST0(cpu_env
, tmp
);
1290 gen_helper_fmul_STN_ST0(cpu_env
, tmp
);
1293 gen_helper_fsubr_STN_ST0(cpu_env
, tmp
);
1296 gen_helper_fsub_STN_ST0(cpu_env
, tmp
);
1299 gen_helper_fdivr_STN_ST0(cpu_env
, tmp
);
1302 gen_helper_fdiv_STN_ST0(cpu_env
, tmp
);
1307 /* if d == OR_TMP0, it means memory operand (address in A0) */
1308 static void gen_op(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
)
1311 gen_op_mov_v_reg(ot
, cpu_T
[0], d
);
1313 gen_op_ld_v(s1
, ot
, cpu_T
[0], cpu_A0
);
1317 gen_compute_eflags_c(s1
, cpu_tmp4
);
1318 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1319 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_tmp4
);
1320 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1321 gen_op_update3_cc(cpu_tmp4
);
1322 set_cc_op(s1
, CC_OP_ADCB
+ ot
);
1325 gen_compute_eflags_c(s1
, cpu_tmp4
);
1326 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1327 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_tmp4
);
1328 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1329 gen_op_update3_cc(cpu_tmp4
);
1330 set_cc_op(s1
, CC_OP_SBBB
+ ot
);
1333 tcg_gen_add_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_ADDB
+ ot
);
1339 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T
[0]);
1340 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1341 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1342 gen_op_update2_cc();
1343 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1347 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1348 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1349 gen_op_update1_cc();
1350 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1353 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1354 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1355 gen_op_update1_cc();
1356 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1359 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1360 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1361 gen_op_update1_cc();
1362 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1365 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
1366 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T
[0]);
1367 tcg_gen_sub_tl(cpu_cc_dst
, cpu_T
[0], cpu_T
[1]);
1368 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1373 /* if d == OR_TMP0, it means memory operand (address in A0) */
1374 static void gen_inc(DisasContext
*s1
, TCGMemOp ot
, int d
, int c
)
1377 gen_op_mov_v_reg(ot
, cpu_T
[0], d
);
1379 gen_op_ld_v(s1
, ot
, cpu_T
[0], cpu_A0
);
1381 gen_compute_eflags_c(s1
, cpu_cc_src
);
1383 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], 1);
1384 set_cc_op(s1
, CC_OP_INCB
+ ot
);
1386 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], -1);
1387 set_cc_op(s1
, CC_OP_DECB
+ ot
);
1389 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1390 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
1393 static void gen_shift_flags(DisasContext
*s
, TCGMemOp ot
, TCGv result
,
1394 TCGv shm1
, TCGv count
, bool is_right
)
1396 TCGv_i32 z32
, s32
, oldop
;
1399 /* Store the results into the CC variables. If we know that the
1400 variable must be dead, store unconditionally. Otherwise we'll
1401 need to not disrupt the current contents. */
1402 z_tl
= tcg_const_tl(0);
1403 if (cc_op_live
[s
->cc_op
] & USES_CC_DST
) {
1404 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_dst
, count
, z_tl
,
1405 result
, cpu_cc_dst
);
1407 tcg_gen_mov_tl(cpu_cc_dst
, result
);
1409 if (cc_op_live
[s
->cc_op
] & USES_CC_SRC
) {
1410 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_src
, count
, z_tl
,
1413 tcg_gen_mov_tl(cpu_cc_src
, shm1
);
1415 tcg_temp_free(z_tl
);
1417 /* Get the two potential CC_OP values into temporaries. */
1418 tcg_gen_movi_i32(cpu_tmp2_i32
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1419 if (s
->cc_op
== CC_OP_DYNAMIC
) {
1422 tcg_gen_movi_i32(cpu_tmp3_i32
, s
->cc_op
);
1423 oldop
= cpu_tmp3_i32
;
1426 /* Conditionally store the CC_OP value. */
1427 z32
= tcg_const_i32(0);
1428 s32
= tcg_temp_new_i32();
1429 tcg_gen_trunc_tl_i32(s32
, count
);
1430 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, s32
, z32
, cpu_tmp2_i32
, oldop
);
1431 tcg_temp_free_i32(z32
);
1432 tcg_temp_free_i32(s32
);
1434 /* The CC_OP value is no longer predictable. */
1435 set_cc_op(s
, CC_OP_DYNAMIC
);
1438 static void gen_shift_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1439 int is_right
, int is_arith
)
1441 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1444 if (op1
== OR_TMP0
) {
1445 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1447 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1450 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], mask
);
1451 tcg_gen_subi_tl(cpu_tmp0
, cpu_T
[1], 1);
1455 gen_exts(ot
, cpu_T
[0]);
1456 tcg_gen_sar_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1457 tcg_gen_sar_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1459 gen_extu(ot
, cpu_T
[0]);
1460 tcg_gen_shr_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1461 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1464 tcg_gen_shl_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1465 tcg_gen_shl_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1469 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1471 gen_shift_flags(s
, ot
, cpu_T
[0], cpu_tmp0
, cpu_T
[1], is_right
);
1474 static void gen_shift_rm_im(DisasContext
*s
, TCGMemOp ot
, int op1
, int op2
,
1475 int is_right
, int is_arith
)
1477 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1481 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1483 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1489 gen_exts(ot
, cpu_T
[0]);
1490 tcg_gen_sari_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1491 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], op2
);
1493 gen_extu(ot
, cpu_T
[0]);
1494 tcg_gen_shri_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1495 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], op2
);
1498 tcg_gen_shli_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1499 tcg_gen_shli_tl(cpu_T
[0], cpu_T
[0], op2
);
1504 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1506 /* update eflags if non zero shift */
1508 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
1509 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
1510 set_cc_op(s
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1514 static void gen_rot_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
, int is_right
)
1516 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1520 if (op1
== OR_TMP0
) {
1521 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1523 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1526 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], mask
);
1530 /* Replicate the 8-bit input so that a 32-bit rotate works. */
1531 tcg_gen_ext8u_tl(cpu_T
[0], cpu_T
[0]);
1532 tcg_gen_muli_tl(cpu_T
[0], cpu_T
[0], 0x01010101);
1535 /* Replicate the 16-bit input so that a 32-bit rotate works. */
1536 tcg_gen_deposit_tl(cpu_T
[0], cpu_T
[0], cpu_T
[0], 16, 16);
1539 #ifdef TARGET_X86_64
1541 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
1542 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
1544 tcg_gen_rotr_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1546 tcg_gen_rotl_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1548 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
1553 tcg_gen_rotr_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1555 tcg_gen_rotl_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1561 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1563 /* We'll need the flags computed into CC_SRC. */
1564 gen_compute_eflags(s
);
1566 /* The value that was "rotated out" is now present at the other end
1567 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1568 since we've computed the flags into CC_SRC, these variables are
1571 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T
[0], mask
- 1);
1572 tcg_gen_shri_tl(cpu_cc_dst
, cpu_T
[0], mask
);
1573 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1575 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T
[0], mask
);
1576 tcg_gen_andi_tl(cpu_cc_dst
, cpu_T
[0], 1);
1578 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1579 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1581 /* Now conditionally store the new CC_OP value. If the shift count
1582 is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1583 Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1584 exactly as we computed above. */
1585 t0
= tcg_const_i32(0);
1586 t1
= tcg_temp_new_i32();
1587 tcg_gen_trunc_tl_i32(t1
, cpu_T
[1]);
1588 tcg_gen_movi_i32(cpu_tmp2_i32
, CC_OP_ADCOX
);
1589 tcg_gen_movi_i32(cpu_tmp3_i32
, CC_OP_EFLAGS
);
1590 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, t1
, t0
,
1591 cpu_tmp2_i32
, cpu_tmp3_i32
);
1592 tcg_temp_free_i32(t0
);
1593 tcg_temp_free_i32(t1
);
1595 /* The CC_OP value is no longer predictable. */
1596 set_cc_op(s
, CC_OP_DYNAMIC
);
1599 static void gen_rot_rm_im(DisasContext
*s
, TCGMemOp ot
, int op1
, int op2
,
1602 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1606 if (op1
== OR_TMP0
) {
1607 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1609 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1615 #ifdef TARGET_X86_64
1617 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
1619 tcg_gen_rotri_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, op2
);
1621 tcg_gen_rotli_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, op2
);
1623 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
1628 tcg_gen_rotri_tl(cpu_T
[0], cpu_T
[0], op2
);
1630 tcg_gen_rotli_tl(cpu_T
[0], cpu_T
[0], op2
);
1641 shift
= mask
+ 1 - shift
;
1643 gen_extu(ot
, cpu_T
[0]);
1644 tcg_gen_shli_tl(cpu_tmp0
, cpu_T
[0], shift
);
1645 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], mask
+ 1 - shift
);
1646 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
1652 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1655 /* Compute the flags into CC_SRC. */
1656 gen_compute_eflags(s
);
1658 /* The value that was "rotated out" is now present at the other end
1659 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1660 since we've computed the flags into CC_SRC, these variables are
1663 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T
[0], mask
- 1);
1664 tcg_gen_shri_tl(cpu_cc_dst
, cpu_T
[0], mask
);
1665 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1667 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T
[0], mask
);
1668 tcg_gen_andi_tl(cpu_cc_dst
, cpu_T
[0], 1);
1670 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1671 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1672 set_cc_op(s
, CC_OP_ADCOX
);
1676 /* XXX: add faster immediate = 1 case */
1677 static void gen_rotc_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1680 gen_compute_eflags(s
);
1681 assert(s
->cc_op
== CC_OP_EFLAGS
);
1685 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1687 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1692 gen_helper_rcrb(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1695 gen_helper_rcrw(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1698 gen_helper_rcrl(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1700 #ifdef TARGET_X86_64
1702 gen_helper_rcrq(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1711 gen_helper_rclb(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1714 gen_helper_rclw(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1717 gen_helper_rcll(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1719 #ifdef TARGET_X86_64
1721 gen_helper_rclq(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1729 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1732 /* XXX: add faster immediate case */
1733 static void gen_shiftd_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1734 bool is_right
, TCGv count_in
)
1736 target_ulong mask
= (ot
== MO_64
? 63 : 31);
1740 if (op1
== OR_TMP0
) {
1741 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1743 gen_op_mov_v_reg(ot
, cpu_T
[0], op1
);
1746 count
= tcg_temp_new();
1747 tcg_gen_andi_tl(count
, count_in
, mask
);
1751 /* Note: we implement the Intel behaviour for shift count > 16.
1752 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A
1753 portion by constructing it as a 32-bit value. */
1755 tcg_gen_deposit_tl(cpu_tmp0
, cpu_T
[0], cpu_T
[1], 16, 16);
1756 tcg_gen_mov_tl(cpu_T
[1], cpu_T
[0]);
1757 tcg_gen_mov_tl(cpu_T
[0], cpu_tmp0
);
1759 tcg_gen_deposit_tl(cpu_T
[1], cpu_T
[0], cpu_T
[1], 16, 16);
1762 #ifdef TARGET_X86_64
1764 /* Concatenate the two 32-bit values and use a 64-bit shift. */
1765 tcg_gen_subi_tl(cpu_tmp0
, count
, 1);
1767 tcg_gen_concat_tl_i64(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1768 tcg_gen_shr_i64(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1769 tcg_gen_shr_i64(cpu_T
[0], cpu_T
[0], count
);
1771 tcg_gen_concat_tl_i64(cpu_T
[0], cpu_T
[1], cpu_T
[0]);
1772 tcg_gen_shl_i64(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1773 tcg_gen_shl_i64(cpu_T
[0], cpu_T
[0], count
);
1774 tcg_gen_shri_i64(cpu_tmp0
, cpu_tmp0
, 32);
1775 tcg_gen_shri_i64(cpu_T
[0], cpu_T
[0], 32);
1780 tcg_gen_subi_tl(cpu_tmp0
, count
, 1);
1782 tcg_gen_shr_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1784 tcg_gen_subfi_tl(cpu_tmp4
, mask
+ 1, count
);
1785 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], count
);
1786 tcg_gen_shl_tl(cpu_T
[1], cpu_T
[1], cpu_tmp4
);
1788 tcg_gen_shl_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1790 /* Only needed if count > 16, for Intel behaviour. */
1791 tcg_gen_subfi_tl(cpu_tmp4
, 33, count
);
1792 tcg_gen_shr_tl(cpu_tmp4
, cpu_T
[1], cpu_tmp4
);
1793 tcg_gen_or_tl(cpu_tmp0
, cpu_tmp0
, cpu_tmp4
);
1796 tcg_gen_subfi_tl(cpu_tmp4
, mask
+ 1, count
);
1797 tcg_gen_shl_tl(cpu_T
[0], cpu_T
[0], count
);
1798 tcg_gen_shr_tl(cpu_T
[1], cpu_T
[1], cpu_tmp4
);
1800 tcg_gen_movi_tl(cpu_tmp4
, 0);
1801 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_T
[1], count
, cpu_tmp4
,
1802 cpu_tmp4
, cpu_T
[1]);
1803 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1808 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1810 gen_shift_flags(s
, ot
, cpu_T
[0], cpu_tmp0
, count
, is_right
);
1811 tcg_temp_free(count
);
1814 static void gen_shift(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
, int s
)
1817 gen_op_mov_v_reg(ot
, cpu_T
[1], s
);
1820 gen_rot_rm_T1(s1
, ot
, d
, 0);
1823 gen_rot_rm_T1(s1
, ot
, d
, 1);
1827 gen_shift_rm_T1(s1
, ot
, d
, 0, 0);
1830 gen_shift_rm_T1(s1
, ot
, d
, 1, 0);
1833 gen_shift_rm_T1(s1
, ot
, d
, 1, 1);
1836 gen_rotc_rm_T1(s1
, ot
, d
, 0);
1839 gen_rotc_rm_T1(s1
, ot
, d
, 1);
1844 static void gen_shifti(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
, int c
)
1848 gen_rot_rm_im(s1
, ot
, d
, c
, 0);
1851 gen_rot_rm_im(s1
, ot
, d
, c
, 1);
1855 gen_shift_rm_im(s1
, ot
, d
, c
, 0, 0);
1858 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 0);
1861 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 1);
1864 /* currently not optimized */
1865 tcg_gen_movi_tl(cpu_T
[1], c
);
1866 gen_shift(s1
, op
, ot
, d
, OR_TMP1
);
1871 static void gen_lea_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
1878 int mod
, rm
, code
, override
, must_add_seg
;
1881 override
= s
->override
;
1882 must_add_seg
= s
->addseg
;
1885 mod
= (modrm
>> 6) & 3;
1898 code
= cpu_ldub_code(env
, s
->pc
++);
1899 scale
= (code
>> 6) & 3;
1900 index
= ((code
>> 3) & 7) | REX_X(s
);
1902 index
= -1; /* no index */
1910 if ((base
& 7) == 5) {
1912 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
1914 if (CODE64(s
) && !havesib
) {
1915 disp
+= s
->pc
+ s
->rip_offset
;
1922 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
1926 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
1931 /* For correct popl handling with esp. */
1932 if (base
== R_ESP
&& s
->popl_esp_hack
) {
1933 disp
+= s
->popl_esp_hack
;
1936 /* Compute the address, with a minimum number of TCG ops. */
1940 sum
= cpu_regs
[index
];
1942 tcg_gen_shli_tl(cpu_A0
, cpu_regs
[index
], scale
);
1946 tcg_gen_add_tl(cpu_A0
, sum
, cpu_regs
[base
]);
1949 } else if (base
>= 0) {
1950 sum
= cpu_regs
[base
];
1952 if (TCGV_IS_UNUSED(sum
)) {
1953 tcg_gen_movi_tl(cpu_A0
, disp
);
1955 tcg_gen_addi_tl(cpu_A0
, sum
, disp
);
1960 if (base
== R_EBP
|| base
== R_ESP
) {
1967 tcg_gen_ld_tl(cpu_tmp0
, cpu_env
,
1968 offsetof(CPUX86State
, segs
[override
].base
));
1970 if (s
->aflag
== MO_32
) {
1971 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
1973 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
1977 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
1980 if (s
->aflag
== MO_32
) {
1981 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
1989 disp
= cpu_lduw_code(env
, s
->pc
);
1991 tcg_gen_movi_tl(cpu_A0
, disp
);
1992 rm
= 0; /* avoid SS override */
1999 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
2003 disp
= (int16_t)cpu_lduw_code(env
, s
->pc
);
2011 tcg_gen_add_tl(cpu_A0
, cpu_regs
[R_EBX
], cpu_regs
[R_ESI
]);
2014 tcg_gen_add_tl(cpu_A0
, cpu_regs
[R_EBX
], cpu_regs
[R_EDI
]);
2017 tcg_gen_add_tl(cpu_A0
, cpu_regs
[R_EBP
], cpu_regs
[R_ESI
]);
2020 tcg_gen_add_tl(cpu_A0
, cpu_regs
[R_EBP
], cpu_regs
[R_EDI
]);
2023 sum
= cpu_regs
[R_ESI
];
2026 sum
= cpu_regs
[R_EDI
];
2029 sum
= cpu_regs
[R_EBP
];
2033 sum
= cpu_regs
[R_EBX
];
2036 tcg_gen_addi_tl(cpu_A0
, sum
, disp
);
2037 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2041 if (rm
== 2 || rm
== 3 || rm
== 6) {
2047 gen_op_addl_A0_seg(s
, override
);
2056 static void gen_nop_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2058 int mod
, rm
, base
, code
;
2060 mod
= (modrm
>> 6) & 3;
2071 code
= cpu_ldub_code(env
, s
->pc
++);
2113 /* used for LEA and MOV AX, mem */
2114 static void gen_add_A0_ds_seg(DisasContext
*s
)
2116 int override
, must_add_seg
;
2117 must_add_seg
= s
->addseg
;
2119 if (s
->override
>= 0) {
2120 override
= s
->override
;
2124 #ifdef TARGET_X86_64
2126 gen_op_addq_A0_seg(override
);
2130 gen_op_addl_A0_seg(s
, override
);
2135 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2137 static void gen_ldst_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2138 TCGMemOp ot
, int reg
, int is_store
)
2142 mod
= (modrm
>> 6) & 3;
2143 rm
= (modrm
& 7) | REX_B(s
);
2147 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
2148 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
2150 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
2152 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
2155 gen_lea_modrm(env
, s
, modrm
);
2158 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
2159 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
2161 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
2163 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
2168 static inline uint32_t insn_get(CPUX86State
*env
, DisasContext
*s
, TCGMemOp ot
)
2174 ret
= cpu_ldub_code(env
, s
->pc
);
2178 ret
= cpu_lduw_code(env
, s
->pc
);
2182 #ifdef TARGET_X86_64
2185 ret
= cpu_ldl_code(env
, s
->pc
);
2194 static inline int insn_const_size(TCGMemOp ot
)
2203 static inline void gen_goto_tb(DisasContext
*s
, int tb_num
, target_ulong eip
)
2205 TranslationBlock
*tb
;
2208 pc
= s
->cs_base
+ eip
;
2210 /* NOTE: we handle the case where the TB spans two pages here */
2211 if ((pc
& TARGET_PAGE_MASK
) == (tb
->pc
& TARGET_PAGE_MASK
) ||
2212 (pc
& TARGET_PAGE_MASK
) == ((s
->pc
- 1) & TARGET_PAGE_MASK
)) {
2213 /* jump to same page: we can use a direct jump */
2214 tcg_gen_goto_tb(tb_num
);
2216 tcg_gen_exit_tb((uintptr_t)tb
+ tb_num
);
2218 /* jump to another page: currently not optimized */
2224 static inline void gen_jcc(DisasContext
*s
, int b
,
2225 target_ulong val
, target_ulong next_eip
)
2230 l1
= gen_new_label();
2233 gen_goto_tb(s
, 0, next_eip
);
2236 gen_goto_tb(s
, 1, val
);
2237 s
->is_jmp
= DISAS_TB_JUMP
;
2239 l1
= gen_new_label();
2240 l2
= gen_new_label();
2243 gen_jmp_im(next_eip
);
2253 static void gen_cmovcc1(CPUX86State
*env
, DisasContext
*s
, TCGMemOp ot
, int b
,
2258 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
2260 cc
= gen_prepare_cc(s
, b
, cpu_T
[1]);
2261 if (cc
.mask
!= -1) {
2262 TCGv t0
= tcg_temp_new();
2263 tcg_gen_andi_tl(t0
, cc
.reg
, cc
.mask
);
2267 cc
.reg2
= tcg_const_tl(cc
.imm
);
2270 tcg_gen_movcond_tl(cc
.cond
, cpu_T
[0], cc
.reg
, cc
.reg2
,
2271 cpu_T
[0], cpu_regs
[reg
]);
2272 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
2274 if (cc
.mask
!= -1) {
2275 tcg_temp_free(cc
.reg
);
2278 tcg_temp_free(cc
.reg2
);
2282 static inline void gen_op_movl_T0_seg(int seg_reg
)
2284 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
,
2285 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2288 static inline void gen_op_movl_seg_T0_vm(int seg_reg
)
2290 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffff);
2291 tcg_gen_st32_tl(cpu_T
[0], cpu_env
,
2292 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2293 tcg_gen_shli_tl(cpu_T
[0], cpu_T
[0], 4);
2294 tcg_gen_st_tl(cpu_T
[0], cpu_env
,
2295 offsetof(CPUX86State
,segs
[seg_reg
].base
));
2298 /* move T0 to seg_reg and compute if the CPU state may change. Never
2299 call this function with seg_reg == R_CS */
2300 static void gen_movl_seg_T0(DisasContext
*s
, int seg_reg
, target_ulong cur_eip
)
2302 if (s
->pe
&& !s
->vm86
) {
2303 /* XXX: optimize by finding processor state dynamically */
2304 gen_update_cc_op(s
);
2305 gen_jmp_im(cur_eip
);
2306 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
2307 gen_helper_load_seg(cpu_env
, tcg_const_i32(seg_reg
), cpu_tmp2_i32
);
2308 /* abort translation because the addseg value may change or
2309 because ss32 may change. For R_SS, translation must always
2310 stop as a special handling must be done to disable hardware
2311 interrupts for the next instruction */
2312 if (seg_reg
== R_SS
|| (s
->code32
&& seg_reg
< R_FS
))
2313 s
->is_jmp
= DISAS_TB_JUMP
;
2315 gen_op_movl_seg_T0_vm(seg_reg
);
2316 if (seg_reg
== R_SS
)
2317 s
->is_jmp
= DISAS_TB_JUMP
;
2321 static inline int svm_is_rep(int prefixes
)
2323 return ((prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) ? 8 : 0);
2327 gen_svm_check_intercept_param(DisasContext
*s
, target_ulong pc_start
,
2328 uint32_t type
, uint64_t param
)
2330 /* no SVM activated; fast case */
2331 if (likely(!(s
->flags
& HF_SVMI_MASK
)))
2333 gen_update_cc_op(s
);
2334 gen_jmp_im(pc_start
- s
->cs_base
);
2335 gen_helper_svm_check_intercept_param(cpu_env
, tcg_const_i32(type
),
2336 tcg_const_i64(param
));
2340 gen_svm_check_intercept(DisasContext
*s
, target_ulong pc_start
, uint64_t type
)
2342 gen_svm_check_intercept_param(s
, pc_start
, type
, 0);
2345 static inline void gen_stack_update(DisasContext
*s
, int addend
)
2347 #ifdef TARGET_X86_64
2349 gen_op_add_reg_im(MO_64
, R_ESP
, addend
);
2353 gen_op_add_reg_im(MO_32
, R_ESP
, addend
);
2355 gen_op_add_reg_im(MO_16
, R_ESP
, addend
);
2359 /* Generate a push. It depends on ss32, addseg and dflag. */
2360 static void gen_push_v(DisasContext
*s
, TCGv val
)
2362 TCGMemOp a_ot
, d_ot
= mo_pushpop(s
, s
->dflag
);
2363 int size
= 1 << d_ot
;
2364 TCGv new_esp
= cpu_A0
;
2366 tcg_gen_subi_tl(cpu_A0
, cpu_regs
[R_ESP
], size
);
2370 } else if (s
->ss32
) {
2374 tcg_gen_mov_tl(new_esp
, cpu_A0
);
2375 gen_op_addl_A0_seg(s
, R_SS
);
2377 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
2382 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2383 tcg_gen_mov_tl(new_esp
, cpu_A0
);
2384 gen_op_addl_A0_seg(s
, R_SS
);
2387 gen_op_st_v(s
, d_ot
, val
, cpu_A0
);
2388 gen_op_mov_reg_v(a_ot
, R_ESP
, new_esp
);
2391 /* two step pop is necessary for precise exceptions */
2392 static TCGMemOp
gen_pop_T0(DisasContext
*s
)
2394 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2398 addr
= cpu_regs
[R_ESP
];
2399 } else if (!s
->ss32
) {
2400 tcg_gen_ext16u_tl(cpu_A0
, cpu_regs
[R_ESP
]);
2401 gen_op_addl_A0_seg(s
, R_SS
);
2402 } else if (s
->addseg
) {
2403 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_ESP
]);
2404 gen_op_addl_A0_seg(s
, R_SS
);
2406 tcg_gen_ext32u_tl(cpu_A0
, cpu_regs
[R_ESP
]);
2409 gen_op_ld_v(s
, d_ot
, cpu_T
[0], addr
);
2413 static void gen_pop_update(DisasContext
*s
, TCGMemOp ot
)
2415 gen_stack_update(s
, 1 << ot
);
2418 static void gen_stack_A0(DisasContext
*s
)
2420 gen_op_movl_A0_reg(R_ESP
);
2422 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2423 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2425 gen_op_addl_A0_seg(s
, R_SS
);
2428 /* NOTE: wrap around in 16 bit not fully handled */
2429 static void gen_pusha(DisasContext
*s
)
2432 gen_op_movl_A0_reg(R_ESP
);
2433 gen_op_addl_A0_im(-8 << s
->dflag
);
2435 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2436 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2438 gen_op_addl_A0_seg(s
, R_SS
);
2439 for(i
= 0;i
< 8; i
++) {
2440 gen_op_mov_v_reg(MO_32
, cpu_T
[0], 7 - i
);
2441 gen_op_st_v(s
, s
->dflag
, cpu_T
[0], cpu_A0
);
2442 gen_op_addl_A0_im(1 << s
->dflag
);
2444 gen_op_mov_reg_v(MO_16
+ s
->ss32
, R_ESP
, cpu_T
[1]);
2447 /* NOTE: wrap around in 16 bit not fully handled */
2448 static void gen_popa(DisasContext
*s
)
2451 gen_op_movl_A0_reg(R_ESP
);
2453 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2454 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2455 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], 8 << s
->dflag
);
2457 gen_op_addl_A0_seg(s
, R_SS
);
2458 for(i
= 0;i
< 8; i
++) {
2459 /* ESP is not reloaded */
2461 gen_op_ld_v(s
, s
->dflag
, cpu_T
[0], cpu_A0
);
2462 gen_op_mov_reg_v(s
->dflag
, 7 - i
, cpu_T
[0]);
2464 gen_op_addl_A0_im(1 << s
->dflag
);
2466 gen_op_mov_reg_v(MO_16
+ s
->ss32
, R_ESP
, cpu_T
[1]);
2469 static void gen_enter(DisasContext
*s
, int esp_addend
, int level
)
2471 TCGMemOp ot
= mo_pushpop(s
, s
->dflag
);
2472 int opsize
= 1 << ot
;
2475 #ifdef TARGET_X86_64
2477 gen_op_movl_A0_reg(R_ESP
);
2478 gen_op_addq_A0_im(-opsize
);
2479 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2482 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EBP
);
2483 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
2485 /* XXX: must save state */
2486 gen_helper_enter64_level(cpu_env
, tcg_const_i32(level
),
2487 tcg_const_i32((ot
== MO_64
)),
2490 gen_op_mov_reg_v(ot
, R_EBP
, cpu_T
[1]);
2491 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], -esp_addend
+ (-opsize
* level
));
2492 gen_op_mov_reg_v(MO_64
, R_ESP
, cpu_T
[1]);
2496 gen_op_movl_A0_reg(R_ESP
);
2497 gen_op_addl_A0_im(-opsize
);
2499 tcg_gen_ext16u_tl(cpu_A0
, cpu_A0
);
2500 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2502 gen_op_addl_A0_seg(s
, R_SS
);
2504 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EBP
);
2505 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
2507 /* XXX: must save state */
2508 gen_helper_enter_level(cpu_env
, tcg_const_i32(level
),
2509 tcg_const_i32(s
->dflag
- 1),
2512 gen_op_mov_reg_v(ot
, R_EBP
, cpu_T
[1]);
2513 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], -esp_addend
+ (-opsize
* level
));
2514 gen_op_mov_reg_v(MO_16
+ s
->ss32
, R_ESP
, cpu_T
[1]);
2518 static void gen_exception(DisasContext
*s
, int trapno
, target_ulong cur_eip
)
2520 gen_update_cc_op(s
);
2521 gen_jmp_im(cur_eip
);
2522 gen_helper_raise_exception(cpu_env
, tcg_const_i32(trapno
));
2523 s
->is_jmp
= DISAS_TB_JUMP
;
2526 /* an interrupt is different from an exception because of the
2528 static void gen_interrupt(DisasContext
*s
, int intno
,
2529 target_ulong cur_eip
, target_ulong next_eip
)
2531 gen_update_cc_op(s
);
2532 gen_jmp_im(cur_eip
);
2533 gen_helper_raise_interrupt(cpu_env
, tcg_const_i32(intno
),
2534 tcg_const_i32(next_eip
- cur_eip
));
2535 s
->is_jmp
= DISAS_TB_JUMP
;
2538 static void gen_debug(DisasContext
*s
, target_ulong cur_eip
)
2540 gen_update_cc_op(s
);
2541 gen_jmp_im(cur_eip
);
2542 gen_helper_debug(cpu_env
);
2543 s
->is_jmp
= DISAS_TB_JUMP
;
2546 /* generate a generic end of block. Trace exception is also generated
2548 static void gen_eob(DisasContext
*s
)
2550 gen_update_cc_op(s
);
2551 if (s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
) {
2552 gen_helper_reset_inhibit_irq(cpu_env
);
2554 if (s
->tb
->flags
& HF_RF_MASK
) {
2555 gen_helper_reset_rf(cpu_env
);
2557 if (s
->singlestep_enabled
) {
2558 gen_helper_debug(cpu_env
);
2560 gen_helper_single_step(cpu_env
);
2564 s
->is_jmp
= DISAS_TB_JUMP
;
2567 /* generate a jump to eip. No segment change must happen before as a
2568 direct call to the next block may occur */
2569 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
)
2571 gen_update_cc_op(s
);
2572 set_cc_op(s
, CC_OP_DYNAMIC
);
2574 gen_goto_tb(s
, tb_num
, eip
);
2575 s
->is_jmp
= DISAS_TB_JUMP
;
2582 static void gen_jmp(DisasContext
*s
, target_ulong eip
)
2584 gen_jmp_tb(s
, eip
, 0);
2587 static inline void gen_ldq_env_A0(DisasContext
*s
, int offset
)
2589 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
2590 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2593 static inline void gen_stq_env_A0(DisasContext
*s
, int offset
)
2595 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2596 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
2599 static inline void gen_ldo_env_A0(DisasContext
*s
, int offset
)
2601 int mem_index
= s
->mem_index
;
2602 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, mem_index
, MO_LEQ
);
2603 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(0)));
2604 tcg_gen_addi_tl(cpu_tmp0
, cpu_A0
, 8);
2605 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
, MO_LEQ
);
2606 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(1)));
2609 static inline void gen_sto_env_A0(DisasContext
*s
, int offset
)
2611 int mem_index
= s
->mem_index
;
2612 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(0)));
2613 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, mem_index
, MO_LEQ
);
2614 tcg_gen_addi_tl(cpu_tmp0
, cpu_A0
, 8);
2615 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(1)));
2616 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
, MO_LEQ
);
2619 static inline void gen_op_movo(int d_offset
, int s_offset
)
2621 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
+ offsetof(XMMReg
, XMM_Q(0)));
2622 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
+ offsetof(XMMReg
, XMM_Q(0)));
2623 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
+ offsetof(XMMReg
, XMM_Q(1)));
2624 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
+ offsetof(XMMReg
, XMM_Q(1)));
2627 static inline void gen_op_movq(int d_offset
, int s_offset
)
2629 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
);
2630 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2633 static inline void gen_op_movl(int d_offset
, int s_offset
)
2635 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
, s_offset
);
2636 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, d_offset
);
2639 static inline void gen_op_movq_env_0(int d_offset
)
2641 tcg_gen_movi_i64(cpu_tmp1_i64
, 0);
2642 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2645 typedef void (*SSEFunc_i_ep
)(TCGv_i32 val
, TCGv_ptr env
, TCGv_ptr reg
);
2646 typedef void (*SSEFunc_l_ep
)(TCGv_i64 val
, TCGv_ptr env
, TCGv_ptr reg
);
2647 typedef void (*SSEFunc_0_epi
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i32 val
);
2648 typedef void (*SSEFunc_0_epl
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i64 val
);
2649 typedef void (*SSEFunc_0_epp
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
);
2650 typedef void (*SSEFunc_0_eppi
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2652 typedef void (*SSEFunc_0_ppi
)(TCGv_ptr reg_a
, TCGv_ptr reg_b
, TCGv_i32 val
);
2653 typedef void (*SSEFunc_0_eppt
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2656 #define SSE_SPECIAL ((void *)1)
2657 #define SSE_DUMMY ((void *)2)
2659 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2660 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2661 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2663 static const SSEFunc_0_epp sse_op_table1
[256][4] = {
2664 /* 3DNow! extensions */
2665 [0x0e] = { SSE_DUMMY
}, /* femms */
2666 [0x0f] = { SSE_DUMMY
}, /* pf... */
2667 /* pure SSE operations */
2668 [0x10] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2669 [0x11] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2670 [0x12] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd, movsldup, movddup */
2671 [0x13] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd */
2672 [0x14] = { gen_helper_punpckldq_xmm
, gen_helper_punpcklqdq_xmm
},
2673 [0x15] = { gen_helper_punpckhdq_xmm
, gen_helper_punpckhqdq_xmm
},
2674 [0x16] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd, movshdup */
2675 [0x17] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd */
2677 [0x28] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2678 [0x29] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2679 [0x2a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2680 [0x2b] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movntps, movntpd, movntss, movntsd */
2681 [0x2c] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2682 [0x2d] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2683 [0x2e] = { gen_helper_ucomiss
, gen_helper_ucomisd
},
2684 [0x2f] = { gen_helper_comiss
, gen_helper_comisd
},
2685 [0x50] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movmskps, movmskpd */
2686 [0x51] = SSE_FOP(sqrt
),
2687 [0x52] = { gen_helper_rsqrtps
, NULL
, gen_helper_rsqrtss
, NULL
},
2688 [0x53] = { gen_helper_rcpps
, NULL
, gen_helper_rcpss
, NULL
},
2689 [0x54] = { gen_helper_pand_xmm
, gen_helper_pand_xmm
}, /* andps, andpd */
2690 [0x55] = { gen_helper_pandn_xmm
, gen_helper_pandn_xmm
}, /* andnps, andnpd */
2691 [0x56] = { gen_helper_por_xmm
, gen_helper_por_xmm
}, /* orps, orpd */
2692 [0x57] = { gen_helper_pxor_xmm
, gen_helper_pxor_xmm
}, /* xorps, xorpd */
2693 [0x58] = SSE_FOP(add
),
2694 [0x59] = SSE_FOP(mul
),
2695 [0x5a] = { gen_helper_cvtps2pd
, gen_helper_cvtpd2ps
,
2696 gen_helper_cvtss2sd
, gen_helper_cvtsd2ss
},
2697 [0x5b] = { gen_helper_cvtdq2ps
, gen_helper_cvtps2dq
, gen_helper_cvttps2dq
},
2698 [0x5c] = SSE_FOP(sub
),
2699 [0x5d] = SSE_FOP(min
),
2700 [0x5e] = SSE_FOP(div
),
2701 [0x5f] = SSE_FOP(max
),
2703 [0xc2] = SSE_FOP(cmpeq
),
2704 [0xc6] = { (SSEFunc_0_epp
)gen_helper_shufps
,
2705 (SSEFunc_0_epp
)gen_helper_shufpd
}, /* XXX: casts */
2707 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */
2708 [0x38] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2709 [0x3a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2711 /* MMX ops and their SSE extensions */
2712 [0x60] = MMX_OP2(punpcklbw
),
2713 [0x61] = MMX_OP2(punpcklwd
),
2714 [0x62] = MMX_OP2(punpckldq
),
2715 [0x63] = MMX_OP2(packsswb
),
2716 [0x64] = MMX_OP2(pcmpgtb
),
2717 [0x65] = MMX_OP2(pcmpgtw
),
2718 [0x66] = MMX_OP2(pcmpgtl
),
2719 [0x67] = MMX_OP2(packuswb
),
2720 [0x68] = MMX_OP2(punpckhbw
),
2721 [0x69] = MMX_OP2(punpckhwd
),
2722 [0x6a] = MMX_OP2(punpckhdq
),
2723 [0x6b] = MMX_OP2(packssdw
),
2724 [0x6c] = { NULL
, gen_helper_punpcklqdq_xmm
},
2725 [0x6d] = { NULL
, gen_helper_punpckhqdq_xmm
},
2726 [0x6e] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movd mm, ea */
2727 [0x6f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, , movqdu */
2728 [0x70] = { (SSEFunc_0_epp
)gen_helper_pshufw_mmx
,
2729 (SSEFunc_0_epp
)gen_helper_pshufd_xmm
,
2730 (SSEFunc_0_epp
)gen_helper_pshufhw_xmm
,
2731 (SSEFunc_0_epp
)gen_helper_pshuflw_xmm
}, /* XXX: casts */
2732 [0x71] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftw */
2733 [0x72] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftd */
2734 [0x73] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftq */
2735 [0x74] = MMX_OP2(pcmpeqb
),
2736 [0x75] = MMX_OP2(pcmpeqw
),
2737 [0x76] = MMX_OP2(pcmpeql
),
2738 [0x77] = { SSE_DUMMY
}, /* emms */
2739 [0x78] = { NULL
, SSE_SPECIAL
, NULL
, SSE_SPECIAL
}, /* extrq_i, insertq_i */
2740 [0x79] = { NULL
, gen_helper_extrq_r
, NULL
, gen_helper_insertq_r
},
2741 [0x7c] = { NULL
, gen_helper_haddpd
, NULL
, gen_helper_haddps
},
2742 [0x7d] = { NULL
, gen_helper_hsubpd
, NULL
, gen_helper_hsubps
},
2743 [0x7e] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movd, movd, , movq */
2744 [0x7f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, movdqu */
2745 [0xc4] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pinsrw */
2746 [0xc5] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pextrw */
2747 [0xd0] = { NULL
, gen_helper_addsubpd
, NULL
, gen_helper_addsubps
},
2748 [0xd1] = MMX_OP2(psrlw
),
2749 [0xd2] = MMX_OP2(psrld
),
2750 [0xd3] = MMX_OP2(psrlq
),
2751 [0xd4] = MMX_OP2(paddq
),
2752 [0xd5] = MMX_OP2(pmullw
),
2753 [0xd6] = { NULL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2754 [0xd7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pmovmskb */
2755 [0xd8] = MMX_OP2(psubusb
),
2756 [0xd9] = MMX_OP2(psubusw
),
2757 [0xda] = MMX_OP2(pminub
),
2758 [0xdb] = MMX_OP2(pand
),
2759 [0xdc] = MMX_OP2(paddusb
),
2760 [0xdd] = MMX_OP2(paddusw
),
2761 [0xde] = MMX_OP2(pmaxub
),
2762 [0xdf] = MMX_OP2(pandn
),
2763 [0xe0] = MMX_OP2(pavgb
),
2764 [0xe1] = MMX_OP2(psraw
),
2765 [0xe2] = MMX_OP2(psrad
),
2766 [0xe3] = MMX_OP2(pavgw
),
2767 [0xe4] = MMX_OP2(pmulhuw
),
2768 [0xe5] = MMX_OP2(pmulhw
),
2769 [0xe6] = { NULL
, gen_helper_cvttpd2dq
, gen_helper_cvtdq2pd
, gen_helper_cvtpd2dq
},
2770 [0xe7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movntq, movntq */
2771 [0xe8] = MMX_OP2(psubsb
),
2772 [0xe9] = MMX_OP2(psubsw
),
2773 [0xea] = MMX_OP2(pminsw
),
2774 [0xeb] = MMX_OP2(por
),
2775 [0xec] = MMX_OP2(paddsb
),
2776 [0xed] = MMX_OP2(paddsw
),
2777 [0xee] = MMX_OP2(pmaxsw
),
2778 [0xef] = MMX_OP2(pxor
),
2779 [0xf0] = { NULL
, NULL
, NULL
, SSE_SPECIAL
}, /* lddqu */
2780 [0xf1] = MMX_OP2(psllw
),
2781 [0xf2] = MMX_OP2(pslld
),
2782 [0xf3] = MMX_OP2(psllq
),
2783 [0xf4] = MMX_OP2(pmuludq
),
2784 [0xf5] = MMX_OP2(pmaddwd
),
2785 [0xf6] = MMX_OP2(psadbw
),
2786 [0xf7] = { (SSEFunc_0_epp
)gen_helper_maskmov_mmx
,
2787 (SSEFunc_0_epp
)gen_helper_maskmov_xmm
}, /* XXX: casts */
2788 [0xf8] = MMX_OP2(psubb
),
2789 [0xf9] = MMX_OP2(psubw
),
2790 [0xfa] = MMX_OP2(psubl
),
2791 [0xfb] = MMX_OP2(psubq
),
2792 [0xfc] = MMX_OP2(paddb
),
2793 [0xfd] = MMX_OP2(paddw
),
2794 [0xfe] = MMX_OP2(paddl
),
2797 static const SSEFunc_0_epp sse_op_table2
[3 * 8][2] = {
2798 [0 + 2] = MMX_OP2(psrlw
),
2799 [0 + 4] = MMX_OP2(psraw
),
2800 [0 + 6] = MMX_OP2(psllw
),
2801 [8 + 2] = MMX_OP2(psrld
),
2802 [8 + 4] = MMX_OP2(psrad
),
2803 [8 + 6] = MMX_OP2(pslld
),
2804 [16 + 2] = MMX_OP2(psrlq
),
2805 [16 + 3] = { NULL
, gen_helper_psrldq_xmm
},
2806 [16 + 6] = MMX_OP2(psllq
),
2807 [16 + 7] = { NULL
, gen_helper_pslldq_xmm
},
2810 static const SSEFunc_0_epi sse_op_table3ai
[] = {
2811 gen_helper_cvtsi2ss
,
2815 #ifdef TARGET_X86_64
2816 static const SSEFunc_0_epl sse_op_table3aq
[] = {
2817 gen_helper_cvtsq2ss
,
2822 static const SSEFunc_i_ep sse_op_table3bi
[] = {
2823 gen_helper_cvttss2si
,
2824 gen_helper_cvtss2si
,
2825 gen_helper_cvttsd2si
,
2829 #ifdef TARGET_X86_64
2830 static const SSEFunc_l_ep sse_op_table3bq
[] = {
2831 gen_helper_cvttss2sq
,
2832 gen_helper_cvtss2sq
,
2833 gen_helper_cvttsd2sq
,
2838 static const SSEFunc_0_epp sse_op_table4
[8][4] = {
2849 static const SSEFunc_0_epp sse_op_table5
[256] = {
2850 [0x0c] = gen_helper_pi2fw
,
2851 [0x0d] = gen_helper_pi2fd
,
2852 [0x1c] = gen_helper_pf2iw
,
2853 [0x1d] = gen_helper_pf2id
,
2854 [0x8a] = gen_helper_pfnacc
,
2855 [0x8e] = gen_helper_pfpnacc
,
2856 [0x90] = gen_helper_pfcmpge
,
2857 [0x94] = gen_helper_pfmin
,
2858 [0x96] = gen_helper_pfrcp
,
2859 [0x97] = gen_helper_pfrsqrt
,
2860 [0x9a] = gen_helper_pfsub
,
2861 [0x9e] = gen_helper_pfadd
,
2862 [0xa0] = gen_helper_pfcmpgt
,
2863 [0xa4] = gen_helper_pfmax
,
2864 [0xa6] = gen_helper_movq
, /* pfrcpit1; no need to actually increase precision */
2865 [0xa7] = gen_helper_movq
, /* pfrsqit1 */
2866 [0xaa] = gen_helper_pfsubr
,
2867 [0xae] = gen_helper_pfacc
,
2868 [0xb0] = gen_helper_pfcmpeq
,
2869 [0xb4] = gen_helper_pfmul
,
2870 [0xb6] = gen_helper_movq
, /* pfrcpit2 */
2871 [0xb7] = gen_helper_pmulhrw_mmx
,
2872 [0xbb] = gen_helper_pswapd
,
2873 [0xbf] = gen_helper_pavgb_mmx
/* pavgusb */
2876 struct SSEOpHelper_epp
{
2877 SSEFunc_0_epp op
[2];
2881 struct SSEOpHelper_eppi
{
2882 SSEFunc_0_eppi op
[2];
2886 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
2887 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
2888 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
2889 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
2890 #define PCLMULQDQ_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, \
2891 CPUID_EXT_PCLMULQDQ }
2892 #define AESNI_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_AES }
2894 static const struct SSEOpHelper_epp sse_op_table6
[256] = {
2895 [0x00] = SSSE3_OP(pshufb
),
2896 [0x01] = SSSE3_OP(phaddw
),
2897 [0x02] = SSSE3_OP(phaddd
),
2898 [0x03] = SSSE3_OP(phaddsw
),
2899 [0x04] = SSSE3_OP(pmaddubsw
),
2900 [0x05] = SSSE3_OP(phsubw
),
2901 [0x06] = SSSE3_OP(phsubd
),
2902 [0x07] = SSSE3_OP(phsubsw
),
2903 [0x08] = SSSE3_OP(psignb
),
2904 [0x09] = SSSE3_OP(psignw
),
2905 [0x0a] = SSSE3_OP(psignd
),
2906 [0x0b] = SSSE3_OP(pmulhrsw
),
2907 [0x10] = SSE41_OP(pblendvb
),
2908 [0x14] = SSE41_OP(blendvps
),
2909 [0x15] = SSE41_OP(blendvpd
),
2910 [0x17] = SSE41_OP(ptest
),
2911 [0x1c] = SSSE3_OP(pabsb
),
2912 [0x1d] = SSSE3_OP(pabsw
),
2913 [0x1e] = SSSE3_OP(pabsd
),
2914 [0x20] = SSE41_OP(pmovsxbw
),
2915 [0x21] = SSE41_OP(pmovsxbd
),
2916 [0x22] = SSE41_OP(pmovsxbq
),
2917 [0x23] = SSE41_OP(pmovsxwd
),
2918 [0x24] = SSE41_OP(pmovsxwq
),
2919 [0x25] = SSE41_OP(pmovsxdq
),
2920 [0x28] = SSE41_OP(pmuldq
),
2921 [0x29] = SSE41_OP(pcmpeqq
),
2922 [0x2a] = SSE41_SPECIAL
, /* movntqda */
2923 [0x2b] = SSE41_OP(packusdw
),
2924 [0x30] = SSE41_OP(pmovzxbw
),
2925 [0x31] = SSE41_OP(pmovzxbd
),
2926 [0x32] = SSE41_OP(pmovzxbq
),
2927 [0x33] = SSE41_OP(pmovzxwd
),
2928 [0x34] = SSE41_OP(pmovzxwq
),
2929 [0x35] = SSE41_OP(pmovzxdq
),
2930 [0x37] = SSE42_OP(pcmpgtq
),
2931 [0x38] = SSE41_OP(pminsb
),
2932 [0x39] = SSE41_OP(pminsd
),
2933 [0x3a] = SSE41_OP(pminuw
),
2934 [0x3b] = SSE41_OP(pminud
),
2935 [0x3c] = SSE41_OP(pmaxsb
),
2936 [0x3d] = SSE41_OP(pmaxsd
),
2937 [0x3e] = SSE41_OP(pmaxuw
),
2938 [0x3f] = SSE41_OP(pmaxud
),
2939 [0x40] = SSE41_OP(pmulld
),
2940 [0x41] = SSE41_OP(phminposuw
),
2941 [0xdb] = AESNI_OP(aesimc
),
2942 [0xdc] = AESNI_OP(aesenc
),
2943 [0xdd] = AESNI_OP(aesenclast
),
2944 [0xde] = AESNI_OP(aesdec
),
2945 [0xdf] = AESNI_OP(aesdeclast
),
2948 static const struct SSEOpHelper_eppi sse_op_table7
[256] = {
2949 [0x08] = SSE41_OP(roundps
),
2950 [0x09] = SSE41_OP(roundpd
),
2951 [0x0a] = SSE41_OP(roundss
),
2952 [0x0b] = SSE41_OP(roundsd
),
2953 [0x0c] = SSE41_OP(blendps
),
2954 [0x0d] = SSE41_OP(blendpd
),
2955 [0x0e] = SSE41_OP(pblendw
),
2956 [0x0f] = SSSE3_OP(palignr
),
2957 [0x14] = SSE41_SPECIAL
, /* pextrb */
2958 [0x15] = SSE41_SPECIAL
, /* pextrw */
2959 [0x16] = SSE41_SPECIAL
, /* pextrd/pextrq */
2960 [0x17] = SSE41_SPECIAL
, /* extractps */
2961 [0x20] = SSE41_SPECIAL
, /* pinsrb */
2962 [0x21] = SSE41_SPECIAL
, /* insertps */
2963 [0x22] = SSE41_SPECIAL
, /* pinsrd/pinsrq */
2964 [0x40] = SSE41_OP(dpps
),
2965 [0x41] = SSE41_OP(dppd
),
2966 [0x42] = SSE41_OP(mpsadbw
),
2967 [0x44] = PCLMULQDQ_OP(pclmulqdq
),
2968 [0x60] = SSE42_OP(pcmpestrm
),
2969 [0x61] = SSE42_OP(pcmpestri
),
2970 [0x62] = SSE42_OP(pcmpistrm
),
2971 [0x63] = SSE42_OP(pcmpistri
),
2972 [0xdf] = AESNI_OP(aeskeygenassist
),
2975 static void gen_sse(CPUX86State
*env
, DisasContext
*s
, int b
,
2976 target_ulong pc_start
, int rex_r
)
2978 int b1
, op1_offset
, op2_offset
, is_xmm
, val
;
2979 int modrm
, mod
, rm
, reg
;
2980 SSEFunc_0_epp sse_fn_epp
;
2981 SSEFunc_0_eppi sse_fn_eppi
;
2982 SSEFunc_0_ppi sse_fn_ppi
;
2983 SSEFunc_0_eppt sse_fn_eppt
;
2987 if (s
->prefix
& PREFIX_DATA
)
2989 else if (s
->prefix
& PREFIX_REPZ
)
2991 else if (s
->prefix
& PREFIX_REPNZ
)
2995 sse_fn_epp
= sse_op_table1
[b
][b1
];
2999 if ((b
<= 0x5f && b
>= 0x10) || b
== 0xc6 || b
== 0xc2) {
3009 /* simple MMX/SSE operation */
3010 if (s
->flags
& HF_TS_MASK
) {
3011 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
3014 if (s
->flags
& HF_EM_MASK
) {
3016 gen_exception(s
, EXCP06_ILLOP
, pc_start
- s
->cs_base
);
3019 if (is_xmm
&& !(s
->flags
& HF_OSFXSR_MASK
))
3020 if ((b
!= 0x38 && b
!= 0x3a) || (s
->prefix
& PREFIX_DATA
))
3023 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
))
3026 gen_helper_emms(cpu_env
);
3031 gen_helper_emms(cpu_env
);
3034 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3035 the static cpu state) */
3037 gen_helper_enter_mmx(cpu_env
);
3040 modrm
= cpu_ldub_code(env
, s
->pc
++);
3041 reg
= ((modrm
>> 3) & 7);
3044 mod
= (modrm
>> 6) & 3;
3045 if (sse_fn_epp
== SSE_SPECIAL
) {
3048 case 0x0e7: /* movntq */
3051 gen_lea_modrm(env
, s
, modrm
);
3052 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3054 case 0x1e7: /* movntdq */
3055 case 0x02b: /* movntps */
3056 case 0x12b: /* movntps */
3059 gen_lea_modrm(env
, s
, modrm
);
3060 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3062 case 0x3f0: /* lddqu */
3065 gen_lea_modrm(env
, s
, modrm
);
3066 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3068 case 0x22b: /* movntss */
3069 case 0x32b: /* movntsd */
3072 gen_lea_modrm(env
, s
, modrm
);
3074 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3075 xmm_regs
[reg
].XMM_Q(0)));
3077 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
3078 xmm_regs
[reg
].XMM_L(0)));
3079 gen_op_st_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
3082 case 0x6e: /* movd mm, ea */
3083 #ifdef TARGET_X86_64
3084 if (s
->dflag
== MO_64
) {
3085 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3086 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3090 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3091 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3092 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3093 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3094 gen_helper_movl_mm_T0_mmx(cpu_ptr0
, cpu_tmp2_i32
);
3097 case 0x16e: /* movd xmm, ea */
3098 #ifdef TARGET_X86_64
3099 if (s
->dflag
== MO_64
) {
3100 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3101 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3102 offsetof(CPUX86State
,xmm_regs
[reg
]));
3103 gen_helper_movq_mm_T0_xmm(cpu_ptr0
, cpu_T
[0]);
3107 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3108 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3109 offsetof(CPUX86State
,xmm_regs
[reg
]));
3110 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3111 gen_helper_movl_mm_T0_xmm(cpu_ptr0
, cpu_tmp2_i32
);
3114 case 0x6f: /* movq mm, ea */
3116 gen_lea_modrm(env
, s
, modrm
);
3117 gen_ldq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3120 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
3121 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3122 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
3123 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3126 case 0x010: /* movups */
3127 case 0x110: /* movupd */
3128 case 0x028: /* movaps */
3129 case 0x128: /* movapd */
3130 case 0x16f: /* movdqa xmm, ea */
3131 case 0x26f: /* movdqu xmm, ea */
3133 gen_lea_modrm(env
, s
, modrm
);
3134 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3136 rm
= (modrm
& 7) | REX_B(s
);
3137 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[reg
]),
3138 offsetof(CPUX86State
,xmm_regs
[rm
]));
3141 case 0x210: /* movss xmm, ea */
3143 gen_lea_modrm(env
, s
, modrm
);
3144 gen_op_ld_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
3145 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3146 tcg_gen_movi_tl(cpu_T
[0], 0);
3147 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(1)));
3148 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)));
3149 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)));
3151 rm
= (modrm
& 7) | REX_B(s
);
3152 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)),
3153 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(0)));
3156 case 0x310: /* movsd xmm, ea */
3158 gen_lea_modrm(env
, s
, modrm
);
3159 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3160 xmm_regs
[reg
].XMM_Q(0)));
3161 tcg_gen_movi_tl(cpu_T
[0], 0);
3162 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)));
3163 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)));
3165 rm
= (modrm
& 7) | REX_B(s
);
3166 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3167 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3170 case 0x012: /* movlps */
3171 case 0x112: /* movlpd */
3173 gen_lea_modrm(env
, s
, modrm
);
3174 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3175 xmm_regs
[reg
].XMM_Q(0)));
3178 rm
= (modrm
& 7) | REX_B(s
);
3179 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3180 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(1)));
3183 case 0x212: /* movsldup */
3185 gen_lea_modrm(env
, s
, modrm
);
3186 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3188 rm
= (modrm
& 7) | REX_B(s
);
3189 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)),
3190 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(0)));
3191 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)),
3192 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(2)));
3194 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(1)),
3195 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3196 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)),
3197 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)));
3199 case 0x312: /* movddup */
3201 gen_lea_modrm(env
, s
, modrm
);
3202 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3203 xmm_regs
[reg
].XMM_Q(0)));
3205 rm
= (modrm
& 7) | REX_B(s
);
3206 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3207 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3209 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)),
3210 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3212 case 0x016: /* movhps */
3213 case 0x116: /* movhpd */
3215 gen_lea_modrm(env
, s
, modrm
);
3216 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3217 xmm_regs
[reg
].XMM_Q(1)));
3220 rm
= (modrm
& 7) | REX_B(s
);
3221 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)),
3222 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3225 case 0x216: /* movshdup */
3227 gen_lea_modrm(env
, s
, modrm
);
3228 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3230 rm
= (modrm
& 7) | REX_B(s
);
3231 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(1)),
3232 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(1)));
3233 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)),
3234 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(3)));
3236 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)),
3237 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(1)));
3238 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)),
3239 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)));
3244 int bit_index
, field_length
;
3246 if (b1
== 1 && reg
!= 0)
3248 field_length
= cpu_ldub_code(env
, s
->pc
++) & 0x3F;
3249 bit_index
= cpu_ldub_code(env
, s
->pc
++) & 0x3F;
3250 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3251 offsetof(CPUX86State
,xmm_regs
[reg
]));
3253 gen_helper_extrq_i(cpu_env
, cpu_ptr0
,
3254 tcg_const_i32(bit_index
),
3255 tcg_const_i32(field_length
));
3257 gen_helper_insertq_i(cpu_env
, cpu_ptr0
,
3258 tcg_const_i32(bit_index
),
3259 tcg_const_i32(field_length
));
3262 case 0x7e: /* movd ea, mm */
3263 #ifdef TARGET_X86_64
3264 if (s
->dflag
== MO_64
) {
3265 tcg_gen_ld_i64(cpu_T
[0], cpu_env
,
3266 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3267 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3271 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
,
3272 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_L(0)));
3273 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3276 case 0x17e: /* movd ea, xmm */
3277 #ifdef TARGET_X86_64
3278 if (s
->dflag
== MO_64
) {
3279 tcg_gen_ld_i64(cpu_T
[0], cpu_env
,
3280 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3281 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3285 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
,
3286 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3287 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3290 case 0x27e: /* movq xmm, ea */
3292 gen_lea_modrm(env
, s
, modrm
);
3293 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3294 xmm_regs
[reg
].XMM_Q(0)));
3296 rm
= (modrm
& 7) | REX_B(s
);
3297 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3298 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3300 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)));
3302 case 0x7f: /* movq ea, mm */
3304 gen_lea_modrm(env
, s
, modrm
);
3305 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3308 gen_op_movq(offsetof(CPUX86State
,fpregs
[rm
].mmx
),
3309 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3312 case 0x011: /* movups */
3313 case 0x111: /* movupd */
3314 case 0x029: /* movaps */
3315 case 0x129: /* movapd */
3316 case 0x17f: /* movdqa ea, xmm */
3317 case 0x27f: /* movdqu ea, xmm */
3319 gen_lea_modrm(env
, s
, modrm
);
3320 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3322 rm
= (modrm
& 7) | REX_B(s
);
3323 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[rm
]),
3324 offsetof(CPUX86State
,xmm_regs
[reg
]));
3327 case 0x211: /* movss ea, xmm */
3329 gen_lea_modrm(env
, s
, modrm
);
3330 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3331 gen_op_st_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
3333 rm
= (modrm
& 7) | REX_B(s
);
3334 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(0)),
3335 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3338 case 0x311: /* movsd ea, xmm */
3340 gen_lea_modrm(env
, s
, modrm
);
3341 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3342 xmm_regs
[reg
].XMM_Q(0)));
3344 rm
= (modrm
& 7) | REX_B(s
);
3345 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)),
3346 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3349 case 0x013: /* movlps */
3350 case 0x113: /* movlpd */
3352 gen_lea_modrm(env
, s
, modrm
);
3353 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3354 xmm_regs
[reg
].XMM_Q(0)));
3359 case 0x017: /* movhps */
3360 case 0x117: /* movhpd */
3362 gen_lea_modrm(env
, s
, modrm
);
3363 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3364 xmm_regs
[reg
].XMM_Q(1)));
3369 case 0x71: /* shift mm, im */
3372 case 0x171: /* shift xmm, im */
3378 val
= cpu_ldub_code(env
, s
->pc
++);
3380 tcg_gen_movi_tl(cpu_T
[0], val
);
3381 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.XMM_L(0)));
3382 tcg_gen_movi_tl(cpu_T
[0], 0);
3383 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.XMM_L(1)));
3384 op1_offset
= offsetof(CPUX86State
,xmm_t0
);
3386 tcg_gen_movi_tl(cpu_T
[0], val
);
3387 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,mmx_t0
.MMX_L(0)));
3388 tcg_gen_movi_tl(cpu_T
[0], 0);
3389 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,mmx_t0
.MMX_L(1)));
3390 op1_offset
= offsetof(CPUX86State
,mmx_t0
);
3392 sse_fn_epp
= sse_op_table2
[((b
- 1) & 3) * 8 +
3393 (((modrm
>> 3)) & 7)][b1
];
3398 rm
= (modrm
& 7) | REX_B(s
);
3399 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3402 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3404 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3405 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op1_offset
);
3406 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3408 case 0x050: /* movmskps */
3409 rm
= (modrm
& 7) | REX_B(s
);
3410 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3411 offsetof(CPUX86State
,xmm_regs
[rm
]));
3412 gen_helper_movmskps(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3413 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3415 case 0x150: /* movmskpd */
3416 rm
= (modrm
& 7) | REX_B(s
);
3417 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3418 offsetof(CPUX86State
,xmm_regs
[rm
]));
3419 gen_helper_movmskpd(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3420 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3422 case 0x02a: /* cvtpi2ps */
3423 case 0x12a: /* cvtpi2pd */
3424 gen_helper_enter_mmx(cpu_env
);
3426 gen_lea_modrm(env
, s
, modrm
);
3427 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3428 gen_ldq_env_A0(s
, op2_offset
);
3431 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3433 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3434 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3435 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3438 gen_helper_cvtpi2ps(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3442 gen_helper_cvtpi2pd(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3446 case 0x22a: /* cvtsi2ss */
3447 case 0x32a: /* cvtsi2sd */
3448 ot
= mo_64_32(s
->dflag
);
3449 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3450 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3451 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3453 SSEFunc_0_epi sse_fn_epi
= sse_op_table3ai
[(b
>> 8) & 1];
3454 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3455 sse_fn_epi(cpu_env
, cpu_ptr0
, cpu_tmp2_i32
);
3457 #ifdef TARGET_X86_64
3458 SSEFunc_0_epl sse_fn_epl
= sse_op_table3aq
[(b
>> 8) & 1];
3459 sse_fn_epl(cpu_env
, cpu_ptr0
, cpu_T
[0]);
3465 case 0x02c: /* cvttps2pi */
3466 case 0x12c: /* cvttpd2pi */
3467 case 0x02d: /* cvtps2pi */
3468 case 0x12d: /* cvtpd2pi */
3469 gen_helper_enter_mmx(cpu_env
);
3471 gen_lea_modrm(env
, s
, modrm
);
3472 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3473 gen_ldo_env_A0(s
, op2_offset
);
3475 rm
= (modrm
& 7) | REX_B(s
);
3476 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3478 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
);
3479 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3480 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3483 gen_helper_cvttps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3486 gen_helper_cvttpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3489 gen_helper_cvtps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3492 gen_helper_cvtpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3496 case 0x22c: /* cvttss2si */
3497 case 0x32c: /* cvttsd2si */
3498 case 0x22d: /* cvtss2si */
3499 case 0x32d: /* cvtsd2si */
3500 ot
= mo_64_32(s
->dflag
);
3502 gen_lea_modrm(env
, s
, modrm
);
3504 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.XMM_Q(0)));
3506 gen_op_ld_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
3507 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.XMM_L(0)));
3509 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3511 rm
= (modrm
& 7) | REX_B(s
);
3512 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3514 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3516 SSEFunc_i_ep sse_fn_i_ep
=
3517 sse_op_table3bi
[((b
>> 7) & 2) | (b
& 1)];
3518 sse_fn_i_ep(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3519 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
3521 #ifdef TARGET_X86_64
3522 SSEFunc_l_ep sse_fn_l_ep
=
3523 sse_op_table3bq
[((b
>> 7) & 2) | (b
& 1)];
3524 sse_fn_l_ep(cpu_T
[0], cpu_env
, cpu_ptr0
);
3529 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3531 case 0xc4: /* pinsrw */
3534 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
3535 val
= cpu_ldub_code(env
, s
->pc
++);
3538 tcg_gen_st16_tl(cpu_T
[0], cpu_env
,
3539 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_W(val
)));
3542 tcg_gen_st16_tl(cpu_T
[0], cpu_env
,
3543 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_W(val
)));
3546 case 0xc5: /* pextrw */
3550 ot
= mo_64_32(s
->dflag
);
3551 val
= cpu_ldub_code(env
, s
->pc
++);
3554 rm
= (modrm
& 7) | REX_B(s
);
3555 tcg_gen_ld16u_tl(cpu_T
[0], cpu_env
,
3556 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_W(val
)));
3560 tcg_gen_ld16u_tl(cpu_T
[0], cpu_env
,
3561 offsetof(CPUX86State
,fpregs
[rm
].mmx
.MMX_W(val
)));
3563 reg
= ((modrm
>> 3) & 7) | rex_r
;
3564 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3566 case 0x1d6: /* movq ea, xmm */
3568 gen_lea_modrm(env
, s
, modrm
);
3569 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3570 xmm_regs
[reg
].XMM_Q(0)));
3572 rm
= (modrm
& 7) | REX_B(s
);
3573 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)),
3574 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3575 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(1)));
3578 case 0x2d6: /* movq2dq */
3579 gen_helper_enter_mmx(cpu_env
);
3581 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3582 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3583 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)));
3585 case 0x3d6: /* movdq2q */
3586 gen_helper_enter_mmx(cpu_env
);
3587 rm
= (modrm
& 7) | REX_B(s
);
3588 gen_op_movq(offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
),
3589 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3591 case 0xd7: /* pmovmskb */
3596 rm
= (modrm
& 7) | REX_B(s
);
3597 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[rm
]));
3598 gen_helper_pmovmskb_xmm(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3601 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3602 gen_helper_pmovmskb_mmx(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3604 reg
= ((modrm
>> 3) & 7) | rex_r
;
3605 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3611 if ((b
& 0xf0) == 0xf0) {
3614 modrm
= cpu_ldub_code(env
, s
->pc
++);
3616 reg
= ((modrm
>> 3) & 7) | rex_r
;
3617 mod
= (modrm
>> 6) & 3;
3622 sse_fn_epp
= sse_op_table6
[b
].op
[b1
];
3626 if (!(s
->cpuid_ext_features
& sse_op_table6
[b
].ext_mask
))
3630 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3632 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
3634 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3635 gen_lea_modrm(env
, s
, modrm
);
3637 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3638 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3639 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3640 gen_ldq_env_A0(s
, op2_offset
+
3641 offsetof(XMMReg
, XMM_Q(0)));
3643 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3644 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3645 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
3646 s
->mem_index
, MO_LEUL
);
3647 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, op2_offset
+
3648 offsetof(XMMReg
, XMM_L(0)));
3650 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3651 tcg_gen_qemu_ld_tl(cpu_tmp0
, cpu_A0
,
3652 s
->mem_index
, MO_LEUW
);
3653 tcg_gen_st16_tl(cpu_tmp0
, cpu_env
, op2_offset
+
3654 offsetof(XMMReg
, XMM_W(0)));
3656 case 0x2a: /* movntqda */
3657 gen_ldo_env_A0(s
, op1_offset
);
3660 gen_ldo_env_A0(s
, op2_offset
);
3664 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
3666 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3668 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3669 gen_lea_modrm(env
, s
, modrm
);
3670 gen_ldq_env_A0(s
, op2_offset
);
3673 if (sse_fn_epp
== SSE_SPECIAL
) {
3677 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3678 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3679 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3682 set_cc_op(s
, CC_OP_EFLAGS
);
3689 /* Various integer extensions at 0f 38 f[0-f]. */
3690 b
= modrm
| (b1
<< 8);
3691 modrm
= cpu_ldub_code(env
, s
->pc
++);
3692 reg
= ((modrm
>> 3) & 7) | rex_r
;
3695 case 0x3f0: /* crc32 Gd,Eb */
3696 case 0x3f1: /* crc32 Gd,Ey */
3698 if (!(s
->cpuid_ext_features
& CPUID_EXT_SSE42
)) {
3701 if ((b
& 0xff) == 0xf0) {
3703 } else if (s
->dflag
!= MO_64
) {
3704 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3709 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[reg
]);
3710 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3711 gen_helper_crc32(cpu_T
[0], cpu_tmp2_i32
,
3712 cpu_T
[0], tcg_const_i32(8 << ot
));
3714 ot
= mo_64_32(s
->dflag
);
3715 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3718 case 0x1f0: /* crc32 or movbe */
3720 /* For these insns, the f3 prefix is supposed to have priority
3721 over the 66 prefix, but that's not what we implement above
3723 if (s
->prefix
& PREFIX_REPNZ
) {
3727 case 0x0f0: /* movbe Gy,My */
3728 case 0x0f1: /* movbe My,Gy */
3729 if (!(s
->cpuid_ext_features
& CPUID_EXT_MOVBE
)) {
3732 if (s
->dflag
!= MO_64
) {
3733 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3738 gen_lea_modrm(env
, s
, modrm
);
3740 tcg_gen_qemu_ld_tl(cpu_T
[0], cpu_A0
,
3741 s
->mem_index
, ot
| MO_BE
);
3742 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3744 tcg_gen_qemu_st_tl(cpu_regs
[reg
], cpu_A0
,
3745 s
->mem_index
, ot
| MO_BE
);
3749 case 0x0f2: /* andn Gy, By, Ey */
3750 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3751 || !(s
->prefix
& PREFIX_VEX
)
3755 ot
= mo_64_32(s
->dflag
);
3756 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3757 tcg_gen_andc_tl(cpu_T
[0], cpu_regs
[s
->vex_v
], cpu_T
[0]);
3758 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3759 gen_op_update1_cc();
3760 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3763 case 0x0f7: /* bextr Gy, Ey, By */
3764 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3765 || !(s
->prefix
& PREFIX_VEX
)
3769 ot
= mo_64_32(s
->dflag
);
3773 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3774 /* Extract START, and shift the operand.
3775 Shifts larger than operand size get zeros. */
3776 tcg_gen_ext8u_tl(cpu_A0
, cpu_regs
[s
->vex_v
]);
3777 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], cpu_A0
);
3779 bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3780 zero
= tcg_const_tl(0);
3781 tcg_gen_movcond_tl(TCG_COND_LEU
, cpu_T
[0], cpu_A0
, bound
,
3783 tcg_temp_free(zero
);
3785 /* Extract the LEN into a mask. Lengths larger than
3786 operand size get all ones. */
3787 tcg_gen_shri_tl(cpu_A0
, cpu_regs
[s
->vex_v
], 8);
3788 tcg_gen_ext8u_tl(cpu_A0
, cpu_A0
);
3789 tcg_gen_movcond_tl(TCG_COND_LEU
, cpu_A0
, cpu_A0
, bound
,
3791 tcg_temp_free(bound
);
3792 tcg_gen_movi_tl(cpu_T
[1], 1);
3793 tcg_gen_shl_tl(cpu_T
[1], cpu_T
[1], cpu_A0
);
3794 tcg_gen_subi_tl(cpu_T
[1], cpu_T
[1], 1);
3795 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
3797 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3798 gen_op_update1_cc();
3799 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3803 case 0x0f5: /* bzhi Gy, Ey, By */
3804 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3805 || !(s
->prefix
& PREFIX_VEX
)
3809 ot
= mo_64_32(s
->dflag
);
3810 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3811 tcg_gen_ext8u_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
3813 TCGv bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3814 /* Note that since we're using BMILG (in order to get O
3815 cleared) we need to store the inverse into C. */
3816 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_cc_src
,
3818 tcg_gen_movcond_tl(TCG_COND_GT
, cpu_T
[1], cpu_T
[1],
3819 bound
, bound
, cpu_T
[1]);
3820 tcg_temp_free(bound
);
3822 tcg_gen_movi_tl(cpu_A0
, -1);
3823 tcg_gen_shl_tl(cpu_A0
, cpu_A0
, cpu_T
[1]);
3824 tcg_gen_andc_tl(cpu_T
[0], cpu_T
[0], cpu_A0
);
3825 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
3826 gen_op_update1_cc();
3827 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
3830 case 0x3f6: /* mulx By, Gy, rdx, Ey */
3831 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3832 || !(s
->prefix
& PREFIX_VEX
)
3836 ot
= mo_64_32(s
->dflag
);
3837 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3840 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3841 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EDX
]);
3842 tcg_gen_mulu2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
3843 cpu_tmp2_i32
, cpu_tmp3_i32
);
3844 tcg_gen_extu_i32_tl(cpu_regs
[s
->vex_v
], cpu_tmp2_i32
);
3845 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp3_i32
);
3847 #ifdef TARGET_X86_64
3849 tcg_gen_mulu2_i64(cpu_regs
[s
->vex_v
], cpu_regs
[reg
],
3850 cpu_T
[0], cpu_regs
[R_EDX
]);
3856 case 0x3f5: /* pdep Gy, By, Ey */
3857 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3858 || !(s
->prefix
& PREFIX_VEX
)
3862 ot
= mo_64_32(s
->dflag
);
3863 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3864 /* Note that by zero-extending the mask operand, we
3865 automatically handle zero-extending the result. */
3867 tcg_gen_mov_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
3869 tcg_gen_ext32u_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
3871 gen_helper_pdep(cpu_regs
[reg
], cpu_T
[0], cpu_T
[1]);
3874 case 0x2f5: /* pext Gy, By, Ey */
3875 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3876 || !(s
->prefix
& PREFIX_VEX
)
3880 ot
= mo_64_32(s
->dflag
);
3881 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3882 /* Note that by zero-extending the mask operand, we
3883 automatically handle zero-extending the result. */
3885 tcg_gen_mov_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
3887 tcg_gen_ext32u_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
3889 gen_helper_pext(cpu_regs
[reg
], cpu_T
[0], cpu_T
[1]);
3892 case 0x1f6: /* adcx Gy, Ey */
3893 case 0x2f6: /* adox Gy, Ey */
3894 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_ADX
)) {
3897 TCGv carry_in
, carry_out
, zero
;
3900 ot
= mo_64_32(s
->dflag
);
3901 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3903 /* Re-use the carry-out from a previous round. */
3904 TCGV_UNUSED(carry_in
);
3905 carry_out
= (b
== 0x1f6 ? cpu_cc_dst
: cpu_cc_src2
);
3909 carry_in
= cpu_cc_dst
;
3910 end_op
= CC_OP_ADCX
;
3912 end_op
= CC_OP_ADCOX
;
3917 end_op
= CC_OP_ADCOX
;
3919 carry_in
= cpu_cc_src2
;
3920 end_op
= CC_OP_ADOX
;
3924 end_op
= CC_OP_ADCOX
;
3925 carry_in
= carry_out
;
3928 end_op
= (b
== 0x1f6 ? CC_OP_ADCX
: CC_OP_ADOX
);
3931 /* If we can't reuse carry-out, get it out of EFLAGS. */
3932 if (TCGV_IS_UNUSED(carry_in
)) {
3933 if (s
->cc_op
!= CC_OP_ADCX
&& s
->cc_op
!= CC_OP_ADOX
) {
3934 gen_compute_eflags(s
);
3936 carry_in
= cpu_tmp0
;
3937 tcg_gen_shri_tl(carry_in
, cpu_cc_src
,
3938 ctz32(b
== 0x1f6 ? CC_C
: CC_O
));
3939 tcg_gen_andi_tl(carry_in
, carry_in
, 1);
3943 #ifdef TARGET_X86_64
3945 /* If we know TL is 64-bit, and we want a 32-bit
3946 result, just do everything in 64-bit arithmetic. */
3947 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_regs
[reg
]);
3948 tcg_gen_ext32u_i64(cpu_T
[0], cpu_T
[0]);
3949 tcg_gen_add_i64(cpu_T
[0], cpu_T
[0], cpu_regs
[reg
]);
3950 tcg_gen_add_i64(cpu_T
[0], cpu_T
[0], carry_in
);
3951 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_T
[0]);
3952 tcg_gen_shri_i64(carry_out
, cpu_T
[0], 32);
3956 /* Otherwise compute the carry-out in two steps. */
3957 zero
= tcg_const_tl(0);
3958 tcg_gen_add2_tl(cpu_T
[0], carry_out
,
3961 tcg_gen_add2_tl(cpu_regs
[reg
], carry_out
,
3962 cpu_regs
[reg
], carry_out
,
3964 tcg_temp_free(zero
);
3967 set_cc_op(s
, end_op
);
3971 case 0x1f7: /* shlx Gy, Ey, By */
3972 case 0x2f7: /* sarx Gy, Ey, By */
3973 case 0x3f7: /* shrx Gy, Ey, By */
3974 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3975 || !(s
->prefix
& PREFIX_VEX
)
3979 ot
= mo_64_32(s
->dflag
);
3980 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3982 tcg_gen_andi_tl(cpu_T
[1], cpu_regs
[s
->vex_v
], 63);
3984 tcg_gen_andi_tl(cpu_T
[1], cpu_regs
[s
->vex_v
], 31);
3987 tcg_gen_shl_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
3988 } else if (b
== 0x2f7) {
3990 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
3992 tcg_gen_sar_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
3995 tcg_gen_ext32u_tl(cpu_T
[0], cpu_T
[0]);
3997 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
3999 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
4005 case 0x3f3: /* Group 17 */
4006 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
4007 || !(s
->prefix
& PREFIX_VEX
)
4011 ot
= mo_64_32(s
->dflag
);
4012 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4015 case 1: /* blsr By,Ey */
4016 tcg_gen_neg_tl(cpu_T
[1], cpu_T
[0]);
4017 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4018 gen_op_mov_reg_v(ot
, s
->vex_v
, cpu_T
[0]);
4019 gen_op_update2_cc();
4020 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4023 case 2: /* blsmsk By,Ey */
4024 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
4025 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], 1);
4026 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_cc_src
);
4027 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4028 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4031 case 3: /* blsi By, Ey */
4032 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
4033 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], 1);
4034 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_cc_src
);
4035 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4036 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4052 modrm
= cpu_ldub_code(env
, s
->pc
++);
4054 reg
= ((modrm
>> 3) & 7) | rex_r
;
4055 mod
= (modrm
>> 6) & 3;
4060 sse_fn_eppi
= sse_op_table7
[b
].op
[b1
];
4064 if (!(s
->cpuid_ext_features
& sse_op_table7
[b
].ext_mask
))
4067 if (sse_fn_eppi
== SSE_SPECIAL
) {
4068 ot
= mo_64_32(s
->dflag
);
4069 rm
= (modrm
& 7) | REX_B(s
);
4071 gen_lea_modrm(env
, s
, modrm
);
4072 reg
= ((modrm
>> 3) & 7) | rex_r
;
4073 val
= cpu_ldub_code(env
, s
->pc
++);
4075 case 0x14: /* pextrb */
4076 tcg_gen_ld8u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4077 xmm_regs
[reg
].XMM_B(val
& 15)));
4079 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4081 tcg_gen_qemu_st_tl(cpu_T
[0], cpu_A0
,
4082 s
->mem_index
, MO_UB
);
4085 case 0x15: /* pextrw */
4086 tcg_gen_ld16u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4087 xmm_regs
[reg
].XMM_W(val
& 7)));
4089 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4091 tcg_gen_qemu_st_tl(cpu_T
[0], cpu_A0
,
4092 s
->mem_index
, MO_LEUW
);
4096 if (ot
== MO_32
) { /* pextrd */
4097 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4098 offsetof(CPUX86State
,
4099 xmm_regs
[reg
].XMM_L(val
& 3)));
4101 tcg_gen_extu_i32_tl(cpu_regs
[rm
], cpu_tmp2_i32
);
4103 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
4104 s
->mem_index
, MO_LEUL
);
4106 } else { /* pextrq */
4107 #ifdef TARGET_X86_64
4108 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
4109 offsetof(CPUX86State
,
4110 xmm_regs
[reg
].XMM_Q(val
& 1)));
4112 tcg_gen_mov_i64(cpu_regs
[rm
], cpu_tmp1_i64
);
4114 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
4115 s
->mem_index
, MO_LEQ
);
4122 case 0x17: /* extractps */
4123 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4124 xmm_regs
[reg
].XMM_L(val
& 3)));
4126 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4128 tcg_gen_qemu_st_tl(cpu_T
[0], cpu_A0
,
4129 s
->mem_index
, MO_LEUL
);
4132 case 0x20: /* pinsrb */
4134 gen_op_mov_v_reg(MO_32
, cpu_T
[0], rm
);
4136 tcg_gen_qemu_ld_tl(cpu_T
[0], cpu_A0
,
4137 s
->mem_index
, MO_UB
);
4139 tcg_gen_st8_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4140 xmm_regs
[reg
].XMM_B(val
& 15)));
4142 case 0x21: /* insertps */
4144 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4145 offsetof(CPUX86State
,xmm_regs
[rm
]
4146 .XMM_L((val
>> 6) & 3)));
4148 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
4149 s
->mem_index
, MO_LEUL
);
4151 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4152 offsetof(CPUX86State
,xmm_regs
[reg
]
4153 .XMM_L((val
>> 4) & 3)));
4155 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4156 cpu_env
, offsetof(CPUX86State
,
4157 xmm_regs
[reg
].XMM_L(0)));
4159 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4160 cpu_env
, offsetof(CPUX86State
,
4161 xmm_regs
[reg
].XMM_L(1)));
4163 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4164 cpu_env
, offsetof(CPUX86State
,
4165 xmm_regs
[reg
].XMM_L(2)));
4167 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4168 cpu_env
, offsetof(CPUX86State
,
4169 xmm_regs
[reg
].XMM_L(3)));
4172 if (ot
== MO_32
) { /* pinsrd */
4174 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[rm
]);
4176 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
4177 s
->mem_index
, MO_LEUL
);
4179 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4180 offsetof(CPUX86State
,
4181 xmm_regs
[reg
].XMM_L(val
& 3)));
4182 } else { /* pinsrq */
4183 #ifdef TARGET_X86_64
4185 gen_op_mov_v_reg(ot
, cpu_tmp1_i64
, rm
);
4187 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
4188 s
->mem_index
, MO_LEQ
);
4190 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
4191 offsetof(CPUX86State
,
4192 xmm_regs
[reg
].XMM_Q(val
& 1)));
4203 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4205 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
4207 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4208 gen_lea_modrm(env
, s
, modrm
);
4209 gen_ldo_env_A0(s
, op2_offset
);
4212 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4214 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4216 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4217 gen_lea_modrm(env
, s
, modrm
);
4218 gen_ldq_env_A0(s
, op2_offset
);
4221 val
= cpu_ldub_code(env
, s
->pc
++);
4223 if ((b
& 0xfc) == 0x60) { /* pcmpXstrX */
4224 set_cc_op(s
, CC_OP_EFLAGS
);
4226 if (s
->dflag
== MO_64
) {
4227 /* The helper must use entire 64-bit gp registers */
4232 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4233 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4234 sse_fn_eppi(cpu_env
, cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4238 /* Various integer extensions at 0f 3a f[0-f]. */
4239 b
= modrm
| (b1
<< 8);
4240 modrm
= cpu_ldub_code(env
, s
->pc
++);
4241 reg
= ((modrm
>> 3) & 7) | rex_r
;
4244 case 0x3f0: /* rorx Gy,Ey, Ib */
4245 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4246 || !(s
->prefix
& PREFIX_VEX
)
4250 ot
= mo_64_32(s
->dflag
);
4251 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4252 b
= cpu_ldub_code(env
, s
->pc
++);
4254 tcg_gen_rotri_tl(cpu_T
[0], cpu_T
[0], b
& 63);
4256 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4257 tcg_gen_rotri_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, b
& 31);
4258 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
4260 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
4272 /* generic MMX or SSE operation */
4274 case 0x70: /* pshufx insn */
4275 case 0xc6: /* pshufx insn */
4276 case 0xc2: /* compare insns */
4283 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4287 gen_lea_modrm(env
, s
, modrm
);
4288 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4294 /* Most sse scalar operations. */
4297 } else if (b1
== 3) {
4302 case 0x2e: /* ucomis[sd] */
4303 case 0x2f: /* comis[sd] */
4315 gen_op_ld_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
4316 tcg_gen_st32_tl(cpu_T
[0], cpu_env
,
4317 offsetof(CPUX86State
,xmm_t0
.XMM_L(0)));
4321 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.XMM_D(0)));
4324 /* 128 bit access */
4325 gen_ldo_env_A0(s
, op2_offset
);
4329 rm
= (modrm
& 7) | REX_B(s
);
4330 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
4333 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4335 gen_lea_modrm(env
, s
, modrm
);
4336 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4337 gen_ldq_env_A0(s
, op2_offset
);
4340 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4344 case 0x0f: /* 3DNow! data insns */
4345 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
))
4347 val
= cpu_ldub_code(env
, s
->pc
++);
4348 sse_fn_epp
= sse_op_table5
[val
];
4352 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4353 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4354 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4356 case 0x70: /* pshufx insn */
4357 case 0xc6: /* pshufx insn */
4358 val
= cpu_ldub_code(env
, s
->pc
++);
4359 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4360 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4361 /* XXX: introduce a new table? */
4362 sse_fn_ppi
= (SSEFunc_0_ppi
)sse_fn_epp
;
4363 sse_fn_ppi(cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4367 val
= cpu_ldub_code(env
, s
->pc
++);
4370 sse_fn_epp
= sse_op_table4
[val
][b1
];
4372 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4373 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4374 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4377 /* maskmov : we must prepare A0 */
4380 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EDI
]);
4381 gen_extu(s
->aflag
, cpu_A0
);
4382 gen_add_A0_ds_seg(s
);
4384 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4385 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4386 /* XXX: introduce a new table? */
4387 sse_fn_eppt
= (SSEFunc_0_eppt
)sse_fn_epp
;
4388 sse_fn_eppt(cpu_env
, cpu_ptr0
, cpu_ptr1
, cpu_A0
);
4391 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4392 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4393 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4396 if (b
== 0x2e || b
== 0x2f) {
4397 set_cc_op(s
, CC_OP_EFLAGS
);
4402 /* convert one instruction. s->is_jmp is set if the translation must
4403 be stopped. Return the next pc value */
4404 static target_ulong
disas_insn(CPUX86State
*env
, DisasContext
*s
,
4405 target_ulong pc_start
)
4409 TCGMemOp ot
, aflag
, dflag
;
4410 int modrm
, reg
, rm
, mod
, op
, opreg
, val
;
4411 target_ulong next_eip
, tval
;
4414 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
4415 tcg_gen_debug_insn_start(pc_start
);
4422 #ifdef TARGET_X86_64
4427 s
->rip_offset
= 0; /* for relative ip address */
4431 b
= cpu_ldub_code(env
, s
->pc
);
4433 /* Collect prefixes. */
4436 prefixes
|= PREFIX_REPZ
;
4439 prefixes
|= PREFIX_REPNZ
;
4442 prefixes
|= PREFIX_LOCK
;
4463 prefixes
|= PREFIX_DATA
;
4466 prefixes
|= PREFIX_ADR
;
4468 #ifdef TARGET_X86_64
4472 rex_w
= (b
>> 3) & 1;
4473 rex_r
= (b
& 0x4) << 1;
4474 s
->rex_x
= (b
& 0x2) << 2;
4475 REX_B(s
) = (b
& 0x1) << 3;
4476 x86_64_hregs
= 1; /* select uniform byte register addressing */
4481 case 0xc5: /* 2-byte VEX */
4482 case 0xc4: /* 3-byte VEX */
4483 /* VEX prefixes cannot be used except in 32-bit mode.
4484 Otherwise the instruction is LES or LDS. */
4485 if (s
->code32
&& !s
->vm86
) {
4486 static const int pp_prefix
[4] = {
4487 0, PREFIX_DATA
, PREFIX_REPZ
, PREFIX_REPNZ
4489 int vex3
, vex2
= cpu_ldub_code(env
, s
->pc
);
4491 if (!CODE64(s
) && (vex2
& 0xc0) != 0xc0) {
4492 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4493 otherwise the instruction is LES or LDS. */
4498 /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
4499 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
4500 | PREFIX_LOCK
| PREFIX_DATA
)) {
4503 #ifdef TARGET_X86_64
4508 rex_r
= (~vex2
>> 4) & 8;
4511 b
= cpu_ldub_code(env
, s
->pc
++);
4513 #ifdef TARGET_X86_64
4514 s
->rex_x
= (~vex2
>> 3) & 8;
4515 s
->rex_b
= (~vex2
>> 2) & 8;
4517 vex3
= cpu_ldub_code(env
, s
->pc
++);
4518 rex_w
= (vex3
>> 7) & 1;
4519 switch (vex2
& 0x1f) {
4520 case 0x01: /* Implied 0f leading opcode bytes. */
4521 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4523 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4526 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4529 default: /* Reserved for future use. */
4533 s
->vex_v
= (~vex3
>> 3) & 0xf;
4534 s
->vex_l
= (vex3
>> 2) & 1;
4535 prefixes
|= pp_prefix
[vex3
& 3] | PREFIX_VEX
;
4540 /* Post-process prefixes. */
4542 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit
4543 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4544 over 0x66 if both are present. */
4545 dflag
= (rex_w
> 0 ? MO_64
: prefixes
& PREFIX_DATA
? MO_16
: MO_32
);
4546 /* In 64-bit mode, 0x67 selects 32-bit addressing. */
4547 aflag
= (prefixes
& PREFIX_ADR
? MO_32
: MO_64
);
4549 /* In 16/32-bit mode, 0x66 selects the opposite data size. */
4550 if (s
->code32
^ ((prefixes
& PREFIX_DATA
) != 0)) {
4555 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */
4556 if (s
->code32
^ ((prefixes
& PREFIX_ADR
) != 0)) {
4563 s
->prefix
= prefixes
;
4567 /* lock generation */
4568 if (prefixes
& PREFIX_LOCK
)
4571 /* now check op code */
4575 /**************************/
4576 /* extended op code */
4577 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4580 /**************************/
4595 ot
= mo_b_d(b
, dflag
);
4598 case 0: /* OP Ev, Gv */
4599 modrm
= cpu_ldub_code(env
, s
->pc
++);
4600 reg
= ((modrm
>> 3) & 7) | rex_r
;
4601 mod
= (modrm
>> 6) & 3;
4602 rm
= (modrm
& 7) | REX_B(s
);
4604 gen_lea_modrm(env
, s
, modrm
);
4606 } else if (op
== OP_XORL
&& rm
== reg
) {
4608 /* xor reg, reg optimisation */
4609 set_cc_op(s
, CC_OP_CLR
);
4610 tcg_gen_movi_tl(cpu_T
[0], 0);
4611 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
4616 gen_op_mov_v_reg(ot
, cpu_T
[1], reg
);
4617 gen_op(s
, op
, ot
, opreg
);
4619 case 1: /* OP Gv, Ev */
4620 modrm
= cpu_ldub_code(env
, s
->pc
++);
4621 mod
= (modrm
>> 6) & 3;
4622 reg
= ((modrm
>> 3) & 7) | rex_r
;
4623 rm
= (modrm
& 7) | REX_B(s
);
4625 gen_lea_modrm(env
, s
, modrm
);
4626 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
4627 } else if (op
== OP_XORL
&& rm
== reg
) {
4630 gen_op_mov_v_reg(ot
, cpu_T
[1], rm
);
4632 gen_op(s
, op
, ot
, reg
);
4634 case 2: /* OP A, Iv */
4635 val
= insn_get(env
, s
, ot
);
4636 tcg_gen_movi_tl(cpu_T
[1], val
);
4637 gen_op(s
, op
, ot
, OR_EAX
);
4646 case 0x80: /* GRP1 */
4652 ot
= mo_b_d(b
, dflag
);
4654 modrm
= cpu_ldub_code(env
, s
->pc
++);
4655 mod
= (modrm
>> 6) & 3;
4656 rm
= (modrm
& 7) | REX_B(s
);
4657 op
= (modrm
>> 3) & 7;
4663 s
->rip_offset
= insn_const_size(ot
);
4664 gen_lea_modrm(env
, s
, modrm
);
4675 val
= insn_get(env
, s
, ot
);
4678 val
= (int8_t)insn_get(env
, s
, MO_8
);
4681 tcg_gen_movi_tl(cpu_T
[1], val
);
4682 gen_op(s
, op
, ot
, opreg
);
4686 /**************************/
4687 /* inc, dec, and other misc arith */
4688 case 0x40 ... 0x47: /* inc Gv */
4690 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), 1);
4692 case 0x48 ... 0x4f: /* dec Gv */
4694 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), -1);
4696 case 0xf6: /* GRP3 */
4698 ot
= mo_b_d(b
, dflag
);
4700 modrm
= cpu_ldub_code(env
, s
->pc
++);
4701 mod
= (modrm
>> 6) & 3;
4702 rm
= (modrm
& 7) | REX_B(s
);
4703 op
= (modrm
>> 3) & 7;
4706 s
->rip_offset
= insn_const_size(ot
);
4707 gen_lea_modrm(env
, s
, modrm
);
4708 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
4710 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
4715 val
= insn_get(env
, s
, ot
);
4716 tcg_gen_movi_tl(cpu_T
[1], val
);
4717 gen_op_testl_T0_T1_cc();
4718 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4721 tcg_gen_not_tl(cpu_T
[0], cpu_T
[0]);
4723 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
4725 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4729 tcg_gen_neg_tl(cpu_T
[0], cpu_T
[0]);
4731 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
4733 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4735 gen_op_update_neg_cc();
4736 set_cc_op(s
, CC_OP_SUBB
+ ot
);
4741 gen_op_mov_v_reg(MO_8
, cpu_T
[1], R_EAX
);
4742 tcg_gen_ext8u_tl(cpu_T
[0], cpu_T
[0]);
4743 tcg_gen_ext8u_tl(cpu_T
[1], cpu_T
[1]);
4744 /* XXX: use 32 bit mul which could be faster */
4745 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4746 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
4747 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4748 tcg_gen_andi_tl(cpu_cc_src
, cpu_T
[0], 0xff00);
4749 set_cc_op(s
, CC_OP_MULB
);
4752 gen_op_mov_v_reg(MO_16
, cpu_T
[1], R_EAX
);
4753 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
4754 tcg_gen_ext16u_tl(cpu_T
[1], cpu_T
[1]);
4755 /* XXX: use 32 bit mul which could be faster */
4756 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4757 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
4758 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4759 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], 16);
4760 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T
[0]);
4761 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
4762 set_cc_op(s
, CC_OP_MULW
);
4766 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4767 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
4768 tcg_gen_mulu2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4769 cpu_tmp2_i32
, cpu_tmp3_i32
);
4770 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
4771 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
4772 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4773 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4774 set_cc_op(s
, CC_OP_MULL
);
4776 #ifdef TARGET_X86_64
4778 tcg_gen_mulu2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4779 cpu_T
[0], cpu_regs
[R_EAX
]);
4780 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4781 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4782 set_cc_op(s
, CC_OP_MULQ
);
4790 gen_op_mov_v_reg(MO_8
, cpu_T
[1], R_EAX
);
4791 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
4792 tcg_gen_ext8s_tl(cpu_T
[1], cpu_T
[1]);
4793 /* XXX: use 32 bit mul which could be faster */
4794 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4795 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
4796 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4797 tcg_gen_ext8s_tl(cpu_tmp0
, cpu_T
[0]);
4798 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
4799 set_cc_op(s
, CC_OP_MULB
);
4802 gen_op_mov_v_reg(MO_16
, cpu_T
[1], R_EAX
);
4803 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
4804 tcg_gen_ext16s_tl(cpu_T
[1], cpu_T
[1]);
4805 /* XXX: use 32 bit mul which could be faster */
4806 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4807 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
4808 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4809 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T
[0]);
4810 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
4811 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], 16);
4812 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T
[0]);
4813 set_cc_op(s
, CC_OP_MULW
);
4817 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4818 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
4819 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4820 cpu_tmp2_i32
, cpu_tmp3_i32
);
4821 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
4822 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
4823 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
4824 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4825 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
4826 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
4827 set_cc_op(s
, CC_OP_MULL
);
4829 #ifdef TARGET_X86_64
4831 tcg_gen_muls2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4832 cpu_T
[0], cpu_regs
[R_EAX
]);
4833 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4834 tcg_gen_sari_tl(cpu_cc_src
, cpu_regs
[R_EAX
], 63);
4835 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_regs
[R_EDX
]);
4836 set_cc_op(s
, CC_OP_MULQ
);
4844 gen_jmp_im(pc_start
- s
->cs_base
);
4845 gen_helper_divb_AL(cpu_env
, cpu_T
[0]);
4848 gen_jmp_im(pc_start
- s
->cs_base
);
4849 gen_helper_divw_AX(cpu_env
, cpu_T
[0]);
4853 gen_jmp_im(pc_start
- s
->cs_base
);
4854 gen_helper_divl_EAX(cpu_env
, cpu_T
[0]);
4856 #ifdef TARGET_X86_64
4858 gen_jmp_im(pc_start
- s
->cs_base
);
4859 gen_helper_divq_EAX(cpu_env
, cpu_T
[0]);
4867 gen_jmp_im(pc_start
- s
->cs_base
);
4868 gen_helper_idivb_AL(cpu_env
, cpu_T
[0]);
4871 gen_jmp_im(pc_start
- s
->cs_base
);
4872 gen_helper_idivw_AX(cpu_env
, cpu_T
[0]);
4876 gen_jmp_im(pc_start
- s
->cs_base
);
4877 gen_helper_idivl_EAX(cpu_env
, cpu_T
[0]);
4879 #ifdef TARGET_X86_64
4881 gen_jmp_im(pc_start
- s
->cs_base
);
4882 gen_helper_idivq_EAX(cpu_env
, cpu_T
[0]);
4892 case 0xfe: /* GRP4 */
4893 case 0xff: /* GRP5 */
4894 ot
= mo_b_d(b
, dflag
);
4896 modrm
= cpu_ldub_code(env
, s
->pc
++);
4897 mod
= (modrm
>> 6) & 3;
4898 rm
= (modrm
& 7) | REX_B(s
);
4899 op
= (modrm
>> 3) & 7;
4900 if (op
>= 2 && b
== 0xfe) {
4904 if (op
== 2 || op
== 4) {
4905 /* operand size for jumps is 64 bit */
4907 } else if (op
== 3 || op
== 5) {
4908 ot
= dflag
!= MO_16
? MO_32
+ (rex_w
== 1) : MO_16
;
4909 } else if (op
== 6) {
4910 /* default push size is 64 bit */
4911 ot
= mo_pushpop(s
, dflag
);
4915 gen_lea_modrm(env
, s
, modrm
);
4916 if (op
>= 2 && op
!= 3 && op
!= 5)
4917 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
4919 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
4923 case 0: /* inc Ev */
4928 gen_inc(s
, ot
, opreg
, 1);
4930 case 1: /* dec Ev */
4935 gen_inc(s
, ot
, opreg
, -1);
4937 case 2: /* call Ev */
4938 /* XXX: optimize if memory (no 'and' is necessary) */
4939 if (dflag
== MO_16
) {
4940 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
4942 next_eip
= s
->pc
- s
->cs_base
;
4943 tcg_gen_movi_tl(cpu_T
[1], next_eip
);
4944 gen_push_v(s
, cpu_T
[1]);
4945 gen_op_jmp_v(cpu_T
[0]);
4948 case 3: /* lcall Ev */
4949 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
4950 gen_add_A0_im(s
, 1 << ot
);
4951 gen_op_ld_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
4953 if (s
->pe
&& !s
->vm86
) {
4954 gen_update_cc_op(s
);
4955 gen_jmp_im(pc_start
- s
->cs_base
);
4956 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4957 gen_helper_lcall_protected(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
4958 tcg_const_i32(dflag
- 1),
4959 tcg_const_i32(s
->pc
- pc_start
));
4961 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4962 gen_helper_lcall_real(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
4963 tcg_const_i32(dflag
- 1),
4964 tcg_const_i32(s
->pc
- s
->cs_base
));
4968 case 4: /* jmp Ev */
4969 if (dflag
== MO_16
) {
4970 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
4972 gen_op_jmp_v(cpu_T
[0]);
4975 case 5: /* ljmp Ev */
4976 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
4977 gen_add_A0_im(s
, 1 << ot
);
4978 gen_op_ld_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
4980 if (s
->pe
&& !s
->vm86
) {
4981 gen_update_cc_op(s
);
4982 gen_jmp_im(pc_start
- s
->cs_base
);
4983 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4984 gen_helper_ljmp_protected(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
4985 tcg_const_i32(s
->pc
- pc_start
));
4987 gen_op_movl_seg_T0_vm(R_CS
);
4988 gen_op_jmp_v(cpu_T
[1]);
4992 case 6: /* push Ev */
4993 gen_push_v(s
, cpu_T
[0]);
5000 case 0x84: /* test Ev, Gv */
5002 ot
= mo_b_d(b
, dflag
);
5004 modrm
= cpu_ldub_code(env
, s
->pc
++);
5005 reg
= ((modrm
>> 3) & 7) | rex_r
;
5007 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5008 gen_op_mov_v_reg(ot
, cpu_T
[1], reg
);
5009 gen_op_testl_T0_T1_cc();
5010 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5013 case 0xa8: /* test eAX, Iv */
5015 ot
= mo_b_d(b
, dflag
);
5016 val
= insn_get(env
, s
, ot
);
5018 gen_op_mov_v_reg(ot
, cpu_T
[0], OR_EAX
);
5019 tcg_gen_movi_tl(cpu_T
[1], val
);
5020 gen_op_testl_T0_T1_cc();
5021 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5024 case 0x98: /* CWDE/CBW */
5026 #ifdef TARGET_X86_64
5028 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EAX
);
5029 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
5030 gen_op_mov_reg_v(MO_64
, R_EAX
, cpu_T
[0]);
5034 gen_op_mov_v_reg(MO_16
, cpu_T
[0], R_EAX
);
5035 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5036 gen_op_mov_reg_v(MO_32
, R_EAX
, cpu_T
[0]);
5039 gen_op_mov_v_reg(MO_8
, cpu_T
[0], R_EAX
);
5040 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
5041 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
5047 case 0x99: /* CDQ/CWD */
5049 #ifdef TARGET_X86_64
5051 gen_op_mov_v_reg(MO_64
, cpu_T
[0], R_EAX
);
5052 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 63);
5053 gen_op_mov_reg_v(MO_64
, R_EDX
, cpu_T
[0]);
5057 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EAX
);
5058 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
5059 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 31);
5060 gen_op_mov_reg_v(MO_32
, R_EDX
, cpu_T
[0]);
5063 gen_op_mov_v_reg(MO_16
, cpu_T
[0], R_EAX
);
5064 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5065 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 15);
5066 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T
[0]);
5072 case 0x1af: /* imul Gv, Ev */
5073 case 0x69: /* imul Gv, Ev, I */
5076 modrm
= cpu_ldub_code(env
, s
->pc
++);
5077 reg
= ((modrm
>> 3) & 7) | rex_r
;
5079 s
->rip_offset
= insn_const_size(ot
);
5082 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5084 val
= insn_get(env
, s
, ot
);
5085 tcg_gen_movi_tl(cpu_T
[1], val
);
5086 } else if (b
== 0x6b) {
5087 val
= (int8_t)insn_get(env
, s
, MO_8
);
5088 tcg_gen_movi_tl(cpu_T
[1], val
);
5090 gen_op_mov_v_reg(ot
, cpu_T
[1], reg
);
5093 #ifdef TARGET_X86_64
5095 tcg_gen_muls2_i64(cpu_regs
[reg
], cpu_T
[1], cpu_T
[0], cpu_T
[1]);
5096 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5097 tcg_gen_sari_tl(cpu_cc_src
, cpu_cc_dst
, 63);
5098 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_T
[1]);
5102 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5103 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
5104 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
5105 cpu_tmp2_i32
, cpu_tmp3_i32
);
5106 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
5107 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
5108 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5109 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
5110 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
5113 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5114 tcg_gen_ext16s_tl(cpu_T
[1], cpu_T
[1]);
5115 /* XXX: use 32 bit mul which could be faster */
5116 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5117 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5118 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T
[0]);
5119 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
5120 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
5123 set_cc_op(s
, CC_OP_MULB
+ ot
);
5126 case 0x1c1: /* xadd Ev, Gv */
5127 ot
= mo_b_d(b
, dflag
);
5128 modrm
= cpu_ldub_code(env
, s
->pc
++);
5129 reg
= ((modrm
>> 3) & 7) | rex_r
;
5130 mod
= (modrm
>> 6) & 3;
5132 rm
= (modrm
& 7) | REX_B(s
);
5133 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
5134 gen_op_mov_v_reg(ot
, cpu_T
[1], rm
);
5135 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5136 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5137 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
5139 gen_lea_modrm(env
, s
, modrm
);
5140 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
5141 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
5142 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5143 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
5144 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5146 gen_op_update2_cc();
5147 set_cc_op(s
, CC_OP_ADDB
+ ot
);
5150 case 0x1b1: /* cmpxchg Ev, Gv */
5152 TCGLabel
*label1
, *label2
;
5153 TCGv t0
, t1
, t2
, a0
;
5155 ot
= mo_b_d(b
, dflag
);
5156 modrm
= cpu_ldub_code(env
, s
->pc
++);
5157 reg
= ((modrm
>> 3) & 7) | rex_r
;
5158 mod
= (modrm
>> 6) & 3;
5159 t0
= tcg_temp_local_new();
5160 t1
= tcg_temp_local_new();
5161 t2
= tcg_temp_local_new();
5162 a0
= tcg_temp_local_new();
5163 gen_op_mov_v_reg(ot
, t1
, reg
);
5165 rm
= (modrm
& 7) | REX_B(s
);
5166 gen_op_mov_v_reg(ot
, t0
, rm
);
5168 gen_lea_modrm(env
, s
, modrm
);
5169 tcg_gen_mov_tl(a0
, cpu_A0
);
5170 gen_op_ld_v(s
, ot
, t0
, a0
);
5171 rm
= 0; /* avoid warning */
5173 label1
= gen_new_label();
5174 tcg_gen_mov_tl(t2
, cpu_regs
[R_EAX
]);
5177 tcg_gen_brcond_tl(TCG_COND_EQ
, t2
, t0
, label1
);
5178 label2
= gen_new_label();
5180 gen_op_mov_reg_v(ot
, R_EAX
, t0
);
5182 gen_set_label(label1
);
5183 gen_op_mov_reg_v(ot
, rm
, t1
);
5185 /* perform no-op store cycle like physical cpu; must be
5186 before changing accumulator to ensure idempotency if
5187 the store faults and the instruction is restarted */
5188 gen_op_st_v(s
, ot
, t0
, a0
);
5189 gen_op_mov_reg_v(ot
, R_EAX
, t0
);
5191 gen_set_label(label1
);
5192 gen_op_st_v(s
, ot
, t1
, a0
);
5194 gen_set_label(label2
);
5195 tcg_gen_mov_tl(cpu_cc_src
, t0
);
5196 tcg_gen_mov_tl(cpu_cc_srcT
, t2
);
5197 tcg_gen_sub_tl(cpu_cc_dst
, t2
, t0
);
5198 set_cc_op(s
, CC_OP_SUBB
+ ot
);
5205 case 0x1c7: /* cmpxchg8b */
5206 modrm
= cpu_ldub_code(env
, s
->pc
++);
5207 mod
= (modrm
>> 6) & 3;
5208 if ((mod
== 3) || ((modrm
& 0x38) != 0x8))
5210 #ifdef TARGET_X86_64
5211 if (dflag
== MO_64
) {
5212 if (!(s
->cpuid_ext_features
& CPUID_EXT_CX16
))
5214 gen_jmp_im(pc_start
- s
->cs_base
);
5215 gen_update_cc_op(s
);
5216 gen_lea_modrm(env
, s
, modrm
);
5217 gen_helper_cmpxchg16b(cpu_env
, cpu_A0
);
5221 if (!(s
->cpuid_features
& CPUID_CX8
))
5223 gen_jmp_im(pc_start
- s
->cs_base
);
5224 gen_update_cc_op(s
);
5225 gen_lea_modrm(env
, s
, modrm
);
5226 gen_helper_cmpxchg8b(cpu_env
, cpu_A0
);
5228 set_cc_op(s
, CC_OP_EFLAGS
);
5231 /**************************/
5233 case 0x50 ... 0x57: /* push */
5234 gen_op_mov_v_reg(MO_32
, cpu_T
[0], (b
& 7) | REX_B(s
));
5235 gen_push_v(s
, cpu_T
[0]);
5237 case 0x58 ... 0x5f: /* pop */
5239 /* NOTE: order is important for pop %sp */
5240 gen_pop_update(s
, ot
);
5241 gen_op_mov_reg_v(ot
, (b
& 7) | REX_B(s
), cpu_T
[0]);
5243 case 0x60: /* pusha */
5248 case 0x61: /* popa */
5253 case 0x68: /* push Iv */
5255 ot
= mo_pushpop(s
, dflag
);
5257 val
= insn_get(env
, s
, ot
);
5259 val
= (int8_t)insn_get(env
, s
, MO_8
);
5260 tcg_gen_movi_tl(cpu_T
[0], val
);
5261 gen_push_v(s
, cpu_T
[0]);
5263 case 0x8f: /* pop Ev */
5264 modrm
= cpu_ldub_code(env
, s
->pc
++);
5265 mod
= (modrm
>> 6) & 3;
5268 /* NOTE: order is important for pop %sp */
5269 gen_pop_update(s
, ot
);
5270 rm
= (modrm
& 7) | REX_B(s
);
5271 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
5273 /* NOTE: order is important too for MMU exceptions */
5274 s
->popl_esp_hack
= 1 << ot
;
5275 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5276 s
->popl_esp_hack
= 0;
5277 gen_pop_update(s
, ot
);
5280 case 0xc8: /* enter */
5283 val
= cpu_lduw_code(env
, s
->pc
);
5285 level
= cpu_ldub_code(env
, s
->pc
++);
5286 gen_enter(s
, val
, level
);
5289 case 0xc9: /* leave */
5290 /* XXX: exception not precise (ESP is updated before potential exception) */
5292 gen_op_mov_v_reg(MO_64
, cpu_T
[0], R_EBP
);
5293 gen_op_mov_reg_v(MO_64
, R_ESP
, cpu_T
[0]);
5294 } else if (s
->ss32
) {
5295 gen_op_mov_v_reg(MO_32
, cpu_T
[0], R_EBP
);
5296 gen_op_mov_reg_v(MO_32
, R_ESP
, cpu_T
[0]);
5298 gen_op_mov_v_reg(MO_16
, cpu_T
[0], R_EBP
);
5299 gen_op_mov_reg_v(MO_16
, R_ESP
, cpu_T
[0]);
5302 gen_op_mov_reg_v(ot
, R_EBP
, cpu_T
[0]);
5303 gen_pop_update(s
, ot
);
5305 case 0x06: /* push es */
5306 case 0x0e: /* push cs */
5307 case 0x16: /* push ss */
5308 case 0x1e: /* push ds */
5311 gen_op_movl_T0_seg(b
>> 3);
5312 gen_push_v(s
, cpu_T
[0]);
5314 case 0x1a0: /* push fs */
5315 case 0x1a8: /* push gs */
5316 gen_op_movl_T0_seg((b
>> 3) & 7);
5317 gen_push_v(s
, cpu_T
[0]);
5319 case 0x07: /* pop es */
5320 case 0x17: /* pop ss */
5321 case 0x1f: /* pop ds */
5326 gen_movl_seg_T0(s
, reg
, pc_start
- s
->cs_base
);
5327 gen_pop_update(s
, ot
);
5329 /* if reg == SS, inhibit interrupts/trace. */
5330 /* If several instructions disable interrupts, only the
5332 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
5333 gen_helper_set_inhibit_irq(cpu_env
);
5337 gen_jmp_im(s
->pc
- s
->cs_base
);
5341 case 0x1a1: /* pop fs */
5342 case 0x1a9: /* pop gs */
5344 gen_movl_seg_T0(s
, (b
>> 3) & 7, pc_start
- s
->cs_base
);
5345 gen_pop_update(s
, ot
);
5347 gen_jmp_im(s
->pc
- s
->cs_base
);
5352 /**************************/
5355 case 0x89: /* mov Gv, Ev */
5356 ot
= mo_b_d(b
, dflag
);
5357 modrm
= cpu_ldub_code(env
, s
->pc
++);
5358 reg
= ((modrm
>> 3) & 7) | rex_r
;
5360 /* generate a generic store */
5361 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
5364 case 0xc7: /* mov Ev, Iv */
5365 ot
= mo_b_d(b
, dflag
);
5366 modrm
= cpu_ldub_code(env
, s
->pc
++);
5367 mod
= (modrm
>> 6) & 3;
5369 s
->rip_offset
= insn_const_size(ot
);
5370 gen_lea_modrm(env
, s
, modrm
);
5372 val
= insn_get(env
, s
, ot
);
5373 tcg_gen_movi_tl(cpu_T
[0], val
);
5375 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
5377 gen_op_mov_reg_v(ot
, (modrm
& 7) | REX_B(s
), cpu_T
[0]);
5381 case 0x8b: /* mov Ev, Gv */
5382 ot
= mo_b_d(b
, dflag
);
5383 modrm
= cpu_ldub_code(env
, s
->pc
++);
5384 reg
= ((modrm
>> 3) & 7) | rex_r
;
5386 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5387 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
5389 case 0x8e: /* mov seg, Gv */
5390 modrm
= cpu_ldub_code(env
, s
->pc
++);
5391 reg
= (modrm
>> 3) & 7;
5392 if (reg
>= 6 || reg
== R_CS
)
5394 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
5395 gen_movl_seg_T0(s
, reg
, pc_start
- s
->cs_base
);
5397 /* if reg == SS, inhibit interrupts/trace */
5398 /* If several instructions disable interrupts, only the
5400 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
5401 gen_helper_set_inhibit_irq(cpu_env
);
5405 gen_jmp_im(s
->pc
- s
->cs_base
);
5409 case 0x8c: /* mov Gv, seg */
5410 modrm
= cpu_ldub_code(env
, s
->pc
++);
5411 reg
= (modrm
>> 3) & 7;
5412 mod
= (modrm
>> 6) & 3;
5415 gen_op_movl_T0_seg(reg
);
5416 ot
= mod
== 3 ? dflag
: MO_16
;
5417 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5420 case 0x1b6: /* movzbS Gv, Eb */
5421 case 0x1b7: /* movzwS Gv, Eb */
5422 case 0x1be: /* movsbS Gv, Eb */
5423 case 0x1bf: /* movswS Gv, Eb */
5428 /* d_ot is the size of destination */
5430 /* ot is the size of source */
5431 ot
= (b
& 1) + MO_8
;
5432 /* s_ot is the sign+size of source */
5433 s_ot
= b
& 8 ? MO_SIGN
| ot
: ot
;
5435 modrm
= cpu_ldub_code(env
, s
->pc
++);
5436 reg
= ((modrm
>> 3) & 7) | rex_r
;
5437 mod
= (modrm
>> 6) & 3;
5438 rm
= (modrm
& 7) | REX_B(s
);
5441 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
5444 tcg_gen_ext8u_tl(cpu_T
[0], cpu_T
[0]);
5447 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
5450 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
5454 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5457 gen_op_mov_reg_v(d_ot
, reg
, cpu_T
[0]);
5459 gen_lea_modrm(env
, s
, modrm
);
5460 gen_op_ld_v(s
, s_ot
, cpu_T
[0], cpu_A0
);
5461 gen_op_mov_reg_v(d_ot
, reg
, cpu_T
[0]);
5466 case 0x8d: /* lea */
5468 modrm
= cpu_ldub_code(env
, s
->pc
++);
5469 mod
= (modrm
>> 6) & 3;
5472 reg
= ((modrm
>> 3) & 7) | rex_r
;
5473 /* we must ensure that no segment is added */
5477 gen_lea_modrm(env
, s
, modrm
);
5479 gen_op_mov_reg_v(ot
, reg
, cpu_A0
);
5482 case 0xa0: /* mov EAX, Ov */
5484 case 0xa2: /* mov Ov, EAX */
5487 target_ulong offset_addr
;
5489 ot
= mo_b_d(b
, dflag
);
5491 #ifdef TARGET_X86_64
5493 offset_addr
= cpu_ldq_code(env
, s
->pc
);
5498 offset_addr
= insn_get(env
, s
, s
->aflag
);
5501 tcg_gen_movi_tl(cpu_A0
, offset_addr
);
5502 gen_add_A0_ds_seg(s
);
5504 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
5505 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T
[0]);
5507 gen_op_mov_v_reg(ot
, cpu_T
[0], R_EAX
);
5508 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
5512 case 0xd7: /* xlat */
5513 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EBX
]);
5514 tcg_gen_ext8u_tl(cpu_T
[0], cpu_regs
[R_EAX
]);
5515 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_T
[0]);
5516 gen_extu(s
->aflag
, cpu_A0
);
5517 gen_add_A0_ds_seg(s
);
5518 gen_op_ld_v(s
, MO_8
, cpu_T
[0], cpu_A0
);
5519 gen_op_mov_reg_v(MO_8
, R_EAX
, cpu_T
[0]);
5521 case 0xb0 ... 0xb7: /* mov R, Ib */
5522 val
= insn_get(env
, s
, MO_8
);
5523 tcg_gen_movi_tl(cpu_T
[0], val
);
5524 gen_op_mov_reg_v(MO_8
, (b
& 7) | REX_B(s
), cpu_T
[0]);
5526 case 0xb8 ... 0xbf: /* mov R, Iv */
5527 #ifdef TARGET_X86_64
5528 if (dflag
== MO_64
) {
5531 tmp
= cpu_ldq_code(env
, s
->pc
);
5533 reg
= (b
& 7) | REX_B(s
);
5534 tcg_gen_movi_tl(cpu_T
[0], tmp
);
5535 gen_op_mov_reg_v(MO_64
, reg
, cpu_T
[0]);
5540 val
= insn_get(env
, s
, ot
);
5541 reg
= (b
& 7) | REX_B(s
);
5542 tcg_gen_movi_tl(cpu_T
[0], val
);
5543 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
5547 case 0x91 ... 0x97: /* xchg R, EAX */
5550 reg
= (b
& 7) | REX_B(s
);
5554 case 0x87: /* xchg Ev, Gv */
5555 ot
= mo_b_d(b
, dflag
);
5556 modrm
= cpu_ldub_code(env
, s
->pc
++);
5557 reg
= ((modrm
>> 3) & 7) | rex_r
;
5558 mod
= (modrm
>> 6) & 3;
5560 rm
= (modrm
& 7) | REX_B(s
);
5562 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
5563 gen_op_mov_v_reg(ot
, cpu_T
[1], rm
);
5564 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
5565 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5567 gen_lea_modrm(env
, s
, modrm
);
5568 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
5569 /* for xchg, lock is implicit */
5570 if (!(prefixes
& PREFIX_LOCK
))
5572 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
5573 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
5574 if (!(prefixes
& PREFIX_LOCK
))
5575 gen_helper_unlock();
5576 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5579 case 0xc4: /* les Gv */
5580 /* In CODE64 this is VEX3; see above. */
5583 case 0xc5: /* lds Gv */
5584 /* In CODE64 this is VEX2; see above. */
5587 case 0x1b2: /* lss Gv */
5590 case 0x1b4: /* lfs Gv */
5593 case 0x1b5: /* lgs Gv */
5596 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
5597 modrm
= cpu_ldub_code(env
, s
->pc
++);
5598 reg
= ((modrm
>> 3) & 7) | rex_r
;
5599 mod
= (modrm
>> 6) & 3;
5602 gen_lea_modrm(env
, s
, modrm
);
5603 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
5604 gen_add_A0_im(s
, 1 << ot
);
5605 /* load the segment first to handle exceptions properly */
5606 gen_op_ld_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
5607 gen_movl_seg_T0(s
, op
, pc_start
- s
->cs_base
);
5608 /* then put the data */
5609 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
5611 gen_jmp_im(s
->pc
- s
->cs_base
);
5616 /************************/
5624 ot
= mo_b_d(b
, dflag
);
5625 modrm
= cpu_ldub_code(env
, s
->pc
++);
5626 mod
= (modrm
>> 6) & 3;
5627 op
= (modrm
>> 3) & 7;
5633 gen_lea_modrm(env
, s
, modrm
);
5636 opreg
= (modrm
& 7) | REX_B(s
);
5641 gen_shift(s
, op
, ot
, opreg
, OR_ECX
);
5644 shift
= cpu_ldub_code(env
, s
->pc
++);
5646 gen_shifti(s
, op
, ot
, opreg
, shift
);
5661 case 0x1a4: /* shld imm */
5665 case 0x1a5: /* shld cl */
5669 case 0x1ac: /* shrd imm */
5673 case 0x1ad: /* shrd cl */
5678 modrm
= cpu_ldub_code(env
, s
->pc
++);
5679 mod
= (modrm
>> 6) & 3;
5680 rm
= (modrm
& 7) | REX_B(s
);
5681 reg
= ((modrm
>> 3) & 7) | rex_r
;
5683 gen_lea_modrm(env
, s
, modrm
);
5688 gen_op_mov_v_reg(ot
, cpu_T
[1], reg
);
5691 TCGv imm
= tcg_const_tl(cpu_ldub_code(env
, s
->pc
++));
5692 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, imm
);
5695 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, cpu_regs
[R_ECX
]);
5699 /************************/
5702 if (s
->flags
& (HF_EM_MASK
| HF_TS_MASK
)) {
5703 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5704 /* XXX: what to do if illegal op ? */
5705 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
5708 modrm
= cpu_ldub_code(env
, s
->pc
++);
5709 mod
= (modrm
>> 6) & 3;
5711 op
= ((b
& 7) << 3) | ((modrm
>> 3) & 7);
5714 gen_lea_modrm(env
, s
, modrm
);
5716 case 0x00 ... 0x07: /* fxxxs */
5717 case 0x10 ... 0x17: /* fixxxl */
5718 case 0x20 ... 0x27: /* fxxxl */
5719 case 0x30 ... 0x37: /* fixxx */
5726 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5727 s
->mem_index
, MO_LEUL
);
5728 gen_helper_flds_FT0(cpu_env
, cpu_tmp2_i32
);
5731 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5732 s
->mem_index
, MO_LEUL
);
5733 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
5736 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
5737 s
->mem_index
, MO_LEQ
);
5738 gen_helper_fldl_FT0(cpu_env
, cpu_tmp1_i64
);
5742 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5743 s
->mem_index
, MO_LESW
);
5744 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
5748 gen_helper_fp_arith_ST0_FT0(op1
);
5750 /* fcomp needs pop */
5751 gen_helper_fpop(cpu_env
);
5755 case 0x08: /* flds */
5756 case 0x0a: /* fsts */
5757 case 0x0b: /* fstps */
5758 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5759 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5760 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5765 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5766 s
->mem_index
, MO_LEUL
);
5767 gen_helper_flds_ST0(cpu_env
, cpu_tmp2_i32
);
5770 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5771 s
->mem_index
, MO_LEUL
);
5772 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
5775 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
5776 s
->mem_index
, MO_LEQ
);
5777 gen_helper_fldl_ST0(cpu_env
, cpu_tmp1_i64
);
5781 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5782 s
->mem_index
, MO_LESW
);
5783 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
5788 /* XXX: the corresponding CPUID bit must be tested ! */
5791 gen_helper_fisttl_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_fisttll_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_fistt_ST0(cpu_tmp2_i32
, cpu_env
);
5803 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5804 s
->mem_index
, MO_LEUW
);
5807 gen_helper_fpop(cpu_env
);
5812 gen_helper_fsts_ST0(cpu_tmp2_i32
, cpu_env
);
5813 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5814 s
->mem_index
, MO_LEUL
);
5817 gen_helper_fistl_ST0(cpu_tmp2_i32
, cpu_env
);
5818 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5819 s
->mem_index
, MO_LEUL
);
5822 gen_helper_fstl_ST0(cpu_tmp1_i64
, cpu_env
);
5823 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
5824 s
->mem_index
, MO_LEQ
);
5828 gen_helper_fist_ST0(cpu_tmp2_i32
, cpu_env
);
5829 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5830 s
->mem_index
, MO_LEUW
);
5834 gen_helper_fpop(cpu_env
);
5838 case 0x0c: /* fldenv mem */
5839 gen_update_cc_op(s
);
5840 gen_jmp_im(pc_start
- s
->cs_base
);
5841 gen_helper_fldenv(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5843 case 0x0d: /* fldcw mem */
5844 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5845 s
->mem_index
, MO_LEUW
);
5846 gen_helper_fldcw(cpu_env
, cpu_tmp2_i32
);
5848 case 0x0e: /* fnstenv mem */
5849 gen_update_cc_op(s
);
5850 gen_jmp_im(pc_start
- s
->cs_base
);
5851 gen_helper_fstenv(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5853 case 0x0f: /* fnstcw mem */
5854 gen_helper_fnstcw(cpu_tmp2_i32
, cpu_env
);
5855 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5856 s
->mem_index
, MO_LEUW
);
5858 case 0x1d: /* fldt mem */
5859 gen_update_cc_op(s
);
5860 gen_jmp_im(pc_start
- s
->cs_base
);
5861 gen_helper_fldt_ST0(cpu_env
, cpu_A0
);
5863 case 0x1f: /* fstpt mem */
5864 gen_update_cc_op(s
);
5865 gen_jmp_im(pc_start
- s
->cs_base
);
5866 gen_helper_fstt_ST0(cpu_env
, cpu_A0
);
5867 gen_helper_fpop(cpu_env
);
5869 case 0x2c: /* frstor mem */
5870 gen_update_cc_op(s
);
5871 gen_jmp_im(pc_start
- s
->cs_base
);
5872 gen_helper_frstor(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5874 case 0x2e: /* fnsave mem */
5875 gen_update_cc_op(s
);
5876 gen_jmp_im(pc_start
- s
->cs_base
);
5877 gen_helper_fsave(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5879 case 0x2f: /* fnstsw mem */
5880 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
5881 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5882 s
->mem_index
, MO_LEUW
);
5884 case 0x3c: /* fbld */
5885 gen_update_cc_op(s
);
5886 gen_jmp_im(pc_start
- s
->cs_base
);
5887 gen_helper_fbld_ST0(cpu_env
, cpu_A0
);
5889 case 0x3e: /* fbstp */
5890 gen_update_cc_op(s
);
5891 gen_jmp_im(pc_start
- s
->cs_base
);
5892 gen_helper_fbst_ST0(cpu_env
, cpu_A0
);
5893 gen_helper_fpop(cpu_env
);
5895 case 0x3d: /* fildll */
5896 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
5897 gen_helper_fildll_ST0(cpu_env
, cpu_tmp1_i64
);
5899 case 0x3f: /* fistpll */
5900 gen_helper_fistll_ST0(cpu_tmp1_i64
, cpu_env
);
5901 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
5902 gen_helper_fpop(cpu_env
);
5908 /* register float ops */
5912 case 0x08: /* fld sti */
5913 gen_helper_fpush(cpu_env
);
5914 gen_helper_fmov_ST0_STN(cpu_env
,
5915 tcg_const_i32((opreg
+ 1) & 7));
5917 case 0x09: /* fxchg sti */
5918 case 0x29: /* fxchg4 sti, undocumented op */
5919 case 0x39: /* fxchg7 sti, undocumented op */
5920 gen_helper_fxchg_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
5922 case 0x0a: /* grp d9/2 */
5925 /* check exceptions (FreeBSD FPU probe) */
5926 gen_update_cc_op(s
);
5927 gen_jmp_im(pc_start
- s
->cs_base
);
5928 gen_helper_fwait(cpu_env
);
5934 case 0x0c: /* grp d9/4 */
5937 gen_helper_fchs_ST0(cpu_env
);
5940 gen_helper_fabs_ST0(cpu_env
);
5943 gen_helper_fldz_FT0(cpu_env
);
5944 gen_helper_fcom_ST0_FT0(cpu_env
);
5947 gen_helper_fxam_ST0(cpu_env
);
5953 case 0x0d: /* grp d9/5 */
5957 gen_helper_fpush(cpu_env
);
5958 gen_helper_fld1_ST0(cpu_env
);
5961 gen_helper_fpush(cpu_env
);
5962 gen_helper_fldl2t_ST0(cpu_env
);
5965 gen_helper_fpush(cpu_env
);
5966 gen_helper_fldl2e_ST0(cpu_env
);
5969 gen_helper_fpush(cpu_env
);
5970 gen_helper_fldpi_ST0(cpu_env
);
5973 gen_helper_fpush(cpu_env
);
5974 gen_helper_fldlg2_ST0(cpu_env
);
5977 gen_helper_fpush(cpu_env
);
5978 gen_helper_fldln2_ST0(cpu_env
);
5981 gen_helper_fpush(cpu_env
);
5982 gen_helper_fldz_ST0(cpu_env
);
5989 case 0x0e: /* grp d9/6 */
5992 gen_helper_f2xm1(cpu_env
);
5995 gen_helper_fyl2x(cpu_env
);
5998 gen_helper_fptan(cpu_env
);
6000 case 3: /* fpatan */
6001 gen_helper_fpatan(cpu_env
);
6003 case 4: /* fxtract */
6004 gen_helper_fxtract(cpu_env
);
6006 case 5: /* fprem1 */
6007 gen_helper_fprem1(cpu_env
);
6009 case 6: /* fdecstp */
6010 gen_helper_fdecstp(cpu_env
);
6013 case 7: /* fincstp */
6014 gen_helper_fincstp(cpu_env
);
6018 case 0x0f: /* grp d9/7 */
6021 gen_helper_fprem(cpu_env
);
6023 case 1: /* fyl2xp1 */
6024 gen_helper_fyl2xp1(cpu_env
);
6027 gen_helper_fsqrt(cpu_env
);
6029 case 3: /* fsincos */
6030 gen_helper_fsincos(cpu_env
);
6032 case 5: /* fscale */
6033 gen_helper_fscale(cpu_env
);
6035 case 4: /* frndint */
6036 gen_helper_frndint(cpu_env
);
6039 gen_helper_fsin(cpu_env
);
6043 gen_helper_fcos(cpu_env
);
6047 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6048 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6049 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6055 gen_helper_fp_arith_STN_ST0(op1
, opreg
);
6057 gen_helper_fpop(cpu_env
);
6059 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6060 gen_helper_fp_arith_ST0_FT0(op1
);
6064 case 0x02: /* fcom */
6065 case 0x22: /* fcom2, undocumented op */
6066 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6067 gen_helper_fcom_ST0_FT0(cpu_env
);
6069 case 0x03: /* fcomp */
6070 case 0x23: /* fcomp3, undocumented op */
6071 case 0x32: /* fcomp5, undocumented op */
6072 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6073 gen_helper_fcom_ST0_FT0(cpu_env
);
6074 gen_helper_fpop(cpu_env
);
6076 case 0x15: /* da/5 */
6078 case 1: /* fucompp */
6079 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6080 gen_helper_fucom_ST0_FT0(cpu_env
);
6081 gen_helper_fpop(cpu_env
);
6082 gen_helper_fpop(cpu_env
);
6090 case 0: /* feni (287 only, just do nop here) */
6092 case 1: /* fdisi (287 only, just do nop here) */
6095 gen_helper_fclex(cpu_env
);
6097 case 3: /* fninit */
6098 gen_helper_fninit(cpu_env
);
6100 case 4: /* fsetpm (287 only, just do nop here) */
6106 case 0x1d: /* fucomi */
6107 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6110 gen_update_cc_op(s
);
6111 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6112 gen_helper_fucomi_ST0_FT0(cpu_env
);
6113 set_cc_op(s
, CC_OP_EFLAGS
);
6115 case 0x1e: /* fcomi */
6116 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6119 gen_update_cc_op(s
);
6120 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6121 gen_helper_fcomi_ST0_FT0(cpu_env
);
6122 set_cc_op(s
, CC_OP_EFLAGS
);
6124 case 0x28: /* ffree sti */
6125 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6127 case 0x2a: /* fst sti */
6128 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6130 case 0x2b: /* fstp sti */
6131 case 0x0b: /* fstp1 sti, undocumented op */
6132 case 0x3a: /* fstp8 sti, undocumented op */
6133 case 0x3b: /* fstp9 sti, undocumented op */
6134 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6135 gen_helper_fpop(cpu_env
);
6137 case 0x2c: /* fucom st(i) */
6138 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6139 gen_helper_fucom_ST0_FT0(cpu_env
);
6141 case 0x2d: /* fucomp st(i) */
6142 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6143 gen_helper_fucom_ST0_FT0(cpu_env
);
6144 gen_helper_fpop(cpu_env
);
6146 case 0x33: /* de/3 */
6148 case 1: /* fcompp */
6149 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6150 gen_helper_fcom_ST0_FT0(cpu_env
);
6151 gen_helper_fpop(cpu_env
);
6152 gen_helper_fpop(cpu_env
);
6158 case 0x38: /* ffreep sti, undocumented op */
6159 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6160 gen_helper_fpop(cpu_env
);
6162 case 0x3c: /* df/4 */
6165 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
6166 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6167 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T
[0]);
6173 case 0x3d: /* fucomip */
6174 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6177 gen_update_cc_op(s
);
6178 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6179 gen_helper_fucomi_ST0_FT0(cpu_env
);
6180 gen_helper_fpop(cpu_env
);
6181 set_cc_op(s
, CC_OP_EFLAGS
);
6183 case 0x3e: /* fcomip */
6184 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6187 gen_update_cc_op(s
);
6188 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6189 gen_helper_fcomi_ST0_FT0(cpu_env
);
6190 gen_helper_fpop(cpu_env
);
6191 set_cc_op(s
, CC_OP_EFLAGS
);
6193 case 0x10 ... 0x13: /* fcmovxx */
6198 static const uint8_t fcmov_cc
[8] = {
6205 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6208 op1
= fcmov_cc
[op
& 3] | (((op
>> 3) & 1) ^ 1);
6209 l1
= gen_new_label();
6210 gen_jcc1_noeob(s
, op1
, l1
);
6211 gen_helper_fmov_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6220 /************************/
6223 case 0xa4: /* movsS */
6225 ot
= mo_b_d(b
, dflag
);
6226 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6227 gen_repz_movs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6233 case 0xaa: /* stosS */
6235 ot
= mo_b_d(b
, dflag
);
6236 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6237 gen_repz_stos(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6242 case 0xac: /* lodsS */
6244 ot
= mo_b_d(b
, dflag
);
6245 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6246 gen_repz_lods(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6251 case 0xae: /* scasS */
6253 ot
= mo_b_d(b
, dflag
);
6254 if (prefixes
& PREFIX_REPNZ
) {
6255 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6256 } else if (prefixes
& PREFIX_REPZ
) {
6257 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6263 case 0xa6: /* cmpsS */
6265 ot
= mo_b_d(b
, dflag
);
6266 if (prefixes
& PREFIX_REPNZ
) {
6267 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6268 } else if (prefixes
& PREFIX_REPZ
) {
6269 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6274 case 0x6c: /* insS */
6276 ot
= mo_b_d32(b
, dflag
);
6277 tcg_gen_ext16u_tl(cpu_T
[0], cpu_regs
[R_EDX
]);
6278 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6279 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
) | 4);
6280 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6281 gen_repz_ins(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6284 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6285 gen_jmp(s
, s
->pc
- s
->cs_base
);
6289 case 0x6e: /* outsS */
6291 ot
= mo_b_d32(b
, dflag
);
6292 tcg_gen_ext16u_tl(cpu_T
[0], cpu_regs
[R_EDX
]);
6293 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6294 svm_is_rep(prefixes
) | 4);
6295 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6296 gen_repz_outs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6299 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6300 gen_jmp(s
, s
->pc
- s
->cs_base
);
6305 /************************/
6310 ot
= mo_b_d32(b
, dflag
);
6311 val
= cpu_ldub_code(env
, s
->pc
++);
6312 tcg_gen_movi_tl(cpu_T
[0], val
);
6313 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6314 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6315 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6318 tcg_gen_movi_i32(cpu_tmp2_i32
, val
);
6319 gen_helper_in_func(ot
, cpu_T
[1], cpu_tmp2_i32
);
6320 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T
[1]);
6321 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6323 gen_jmp(s
, s
->pc
- s
->cs_base
);
6328 ot
= mo_b_d32(b
, dflag
);
6329 val
= cpu_ldub_code(env
, s
->pc
++);
6330 tcg_gen_movi_tl(cpu_T
[0], val
);
6331 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6332 svm_is_rep(prefixes
));
6333 gen_op_mov_v_reg(ot
, cpu_T
[1], R_EAX
);
6335 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6338 tcg_gen_movi_i32(cpu_tmp2_i32
, val
);
6339 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
6340 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6341 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6343 gen_jmp(s
, s
->pc
- s
->cs_base
);
6348 ot
= mo_b_d32(b
, dflag
);
6349 tcg_gen_ext16u_tl(cpu_T
[0], cpu_regs
[R_EDX
]);
6350 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6351 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6352 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6355 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6356 gen_helper_in_func(ot
, cpu_T
[1], cpu_tmp2_i32
);
6357 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T
[1]);
6358 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6360 gen_jmp(s
, s
->pc
- s
->cs_base
);
6365 ot
= mo_b_d32(b
, dflag
);
6366 tcg_gen_ext16u_tl(cpu_T
[0], cpu_regs
[R_EDX
]);
6367 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6368 svm_is_rep(prefixes
));
6369 gen_op_mov_v_reg(ot
, cpu_T
[1], R_EAX
);
6371 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6374 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6375 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
6376 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6377 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
6379 gen_jmp(s
, s
->pc
- s
->cs_base
);
6383 /************************/
6385 case 0xc2: /* ret im */
6386 val
= cpu_ldsw_code(env
, s
->pc
);
6389 gen_stack_update(s
, val
+ (1 << ot
));
6390 /* Note that gen_pop_T0 uses a zero-extending load. */
6391 gen_op_jmp_v(cpu_T
[0]);
6394 case 0xc3: /* ret */
6396 gen_pop_update(s
, ot
);
6397 /* Note that gen_pop_T0 uses a zero-extending load. */
6398 gen_op_jmp_v(cpu_T
[0]);
6401 case 0xca: /* lret im */
6402 val
= cpu_ldsw_code(env
, s
->pc
);
6405 if (s
->pe
&& !s
->vm86
) {
6406 gen_update_cc_op(s
);
6407 gen_jmp_im(pc_start
- s
->cs_base
);
6408 gen_helper_lret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6409 tcg_const_i32(val
));
6413 gen_op_ld_v(s
, dflag
, cpu_T
[0], cpu_A0
);
6414 /* NOTE: keeping EIP updated is not a problem in case of
6416 gen_op_jmp_v(cpu_T
[0]);
6418 gen_op_addl_A0_im(1 << dflag
);
6419 gen_op_ld_v(s
, dflag
, cpu_T
[0], cpu_A0
);
6420 gen_op_movl_seg_T0_vm(R_CS
);
6421 /* add stack offset */
6422 gen_stack_update(s
, val
+ (2 << dflag
));
6426 case 0xcb: /* lret */
6429 case 0xcf: /* iret */
6430 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IRET
);
6433 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6434 set_cc_op(s
, CC_OP_EFLAGS
);
6435 } else if (s
->vm86
) {
6437 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6439 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6440 set_cc_op(s
, CC_OP_EFLAGS
);
6443 gen_update_cc_op(s
);
6444 gen_jmp_im(pc_start
- s
->cs_base
);
6445 gen_helper_iret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6446 tcg_const_i32(s
->pc
- s
->cs_base
));
6447 set_cc_op(s
, CC_OP_EFLAGS
);
6451 case 0xe8: /* call im */
6453 if (dflag
!= MO_16
) {
6454 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6456 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6458 next_eip
= s
->pc
- s
->cs_base
;
6460 if (dflag
== MO_16
) {
6462 } else if (!CODE64(s
)) {
6465 tcg_gen_movi_tl(cpu_T
[0], next_eip
);
6466 gen_push_v(s
, cpu_T
[0]);
6470 case 0x9a: /* lcall im */
6472 unsigned int selector
, offset
;
6477 offset
= insn_get(env
, s
, ot
);
6478 selector
= insn_get(env
, s
, MO_16
);
6480 tcg_gen_movi_tl(cpu_T
[0], selector
);
6481 tcg_gen_movi_tl(cpu_T
[1], offset
);
6484 case 0xe9: /* jmp im */
6485 if (dflag
!= MO_16
) {
6486 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6488 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6490 tval
+= s
->pc
- s
->cs_base
;
6491 if (dflag
== MO_16
) {
6493 } else if (!CODE64(s
)) {
6498 case 0xea: /* ljmp im */
6500 unsigned int selector
, offset
;
6505 offset
= insn_get(env
, s
, ot
);
6506 selector
= insn_get(env
, s
, MO_16
);
6508 tcg_gen_movi_tl(cpu_T
[0], selector
);
6509 tcg_gen_movi_tl(cpu_T
[1], offset
);
6512 case 0xeb: /* jmp Jb */
6513 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6514 tval
+= s
->pc
- s
->cs_base
;
6515 if (dflag
== MO_16
) {
6520 case 0x70 ... 0x7f: /* jcc Jb */
6521 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6523 case 0x180 ... 0x18f: /* jcc Jv */
6524 if (dflag
!= MO_16
) {
6525 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6527 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6530 next_eip
= s
->pc
- s
->cs_base
;
6532 if (dflag
== MO_16
) {
6535 gen_jcc(s
, b
, tval
, next_eip
);
6538 case 0x190 ... 0x19f: /* setcc Gv */
6539 modrm
= cpu_ldub_code(env
, s
->pc
++);
6540 gen_setcc1(s
, b
, cpu_T
[0]);
6541 gen_ldst_modrm(env
, s
, modrm
, MO_8
, OR_TMP0
, 1);
6543 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6544 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6548 modrm
= cpu_ldub_code(env
, s
->pc
++);
6549 reg
= ((modrm
>> 3) & 7) | rex_r
;
6550 gen_cmovcc1(env
, s
, ot
, b
, modrm
, reg
);
6553 /************************/
6555 case 0x9c: /* pushf */
6556 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_PUSHF
);
6557 if (s
->vm86
&& s
->iopl
!= 3) {
6558 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6560 gen_update_cc_op(s
);
6561 gen_helper_read_eflags(cpu_T
[0], cpu_env
);
6562 gen_push_v(s
, cpu_T
[0]);
6565 case 0x9d: /* popf */
6566 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_POPF
);
6567 if (s
->vm86
&& s
->iopl
!= 3) {
6568 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6572 if (dflag
!= MO_16
) {
6573 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6574 tcg_const_i32((TF_MASK
| AC_MASK
|
6579 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6580 tcg_const_i32((TF_MASK
| AC_MASK
|
6582 IF_MASK
| IOPL_MASK
)
6586 if (s
->cpl
<= s
->iopl
) {
6587 if (dflag
!= MO_16
) {
6588 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6589 tcg_const_i32((TF_MASK
|
6595 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6596 tcg_const_i32((TF_MASK
|
6604 if (dflag
!= MO_16
) {
6605 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6606 tcg_const_i32((TF_MASK
| AC_MASK
|
6607 ID_MASK
| NT_MASK
)));
6609 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6610 tcg_const_i32((TF_MASK
| AC_MASK
|
6616 gen_pop_update(s
, ot
);
6617 set_cc_op(s
, CC_OP_EFLAGS
);
6618 /* abort translation because TF/AC flag may change */
6619 gen_jmp_im(s
->pc
- s
->cs_base
);
6623 case 0x9e: /* sahf */
6624 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6626 gen_op_mov_v_reg(MO_8
, cpu_T
[0], R_AH
);
6627 gen_compute_eflags(s
);
6628 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, CC_O
);
6629 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], CC_S
| CC_Z
| CC_A
| CC_P
| CC_C
);
6630 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, cpu_T
[0]);
6632 case 0x9f: /* lahf */
6633 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6635 gen_compute_eflags(s
);
6636 /* Note: gen_compute_eflags() only gives the condition codes */
6637 tcg_gen_ori_tl(cpu_T
[0], cpu_cc_src
, 0x02);
6638 gen_op_mov_reg_v(MO_8
, R_AH
, cpu_T
[0]);
6640 case 0xf5: /* cmc */
6641 gen_compute_eflags(s
);
6642 tcg_gen_xori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6644 case 0xf8: /* clc */
6645 gen_compute_eflags(s
);
6646 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_C
);
6648 case 0xf9: /* stc */
6649 gen_compute_eflags(s
);
6650 tcg_gen_ori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6652 case 0xfc: /* cld */
6653 tcg_gen_movi_i32(cpu_tmp2_i32
, 1);
6654 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6656 case 0xfd: /* std */
6657 tcg_gen_movi_i32(cpu_tmp2_i32
, -1);
6658 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6661 /************************/
6662 /* bit operations */
6663 case 0x1ba: /* bt/bts/btr/btc Gv, im */
6665 modrm
= cpu_ldub_code(env
, s
->pc
++);
6666 op
= (modrm
>> 3) & 7;
6667 mod
= (modrm
>> 6) & 3;
6668 rm
= (modrm
& 7) | REX_B(s
);
6671 gen_lea_modrm(env
, s
, modrm
);
6672 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
6674 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
6677 val
= cpu_ldub_code(env
, s
->pc
++);
6678 tcg_gen_movi_tl(cpu_T
[1], val
);
6683 case 0x1a3: /* bt Gv, Ev */
6686 case 0x1ab: /* bts */
6689 case 0x1b3: /* btr */
6692 case 0x1bb: /* btc */
6696 modrm
= cpu_ldub_code(env
, s
->pc
++);
6697 reg
= ((modrm
>> 3) & 7) | rex_r
;
6698 mod
= (modrm
>> 6) & 3;
6699 rm
= (modrm
& 7) | REX_B(s
);
6700 gen_op_mov_v_reg(MO_32
, cpu_T
[1], reg
);
6702 gen_lea_modrm(env
, s
, modrm
);
6703 /* specific case: we need to add a displacement */
6704 gen_exts(ot
, cpu_T
[1]);
6705 tcg_gen_sari_tl(cpu_tmp0
, cpu_T
[1], 3 + ot
);
6706 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, ot
);
6707 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
6708 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
6710 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
6713 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], (1 << (3 + ot
)) - 1);
6714 tcg_gen_shr_tl(cpu_tmp4
, cpu_T
[0], cpu_T
[1]);
6719 tcg_gen_movi_tl(cpu_tmp0
, 1);
6720 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
6721 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
6724 tcg_gen_movi_tl(cpu_tmp0
, 1);
6725 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
6726 tcg_gen_andc_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
6730 tcg_gen_movi_tl(cpu_tmp0
, 1);
6731 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
6732 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
6737 gen_op_st_v(s
, ot
, cpu_T
[0], cpu_A0
);
6739 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
6743 /* Delay all CC updates until after the store above. Note that
6744 C is the result of the test, Z is unchanged, and the others
6745 are all undefined. */
6747 case CC_OP_MULB
... CC_OP_MULQ
:
6748 case CC_OP_ADDB
... CC_OP_ADDQ
:
6749 case CC_OP_ADCB
... CC_OP_ADCQ
:
6750 case CC_OP_SUBB
... CC_OP_SUBQ
:
6751 case CC_OP_SBBB
... CC_OP_SBBQ
:
6752 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
6753 case CC_OP_INCB
... CC_OP_INCQ
:
6754 case CC_OP_DECB
... CC_OP_DECQ
:
6755 case CC_OP_SHLB
... CC_OP_SHLQ
:
6756 case CC_OP_SARB
... CC_OP_SARQ
:
6757 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
6758 /* Z was going to be computed from the non-zero status of CC_DST.
6759 We can get that same Z value (and the new C value) by leaving
6760 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
6762 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
6763 set_cc_op(s
, ((s
->cc_op
- CC_OP_MULB
) & 3) + CC_OP_SARB
);
6766 /* Otherwise, generate EFLAGS and replace the C bit. */
6767 gen_compute_eflags(s
);
6768 tcg_gen_deposit_tl(cpu_cc_src
, cpu_cc_src
, cpu_tmp4
,
6773 case 0x1bc: /* bsf / tzcnt */
6774 case 0x1bd: /* bsr / lzcnt */
6776 modrm
= cpu_ldub_code(env
, s
->pc
++);
6777 reg
= ((modrm
>> 3) & 7) | rex_r
;
6778 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
6779 gen_extu(ot
, cpu_T
[0]);
6781 /* Note that lzcnt and tzcnt are in different extensions. */
6782 if ((prefixes
& PREFIX_REPZ
)
6784 ? s
->cpuid_ext3_features
& CPUID_EXT3_ABM
6785 : s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)) {
6787 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
6789 /* For lzcnt, reduce the target_ulong result by the
6790 number of zeros that we expect to find at the top. */
6791 gen_helper_clz(cpu_T
[0], cpu_T
[0]);
6792 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], TARGET_LONG_BITS
- size
);
6794 /* For tzcnt, a zero input must return the operand size:
6795 force all bits outside the operand size to 1. */
6796 target_ulong mask
= (target_ulong
)-2 << (size
- 1);
6797 tcg_gen_ori_tl(cpu_T
[0], cpu_T
[0], mask
);
6798 gen_helper_ctz(cpu_T
[0], cpu_T
[0]);
6800 /* For lzcnt/tzcnt, C and Z bits are defined and are
6801 related to the result. */
6802 gen_op_update1_cc();
6803 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
6805 /* For bsr/bsf, only the Z bit is defined and it is related
6806 to the input and not the result. */
6807 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
6808 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
6810 /* For bsr, return the bit index of the first 1 bit,
6811 not the count of leading zeros. */
6812 gen_helper_clz(cpu_T
[0], cpu_T
[0]);
6813 tcg_gen_xori_tl(cpu_T
[0], cpu_T
[0], TARGET_LONG_BITS
- 1);
6815 gen_helper_ctz(cpu_T
[0], cpu_T
[0]);
6817 /* ??? The manual says that the output is undefined when the
6818 input is zero, but real hardware leaves it unchanged, and
6819 real programs appear to depend on that. */
6820 tcg_gen_movi_tl(cpu_tmp0
, 0);
6821 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_T
[0], cpu_cc_dst
, cpu_tmp0
,
6822 cpu_regs
[reg
], cpu_T
[0]);
6824 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
6826 /************************/
6828 case 0x27: /* daa */
6831 gen_update_cc_op(s
);
6832 gen_helper_daa(cpu_env
);
6833 set_cc_op(s
, CC_OP_EFLAGS
);
6835 case 0x2f: /* das */
6838 gen_update_cc_op(s
);
6839 gen_helper_das(cpu_env
);
6840 set_cc_op(s
, CC_OP_EFLAGS
);
6842 case 0x37: /* aaa */
6845 gen_update_cc_op(s
);
6846 gen_helper_aaa(cpu_env
);
6847 set_cc_op(s
, CC_OP_EFLAGS
);
6849 case 0x3f: /* aas */
6852 gen_update_cc_op(s
);
6853 gen_helper_aas(cpu_env
);
6854 set_cc_op(s
, CC_OP_EFLAGS
);
6856 case 0xd4: /* aam */
6859 val
= cpu_ldub_code(env
, s
->pc
++);
6861 gen_exception(s
, EXCP00_DIVZ
, pc_start
- s
->cs_base
);
6863 gen_helper_aam(cpu_env
, tcg_const_i32(val
));
6864 set_cc_op(s
, CC_OP_LOGICB
);
6867 case 0xd5: /* aad */
6870 val
= cpu_ldub_code(env
, s
->pc
++);
6871 gen_helper_aad(cpu_env
, tcg_const_i32(val
));
6872 set_cc_op(s
, CC_OP_LOGICB
);
6874 /************************/
6876 case 0x90: /* nop */
6877 /* XXX: correct lock test for all insn */
6878 if (prefixes
& PREFIX_LOCK
) {
6881 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
6883 goto do_xchg_reg_eax
;
6885 if (prefixes
& PREFIX_REPZ
) {
6886 gen_update_cc_op(s
);
6887 gen_jmp_im(pc_start
- s
->cs_base
);
6888 gen_helper_pause(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
6889 s
->is_jmp
= DISAS_TB_JUMP
;
6892 case 0x9b: /* fwait */
6893 if ((s
->flags
& (HF_MP_MASK
| HF_TS_MASK
)) ==
6894 (HF_MP_MASK
| HF_TS_MASK
)) {
6895 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
6897 gen_update_cc_op(s
);
6898 gen_jmp_im(pc_start
- s
->cs_base
);
6899 gen_helper_fwait(cpu_env
);
6902 case 0xcc: /* int3 */
6903 gen_interrupt(s
, EXCP03_INT3
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6905 case 0xcd: /* int N */
6906 val
= cpu_ldub_code(env
, s
->pc
++);
6907 if (s
->vm86
&& s
->iopl
!= 3) {
6908 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6910 gen_interrupt(s
, val
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6913 case 0xce: /* into */
6916 gen_update_cc_op(s
);
6917 gen_jmp_im(pc_start
- s
->cs_base
);
6918 gen_helper_into(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
6921 case 0xf1: /* icebp (undocumented, exits to external debugger) */
6922 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_ICEBP
);
6924 gen_debug(s
, pc_start
- s
->cs_base
);
6927 tb_flush(CPU(x86_env_get_cpu(env
)));
6928 qemu_set_log(CPU_LOG_INT
| CPU_LOG_TB_IN_ASM
);
6932 case 0xfa: /* cli */
6934 if (s
->cpl
<= s
->iopl
) {
6935 gen_helper_cli(cpu_env
);
6937 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6941 gen_helper_cli(cpu_env
);
6943 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6947 case 0xfb: /* sti */
6949 if (s
->cpl
<= s
->iopl
) {
6951 gen_helper_sti(cpu_env
);
6952 /* interruptions are enabled only the first insn after sti */
6953 /* If several instructions disable interrupts, only the
6955 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
6956 gen_helper_set_inhibit_irq(cpu_env
);
6957 /* give a chance to handle pending irqs */
6958 gen_jmp_im(s
->pc
- s
->cs_base
);
6961 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6967 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6971 case 0x62: /* bound */
6975 modrm
= cpu_ldub_code(env
, s
->pc
++);
6976 reg
= (modrm
>> 3) & 7;
6977 mod
= (modrm
>> 6) & 3;
6980 gen_op_mov_v_reg(ot
, cpu_T
[0], reg
);
6981 gen_lea_modrm(env
, s
, modrm
);
6982 gen_jmp_im(pc_start
- s
->cs_base
);
6983 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6985 gen_helper_boundw(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
6987 gen_helper_boundl(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
6990 case 0x1c8 ... 0x1cf: /* bswap reg */
6991 reg
= (b
& 7) | REX_B(s
);
6992 #ifdef TARGET_X86_64
6993 if (dflag
== MO_64
) {
6994 gen_op_mov_v_reg(MO_64
, cpu_T
[0], reg
);
6995 tcg_gen_bswap64_i64(cpu_T
[0], cpu_T
[0]);
6996 gen_op_mov_reg_v(MO_64
, reg
, cpu_T
[0]);
7000 gen_op_mov_v_reg(MO_32
, cpu_T
[0], reg
);
7001 tcg_gen_ext32u_tl(cpu_T
[0], cpu_T
[0]);
7002 tcg_gen_bswap32_tl(cpu_T
[0], cpu_T
[0]);
7003 gen_op_mov_reg_v(MO_32
, reg
, cpu_T
[0]);
7006 case 0xd6: /* salc */
7009 gen_compute_eflags_c(s
, cpu_T
[0]);
7010 tcg_gen_neg_tl(cpu_T
[0], cpu_T
[0]);
7011 gen_op_mov_reg_v(MO_8
, R_EAX
, cpu_T
[0]);
7013 case 0xe0: /* loopnz */
7014 case 0xe1: /* loopz */
7015 case 0xe2: /* loop */
7016 case 0xe3: /* jecxz */
7018 TCGLabel
*l1
, *l2
, *l3
;
7020 tval
= (int8_t)insn_get(env
, s
, MO_8
);
7021 next_eip
= s
->pc
- s
->cs_base
;
7023 if (dflag
== MO_16
) {
7027 l1
= gen_new_label();
7028 l2
= gen_new_label();
7029 l3
= gen_new_label();
7032 case 0: /* loopnz */
7034 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
7035 gen_op_jz_ecx(s
->aflag
, l3
);
7036 gen_jcc1(s
, (JCC_Z
<< 1) | (b
^ 1), l1
);
7039 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
7040 gen_op_jnz_ecx(s
->aflag
, l1
);
7044 gen_op_jz_ecx(s
->aflag
, l1
);
7049 gen_jmp_im(next_eip
);
7058 case 0x130: /* wrmsr */
7059 case 0x132: /* rdmsr */
7061 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7063 gen_update_cc_op(s
);
7064 gen_jmp_im(pc_start
- s
->cs_base
);
7066 gen_helper_rdmsr(cpu_env
);
7068 gen_helper_wrmsr(cpu_env
);
7072 case 0x131: /* rdtsc */
7073 gen_update_cc_op(s
);
7074 gen_jmp_im(pc_start
- s
->cs_base
);
7075 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7078 gen_helper_rdtsc(cpu_env
);
7079 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7081 gen_jmp(s
, s
->pc
- s
->cs_base
);
7084 case 0x133: /* rdpmc */
7085 gen_update_cc_op(s
);
7086 gen_jmp_im(pc_start
- s
->cs_base
);
7087 gen_helper_rdpmc(cpu_env
);
7089 case 0x134: /* sysenter */
7090 /* For Intel SYSENTER is valid on 64-bit */
7091 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7094 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7096 gen_update_cc_op(s
);
7097 gen_jmp_im(pc_start
- s
->cs_base
);
7098 gen_helper_sysenter(cpu_env
);
7102 case 0x135: /* sysexit */
7103 /* For Intel SYSEXIT is valid on 64-bit */
7104 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7107 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7109 gen_update_cc_op(s
);
7110 gen_jmp_im(pc_start
- s
->cs_base
);
7111 gen_helper_sysexit(cpu_env
, tcg_const_i32(dflag
- 1));
7115 #ifdef TARGET_X86_64
7116 case 0x105: /* syscall */
7117 /* XXX: is it usable in real mode ? */
7118 gen_update_cc_op(s
);
7119 gen_jmp_im(pc_start
- s
->cs_base
);
7120 gen_helper_syscall(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7123 case 0x107: /* sysret */
7125 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7127 gen_update_cc_op(s
);
7128 gen_jmp_im(pc_start
- s
->cs_base
);
7129 gen_helper_sysret(cpu_env
, tcg_const_i32(dflag
- 1));
7130 /* condition codes are modified only in long mode */
7132 set_cc_op(s
, CC_OP_EFLAGS
);
7138 case 0x1a2: /* cpuid */
7139 gen_update_cc_op(s
);
7140 gen_jmp_im(pc_start
- s
->cs_base
);
7141 gen_helper_cpuid(cpu_env
);
7143 case 0xf4: /* hlt */
7145 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7147 gen_update_cc_op(s
);
7148 gen_jmp_im(pc_start
- s
->cs_base
);
7149 gen_helper_hlt(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7150 s
->is_jmp
= DISAS_TB_JUMP
;
7154 modrm
= cpu_ldub_code(env
, s
->pc
++);
7155 mod
= (modrm
>> 6) & 3;
7156 op
= (modrm
>> 3) & 7;
7159 if (!s
->pe
|| s
->vm86
)
7161 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_READ
);
7162 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,ldt
.selector
));
7163 ot
= mod
== 3 ? dflag
: MO_16
;
7164 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7167 if (!s
->pe
|| s
->vm86
)
7170 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7172 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_WRITE
);
7173 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7174 gen_jmp_im(pc_start
- s
->cs_base
);
7175 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
7176 gen_helper_lldt(cpu_env
, cpu_tmp2_i32
);
7180 if (!s
->pe
|| s
->vm86
)
7182 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_READ
);
7183 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,tr
.selector
));
7184 ot
= mod
== 3 ? dflag
: MO_16
;
7185 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7188 if (!s
->pe
|| s
->vm86
)
7191 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7193 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_WRITE
);
7194 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7195 gen_jmp_im(pc_start
- s
->cs_base
);
7196 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
7197 gen_helper_ltr(cpu_env
, cpu_tmp2_i32
);
7202 if (!s
->pe
|| s
->vm86
)
7204 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7205 gen_update_cc_op(s
);
7207 gen_helper_verr(cpu_env
, cpu_T
[0]);
7209 gen_helper_verw(cpu_env
, cpu_T
[0]);
7211 set_cc_op(s
, CC_OP_EFLAGS
);
7218 modrm
= cpu_ldub_code(env
, s
->pc
++);
7219 mod
= (modrm
>> 6) & 3;
7220 op
= (modrm
>> 3) & 7;
7226 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_READ
);
7227 gen_lea_modrm(env
, s
, modrm
);
7228 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7229 gen_op_st_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
7230 gen_add_A0_im(s
, 2);
7231 tcg_gen_ld_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7232 if (dflag
== MO_16
) {
7233 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffffff);
7235 gen_op_st_v(s
, CODE64(s
) + MO_32
, cpu_T
[0], cpu_A0
);
7240 case 0: /* monitor */
7241 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) ||
7244 gen_update_cc_op(s
);
7245 gen_jmp_im(pc_start
- s
->cs_base
);
7246 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EAX
]);
7247 gen_extu(s
->aflag
, cpu_A0
);
7248 gen_add_A0_ds_seg(s
);
7249 gen_helper_monitor(cpu_env
, cpu_A0
);
7252 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) ||
7255 gen_update_cc_op(s
);
7256 gen_jmp_im(pc_start
- s
->cs_base
);
7257 gen_helper_mwait(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7261 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
) ||
7265 gen_helper_clac(cpu_env
);
7266 gen_jmp_im(s
->pc
- s
->cs_base
);
7270 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
) ||
7274 gen_helper_stac(cpu_env
);
7275 gen_jmp_im(s
->pc
- s
->cs_base
);
7282 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_READ
);
7283 gen_lea_modrm(env
, s
, modrm
);
7284 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7285 gen_op_st_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
7286 gen_add_A0_im(s
, 2);
7287 tcg_gen_ld_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, idt
.base
));
7288 if (dflag
== MO_16
) {
7289 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffffff);
7291 gen_op_st_v(s
, CODE64(s
) + MO_32
, cpu_T
[0], cpu_A0
);
7297 gen_update_cc_op(s
);
7298 gen_jmp_im(pc_start
- s
->cs_base
);
7301 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7304 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7307 gen_helper_vmrun(cpu_env
, tcg_const_i32(s
->aflag
- 1),
7308 tcg_const_i32(s
->pc
- pc_start
));
7310 s
->is_jmp
= DISAS_TB_JUMP
;
7313 case 1: /* VMMCALL */
7314 if (!(s
->flags
& HF_SVME_MASK
))
7316 gen_helper_vmmcall(cpu_env
);
7318 case 2: /* VMLOAD */
7319 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7322 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7325 gen_helper_vmload(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7328 case 3: /* VMSAVE */
7329 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7332 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7335 gen_helper_vmsave(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7339 if ((!(s
->flags
& HF_SVME_MASK
) &&
7340 !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
)) ||
7344 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7347 gen_helper_stgi(cpu_env
);
7351 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7354 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7357 gen_helper_clgi(cpu_env
);
7360 case 6: /* SKINIT */
7361 if ((!(s
->flags
& HF_SVME_MASK
) &&
7362 !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
)) ||
7365 gen_helper_skinit(cpu_env
);
7367 case 7: /* INVLPGA */
7368 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7371 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7374 gen_helper_invlpga(cpu_env
,
7375 tcg_const_i32(s
->aflag
- 1));
7381 } else if (s
->cpl
!= 0) {
7382 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7384 gen_svm_check_intercept(s
, pc_start
,
7385 op
==2 ? SVM_EXIT_GDTR_WRITE
: SVM_EXIT_IDTR_WRITE
);
7386 gen_lea_modrm(env
, s
, modrm
);
7387 gen_op_ld_v(s
, MO_16
, cpu_T
[1], cpu_A0
);
7388 gen_add_A0_im(s
, 2);
7389 gen_op_ld_v(s
, CODE64(s
) + MO_32
, cpu_T
[0], cpu_A0
);
7390 if (dflag
== MO_16
) {
7391 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffffff);
7394 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,gdt
.base
));
7395 tcg_gen_st32_tl(cpu_T
[1], cpu_env
, offsetof(CPUX86State
,gdt
.limit
));
7397 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,idt
.base
));
7398 tcg_gen_st32_tl(cpu_T
[1], cpu_env
, offsetof(CPUX86State
,idt
.limit
));
7403 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_CR0
);
7404 #if defined TARGET_X86_64 && defined HOST_WORDS_BIGENDIAN
7405 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,cr
[0]) + 4);
7407 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,cr
[0]));
7409 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 1);
7413 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7415 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7416 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7417 gen_helper_lmsw(cpu_env
, cpu_T
[0]);
7418 gen_jmp_im(s
->pc
- s
->cs_base
);
7423 if (mod
!= 3) { /* invlpg */
7425 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7427 gen_update_cc_op(s
);
7428 gen_jmp_im(pc_start
- s
->cs_base
);
7429 gen_lea_modrm(env
, s
, modrm
);
7430 gen_helper_invlpg(cpu_env
, cpu_A0
);
7431 gen_jmp_im(s
->pc
- s
->cs_base
);
7436 case 0: /* swapgs */
7437 #ifdef TARGET_X86_64
7440 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7442 tcg_gen_ld_tl(cpu_T
[0], cpu_env
,
7443 offsetof(CPUX86State
,segs
[R_GS
].base
));
7444 tcg_gen_ld_tl(cpu_T
[1], cpu_env
,
7445 offsetof(CPUX86State
,kernelgsbase
));
7446 tcg_gen_st_tl(cpu_T
[1], cpu_env
,
7447 offsetof(CPUX86State
,segs
[R_GS
].base
));
7448 tcg_gen_st_tl(cpu_T
[0], cpu_env
,
7449 offsetof(CPUX86State
,kernelgsbase
));
7457 case 1: /* rdtscp */
7458 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_RDTSCP
))
7460 gen_update_cc_op(s
);
7461 gen_jmp_im(pc_start
- s
->cs_base
);
7462 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7465 gen_helper_rdtscp(cpu_env
);
7466 if (s
->tb
->cflags
& CF_USE_ICOUNT
) {
7468 gen_jmp(s
, s
->pc
- s
->cs_base
);
7480 case 0x108: /* invd */
7481 case 0x109: /* wbinvd */
7483 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7485 gen_svm_check_intercept(s
, pc_start
, (b
& 2) ? SVM_EXIT_INVD
: SVM_EXIT_WBINVD
);
7489 case 0x63: /* arpl or movslS (x86_64) */
7490 #ifdef TARGET_X86_64
7493 /* d_ot is the size of destination */
7496 modrm
= cpu_ldub_code(env
, s
->pc
++);
7497 reg
= ((modrm
>> 3) & 7) | rex_r
;
7498 mod
= (modrm
>> 6) & 3;
7499 rm
= (modrm
& 7) | REX_B(s
);
7502 gen_op_mov_v_reg(MO_32
, cpu_T
[0], rm
);
7504 if (d_ot
== MO_64
) {
7505 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
7507 gen_op_mov_reg_v(d_ot
, reg
, cpu_T
[0]);
7509 gen_lea_modrm(env
, s
, modrm
);
7510 gen_op_ld_v(s
, MO_32
| MO_SIGN
, cpu_T
[0], cpu_A0
);
7511 gen_op_mov_reg_v(d_ot
, reg
, cpu_T
[0]);
7517 TCGv t0
, t1
, t2
, a0
;
7519 if (!s
->pe
|| s
->vm86
)
7521 t0
= tcg_temp_local_new();
7522 t1
= tcg_temp_local_new();
7523 t2
= tcg_temp_local_new();
7525 modrm
= cpu_ldub_code(env
, s
->pc
++);
7526 reg
= (modrm
>> 3) & 7;
7527 mod
= (modrm
>> 6) & 3;
7530 gen_lea_modrm(env
, s
, modrm
);
7531 gen_op_ld_v(s
, ot
, t0
, cpu_A0
);
7532 a0
= tcg_temp_local_new();
7533 tcg_gen_mov_tl(a0
, cpu_A0
);
7535 gen_op_mov_v_reg(ot
, t0
, rm
);
7538 gen_op_mov_v_reg(ot
, t1
, reg
);
7539 tcg_gen_andi_tl(cpu_tmp0
, t0
, 3);
7540 tcg_gen_andi_tl(t1
, t1
, 3);
7541 tcg_gen_movi_tl(t2
, 0);
7542 label1
= gen_new_label();
7543 tcg_gen_brcond_tl(TCG_COND_GE
, cpu_tmp0
, t1
, label1
);
7544 tcg_gen_andi_tl(t0
, t0
, ~3);
7545 tcg_gen_or_tl(t0
, t0
, t1
);
7546 tcg_gen_movi_tl(t2
, CC_Z
);
7547 gen_set_label(label1
);
7549 gen_op_st_v(s
, ot
, t0
, a0
);
7552 gen_op_mov_reg_v(ot
, rm
, t0
);
7554 gen_compute_eflags(s
);
7555 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_Z
);
7556 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, t2
);
7562 case 0x102: /* lar */
7563 case 0x103: /* lsl */
7567 if (!s
->pe
|| s
->vm86
)
7569 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
7570 modrm
= cpu_ldub_code(env
, s
->pc
++);
7571 reg
= ((modrm
>> 3) & 7) | rex_r
;
7572 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7573 t0
= tcg_temp_local_new();
7574 gen_update_cc_op(s
);
7576 gen_helper_lar(t0
, cpu_env
, cpu_T
[0]);
7578 gen_helper_lsl(t0
, cpu_env
, cpu_T
[0]);
7580 tcg_gen_andi_tl(cpu_tmp0
, cpu_cc_src
, CC_Z
);
7581 label1
= gen_new_label();
7582 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
7583 gen_op_mov_reg_v(ot
, reg
, t0
);
7584 gen_set_label(label1
);
7585 set_cc_op(s
, CC_OP_EFLAGS
);
7590 modrm
= cpu_ldub_code(env
, s
->pc
++);
7591 mod
= (modrm
>> 6) & 3;
7592 op
= (modrm
>> 3) & 7;
7594 case 0: /* prefetchnta */
7595 case 1: /* prefetchnt0 */
7596 case 2: /* prefetchnt0 */
7597 case 3: /* prefetchnt0 */
7600 gen_lea_modrm(env
, s
, modrm
);
7601 /* nothing more to do */
7603 default: /* nop (multi byte) */
7604 gen_nop_modrm(env
, s
, modrm
);
7608 case 0x119 ... 0x11f: /* nop (multi byte) */
7609 modrm
= cpu_ldub_code(env
, s
->pc
++);
7610 gen_nop_modrm(env
, s
, modrm
);
7612 case 0x120: /* mov reg, crN */
7613 case 0x122: /* mov crN, reg */
7615 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7617 modrm
= cpu_ldub_code(env
, s
->pc
++);
7618 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7619 * AMD documentation (24594.pdf) and testing of
7620 * intel 386 and 486 processors all show that the mod bits
7621 * are assumed to be 1's, regardless of actual values.
7623 rm
= (modrm
& 7) | REX_B(s
);
7624 reg
= ((modrm
>> 3) & 7) | rex_r
;
7629 if ((prefixes
& PREFIX_LOCK
) && (reg
== 0) &&
7630 (s
->cpuid_ext3_features
& CPUID_EXT3_CR8LEG
)) {
7639 gen_update_cc_op(s
);
7640 gen_jmp_im(pc_start
- s
->cs_base
);
7642 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
7643 gen_helper_write_crN(cpu_env
, tcg_const_i32(reg
),
7645 gen_jmp_im(s
->pc
- s
->cs_base
);
7648 gen_helper_read_crN(cpu_T
[0], cpu_env
, tcg_const_i32(reg
));
7649 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
7657 case 0x121: /* mov reg, drN */
7658 case 0x123: /* mov drN, reg */
7660 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7662 modrm
= cpu_ldub_code(env
, s
->pc
++);
7663 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7664 * AMD documentation (24594.pdf) and testing of
7665 * intel 386 and 486 processors all show that the mod bits
7666 * are assumed to be 1's, regardless of actual values.
7668 rm
= (modrm
& 7) | REX_B(s
);
7669 reg
= ((modrm
>> 3) & 7) | rex_r
;
7674 /* XXX: do it dynamically with CR4.DE bit */
7675 if (reg
== 4 || reg
== 5 || reg
>= 8)
7678 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_DR0
+ reg
);
7679 gen_op_mov_v_reg(ot
, cpu_T
[0], rm
);
7680 gen_helper_movl_drN_T0(cpu_env
, tcg_const_i32(reg
), cpu_T
[0]);
7681 gen_jmp_im(s
->pc
- s
->cs_base
);
7684 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_DR0
+ reg
);
7685 tcg_gen_ld_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,dr
[reg
]));
7686 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
7690 case 0x106: /* clts */
7692 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7694 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7695 gen_helper_clts(cpu_env
);
7696 /* abort block because static cpu state changed */
7697 gen_jmp_im(s
->pc
- s
->cs_base
);
7701 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
7702 case 0x1c3: /* MOVNTI reg, mem */
7703 if (!(s
->cpuid_features
& CPUID_SSE2
))
7705 ot
= mo_64_32(dflag
);
7706 modrm
= cpu_ldub_code(env
, s
->pc
++);
7707 mod
= (modrm
>> 6) & 3;
7710 reg
= ((modrm
>> 3) & 7) | rex_r
;
7711 /* generate a generic store */
7712 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
7715 modrm
= cpu_ldub_code(env
, s
->pc
++);
7716 mod
= (modrm
>> 6) & 3;
7717 op
= (modrm
>> 3) & 7;
7719 case 0: /* fxsave */
7720 if (mod
== 3 || !(s
->cpuid_features
& CPUID_FXSR
) ||
7721 (s
->prefix
& PREFIX_LOCK
))
7723 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
7724 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7727 gen_lea_modrm(env
, s
, modrm
);
7728 gen_update_cc_op(s
);
7729 gen_jmp_im(pc_start
- s
->cs_base
);
7730 gen_helper_fxsave(cpu_env
, cpu_A0
, tcg_const_i32(dflag
== MO_64
));
7732 case 1: /* fxrstor */
7733 if (mod
== 3 || !(s
->cpuid_features
& CPUID_FXSR
) ||
7734 (s
->prefix
& PREFIX_LOCK
))
7736 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
7737 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7740 gen_lea_modrm(env
, s
, modrm
);
7741 gen_update_cc_op(s
);
7742 gen_jmp_im(pc_start
- s
->cs_base
);
7743 gen_helper_fxrstor(cpu_env
, cpu_A0
, tcg_const_i32(dflag
== MO_64
));
7745 case 2: /* ldmxcsr */
7746 case 3: /* stmxcsr */
7747 if (s
->flags
& HF_TS_MASK
) {
7748 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7751 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
) ||
7754 gen_lea_modrm(env
, s
, modrm
);
7756 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
7757 s
->mem_index
, MO_LEUL
);
7758 gen_helper_ldmxcsr(cpu_env
, cpu_tmp2_i32
);
7760 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, mxcsr
));
7761 gen_op_st_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
7764 case 5: /* lfence */
7765 case 6: /* mfence */
7766 if ((modrm
& 0xc7) != 0xc0 || !(s
->cpuid_features
& CPUID_SSE2
))
7769 case 7: /* sfence / clflush */
7770 if ((modrm
& 0xc7) == 0xc0) {
7772 /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX */
7773 if (!(s
->cpuid_features
& CPUID_SSE
))
7777 if (!(s
->cpuid_features
& CPUID_CLFLUSH
))
7779 gen_lea_modrm(env
, s
, modrm
);
7786 case 0x10d: /* 3DNow! prefetch(w) */
7787 modrm
= cpu_ldub_code(env
, s
->pc
++);
7788 mod
= (modrm
>> 6) & 3;
7791 gen_lea_modrm(env
, s
, modrm
);
7792 /* ignore for now */
7794 case 0x1aa: /* rsm */
7795 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_RSM
);
7796 if (!(s
->flags
& HF_SMM_MASK
))
7798 gen_update_cc_op(s
);
7799 gen_jmp_im(s
->pc
- s
->cs_base
);
7800 gen_helper_rsm(cpu_env
);
7803 case 0x1b8: /* SSE4.2 popcnt */
7804 if ((prefixes
& (PREFIX_REPZ
| PREFIX_LOCK
| PREFIX_REPNZ
)) !=
7807 if (!(s
->cpuid_ext_features
& CPUID_EXT_POPCNT
))
7810 modrm
= cpu_ldub_code(env
, s
->pc
++);
7811 reg
= ((modrm
>> 3) & 7) | rex_r
;
7813 if (s
->prefix
& PREFIX_DATA
) {
7816 ot
= mo_64_32(dflag
);
7819 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
7820 gen_helper_popcnt(cpu_T
[0], cpu_env
, cpu_T
[0], tcg_const_i32(ot
));
7821 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
7823 set_cc_op(s
, CC_OP_EFLAGS
);
7825 case 0x10e ... 0x10f:
7826 /* 3DNow! instructions, ignore prefixes */
7827 s
->prefix
&= ~(PREFIX_REPZ
| PREFIX_REPNZ
| PREFIX_DATA
);
7828 case 0x110 ... 0x117:
7829 case 0x128 ... 0x12f:
7830 case 0x138 ... 0x13a:
7831 case 0x150 ... 0x179:
7832 case 0x17c ... 0x17f:
7834 case 0x1c4 ... 0x1c6:
7835 case 0x1d0 ... 0x1fe:
7836 gen_sse(env
, s
, b
, pc_start
, rex_r
);
7841 /* lock generation */
7842 if (s
->prefix
& PREFIX_LOCK
)
7843 gen_helper_unlock();
7846 if (s
->prefix
& PREFIX_LOCK
)
7847 gen_helper_unlock();
7848 /* XXX: ensure that no lock was generated */
7849 gen_exception(s
, EXCP06_ILLOP
, pc_start
- s
->cs_base
);
7853 void optimize_flags_init(void)
7855 static const char reg_names
[CPU_NB_REGS
][4] = {
7856 #ifdef TARGET_X86_64
7886 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
7887 cpu_cc_op
= tcg_global_mem_new_i32(TCG_AREG0
,
7888 offsetof(CPUX86State
, cc_op
), "cc_op");
7889 cpu_cc_dst
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_dst
),
7891 cpu_cc_src
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_src
),
7893 cpu_cc_src2
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_src2
),
7896 for (i
= 0; i
< CPU_NB_REGS
; ++i
) {
7897 cpu_regs
[i
] = tcg_global_mem_new(TCG_AREG0
,
7898 offsetof(CPUX86State
, regs
[i
]),
7903 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
7904 basic block 'tb'. If search_pc is TRUE, also generate PC
7905 information for each intermediate instruction. */
7906 static inline void gen_intermediate_code_internal(X86CPU
*cpu
,
7907 TranslationBlock
*tb
,
7910 CPUState
*cs
= CPU(cpu
);
7911 CPUX86State
*env
= &cpu
->env
;
7912 DisasContext dc1
, *dc
= &dc1
;
7913 target_ulong pc_ptr
;
7917 target_ulong pc_start
;
7918 target_ulong cs_base
;
7922 /* generate intermediate code */
7924 cs_base
= tb
->cs_base
;
7927 dc
->pe
= (flags
>> HF_PE_SHIFT
) & 1;
7928 dc
->code32
= (flags
>> HF_CS32_SHIFT
) & 1;
7929 dc
->ss32
= (flags
>> HF_SS32_SHIFT
) & 1;
7930 dc
->addseg
= (flags
>> HF_ADDSEG_SHIFT
) & 1;
7932 dc
->vm86
= (flags
>> VM_SHIFT
) & 1;
7933 dc
->cpl
= (flags
>> HF_CPL_SHIFT
) & 3;
7934 dc
->iopl
= (flags
>> IOPL_SHIFT
) & 3;
7935 dc
->tf
= (flags
>> TF_SHIFT
) & 1;
7936 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
7937 dc
->cc_op
= CC_OP_DYNAMIC
;
7938 dc
->cc_op_dirty
= false;
7939 dc
->cs_base
= cs_base
;
7941 dc
->popl_esp_hack
= 0;
7942 /* select memory access functions */
7944 if (flags
& HF_SOFTMMU_MASK
) {
7945 dc
->mem_index
= cpu_mmu_index(env
, false);
7947 dc
->cpuid_features
= env
->features
[FEAT_1_EDX
];
7948 dc
->cpuid_ext_features
= env
->features
[FEAT_1_ECX
];
7949 dc
->cpuid_ext2_features
= env
->features
[FEAT_8000_0001_EDX
];
7950 dc
->cpuid_ext3_features
= env
->features
[FEAT_8000_0001_ECX
];
7951 dc
->cpuid_7_0_ebx_features
= env
->features
[FEAT_7_0_EBX
];
7952 #ifdef TARGET_X86_64
7953 dc
->lma
= (flags
>> HF_LMA_SHIFT
) & 1;
7954 dc
->code64
= (flags
>> HF_CS64_SHIFT
) & 1;
7957 dc
->jmp_opt
= !(dc
->tf
|| cs
->singlestep_enabled
||
7958 (flags
& HF_INHIBIT_IRQ_MASK
)
7959 #ifndef CONFIG_SOFTMMU
7960 || (flags
& HF_SOFTMMU_MASK
)
7963 /* Do not optimize repz jumps at all in icount mode, because
7964 rep movsS instructions are execured with different paths
7965 in !repz_opt and repz_opt modes. The first one was used
7966 always except single step mode. And this setting
7967 disables jumps optimization and control paths become
7968 equivalent in run and single step modes.
7969 Now there will be no jump optimization for repz in
7970 record/replay modes and there will always be an
7971 additional step for ecx=0 when icount is enabled.
7973 dc
->repz_opt
= !dc
->jmp_opt
&& !(tb
->cflags
& CF_USE_ICOUNT
);
7975 /* check addseg logic */
7976 if (!dc
->addseg
&& (dc
->vm86
|| !dc
->pe
|| !dc
->code32
))
7977 printf("ERROR addseg\n");
7980 cpu_T
[0] = tcg_temp_new();
7981 cpu_T
[1] = tcg_temp_new();
7982 cpu_A0
= tcg_temp_new();
7984 cpu_tmp0
= tcg_temp_new();
7985 cpu_tmp1_i64
= tcg_temp_new_i64();
7986 cpu_tmp2_i32
= tcg_temp_new_i32();
7987 cpu_tmp3_i32
= tcg_temp_new_i32();
7988 cpu_tmp4
= tcg_temp_new();
7989 cpu_ptr0
= tcg_temp_new_ptr();
7990 cpu_ptr1
= tcg_temp_new_ptr();
7991 cpu_cc_srcT
= tcg_temp_local_new();
7993 dc
->is_jmp
= DISAS_NEXT
;
7997 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
7999 max_insns
= CF_COUNT_MASK
;
8003 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
8004 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
8005 if (bp
->pc
== pc_ptr
&&
8006 !((bp
->flags
& BP_CPU
) && (tb
->flags
& HF_RF_MASK
))) {
8007 gen_debug(dc
, pc_ptr
- dc
->cs_base
);
8008 goto done_generating
;
8013 j
= tcg_op_buf_count();
8017 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
8019 tcg_ctx
.gen_opc_pc
[lj
] = pc_ptr
;
8020 gen_opc_cc_op
[lj
] = dc
->cc_op
;
8021 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
8022 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
8024 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
8027 pc_ptr
= disas_insn(env
, dc
, pc_ptr
);
8029 /* stop translation if indicated */
8032 /* if single step mode, we generate only one instruction and
8033 generate an exception */
8034 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
8035 the flag and abort the translation to give the irqs a
8036 change to be happen */
8037 if (dc
->tf
|| dc
->singlestep_enabled
||
8038 (flags
& HF_INHIBIT_IRQ_MASK
)) {
8039 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8043 /* Do not cross the boundary of the pages in icount mode,
8044 it can cause an exception. Do it only when boundary is
8045 crossed by the first instruction in the block.
8046 If current instruction already crossed the bound - it's ok,
8047 because an exception hasn't stopped this code.
8049 if ((tb
->cflags
& CF_USE_ICOUNT
)
8050 && ((pc_ptr
& TARGET_PAGE_MASK
)
8051 != ((pc_ptr
+ TARGET_MAX_INSN_SIZE
- 1) & TARGET_PAGE_MASK
)
8052 || (pc_ptr
& ~TARGET_PAGE_MASK
) == 0)) {
8053 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8057 /* if too long translation, stop generation too */
8058 if (tcg_op_buf_full() ||
8059 (pc_ptr
- pc_start
) >= (TARGET_PAGE_SIZE
- 32) ||
8060 num_insns
>= max_insns
) {
8061 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8066 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8071 if (tb
->cflags
& CF_LAST_IO
)
8074 gen_tb_end(tb
, num_insns
);
8076 /* we don't forget to fill the last values */
8078 j
= tcg_op_buf_count();
8081 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
8085 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
8087 qemu_log("----------------\n");
8088 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
8089 #ifdef TARGET_X86_64
8094 disas_flags
= !dc
->code32
;
8095 log_target_disas(cs
, pc_start
, pc_ptr
- pc_start
, disas_flags
);
8101 tb
->size
= pc_ptr
- pc_start
;
8102 tb
->icount
= num_insns
;
8106 void gen_intermediate_code(CPUX86State
*env
, TranslationBlock
*tb
)
8108 gen_intermediate_code_internal(x86_env_get_cpu(env
), tb
, false);
8111 void gen_intermediate_code_pc(CPUX86State
*env
, TranslationBlock
*tb
)
8113 gen_intermediate_code_internal(x86_env_get_cpu(env
), tb
, true);
8116 void restore_state_to_opc(CPUX86State
*env
, TranslationBlock
*tb
, int pc_pos
)
8120 if (qemu_loglevel_mask(CPU_LOG_TB_OP
)) {
8122 qemu_log("RESTORE:\n");
8123 for(i
= 0;i
<= pc_pos
; i
++) {
8124 if (tcg_ctx
.gen_opc_instr_start
[i
]) {
8125 qemu_log("0x%04x: " TARGET_FMT_lx
"\n", i
,
8126 tcg_ctx
.gen_opc_pc
[i
]);
8129 qemu_log("pc_pos=0x%x eip=" TARGET_FMT_lx
" cs_base=%x\n",
8130 pc_pos
, tcg_ctx
.gen_opc_pc
[pc_pos
] - tb
->cs_base
,
8131 (uint32_t)tb
->cs_base
);
8134 env
->eip
= tcg_ctx
.gen_opc_pc
[pc_pos
] - tb
->cs_base
;
8135 cc_op
= gen_opc_cc_op
[pc_pos
];
8136 if (cc_op
!= CC_OP_DYNAMIC
)