4 * Copyright (c) 2003 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 #include "qemu/osdep.h"
21 #include "qemu/host-utils.h"
23 #include "disas/disas.h"
24 #include "exec/exec-all.h"
26 #include "exec/cpu_ldst.h"
27 #include "exec/translator.h"
29 #include "exec/helper-proto.h"
30 #include "exec/helper-gen.h"
32 #include "trace-tcg.h"
35 #define PREFIX_REPZ 0x01
36 #define PREFIX_REPNZ 0x02
37 #define PREFIX_LOCK 0x04
38 #define PREFIX_DATA 0x08
39 #define PREFIX_ADR 0x10
40 #define PREFIX_VEX 0x20
43 #define CODE64(s) ((s)->code64)
44 #define REX_X(s) ((s)->rex_x)
45 #define REX_B(s) ((s)->rex_b)
60 /* For a switch indexed by MODRM, match all memory operands for a given OP. */
61 #define CASE_MODRM_MEM_OP(OP) \
62 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
63 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
64 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7
66 #define CASE_MODRM_OP(OP) \
67 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
68 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
69 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7: \
70 case (3 << 6) | (OP << 3) | 0 ... (3 << 6) | (OP << 3) | 7
72 //#define MACRO_TEST 1
74 /* global register indexes */
75 static TCGv_env cpu_env
;
77 static TCGv cpu_cc_dst
, cpu_cc_src
, cpu_cc_src2
, cpu_cc_srcT
;
78 static TCGv_i32 cpu_cc_op
;
79 static TCGv cpu_regs
[CPU_NB_REGS
];
80 static TCGv cpu_seg_base
[6];
81 static TCGv_i64 cpu_bndl
[4];
82 static TCGv_i64 cpu_bndu
[4];
84 static TCGv cpu_T0
, cpu_T1
;
85 /* local register indexes (only used inside old micro ops) */
86 static TCGv cpu_tmp0
, cpu_tmp4
;
87 static TCGv_ptr cpu_ptr0
, cpu_ptr1
;
88 static TCGv_i32 cpu_tmp2_i32
, cpu_tmp3_i32
;
89 static TCGv_i64 cpu_tmp1_i64
;
91 #include "exec/gen-icount.h"
94 static int x86_64_hregs
;
97 typedef struct DisasContext
{
98 DisasContextBase base
;
100 /* current insn context */
101 int override
; /* -1 if no override */
105 target_ulong pc_start
;
106 target_ulong pc
; /* pc = eip + cs_base */
107 /* current block context */
108 target_ulong cs_base
; /* base of CS segment */
109 int pe
; /* protected mode */
110 int code32
; /* 32 bit code segment */
112 int lma
; /* long mode active */
113 int code64
; /* 64 bit code segment */
116 int vex_l
; /* vex vector length */
117 int vex_v
; /* vex vvvv register, without 1's compliment. */
118 int ss32
; /* 32 bit stack segment */
119 CCOp cc_op
; /* current CC operation */
121 int addseg
; /* non zero if either DS/ES/SS have a non zero base */
122 int f_st
; /* currently unused */
123 int vm86
; /* vm86 mode */
126 int tf
; /* TF cpu flag */
127 int jmp_opt
; /* use direct block chaining for direct jumps */
128 int repz_opt
; /* optimize jumps within repz instructions */
129 int mem_index
; /* select memory access functions */
130 uint64_t flags
; /* all execution flags */
131 int popl_esp_hack
; /* for correct popl with esp base handling */
132 int rip_offset
; /* only used in x86_64, but left for simplicity */
134 int cpuid_ext_features
;
135 int cpuid_ext2_features
;
136 int cpuid_ext3_features
;
137 int cpuid_7_0_ebx_features
;
138 int cpuid_xsave_features
;
141 static void gen_eob(DisasContext
*s
);
142 static void gen_jr(DisasContext
*s
, TCGv dest
);
143 static void gen_jmp(DisasContext
*s
, target_ulong eip
);
144 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
);
145 static void gen_op(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
);
147 /* i386 arith/logic operations */
167 OP_SHL1
, /* undocumented */
183 /* I386 int registers */
184 OR_EAX
, /* MUST be even numbered */
193 OR_TMP0
= 16, /* temporary operand register */
195 OR_A0
, /* temporary register used when doing address evaluation */
205 /* Bit set if the global variable is live after setting CC_OP to X. */
206 static const uint8_t cc_op_live
[CC_OP_NB
] = {
207 [CC_OP_DYNAMIC
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
208 [CC_OP_EFLAGS
] = USES_CC_SRC
,
209 [CC_OP_MULB
... CC_OP_MULQ
] = USES_CC_DST
| USES_CC_SRC
,
210 [CC_OP_ADDB
... CC_OP_ADDQ
] = USES_CC_DST
| USES_CC_SRC
,
211 [CC_OP_ADCB
... CC_OP_ADCQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
212 [CC_OP_SUBB
... CC_OP_SUBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRCT
,
213 [CC_OP_SBBB
... CC_OP_SBBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
214 [CC_OP_LOGICB
... CC_OP_LOGICQ
] = USES_CC_DST
,
215 [CC_OP_INCB
... CC_OP_INCQ
] = USES_CC_DST
| USES_CC_SRC
,
216 [CC_OP_DECB
... CC_OP_DECQ
] = USES_CC_DST
| USES_CC_SRC
,
217 [CC_OP_SHLB
... CC_OP_SHLQ
] = USES_CC_DST
| USES_CC_SRC
,
218 [CC_OP_SARB
... CC_OP_SARQ
] = USES_CC_DST
| USES_CC_SRC
,
219 [CC_OP_BMILGB
... CC_OP_BMILGQ
] = USES_CC_DST
| USES_CC_SRC
,
220 [CC_OP_ADCX
] = USES_CC_DST
| USES_CC_SRC
,
221 [CC_OP_ADOX
] = USES_CC_SRC
| USES_CC_SRC2
,
222 [CC_OP_ADCOX
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
224 [CC_OP_POPCNT
] = USES_CC_SRC
,
227 static void set_cc_op(DisasContext
*s
, CCOp op
)
231 if (s
->cc_op
== op
) {
235 /* Discard CC computation that will no longer be used. */
236 dead
= cc_op_live
[s
->cc_op
] & ~cc_op_live
[op
];
237 if (dead
& USES_CC_DST
) {
238 tcg_gen_discard_tl(cpu_cc_dst
);
240 if (dead
& USES_CC_SRC
) {
241 tcg_gen_discard_tl(cpu_cc_src
);
243 if (dead
& USES_CC_SRC2
) {
244 tcg_gen_discard_tl(cpu_cc_src2
);
246 if (dead
& USES_CC_SRCT
) {
247 tcg_gen_discard_tl(cpu_cc_srcT
);
250 if (op
== CC_OP_DYNAMIC
) {
251 /* The DYNAMIC setting is translator only, and should never be
252 stored. Thus we always consider it clean. */
253 s
->cc_op_dirty
= false;
255 /* Discard any computed CC_OP value (see shifts). */
256 if (s
->cc_op
== CC_OP_DYNAMIC
) {
257 tcg_gen_discard_i32(cpu_cc_op
);
259 s
->cc_op_dirty
= true;
264 static void gen_update_cc_op(DisasContext
*s
)
266 if (s
->cc_op_dirty
) {
267 tcg_gen_movi_i32(cpu_cc_op
, s
->cc_op
);
268 s
->cc_op_dirty
= false;
274 #define NB_OP_SIZES 4
276 #else /* !TARGET_X86_64 */
278 #define NB_OP_SIZES 3
280 #endif /* !TARGET_X86_64 */
282 #if defined(HOST_WORDS_BIGENDIAN)
283 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
284 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
285 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
286 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
287 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
289 #define REG_B_OFFSET 0
290 #define REG_H_OFFSET 1
291 #define REG_W_OFFSET 0
292 #define REG_L_OFFSET 0
293 #define REG_LH_OFFSET 4
296 /* In instruction encodings for byte register accesses the
297 * register number usually indicates "low 8 bits of register N";
298 * however there are some special cases where N 4..7 indicates
299 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
300 * true for this special case, false otherwise.
302 static inline bool byte_reg_is_xH(int reg
)
308 if (reg
>= 8 || x86_64_hregs
) {
315 /* Select the size of a push/pop operation. */
316 static inline TCGMemOp
mo_pushpop(DisasContext
*s
, TCGMemOp ot
)
319 return ot
== MO_16
? MO_16
: MO_64
;
325 /* Select the size of the stack pointer. */
326 static inline TCGMemOp
mo_stacksize(DisasContext
*s
)
328 return CODE64(s
) ? MO_64
: s
->ss32
? MO_32
: MO_16
;
331 /* Select only size 64 else 32. Used for SSE operand sizes. */
332 static inline TCGMemOp
mo_64_32(TCGMemOp ot
)
335 return ot
== MO_64
? MO_64
: MO_32
;
341 /* Select size 8 if lsb of B is clear, else OT. Used for decoding
342 byte vs word opcodes. */
343 static inline TCGMemOp
mo_b_d(int b
, TCGMemOp ot
)
345 return b
& 1 ? ot
: MO_8
;
348 /* Select size 8 if lsb of B is clear, else OT capped at 32.
349 Used for decoding operand size of port opcodes. */
350 static inline TCGMemOp
mo_b_d32(int b
, TCGMemOp ot
)
352 return b
& 1 ? (ot
== MO_16
? MO_16
: MO_32
) : MO_8
;
355 static void gen_op_mov_reg_v(TCGMemOp ot
, int reg
, TCGv t0
)
359 if (!byte_reg_is_xH(reg
)) {
360 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 8);
362 tcg_gen_deposit_tl(cpu_regs
[reg
- 4], cpu_regs
[reg
- 4], t0
, 8, 8);
366 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 16);
369 /* For x86_64, this sets the higher half of register to zero.
370 For i386, this is equivalent to a mov. */
371 tcg_gen_ext32u_tl(cpu_regs
[reg
], t0
);
375 tcg_gen_mov_tl(cpu_regs
[reg
], t0
);
383 static inline void gen_op_mov_v_reg(TCGMemOp ot
, TCGv t0
, int reg
)
385 if (ot
== MO_8
&& byte_reg_is_xH(reg
)) {
386 tcg_gen_extract_tl(t0
, cpu_regs
[reg
- 4], 8, 8);
388 tcg_gen_mov_tl(t0
, cpu_regs
[reg
]);
392 static void gen_add_A0_im(DisasContext
*s
, int val
)
394 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, val
);
396 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
400 static inline void gen_op_jmp_v(TCGv dest
)
402 tcg_gen_st_tl(dest
, cpu_env
, offsetof(CPUX86State
, eip
));
405 static inline void gen_op_add_reg_im(TCGMemOp size
, int reg
, int32_t val
)
407 tcg_gen_addi_tl(cpu_tmp0
, cpu_regs
[reg
], val
);
408 gen_op_mov_reg_v(size
, reg
, cpu_tmp0
);
411 static inline void gen_op_add_reg_T0(TCGMemOp size
, int reg
)
413 tcg_gen_add_tl(cpu_tmp0
, cpu_regs
[reg
], cpu_T0
);
414 gen_op_mov_reg_v(size
, reg
, cpu_tmp0
);
417 static inline void gen_op_ld_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
419 tcg_gen_qemu_ld_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
422 static inline void gen_op_st_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
424 tcg_gen_qemu_st_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
427 static inline void gen_op_st_rm_T0_A0(DisasContext
*s
, int idx
, int d
)
430 gen_op_st_v(s
, idx
, cpu_T0
, cpu_A0
);
432 gen_op_mov_reg_v(idx
, d
, cpu_T0
);
436 static inline void gen_jmp_im(target_ulong pc
)
438 tcg_gen_movi_tl(cpu_tmp0
, pc
);
439 gen_op_jmp_v(cpu_tmp0
);
442 /* Compute SEG:REG into A0. SEG is selected from the override segment
443 (OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to
444 indicate no override. */
445 static void gen_lea_v_seg(DisasContext
*s
, TCGMemOp aflag
, TCGv a0
,
446 int def_seg
, int ovr_seg
)
452 tcg_gen_mov_tl(cpu_A0
, a0
);
459 if (ovr_seg
< 0 && s
->addseg
) {
463 tcg_gen_ext32u_tl(cpu_A0
, a0
);
469 tcg_gen_ext16u_tl(cpu_A0
, a0
);
484 TCGv seg
= cpu_seg_base
[ovr_seg
];
486 if (aflag
== MO_64
) {
487 tcg_gen_add_tl(cpu_A0
, a0
, seg
);
488 } else if (CODE64(s
)) {
489 tcg_gen_ext32u_tl(cpu_A0
, a0
);
490 tcg_gen_add_tl(cpu_A0
, cpu_A0
, seg
);
492 tcg_gen_add_tl(cpu_A0
, a0
, seg
);
493 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
498 static inline void gen_string_movl_A0_ESI(DisasContext
*s
)
500 gen_lea_v_seg(s
, s
->aflag
, cpu_regs
[R_ESI
], R_DS
, s
->override
);
503 static inline void gen_string_movl_A0_EDI(DisasContext
*s
)
505 gen_lea_v_seg(s
, s
->aflag
, cpu_regs
[R_EDI
], R_ES
, -1);
508 static inline void gen_op_movl_T0_Dshift(TCGMemOp ot
)
510 tcg_gen_ld32s_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, df
));
511 tcg_gen_shli_tl(cpu_T0
, cpu_T0
, ot
);
514 static TCGv
gen_ext_tl(TCGv dst
, TCGv src
, TCGMemOp size
, bool sign
)
519 tcg_gen_ext8s_tl(dst
, src
);
521 tcg_gen_ext8u_tl(dst
, src
);
526 tcg_gen_ext16s_tl(dst
, src
);
528 tcg_gen_ext16u_tl(dst
, src
);
534 tcg_gen_ext32s_tl(dst
, src
);
536 tcg_gen_ext32u_tl(dst
, src
);
545 static void gen_extu(TCGMemOp ot
, TCGv reg
)
547 gen_ext_tl(reg
, reg
, ot
, false);
550 static void gen_exts(TCGMemOp ot
, TCGv reg
)
552 gen_ext_tl(reg
, reg
, ot
, true);
555 static inline void gen_op_jnz_ecx(TCGMemOp size
, TCGLabel
*label1
)
557 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[R_ECX
]);
558 gen_extu(size
, cpu_tmp0
);
559 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_tmp0
, 0, label1
);
562 static inline void gen_op_jz_ecx(TCGMemOp size
, TCGLabel
*label1
)
564 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[R_ECX
]);
565 gen_extu(size
, cpu_tmp0
);
566 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
569 static void gen_helper_in_func(TCGMemOp ot
, TCGv v
, TCGv_i32 n
)
573 gen_helper_inb(v
, cpu_env
, n
);
576 gen_helper_inw(v
, cpu_env
, n
);
579 gen_helper_inl(v
, cpu_env
, n
);
586 static void gen_helper_out_func(TCGMemOp ot
, TCGv_i32 v
, TCGv_i32 n
)
590 gen_helper_outb(cpu_env
, v
, n
);
593 gen_helper_outw(cpu_env
, v
, n
);
596 gen_helper_outl(cpu_env
, v
, n
);
603 static void gen_check_io(DisasContext
*s
, TCGMemOp ot
, target_ulong cur_eip
,
606 target_ulong next_eip
;
608 if (s
->pe
&& (s
->cpl
> s
->iopl
|| s
->vm86
)) {
609 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
612 gen_helper_check_iob(cpu_env
, cpu_tmp2_i32
);
615 gen_helper_check_iow(cpu_env
, cpu_tmp2_i32
);
618 gen_helper_check_iol(cpu_env
, cpu_tmp2_i32
);
624 if(s
->flags
& HF_SVMI_MASK
) {
627 svm_flags
|= (1 << (4 + ot
));
628 next_eip
= s
->pc
- s
->cs_base
;
629 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
630 gen_helper_svm_check_io(cpu_env
, cpu_tmp2_i32
,
631 tcg_const_i32(svm_flags
),
632 tcg_const_i32(next_eip
- cur_eip
));
636 static inline void gen_movs(DisasContext
*s
, TCGMemOp ot
)
638 gen_string_movl_A0_ESI(s
);
639 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
640 gen_string_movl_A0_EDI(s
);
641 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
642 gen_op_movl_T0_Dshift(ot
);
643 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
644 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
647 static void gen_op_update1_cc(void)
649 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
652 static void gen_op_update2_cc(void)
654 tcg_gen_mov_tl(cpu_cc_src
, cpu_T1
);
655 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
658 static void gen_op_update3_cc(TCGv reg
)
660 tcg_gen_mov_tl(cpu_cc_src2
, reg
);
661 tcg_gen_mov_tl(cpu_cc_src
, cpu_T1
);
662 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
665 static inline void gen_op_testl_T0_T1_cc(void)
667 tcg_gen_and_tl(cpu_cc_dst
, cpu_T0
, cpu_T1
);
670 static void gen_op_update_neg_cc(void)
672 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
673 tcg_gen_neg_tl(cpu_cc_src
, cpu_T0
);
674 tcg_gen_movi_tl(cpu_cc_srcT
, 0);
677 /* compute all eflags to cc_src */
678 static void gen_compute_eflags(DisasContext
*s
)
680 TCGv zero
, dst
, src1
, src2
;
683 if (s
->cc_op
== CC_OP_EFLAGS
) {
686 if (s
->cc_op
== CC_OP_CLR
) {
687 tcg_gen_movi_tl(cpu_cc_src
, CC_Z
| CC_P
);
688 set_cc_op(s
, CC_OP_EFLAGS
);
697 /* Take care to not read values that are not live. */
698 live
= cc_op_live
[s
->cc_op
] & ~USES_CC_SRCT
;
699 dead
= live
^ (USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
);
701 zero
= tcg_const_tl(0);
702 if (dead
& USES_CC_DST
) {
705 if (dead
& USES_CC_SRC
) {
708 if (dead
& USES_CC_SRC2
) {
714 gen_helper_cc_compute_all(cpu_cc_src
, dst
, src1
, src2
, cpu_cc_op
);
715 set_cc_op(s
, CC_OP_EFLAGS
);
722 typedef struct CCPrepare
{
732 /* compute eflags.C to reg */
733 static CCPrepare
gen_prepare_eflags_c(DisasContext
*s
, TCGv reg
)
739 case CC_OP_SUBB
... CC_OP_SUBQ
:
740 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
741 size
= s
->cc_op
- CC_OP_SUBB
;
742 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
743 /* If no temporary was used, be careful not to alias t1 and t0. */
744 t0
= TCGV_EQUAL(t1
, cpu_cc_src
) ? cpu_tmp0
: reg
;
745 tcg_gen_mov_tl(t0
, cpu_cc_srcT
);
749 case CC_OP_ADDB
... CC_OP_ADDQ
:
750 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
751 size
= s
->cc_op
- CC_OP_ADDB
;
752 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
753 t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
755 return (CCPrepare
) { .cond
= TCG_COND_LTU
, .reg
= t0
,
756 .reg2
= t1
, .mask
= -1, .use_reg2
= true };
758 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
761 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
763 case CC_OP_INCB
... CC_OP_INCQ
:
764 case CC_OP_DECB
... CC_OP_DECQ
:
765 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
766 .mask
= -1, .no_setcond
= true };
768 case CC_OP_SHLB
... CC_OP_SHLQ
:
769 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
770 size
= s
->cc_op
- CC_OP_SHLB
;
771 shift
= (8 << size
) - 1;
772 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
773 .mask
= (target_ulong
)1 << shift
};
775 case CC_OP_MULB
... CC_OP_MULQ
:
776 return (CCPrepare
) { .cond
= TCG_COND_NE
,
777 .reg
= cpu_cc_src
, .mask
= -1 };
779 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
780 size
= s
->cc_op
- CC_OP_BMILGB
;
781 t0
= gen_ext_tl(reg
, cpu_cc_src
, size
, false);
782 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
786 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_dst
,
787 .mask
= -1, .no_setcond
= true };
790 case CC_OP_SARB
... CC_OP_SARQ
:
792 return (CCPrepare
) { .cond
= TCG_COND_NE
,
793 .reg
= cpu_cc_src
, .mask
= CC_C
};
796 /* The need to compute only C from CC_OP_DYNAMIC is important
797 in efficiently implementing e.g. INC at the start of a TB. */
799 gen_helper_cc_compute_c(reg
, cpu_cc_dst
, cpu_cc_src
,
800 cpu_cc_src2
, cpu_cc_op
);
801 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
802 .mask
= -1, .no_setcond
= true };
806 /* compute eflags.P to reg */
807 static CCPrepare
gen_prepare_eflags_p(DisasContext
*s
, TCGv reg
)
809 gen_compute_eflags(s
);
810 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
814 /* compute eflags.S to reg */
815 static CCPrepare
gen_prepare_eflags_s(DisasContext
*s
, TCGv reg
)
819 gen_compute_eflags(s
);
825 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
829 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
832 TCGMemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
833 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, true);
834 return (CCPrepare
) { .cond
= TCG_COND_LT
, .reg
= t0
, .mask
= -1 };
839 /* compute eflags.O to reg */
840 static CCPrepare
gen_prepare_eflags_o(DisasContext
*s
, TCGv reg
)
845 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src2
,
846 .mask
= -1, .no_setcond
= true };
849 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
851 gen_compute_eflags(s
);
852 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
857 /* compute eflags.Z to reg */
858 static CCPrepare
gen_prepare_eflags_z(DisasContext
*s
, TCGv reg
)
862 gen_compute_eflags(s
);
868 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
871 return (CCPrepare
) { .cond
= TCG_COND_ALWAYS
, .mask
= -1 };
873 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= cpu_cc_src
,
877 TCGMemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
878 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
879 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
884 /* perform a conditional store into register 'reg' according to jump opcode
885 value 'b'. In the fast case, T0 is guaranted not to be used. */
886 static CCPrepare
gen_prepare_cc(DisasContext
*s
, int b
, TCGv reg
)
888 int inv
, jcc_op
, cond
;
894 jcc_op
= (b
>> 1) & 7;
897 case CC_OP_SUBB
... CC_OP_SUBQ
:
898 /* We optimize relational operators for the cmp/jcc case. */
899 size
= s
->cc_op
- CC_OP_SUBB
;
902 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
903 gen_extu(size
, cpu_tmp4
);
904 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
905 cc
= (CCPrepare
) { .cond
= TCG_COND_LEU
, .reg
= cpu_tmp4
,
906 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
915 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
916 gen_exts(size
, cpu_tmp4
);
917 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, true);
918 cc
= (CCPrepare
) { .cond
= cond
, .reg
= cpu_tmp4
,
919 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
929 /* This actually generates good code for JC, JZ and JS. */
932 cc
= gen_prepare_eflags_o(s
, reg
);
935 cc
= gen_prepare_eflags_c(s
, reg
);
938 cc
= gen_prepare_eflags_z(s
, reg
);
941 gen_compute_eflags(s
);
942 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
943 .mask
= CC_Z
| CC_C
};
946 cc
= gen_prepare_eflags_s(s
, reg
);
949 cc
= gen_prepare_eflags_p(s
, reg
);
952 gen_compute_eflags(s
);
953 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
956 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
957 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
958 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
963 gen_compute_eflags(s
);
964 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
967 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
968 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
969 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
970 .mask
= CC_S
| CC_Z
};
977 cc
.cond
= tcg_invert_cond(cc
.cond
);
982 static void gen_setcc1(DisasContext
*s
, int b
, TCGv reg
)
984 CCPrepare cc
= gen_prepare_cc(s
, b
, reg
);
987 if (cc
.cond
== TCG_COND_EQ
) {
988 tcg_gen_xori_tl(reg
, cc
.reg
, 1);
990 tcg_gen_mov_tl(reg
, cc
.reg
);
995 if (cc
.cond
== TCG_COND_NE
&& !cc
.use_reg2
&& cc
.imm
== 0 &&
996 cc
.mask
!= 0 && (cc
.mask
& (cc
.mask
- 1)) == 0) {
997 tcg_gen_shri_tl(reg
, cc
.reg
, ctztl(cc
.mask
));
998 tcg_gen_andi_tl(reg
, reg
, 1);
1001 if (cc
.mask
!= -1) {
1002 tcg_gen_andi_tl(reg
, cc
.reg
, cc
.mask
);
1006 tcg_gen_setcond_tl(cc
.cond
, reg
, cc
.reg
, cc
.reg2
);
1008 tcg_gen_setcondi_tl(cc
.cond
, reg
, cc
.reg
, cc
.imm
);
1012 static inline void gen_compute_eflags_c(DisasContext
*s
, TCGv reg
)
1014 gen_setcc1(s
, JCC_B
<< 1, reg
);
1017 /* generate a conditional jump to label 'l1' according to jump opcode
1018 value 'b'. In the fast case, T0 is guaranted not to be used. */
1019 static inline void gen_jcc1_noeob(DisasContext
*s
, int b
, TCGLabel
*l1
)
1021 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T0
);
1023 if (cc
.mask
!= -1) {
1024 tcg_gen_andi_tl(cpu_T0
, cc
.reg
, cc
.mask
);
1028 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1030 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1034 /* Generate a conditional jump to label 'l1' according to jump opcode
1035 value 'b'. In the fast case, T0 is guaranted not to be used.
1036 A translation block must end soon. */
1037 static inline void gen_jcc1(DisasContext
*s
, int b
, TCGLabel
*l1
)
1039 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T0
);
1041 gen_update_cc_op(s
);
1042 if (cc
.mask
!= -1) {
1043 tcg_gen_andi_tl(cpu_T0
, cc
.reg
, cc
.mask
);
1046 set_cc_op(s
, CC_OP_DYNAMIC
);
1048 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1050 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1054 /* XXX: does not work with gdbstub "ice" single step - not a
1056 static TCGLabel
*gen_jz_ecx_string(DisasContext
*s
, target_ulong next_eip
)
1058 TCGLabel
*l1
= gen_new_label();
1059 TCGLabel
*l2
= gen_new_label();
1060 gen_op_jnz_ecx(s
->aflag
, l1
);
1062 gen_jmp_tb(s
, next_eip
, 1);
1067 static inline void gen_stos(DisasContext
*s
, TCGMemOp ot
)
1069 gen_op_mov_v_reg(MO_32
, cpu_T0
, R_EAX
);
1070 gen_string_movl_A0_EDI(s
);
1071 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
1072 gen_op_movl_T0_Dshift(ot
);
1073 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1076 static inline void gen_lods(DisasContext
*s
, TCGMemOp ot
)
1078 gen_string_movl_A0_ESI(s
);
1079 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1080 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T0
);
1081 gen_op_movl_T0_Dshift(ot
);
1082 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1085 static inline void gen_scas(DisasContext
*s
, TCGMemOp ot
)
1087 gen_string_movl_A0_EDI(s
);
1088 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
1089 gen_op(s
, OP_CMPL
, ot
, R_EAX
);
1090 gen_op_movl_T0_Dshift(ot
);
1091 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1094 static inline void gen_cmps(DisasContext
*s
, TCGMemOp ot
)
1096 gen_string_movl_A0_EDI(s
);
1097 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
1098 gen_string_movl_A0_ESI(s
);
1099 gen_op(s
, OP_CMPL
, ot
, OR_TMP0
);
1100 gen_op_movl_T0_Dshift(ot
);
1101 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1102 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1105 static void gen_bpt_io(DisasContext
*s
, TCGv_i32 t_port
, int ot
)
1107 if (s
->flags
& HF_IOBPT_MASK
) {
1108 TCGv_i32 t_size
= tcg_const_i32(1 << ot
);
1109 TCGv t_next
= tcg_const_tl(s
->pc
- s
->cs_base
);
1111 gen_helper_bpt_io(cpu_env
, t_port
, t_size
, t_next
);
1112 tcg_temp_free_i32(t_size
);
1113 tcg_temp_free(t_next
);
1118 static inline void gen_ins(DisasContext
*s
, TCGMemOp ot
)
1120 if (s
->base
.tb
->cflags
& CF_USE_ICOUNT
) {
1123 gen_string_movl_A0_EDI(s
);
1124 /* Note: we must do this dummy write first to be restartable in
1125 case of page fault. */
1126 tcg_gen_movi_tl(cpu_T0
, 0);
1127 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
1128 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_EDX
]);
1129 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1130 gen_helper_in_func(ot
, cpu_T0
, cpu_tmp2_i32
);
1131 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
1132 gen_op_movl_T0_Dshift(ot
);
1133 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1134 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
1135 if (s
->base
.tb
->cflags
& CF_USE_ICOUNT
) {
1140 static inline void gen_outs(DisasContext
*s
, TCGMemOp ot
)
1142 if (s
->base
.tb
->cflags
& CF_USE_ICOUNT
) {
1145 gen_string_movl_A0_ESI(s
);
1146 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1148 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_EDX
]);
1149 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1150 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T0
);
1151 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1152 gen_op_movl_T0_Dshift(ot
);
1153 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1154 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
1155 if (s
->base
.tb
->cflags
& CF_USE_ICOUNT
) {
1160 /* same method as Valgrind : we generate jumps to current or next
1162 #define GEN_REPZ(op) \
1163 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1164 target_ulong cur_eip, target_ulong next_eip) \
1167 gen_update_cc_op(s); \
1168 l2 = gen_jz_ecx_string(s, next_eip); \
1169 gen_ ## op(s, ot); \
1170 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1171 /* a loop would cause two single step exceptions if ECX = 1 \
1172 before rep string_insn */ \
1174 gen_op_jz_ecx(s->aflag, l2); \
1175 gen_jmp(s, cur_eip); \
1178 #define GEN_REPZ2(op) \
1179 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1180 target_ulong cur_eip, \
1181 target_ulong next_eip, \
1185 gen_update_cc_op(s); \
1186 l2 = gen_jz_ecx_string(s, next_eip); \
1187 gen_ ## op(s, ot); \
1188 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1189 gen_update_cc_op(s); \
1190 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
1192 gen_op_jz_ecx(s->aflag, l2); \
1193 gen_jmp(s, cur_eip); \
1204 static void gen_helper_fp_arith_ST0_FT0(int op
)
1208 gen_helper_fadd_ST0_FT0(cpu_env
);
1211 gen_helper_fmul_ST0_FT0(cpu_env
);
1214 gen_helper_fcom_ST0_FT0(cpu_env
);
1217 gen_helper_fcom_ST0_FT0(cpu_env
);
1220 gen_helper_fsub_ST0_FT0(cpu_env
);
1223 gen_helper_fsubr_ST0_FT0(cpu_env
);
1226 gen_helper_fdiv_ST0_FT0(cpu_env
);
1229 gen_helper_fdivr_ST0_FT0(cpu_env
);
1234 /* NOTE the exception in "r" op ordering */
1235 static void gen_helper_fp_arith_STN_ST0(int op
, int opreg
)
1237 TCGv_i32 tmp
= tcg_const_i32(opreg
);
1240 gen_helper_fadd_STN_ST0(cpu_env
, tmp
);
1243 gen_helper_fmul_STN_ST0(cpu_env
, tmp
);
1246 gen_helper_fsubr_STN_ST0(cpu_env
, tmp
);
1249 gen_helper_fsub_STN_ST0(cpu_env
, tmp
);
1252 gen_helper_fdivr_STN_ST0(cpu_env
, tmp
);
1255 gen_helper_fdiv_STN_ST0(cpu_env
, tmp
);
1260 /* if d == OR_TMP0, it means memory operand (address in A0) */
1261 static void gen_op(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
)
1264 gen_op_mov_v_reg(ot
, cpu_T0
, d
);
1265 } else if (!(s1
->prefix
& PREFIX_LOCK
)) {
1266 gen_op_ld_v(s1
, ot
, cpu_T0
, cpu_A0
);
1270 gen_compute_eflags_c(s1
, cpu_tmp4
);
1271 if (s1
->prefix
& PREFIX_LOCK
) {
1272 tcg_gen_add_tl(cpu_T0
, cpu_tmp4
, cpu_T1
);
1273 tcg_gen_atomic_add_fetch_tl(cpu_T0
, cpu_A0
, cpu_T0
,
1274 s1
->mem_index
, ot
| MO_LE
);
1276 tcg_gen_add_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1277 tcg_gen_add_tl(cpu_T0
, cpu_T0
, cpu_tmp4
);
1278 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1280 gen_op_update3_cc(cpu_tmp4
);
1281 set_cc_op(s1
, CC_OP_ADCB
+ ot
);
1284 gen_compute_eflags_c(s1
, cpu_tmp4
);
1285 if (s1
->prefix
& PREFIX_LOCK
) {
1286 tcg_gen_add_tl(cpu_T0
, cpu_T1
, cpu_tmp4
);
1287 tcg_gen_neg_tl(cpu_T0
, cpu_T0
);
1288 tcg_gen_atomic_add_fetch_tl(cpu_T0
, cpu_A0
, cpu_T0
,
1289 s1
->mem_index
, ot
| MO_LE
);
1291 tcg_gen_sub_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1292 tcg_gen_sub_tl(cpu_T0
, cpu_T0
, cpu_tmp4
);
1293 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1295 gen_op_update3_cc(cpu_tmp4
);
1296 set_cc_op(s1
, CC_OP_SBBB
+ ot
);
1299 if (s1
->prefix
& PREFIX_LOCK
) {
1300 tcg_gen_atomic_add_fetch_tl(cpu_T0
, cpu_A0
, cpu_T1
,
1301 s1
->mem_index
, ot
| MO_LE
);
1303 tcg_gen_add_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1304 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1306 gen_op_update2_cc();
1307 set_cc_op(s1
, CC_OP_ADDB
+ ot
);
1310 if (s1
->prefix
& PREFIX_LOCK
) {
1311 tcg_gen_neg_tl(cpu_T0
, cpu_T1
);
1312 tcg_gen_atomic_fetch_add_tl(cpu_cc_srcT
, cpu_A0
, cpu_T0
,
1313 s1
->mem_index
, ot
| MO_LE
);
1314 tcg_gen_sub_tl(cpu_T0
, cpu_cc_srcT
, cpu_T1
);
1316 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T0
);
1317 tcg_gen_sub_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1318 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1320 gen_op_update2_cc();
1321 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1325 if (s1
->prefix
& PREFIX_LOCK
) {
1326 tcg_gen_atomic_and_fetch_tl(cpu_T0
, cpu_A0
, cpu_T1
,
1327 s1
->mem_index
, ot
| MO_LE
);
1329 tcg_gen_and_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1330 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1332 gen_op_update1_cc();
1333 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1336 if (s1
->prefix
& PREFIX_LOCK
) {
1337 tcg_gen_atomic_or_fetch_tl(cpu_T0
, cpu_A0
, cpu_T1
,
1338 s1
->mem_index
, ot
| MO_LE
);
1340 tcg_gen_or_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1341 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1343 gen_op_update1_cc();
1344 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1347 if (s1
->prefix
& PREFIX_LOCK
) {
1348 tcg_gen_atomic_xor_fetch_tl(cpu_T0
, cpu_A0
, cpu_T1
,
1349 s1
->mem_index
, ot
| MO_LE
);
1351 tcg_gen_xor_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1352 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1354 gen_op_update1_cc();
1355 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1358 tcg_gen_mov_tl(cpu_cc_src
, cpu_T1
);
1359 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T0
);
1360 tcg_gen_sub_tl(cpu_cc_dst
, cpu_T0
, cpu_T1
);
1361 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1366 /* if d == OR_TMP0, it means memory operand (address in A0) */
1367 static void gen_inc(DisasContext
*s1
, TCGMemOp ot
, int d
, int c
)
1369 if (s1
->prefix
& PREFIX_LOCK
) {
1370 tcg_gen_movi_tl(cpu_T0
, c
> 0 ? 1 : -1);
1371 tcg_gen_atomic_add_fetch_tl(cpu_T0
, cpu_A0
, cpu_T0
,
1372 s1
->mem_index
, ot
| MO_LE
);
1375 gen_op_mov_v_reg(ot
, cpu_T0
, d
);
1377 gen_op_ld_v(s1
, ot
, cpu_T0
, cpu_A0
);
1379 tcg_gen_addi_tl(cpu_T0
, cpu_T0
, (c
> 0 ? 1 : -1));
1380 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1383 gen_compute_eflags_c(s1
, cpu_cc_src
);
1384 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
1385 set_cc_op(s1
, (c
> 0 ? CC_OP_INCB
: CC_OP_DECB
) + ot
);
1388 static void gen_shift_flags(DisasContext
*s
, TCGMemOp ot
, TCGv result
,
1389 TCGv shm1
, TCGv count
, bool is_right
)
1391 TCGv_i32 z32
, s32
, oldop
;
1394 /* Store the results into the CC variables. If we know that the
1395 variable must be dead, store unconditionally. Otherwise we'll
1396 need to not disrupt the current contents. */
1397 z_tl
= tcg_const_tl(0);
1398 if (cc_op_live
[s
->cc_op
] & USES_CC_DST
) {
1399 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_dst
, count
, z_tl
,
1400 result
, cpu_cc_dst
);
1402 tcg_gen_mov_tl(cpu_cc_dst
, result
);
1404 if (cc_op_live
[s
->cc_op
] & USES_CC_SRC
) {
1405 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_src
, count
, z_tl
,
1408 tcg_gen_mov_tl(cpu_cc_src
, shm1
);
1410 tcg_temp_free(z_tl
);
1412 /* Get the two potential CC_OP values into temporaries. */
1413 tcg_gen_movi_i32(cpu_tmp2_i32
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1414 if (s
->cc_op
== CC_OP_DYNAMIC
) {
1417 tcg_gen_movi_i32(cpu_tmp3_i32
, s
->cc_op
);
1418 oldop
= cpu_tmp3_i32
;
1421 /* Conditionally store the CC_OP value. */
1422 z32
= tcg_const_i32(0);
1423 s32
= tcg_temp_new_i32();
1424 tcg_gen_trunc_tl_i32(s32
, count
);
1425 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, s32
, z32
, cpu_tmp2_i32
, oldop
);
1426 tcg_temp_free_i32(z32
);
1427 tcg_temp_free_i32(s32
);
1429 /* The CC_OP value is no longer predictable. */
1430 set_cc_op(s
, CC_OP_DYNAMIC
);
1433 static void gen_shift_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1434 int is_right
, int is_arith
)
1436 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1439 if (op1
== OR_TMP0
) {
1440 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1442 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1445 tcg_gen_andi_tl(cpu_T1
, cpu_T1
, mask
);
1446 tcg_gen_subi_tl(cpu_tmp0
, cpu_T1
, 1);
1450 gen_exts(ot
, cpu_T0
);
1451 tcg_gen_sar_tl(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1452 tcg_gen_sar_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1454 gen_extu(ot
, cpu_T0
);
1455 tcg_gen_shr_tl(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1456 tcg_gen_shr_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1459 tcg_gen_shl_tl(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1460 tcg_gen_shl_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1464 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1466 gen_shift_flags(s
, ot
, cpu_T0
, cpu_tmp0
, cpu_T1
, is_right
);
1469 static void gen_shift_rm_im(DisasContext
*s
, TCGMemOp ot
, int op1
, int op2
,
1470 int is_right
, int is_arith
)
1472 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1476 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1478 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1484 gen_exts(ot
, cpu_T0
);
1485 tcg_gen_sari_tl(cpu_tmp4
, cpu_T0
, op2
- 1);
1486 tcg_gen_sari_tl(cpu_T0
, cpu_T0
, op2
);
1488 gen_extu(ot
, cpu_T0
);
1489 tcg_gen_shri_tl(cpu_tmp4
, cpu_T0
, op2
- 1);
1490 tcg_gen_shri_tl(cpu_T0
, cpu_T0
, op2
);
1493 tcg_gen_shli_tl(cpu_tmp4
, cpu_T0
, op2
- 1);
1494 tcg_gen_shli_tl(cpu_T0
, cpu_T0
, op2
);
1499 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1501 /* update eflags if non zero shift */
1503 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
1504 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
1505 set_cc_op(s
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1509 static void gen_rot_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
, int is_right
)
1511 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1515 if (op1
== OR_TMP0
) {
1516 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1518 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1521 tcg_gen_andi_tl(cpu_T1
, cpu_T1
, mask
);
1525 /* Replicate the 8-bit input so that a 32-bit rotate works. */
1526 tcg_gen_ext8u_tl(cpu_T0
, cpu_T0
);
1527 tcg_gen_muli_tl(cpu_T0
, cpu_T0
, 0x01010101);
1530 /* Replicate the 16-bit input so that a 32-bit rotate works. */
1531 tcg_gen_deposit_tl(cpu_T0
, cpu_T0
, cpu_T0
, 16, 16);
1534 #ifdef TARGET_X86_64
1536 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
1537 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T1
);
1539 tcg_gen_rotr_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1541 tcg_gen_rotl_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1543 tcg_gen_extu_i32_tl(cpu_T0
, cpu_tmp2_i32
);
1548 tcg_gen_rotr_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1550 tcg_gen_rotl_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1556 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1558 /* We'll need the flags computed into CC_SRC. */
1559 gen_compute_eflags(s
);
1561 /* The value that was "rotated out" is now present at the other end
1562 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1563 since we've computed the flags into CC_SRC, these variables are
1566 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T0
, mask
- 1);
1567 tcg_gen_shri_tl(cpu_cc_dst
, cpu_T0
, mask
);
1568 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1570 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T0
, mask
);
1571 tcg_gen_andi_tl(cpu_cc_dst
, cpu_T0
, 1);
1573 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1574 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1576 /* Now conditionally store the new CC_OP value. If the shift count
1577 is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1578 Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1579 exactly as we computed above. */
1580 t0
= tcg_const_i32(0);
1581 t1
= tcg_temp_new_i32();
1582 tcg_gen_trunc_tl_i32(t1
, cpu_T1
);
1583 tcg_gen_movi_i32(cpu_tmp2_i32
, CC_OP_ADCOX
);
1584 tcg_gen_movi_i32(cpu_tmp3_i32
, CC_OP_EFLAGS
);
1585 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, t1
, t0
,
1586 cpu_tmp2_i32
, cpu_tmp3_i32
);
1587 tcg_temp_free_i32(t0
);
1588 tcg_temp_free_i32(t1
);
1590 /* The CC_OP value is no longer predictable. */
1591 set_cc_op(s
, CC_OP_DYNAMIC
);
1594 static void gen_rot_rm_im(DisasContext
*s
, TCGMemOp ot
, int op1
, int op2
,
1597 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1601 if (op1
== OR_TMP0
) {
1602 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1604 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1610 #ifdef TARGET_X86_64
1612 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
1614 tcg_gen_rotri_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, op2
);
1616 tcg_gen_rotli_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, op2
);
1618 tcg_gen_extu_i32_tl(cpu_T0
, cpu_tmp2_i32
);
1623 tcg_gen_rotri_tl(cpu_T0
, cpu_T0
, op2
);
1625 tcg_gen_rotli_tl(cpu_T0
, cpu_T0
, op2
);
1636 shift
= mask
+ 1 - shift
;
1638 gen_extu(ot
, cpu_T0
);
1639 tcg_gen_shli_tl(cpu_tmp0
, cpu_T0
, shift
);
1640 tcg_gen_shri_tl(cpu_T0
, cpu_T0
, mask
+ 1 - shift
);
1641 tcg_gen_or_tl(cpu_T0
, cpu_T0
, cpu_tmp0
);
1647 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1650 /* Compute the flags into CC_SRC. */
1651 gen_compute_eflags(s
);
1653 /* The value that was "rotated out" is now present at the other end
1654 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1655 since we've computed the flags into CC_SRC, these variables are
1658 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T0
, mask
- 1);
1659 tcg_gen_shri_tl(cpu_cc_dst
, cpu_T0
, mask
);
1660 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1662 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T0
, mask
);
1663 tcg_gen_andi_tl(cpu_cc_dst
, cpu_T0
, 1);
1665 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1666 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1667 set_cc_op(s
, CC_OP_ADCOX
);
1671 /* XXX: add faster immediate = 1 case */
1672 static void gen_rotc_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1675 gen_compute_eflags(s
);
1676 assert(s
->cc_op
== CC_OP_EFLAGS
);
1680 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1682 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1687 gen_helper_rcrb(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1690 gen_helper_rcrw(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1693 gen_helper_rcrl(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1695 #ifdef TARGET_X86_64
1697 gen_helper_rcrq(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1706 gen_helper_rclb(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1709 gen_helper_rclw(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1712 gen_helper_rcll(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1714 #ifdef TARGET_X86_64
1716 gen_helper_rclq(cpu_T0
, cpu_env
, cpu_T0
, cpu_T1
);
1724 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1727 /* XXX: add faster immediate case */
1728 static void gen_shiftd_rm_T1(DisasContext
*s
, TCGMemOp ot
, int op1
,
1729 bool is_right
, TCGv count_in
)
1731 target_ulong mask
= (ot
== MO_64
? 63 : 31);
1735 if (op1
== OR_TMP0
) {
1736 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
1738 gen_op_mov_v_reg(ot
, cpu_T0
, op1
);
1741 count
= tcg_temp_new();
1742 tcg_gen_andi_tl(count
, count_in
, mask
);
1746 /* Note: we implement the Intel behaviour for shift count > 16.
1747 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A
1748 portion by constructing it as a 32-bit value. */
1750 tcg_gen_deposit_tl(cpu_tmp0
, cpu_T0
, cpu_T1
, 16, 16);
1751 tcg_gen_mov_tl(cpu_T1
, cpu_T0
);
1752 tcg_gen_mov_tl(cpu_T0
, cpu_tmp0
);
1754 tcg_gen_deposit_tl(cpu_T1
, cpu_T0
, cpu_T1
, 16, 16);
1757 #ifdef TARGET_X86_64
1759 /* Concatenate the two 32-bit values and use a 64-bit shift. */
1760 tcg_gen_subi_tl(cpu_tmp0
, count
, 1);
1762 tcg_gen_concat_tl_i64(cpu_T0
, cpu_T0
, cpu_T1
);
1763 tcg_gen_shr_i64(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1764 tcg_gen_shr_i64(cpu_T0
, cpu_T0
, count
);
1766 tcg_gen_concat_tl_i64(cpu_T0
, cpu_T1
, cpu_T0
);
1767 tcg_gen_shl_i64(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1768 tcg_gen_shl_i64(cpu_T0
, cpu_T0
, count
);
1769 tcg_gen_shri_i64(cpu_tmp0
, cpu_tmp0
, 32);
1770 tcg_gen_shri_i64(cpu_T0
, cpu_T0
, 32);
1775 tcg_gen_subi_tl(cpu_tmp0
, count
, 1);
1777 tcg_gen_shr_tl(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1779 tcg_gen_subfi_tl(cpu_tmp4
, mask
+ 1, count
);
1780 tcg_gen_shr_tl(cpu_T0
, cpu_T0
, count
);
1781 tcg_gen_shl_tl(cpu_T1
, cpu_T1
, cpu_tmp4
);
1783 tcg_gen_shl_tl(cpu_tmp0
, cpu_T0
, cpu_tmp0
);
1785 /* Only needed if count > 16, for Intel behaviour. */
1786 tcg_gen_subfi_tl(cpu_tmp4
, 33, count
);
1787 tcg_gen_shr_tl(cpu_tmp4
, cpu_T1
, cpu_tmp4
);
1788 tcg_gen_or_tl(cpu_tmp0
, cpu_tmp0
, cpu_tmp4
);
1791 tcg_gen_subfi_tl(cpu_tmp4
, mask
+ 1, count
);
1792 tcg_gen_shl_tl(cpu_T0
, cpu_T0
, count
);
1793 tcg_gen_shr_tl(cpu_T1
, cpu_T1
, cpu_tmp4
);
1795 tcg_gen_movi_tl(cpu_tmp4
, 0);
1796 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_T1
, count
, cpu_tmp4
,
1798 tcg_gen_or_tl(cpu_T0
, cpu_T0
, cpu_T1
);
1803 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1805 gen_shift_flags(s
, ot
, cpu_T0
, cpu_tmp0
, count
, is_right
);
1806 tcg_temp_free(count
);
1809 static void gen_shift(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
, int s
)
1812 gen_op_mov_v_reg(ot
, cpu_T1
, s
);
1815 gen_rot_rm_T1(s1
, ot
, d
, 0);
1818 gen_rot_rm_T1(s1
, ot
, d
, 1);
1822 gen_shift_rm_T1(s1
, ot
, d
, 0, 0);
1825 gen_shift_rm_T1(s1
, ot
, d
, 1, 0);
1828 gen_shift_rm_T1(s1
, ot
, d
, 1, 1);
1831 gen_rotc_rm_T1(s1
, ot
, d
, 0);
1834 gen_rotc_rm_T1(s1
, ot
, d
, 1);
1839 static void gen_shifti(DisasContext
*s1
, int op
, TCGMemOp ot
, int d
, int c
)
1843 gen_rot_rm_im(s1
, ot
, d
, c
, 0);
1846 gen_rot_rm_im(s1
, ot
, d
, c
, 1);
1850 gen_shift_rm_im(s1
, ot
, d
, c
, 0, 0);
1853 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 0);
1856 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 1);
1859 /* currently not optimized */
1860 tcg_gen_movi_tl(cpu_T1
, c
);
1861 gen_shift(s1
, op
, ot
, d
, OR_TMP1
);
1866 /* Decompose an address. */
1868 typedef struct AddressParts
{
1876 static AddressParts
gen_lea_modrm_0(CPUX86State
*env
, DisasContext
*s
,
1879 int def_seg
, base
, index
, scale
, mod
, rm
;
1888 mod
= (modrm
>> 6) & 3;
1890 base
= rm
| REX_B(s
);
1893 /* Normally filtered out earlier, but including this path
1894 simplifies multi-byte nop, as well as bndcl, bndcu, bndcn. */
1903 int code
= cpu_ldub_code(env
, s
->pc
++);
1904 scale
= (code
>> 6) & 3;
1905 index
= ((code
>> 3) & 7) | REX_X(s
);
1907 index
= -1; /* no index */
1909 base
= (code
& 7) | REX_B(s
);
1915 if ((base
& 7) == 5) {
1917 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
1919 if (CODE64(s
) && !havesib
) {
1921 disp
+= s
->pc
+ s
->rip_offset
;
1926 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
1930 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
1935 /* For correct popl handling with esp. */
1936 if (base
== R_ESP
&& s
->popl_esp_hack
) {
1937 disp
+= s
->popl_esp_hack
;
1939 if (base
== R_EBP
|| base
== R_ESP
) {
1948 disp
= cpu_lduw_code(env
, s
->pc
);
1952 } else if (mod
== 1) {
1953 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
1955 disp
= (int16_t)cpu_lduw_code(env
, s
->pc
);
2000 return (AddressParts
){ def_seg
, base
, index
, scale
, disp
};
2003 /* Compute the address, with a minimum number of TCG ops. */
2004 static TCGv
gen_lea_modrm_1(AddressParts a
)
2011 ea
= cpu_regs
[a
.index
];
2013 tcg_gen_shli_tl(cpu_A0
, cpu_regs
[a
.index
], a
.scale
);
2017 tcg_gen_add_tl(cpu_A0
, ea
, cpu_regs
[a
.base
]);
2020 } else if (a
.base
>= 0) {
2021 ea
= cpu_regs
[a
.base
];
2023 if (TCGV_IS_UNUSED(ea
)) {
2024 tcg_gen_movi_tl(cpu_A0
, a
.disp
);
2026 } else if (a
.disp
!= 0) {
2027 tcg_gen_addi_tl(cpu_A0
, ea
, a
.disp
);
2034 static void gen_lea_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2036 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
2037 TCGv ea
= gen_lea_modrm_1(a
);
2038 gen_lea_v_seg(s
, s
->aflag
, ea
, a
.def_seg
, s
->override
);
2041 static void gen_nop_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2043 (void)gen_lea_modrm_0(env
, s
, modrm
);
2046 /* Used for BNDCL, BNDCU, BNDCN. */
2047 static void gen_bndck(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2048 TCGCond cond
, TCGv_i64 bndv
)
2050 TCGv ea
= gen_lea_modrm_1(gen_lea_modrm_0(env
, s
, modrm
));
2052 tcg_gen_extu_tl_i64(cpu_tmp1_i64
, ea
);
2054 tcg_gen_ext32u_i64(cpu_tmp1_i64
, cpu_tmp1_i64
);
2056 tcg_gen_setcond_i64(cond
, cpu_tmp1_i64
, cpu_tmp1_i64
, bndv
);
2057 tcg_gen_extrl_i64_i32(cpu_tmp2_i32
, cpu_tmp1_i64
);
2058 gen_helper_bndck(cpu_env
, cpu_tmp2_i32
);
2061 /* used for LEA and MOV AX, mem */
2062 static void gen_add_A0_ds_seg(DisasContext
*s
)
2064 gen_lea_v_seg(s
, s
->aflag
, cpu_A0
, R_DS
, s
->override
);
2067 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2069 static void gen_ldst_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2070 TCGMemOp ot
, int reg
, int is_store
)
2074 mod
= (modrm
>> 6) & 3;
2075 rm
= (modrm
& 7) | REX_B(s
);
2079 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
2080 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
2082 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
2084 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
2087 gen_lea_modrm(env
, s
, modrm
);
2090 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
2091 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
2093 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
2095 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
2100 static inline uint32_t insn_get(CPUX86State
*env
, DisasContext
*s
, TCGMemOp ot
)
2106 ret
= cpu_ldub_code(env
, s
->pc
);
2110 ret
= cpu_lduw_code(env
, s
->pc
);
2114 #ifdef TARGET_X86_64
2117 ret
= cpu_ldl_code(env
, s
->pc
);
2126 static inline int insn_const_size(TCGMemOp ot
)
2135 static inline bool use_goto_tb(DisasContext
*s
, target_ulong pc
)
2137 #ifndef CONFIG_USER_ONLY
2138 return (pc
& TARGET_PAGE_MASK
) == (s
->base
.tb
->pc
& TARGET_PAGE_MASK
) ||
2139 (pc
& TARGET_PAGE_MASK
) == (s
->pc_start
& TARGET_PAGE_MASK
);
2145 static inline void gen_goto_tb(DisasContext
*s
, int tb_num
, target_ulong eip
)
2147 target_ulong pc
= s
->cs_base
+ eip
;
2149 if (use_goto_tb(s
, pc
)) {
2150 /* jump to same page: we can use a direct jump */
2151 tcg_gen_goto_tb(tb_num
);
2153 tcg_gen_exit_tb((uintptr_t)s
->base
.tb
+ tb_num
);
2154 s
->base
.is_jmp
= DISAS_NORETURN
;
2156 /* jump to another page */
2158 gen_jr(s
, cpu_tmp0
);
2162 static inline void gen_jcc(DisasContext
*s
, int b
,
2163 target_ulong val
, target_ulong next_eip
)
2168 l1
= gen_new_label();
2171 gen_goto_tb(s
, 0, next_eip
);
2174 gen_goto_tb(s
, 1, val
);
2176 l1
= gen_new_label();
2177 l2
= gen_new_label();
2180 gen_jmp_im(next_eip
);
2190 static void gen_cmovcc1(CPUX86State
*env
, DisasContext
*s
, TCGMemOp ot
, int b
,
2195 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
2197 cc
= gen_prepare_cc(s
, b
, cpu_T1
);
2198 if (cc
.mask
!= -1) {
2199 TCGv t0
= tcg_temp_new();
2200 tcg_gen_andi_tl(t0
, cc
.reg
, cc
.mask
);
2204 cc
.reg2
= tcg_const_tl(cc
.imm
);
2207 tcg_gen_movcond_tl(cc
.cond
, cpu_T0
, cc
.reg
, cc
.reg2
,
2208 cpu_T0
, cpu_regs
[reg
]);
2209 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
2211 if (cc
.mask
!= -1) {
2212 tcg_temp_free(cc
.reg
);
2215 tcg_temp_free(cc
.reg2
);
2219 static inline void gen_op_movl_T0_seg(int seg_reg
)
2221 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
,
2222 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2225 static inline void gen_op_movl_seg_T0_vm(int seg_reg
)
2227 tcg_gen_ext16u_tl(cpu_T0
, cpu_T0
);
2228 tcg_gen_st32_tl(cpu_T0
, cpu_env
,
2229 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2230 tcg_gen_shli_tl(cpu_seg_base
[seg_reg
], cpu_T0
, 4);
2233 /* move T0 to seg_reg and compute if the CPU state may change. Never
2234 call this function with seg_reg == R_CS */
2235 static void gen_movl_seg_T0(DisasContext
*s
, int seg_reg
)
2237 if (s
->pe
&& !s
->vm86
) {
2238 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
2239 gen_helper_load_seg(cpu_env
, tcg_const_i32(seg_reg
), cpu_tmp2_i32
);
2240 /* abort translation because the addseg value may change or
2241 because ss32 may change. For R_SS, translation must always
2242 stop as a special handling must be done to disable hardware
2243 interrupts for the next instruction */
2244 if (seg_reg
== R_SS
|| (s
->code32
&& seg_reg
< R_FS
)) {
2245 s
->base
.is_jmp
= DISAS_TOO_MANY
;
2248 gen_op_movl_seg_T0_vm(seg_reg
);
2249 if (seg_reg
== R_SS
) {
2250 s
->base
.is_jmp
= DISAS_TOO_MANY
;
2255 static inline int svm_is_rep(int prefixes
)
2257 return ((prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) ? 8 : 0);
2261 gen_svm_check_intercept_param(DisasContext
*s
, target_ulong pc_start
,
2262 uint32_t type
, uint64_t param
)
2264 /* no SVM activated; fast case */
2265 if (likely(!(s
->flags
& HF_SVMI_MASK
)))
2267 gen_update_cc_op(s
);
2268 gen_jmp_im(pc_start
- s
->cs_base
);
2269 gen_helper_svm_check_intercept_param(cpu_env
, tcg_const_i32(type
),
2270 tcg_const_i64(param
));
2274 gen_svm_check_intercept(DisasContext
*s
, target_ulong pc_start
, uint64_t type
)
2276 gen_svm_check_intercept_param(s
, pc_start
, type
, 0);
2279 static inline void gen_stack_update(DisasContext
*s
, int addend
)
2281 gen_op_add_reg_im(mo_stacksize(s
), R_ESP
, addend
);
2284 /* Generate a push. It depends on ss32, addseg and dflag. */
2285 static void gen_push_v(DisasContext
*s
, TCGv val
)
2287 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2288 TCGMemOp a_ot
= mo_stacksize(s
);
2289 int size
= 1 << d_ot
;
2290 TCGv new_esp
= cpu_A0
;
2292 tcg_gen_subi_tl(cpu_A0
, cpu_regs
[R_ESP
], size
);
2297 tcg_gen_mov_tl(new_esp
, cpu_A0
);
2299 gen_lea_v_seg(s
, a_ot
, cpu_A0
, R_SS
, -1);
2302 gen_op_st_v(s
, d_ot
, val
, cpu_A0
);
2303 gen_op_mov_reg_v(a_ot
, R_ESP
, new_esp
);
2306 /* two step pop is necessary for precise exceptions */
2307 static TCGMemOp
gen_pop_T0(DisasContext
*s
)
2309 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2311 gen_lea_v_seg(s
, mo_stacksize(s
), cpu_regs
[R_ESP
], R_SS
, -1);
2312 gen_op_ld_v(s
, d_ot
, cpu_T0
, cpu_A0
);
2317 static inline void gen_pop_update(DisasContext
*s
, TCGMemOp ot
)
2319 gen_stack_update(s
, 1 << ot
);
2322 static inline void gen_stack_A0(DisasContext
*s
)
2324 gen_lea_v_seg(s
, s
->ss32
? MO_32
: MO_16
, cpu_regs
[R_ESP
], R_SS
, -1);
2327 static void gen_pusha(DisasContext
*s
)
2329 TCGMemOp s_ot
= s
->ss32
? MO_32
: MO_16
;
2330 TCGMemOp d_ot
= s
->dflag
;
2331 int size
= 1 << d_ot
;
2334 for (i
= 0; i
< 8; i
++) {
2335 tcg_gen_addi_tl(cpu_A0
, cpu_regs
[R_ESP
], (i
- 8) * size
);
2336 gen_lea_v_seg(s
, s_ot
, cpu_A0
, R_SS
, -1);
2337 gen_op_st_v(s
, d_ot
, cpu_regs
[7 - i
], cpu_A0
);
2340 gen_stack_update(s
, -8 * size
);
2343 static void gen_popa(DisasContext
*s
)
2345 TCGMemOp s_ot
= s
->ss32
? MO_32
: MO_16
;
2346 TCGMemOp d_ot
= s
->dflag
;
2347 int size
= 1 << d_ot
;
2350 for (i
= 0; i
< 8; i
++) {
2351 /* ESP is not reloaded */
2352 if (7 - i
== R_ESP
) {
2355 tcg_gen_addi_tl(cpu_A0
, cpu_regs
[R_ESP
], i
* size
);
2356 gen_lea_v_seg(s
, s_ot
, cpu_A0
, R_SS
, -1);
2357 gen_op_ld_v(s
, d_ot
, cpu_T0
, cpu_A0
);
2358 gen_op_mov_reg_v(d_ot
, 7 - i
, cpu_T0
);
2361 gen_stack_update(s
, 8 * size
);
2364 static void gen_enter(DisasContext
*s
, int esp_addend
, int level
)
2366 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2367 TCGMemOp a_ot
= CODE64(s
) ? MO_64
: s
->ss32
? MO_32
: MO_16
;
2368 int size
= 1 << d_ot
;
2370 /* Push BP; compute FrameTemp into T1. */
2371 tcg_gen_subi_tl(cpu_T1
, cpu_regs
[R_ESP
], size
);
2372 gen_lea_v_seg(s
, a_ot
, cpu_T1
, R_SS
, -1);
2373 gen_op_st_v(s
, d_ot
, cpu_regs
[R_EBP
], cpu_A0
);
2379 /* Copy level-1 pointers from the previous frame. */
2380 for (i
= 1; i
< level
; ++i
) {
2381 tcg_gen_subi_tl(cpu_A0
, cpu_regs
[R_EBP
], size
* i
);
2382 gen_lea_v_seg(s
, a_ot
, cpu_A0
, R_SS
, -1);
2383 gen_op_ld_v(s
, d_ot
, cpu_tmp0
, cpu_A0
);
2385 tcg_gen_subi_tl(cpu_A0
, cpu_T1
, size
* i
);
2386 gen_lea_v_seg(s
, a_ot
, cpu_A0
, R_SS
, -1);
2387 gen_op_st_v(s
, d_ot
, cpu_tmp0
, cpu_A0
);
2390 /* Push the current FrameTemp as the last level. */
2391 tcg_gen_subi_tl(cpu_A0
, cpu_T1
, size
* level
);
2392 gen_lea_v_seg(s
, a_ot
, cpu_A0
, R_SS
, -1);
2393 gen_op_st_v(s
, d_ot
, cpu_T1
, cpu_A0
);
2396 /* Copy the FrameTemp value to EBP. */
2397 gen_op_mov_reg_v(a_ot
, R_EBP
, cpu_T1
);
2399 /* Compute the final value of ESP. */
2400 tcg_gen_subi_tl(cpu_T1
, cpu_T1
, esp_addend
+ size
* level
);
2401 gen_op_mov_reg_v(a_ot
, R_ESP
, cpu_T1
);
2404 static void gen_leave(DisasContext
*s
)
2406 TCGMemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2407 TCGMemOp a_ot
= mo_stacksize(s
);
2409 gen_lea_v_seg(s
, a_ot
, cpu_regs
[R_EBP
], R_SS
, -1);
2410 gen_op_ld_v(s
, d_ot
, cpu_T0
, cpu_A0
);
2412 tcg_gen_addi_tl(cpu_T1
, cpu_regs
[R_EBP
], 1 << d_ot
);
2414 gen_op_mov_reg_v(d_ot
, R_EBP
, cpu_T0
);
2415 gen_op_mov_reg_v(a_ot
, R_ESP
, cpu_T1
);
2418 static void gen_exception(DisasContext
*s
, int trapno
, target_ulong cur_eip
)
2420 gen_update_cc_op(s
);
2421 gen_jmp_im(cur_eip
);
2422 gen_helper_raise_exception(cpu_env
, tcg_const_i32(trapno
));
2423 s
->base
.is_jmp
= DISAS_NORETURN
;
2426 /* Generate #UD for the current instruction. The assumption here is that
2427 the instruction is known, but it isn't allowed in the current cpu mode. */
2428 static void gen_illegal_opcode(DisasContext
*s
)
2430 gen_exception(s
, EXCP06_ILLOP
, s
->pc_start
- s
->cs_base
);
2433 /* Similarly, except that the assumption here is that we don't decode
2434 the instruction at all -- either a missing opcode, an unimplemented
2435 feature, or just a bogus instruction stream. */
2436 static void gen_unknown_opcode(CPUX86State
*env
, DisasContext
*s
)
2438 gen_illegal_opcode(s
);
2440 if (qemu_loglevel_mask(LOG_UNIMP
)) {
2441 target_ulong pc
= s
->pc_start
, end
= s
->pc
;
2443 qemu_log("ILLOPC: " TARGET_FMT_lx
":", pc
);
2444 for (; pc
< end
; ++pc
) {
2445 qemu_log(" %02x", cpu_ldub_code(env
, pc
));
2452 /* an interrupt is different from an exception because of the
2454 static void gen_interrupt(DisasContext
*s
, int intno
,
2455 target_ulong cur_eip
, target_ulong next_eip
)
2457 gen_update_cc_op(s
);
2458 gen_jmp_im(cur_eip
);
2459 gen_helper_raise_interrupt(cpu_env
, tcg_const_i32(intno
),
2460 tcg_const_i32(next_eip
- cur_eip
));
2461 s
->base
.is_jmp
= DISAS_NORETURN
;
2464 static void gen_debug(DisasContext
*s
, target_ulong cur_eip
)
2466 gen_update_cc_op(s
);
2467 gen_jmp_im(cur_eip
);
2468 gen_helper_debug(cpu_env
);
2469 s
->base
.is_jmp
= DISAS_NORETURN
;
2472 static void gen_set_hflag(DisasContext
*s
, uint32_t mask
)
2474 if ((s
->flags
& mask
) == 0) {
2475 TCGv_i32 t
= tcg_temp_new_i32();
2476 tcg_gen_ld_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2477 tcg_gen_ori_i32(t
, t
, mask
);
2478 tcg_gen_st_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2479 tcg_temp_free_i32(t
);
2484 static void gen_reset_hflag(DisasContext
*s
, uint32_t mask
)
2486 if (s
->flags
& mask
) {
2487 TCGv_i32 t
= tcg_temp_new_i32();
2488 tcg_gen_ld_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2489 tcg_gen_andi_i32(t
, t
, ~mask
);
2490 tcg_gen_st_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2491 tcg_temp_free_i32(t
);
2496 /* Clear BND registers during legacy branches. */
2497 static void gen_bnd_jmp(DisasContext
*s
)
2499 /* Clear the registers only if BND prefix is missing, MPX is enabled,
2500 and if the BNDREGs are known to be in use (non-zero) already.
2501 The helper itself will check BNDPRESERVE at runtime. */
2502 if ((s
->prefix
& PREFIX_REPNZ
) == 0
2503 && (s
->flags
& HF_MPX_EN_MASK
) != 0
2504 && (s
->flags
& HF_MPX_IU_MASK
) != 0) {
2505 gen_helper_bnd_jmp(cpu_env
);
2509 /* Generate an end of block. Trace exception is also generated if needed.
2510 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set.
2511 If RECHECK_TF, emit a rechecking helper for #DB, ignoring the state of
2512 S->TF. This is used by the syscall/sysret insns. */
2514 do_gen_eob_worker(DisasContext
*s
, bool inhibit
, bool recheck_tf
, bool jr
)
2516 gen_update_cc_op(s
);
2518 /* If several instructions disable interrupts, only the first does it. */
2519 if (inhibit
&& !(s
->flags
& HF_INHIBIT_IRQ_MASK
)) {
2520 gen_set_hflag(s
, HF_INHIBIT_IRQ_MASK
);
2522 gen_reset_hflag(s
, HF_INHIBIT_IRQ_MASK
);
2525 if (s
->base
.tb
->flags
& HF_RF_MASK
) {
2526 gen_helper_reset_rf(cpu_env
);
2528 if (s
->base
.singlestep_enabled
) {
2529 gen_helper_debug(cpu_env
);
2530 } else if (recheck_tf
) {
2531 gen_helper_rechecking_single_step(cpu_env
);
2534 gen_helper_single_step(cpu_env
);
2536 tcg_gen_lookup_and_goto_ptr();
2540 s
->base
.is_jmp
= DISAS_NORETURN
;
2544 gen_eob_worker(DisasContext
*s
, bool inhibit
, bool recheck_tf
)
2546 do_gen_eob_worker(s
, inhibit
, recheck_tf
, false);
2550 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set. */
2551 static void gen_eob_inhibit_irq(DisasContext
*s
, bool inhibit
)
2553 gen_eob_worker(s
, inhibit
, false);
2556 /* End of block, resetting the inhibit irq flag. */
2557 static void gen_eob(DisasContext
*s
)
2559 gen_eob_worker(s
, false, false);
2562 /* Jump to register */
2563 static void gen_jr(DisasContext
*s
, TCGv dest
)
2565 do_gen_eob_worker(s
, false, false, true);
2568 /* generate a jump to eip. No segment change must happen before as a
2569 direct call to the next block may occur */
2570 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
)
2572 gen_update_cc_op(s
);
2573 set_cc_op(s
, CC_OP_DYNAMIC
);
2575 gen_goto_tb(s
, tb_num
, eip
);
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(ZMMReg
, ZMM_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(ZMMReg
, ZMM_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(ZMMReg
, ZMM_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(ZMMReg
, ZMM_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(ZMMReg
, ZMM_Q(0)));
2622 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2623 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2624 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
+ offsetof(ZMMReg
, ZMM_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_illegal_opcode(s
);
3020 && !(s
->flags
& HF_OSFXSR_MASK
)
3021 && ((b
!= 0x38 && b
!= 0x3a) || (s
->prefix
& PREFIX_DATA
))) {
3025 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
)) {
3026 /* If we were fully decoding this we might use illegal_op. */
3030 gen_helper_emms(cpu_env
);
3035 gen_helper_emms(cpu_env
);
3038 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3039 the static cpu state) */
3041 gen_helper_enter_mmx(cpu_env
);
3044 modrm
= cpu_ldub_code(env
, s
->pc
++);
3045 reg
= ((modrm
>> 3) & 7);
3048 mod
= (modrm
>> 6) & 3;
3049 if (sse_fn_epp
== SSE_SPECIAL
) {
3052 case 0x0e7: /* movntq */
3056 gen_lea_modrm(env
, s
, modrm
);
3057 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3059 case 0x1e7: /* movntdq */
3060 case 0x02b: /* movntps */
3061 case 0x12b: /* movntps */
3064 gen_lea_modrm(env
, s
, modrm
);
3065 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3067 case 0x3f0: /* lddqu */
3070 gen_lea_modrm(env
, s
, modrm
);
3071 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3073 case 0x22b: /* movntss */
3074 case 0x32b: /* movntsd */
3077 gen_lea_modrm(env
, s
, modrm
);
3079 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3080 xmm_regs
[reg
].ZMM_Q(0)));
3082 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,
3083 xmm_regs
[reg
].ZMM_L(0)));
3084 gen_op_st_v(s
, MO_32
, cpu_T0
, cpu_A0
);
3087 case 0x6e: /* movd mm, ea */
3088 #ifdef TARGET_X86_64
3089 if (s
->dflag
== MO_64
) {
3090 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3091 tcg_gen_st_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3095 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3096 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3097 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3098 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
3099 gen_helper_movl_mm_T0_mmx(cpu_ptr0
, cpu_tmp2_i32
);
3102 case 0x16e: /* movd xmm, ea */
3103 #ifdef TARGET_X86_64
3104 if (s
->dflag
== MO_64
) {
3105 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3106 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3107 offsetof(CPUX86State
,xmm_regs
[reg
]));
3108 gen_helper_movq_mm_T0_xmm(cpu_ptr0
, cpu_T0
);
3112 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3113 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3114 offsetof(CPUX86State
,xmm_regs
[reg
]));
3115 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
3116 gen_helper_movl_mm_T0_xmm(cpu_ptr0
, cpu_tmp2_i32
);
3119 case 0x6f: /* movq mm, ea */
3121 gen_lea_modrm(env
, s
, modrm
);
3122 gen_ldq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3125 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
3126 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3127 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
3128 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3131 case 0x010: /* movups */
3132 case 0x110: /* movupd */
3133 case 0x028: /* movaps */
3134 case 0x128: /* movapd */
3135 case 0x16f: /* movdqa xmm, ea */
3136 case 0x26f: /* movdqu xmm, ea */
3138 gen_lea_modrm(env
, s
, modrm
);
3139 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3141 rm
= (modrm
& 7) | REX_B(s
);
3142 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[reg
]),
3143 offsetof(CPUX86State
,xmm_regs
[rm
]));
3146 case 0x210: /* movss xmm, ea */
3148 gen_lea_modrm(env
, s
, modrm
);
3149 gen_op_ld_v(s
, MO_32
, cpu_T0
, cpu_A0
);
3150 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3151 tcg_gen_movi_tl(cpu_T0
, 0);
3152 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)));
3153 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)));
3154 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)));
3156 rm
= (modrm
& 7) | REX_B(s
);
3157 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)),
3158 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)));
3161 case 0x310: /* movsd xmm, ea */
3163 gen_lea_modrm(env
, s
, modrm
);
3164 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3165 xmm_regs
[reg
].ZMM_Q(0)));
3166 tcg_gen_movi_tl(cpu_T0
, 0);
3167 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)));
3168 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)));
3170 rm
= (modrm
& 7) | REX_B(s
);
3171 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3172 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3175 case 0x012: /* movlps */
3176 case 0x112: /* movlpd */
3178 gen_lea_modrm(env
, s
, modrm
);
3179 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3180 xmm_regs
[reg
].ZMM_Q(0)));
3183 rm
= (modrm
& 7) | REX_B(s
);
3184 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3185 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(1)));
3188 case 0x212: /* movsldup */
3190 gen_lea_modrm(env
, s
, modrm
);
3191 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3193 rm
= (modrm
& 7) | REX_B(s
);
3194 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)),
3195 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)));
3196 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)),
3197 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(2)));
3199 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)),
3200 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3201 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)),
3202 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)));
3204 case 0x312: /* movddup */
3206 gen_lea_modrm(env
, s
, modrm
);
3207 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3208 xmm_regs
[reg
].ZMM_Q(0)));
3210 rm
= (modrm
& 7) | REX_B(s
);
3211 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3212 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3214 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)),
3215 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3217 case 0x016: /* movhps */
3218 case 0x116: /* movhpd */
3220 gen_lea_modrm(env
, s
, modrm
);
3221 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3222 xmm_regs
[reg
].ZMM_Q(1)));
3225 rm
= (modrm
& 7) | REX_B(s
);
3226 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)),
3227 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3230 case 0x216: /* movshdup */
3232 gen_lea_modrm(env
, s
, modrm
);
3233 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3235 rm
= (modrm
& 7) | REX_B(s
);
3236 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)),
3237 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(1)));
3238 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)),
3239 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(3)));
3241 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)),
3242 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)));
3243 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)),
3244 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)));
3249 int bit_index
, field_length
;
3251 if (b1
== 1 && reg
!= 0)
3253 field_length
= cpu_ldub_code(env
, s
->pc
++) & 0x3F;
3254 bit_index
= cpu_ldub_code(env
, s
->pc
++) & 0x3F;
3255 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3256 offsetof(CPUX86State
,xmm_regs
[reg
]));
3258 gen_helper_extrq_i(cpu_env
, cpu_ptr0
,
3259 tcg_const_i32(bit_index
),
3260 tcg_const_i32(field_length
));
3262 gen_helper_insertq_i(cpu_env
, cpu_ptr0
,
3263 tcg_const_i32(bit_index
),
3264 tcg_const_i32(field_length
));
3267 case 0x7e: /* movd ea, mm */
3268 #ifdef TARGET_X86_64
3269 if (s
->dflag
== MO_64
) {
3270 tcg_gen_ld_i64(cpu_T0
, cpu_env
,
3271 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3272 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3276 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
,
3277 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_L(0)));
3278 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3281 case 0x17e: /* movd ea, xmm */
3282 #ifdef TARGET_X86_64
3283 if (s
->dflag
== MO_64
) {
3284 tcg_gen_ld_i64(cpu_T0
, cpu_env
,
3285 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3286 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3290 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
,
3291 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3292 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3295 case 0x27e: /* movq xmm, ea */
3297 gen_lea_modrm(env
, s
, modrm
);
3298 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3299 xmm_regs
[reg
].ZMM_Q(0)));
3301 rm
= (modrm
& 7) | REX_B(s
);
3302 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3303 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3305 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)));
3307 case 0x7f: /* movq ea, mm */
3309 gen_lea_modrm(env
, s
, modrm
);
3310 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3313 gen_op_movq(offsetof(CPUX86State
,fpregs
[rm
].mmx
),
3314 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3317 case 0x011: /* movups */
3318 case 0x111: /* movupd */
3319 case 0x029: /* movaps */
3320 case 0x129: /* movapd */
3321 case 0x17f: /* movdqa ea, xmm */
3322 case 0x27f: /* movdqu ea, xmm */
3324 gen_lea_modrm(env
, s
, modrm
);
3325 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3327 rm
= (modrm
& 7) | REX_B(s
);
3328 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[rm
]),
3329 offsetof(CPUX86State
,xmm_regs
[reg
]));
3332 case 0x211: /* movss ea, xmm */
3334 gen_lea_modrm(env
, s
, modrm
);
3335 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3336 gen_op_st_v(s
, MO_32
, cpu_T0
, cpu_A0
);
3338 rm
= (modrm
& 7) | REX_B(s
);
3339 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)),
3340 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3343 case 0x311: /* movsd ea, xmm */
3345 gen_lea_modrm(env
, s
, modrm
);
3346 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3347 xmm_regs
[reg
].ZMM_Q(0)));
3349 rm
= (modrm
& 7) | REX_B(s
);
3350 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)),
3351 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3354 case 0x013: /* movlps */
3355 case 0x113: /* movlpd */
3357 gen_lea_modrm(env
, s
, modrm
);
3358 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3359 xmm_regs
[reg
].ZMM_Q(0)));
3364 case 0x017: /* movhps */
3365 case 0x117: /* movhpd */
3367 gen_lea_modrm(env
, s
, modrm
);
3368 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3369 xmm_regs
[reg
].ZMM_Q(1)));
3374 case 0x71: /* shift mm, im */
3377 case 0x171: /* shift xmm, im */
3383 val
= cpu_ldub_code(env
, s
->pc
++);
3385 tcg_gen_movi_tl(cpu_T0
, val
);
3386 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_t0
.ZMM_L(0)));
3387 tcg_gen_movi_tl(cpu_T0
, 0);
3388 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_t0
.ZMM_L(1)));
3389 op1_offset
= offsetof(CPUX86State
,xmm_t0
);
3391 tcg_gen_movi_tl(cpu_T0
, val
);
3392 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,mmx_t0
.MMX_L(0)));
3393 tcg_gen_movi_tl(cpu_T0
, 0);
3394 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,mmx_t0
.MMX_L(1)));
3395 op1_offset
= offsetof(CPUX86State
,mmx_t0
);
3397 sse_fn_epp
= sse_op_table2
[((b
- 1) & 3) * 8 +
3398 (((modrm
>> 3)) & 7)][b1
];
3403 rm
= (modrm
& 7) | REX_B(s
);
3404 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3407 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3409 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3410 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op1_offset
);
3411 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3413 case 0x050: /* movmskps */
3414 rm
= (modrm
& 7) | REX_B(s
);
3415 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3416 offsetof(CPUX86State
,xmm_regs
[rm
]));
3417 gen_helper_movmskps(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3418 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3420 case 0x150: /* movmskpd */
3421 rm
= (modrm
& 7) | REX_B(s
);
3422 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3423 offsetof(CPUX86State
,xmm_regs
[rm
]));
3424 gen_helper_movmskpd(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3425 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3427 case 0x02a: /* cvtpi2ps */
3428 case 0x12a: /* cvtpi2pd */
3429 gen_helper_enter_mmx(cpu_env
);
3431 gen_lea_modrm(env
, s
, modrm
);
3432 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3433 gen_ldq_env_A0(s
, op2_offset
);
3436 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3438 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3439 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3440 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3443 gen_helper_cvtpi2ps(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3447 gen_helper_cvtpi2pd(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3451 case 0x22a: /* cvtsi2ss */
3452 case 0x32a: /* cvtsi2sd */
3453 ot
= mo_64_32(s
->dflag
);
3454 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3455 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3456 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3458 SSEFunc_0_epi sse_fn_epi
= sse_op_table3ai
[(b
>> 8) & 1];
3459 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
3460 sse_fn_epi(cpu_env
, cpu_ptr0
, cpu_tmp2_i32
);
3462 #ifdef TARGET_X86_64
3463 SSEFunc_0_epl sse_fn_epl
= sse_op_table3aq
[(b
>> 8) & 1];
3464 sse_fn_epl(cpu_env
, cpu_ptr0
, cpu_T0
);
3470 case 0x02c: /* cvttps2pi */
3471 case 0x12c: /* cvttpd2pi */
3472 case 0x02d: /* cvtps2pi */
3473 case 0x12d: /* cvtpd2pi */
3474 gen_helper_enter_mmx(cpu_env
);
3476 gen_lea_modrm(env
, s
, modrm
);
3477 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3478 gen_ldo_env_A0(s
, op2_offset
);
3480 rm
= (modrm
& 7) | REX_B(s
);
3481 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3483 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
);
3484 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3485 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3488 gen_helper_cvttps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3491 gen_helper_cvttpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3494 gen_helper_cvtps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3497 gen_helper_cvtpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3501 case 0x22c: /* cvttss2si */
3502 case 0x32c: /* cvttsd2si */
3503 case 0x22d: /* cvtss2si */
3504 case 0x32d: /* cvtsd2si */
3505 ot
= mo_64_32(s
->dflag
);
3507 gen_lea_modrm(env
, s
, modrm
);
3509 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.ZMM_Q(0)));
3511 gen_op_ld_v(s
, MO_32
, cpu_T0
, cpu_A0
);
3512 tcg_gen_st32_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,xmm_t0
.ZMM_L(0)));
3514 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3516 rm
= (modrm
& 7) | REX_B(s
);
3517 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3519 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3521 SSEFunc_i_ep sse_fn_i_ep
=
3522 sse_op_table3bi
[((b
>> 7) & 2) | (b
& 1)];
3523 sse_fn_i_ep(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3524 tcg_gen_extu_i32_tl(cpu_T0
, cpu_tmp2_i32
);
3526 #ifdef TARGET_X86_64
3527 SSEFunc_l_ep sse_fn_l_ep
=
3528 sse_op_table3bq
[((b
>> 7) & 2) | (b
& 1)];
3529 sse_fn_l_ep(cpu_T0
, cpu_env
, cpu_ptr0
);
3534 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3536 case 0xc4: /* pinsrw */
3539 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
3540 val
= cpu_ldub_code(env
, s
->pc
++);
3543 tcg_gen_st16_tl(cpu_T0
, cpu_env
,
3544 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_W(val
)));
3547 tcg_gen_st16_tl(cpu_T0
, cpu_env
,
3548 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_W(val
)));
3551 case 0xc5: /* pextrw */
3555 ot
= mo_64_32(s
->dflag
);
3556 val
= cpu_ldub_code(env
, s
->pc
++);
3559 rm
= (modrm
& 7) | REX_B(s
);
3560 tcg_gen_ld16u_tl(cpu_T0
, cpu_env
,
3561 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_W(val
)));
3565 tcg_gen_ld16u_tl(cpu_T0
, cpu_env
,
3566 offsetof(CPUX86State
,fpregs
[rm
].mmx
.MMX_W(val
)));
3568 reg
= ((modrm
>> 3) & 7) | rex_r
;
3569 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3571 case 0x1d6: /* movq ea, xmm */
3573 gen_lea_modrm(env
, s
, modrm
);
3574 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3575 xmm_regs
[reg
].ZMM_Q(0)));
3577 rm
= (modrm
& 7) | REX_B(s
);
3578 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)),
3579 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3580 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(1)));
3583 case 0x2d6: /* movq2dq */
3584 gen_helper_enter_mmx(cpu_env
);
3586 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)),
3587 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3588 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(1)));
3590 case 0x3d6: /* movdq2q */
3591 gen_helper_enter_mmx(cpu_env
);
3592 rm
= (modrm
& 7) | REX_B(s
);
3593 gen_op_movq(offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
),
3594 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3596 case 0xd7: /* pmovmskb */
3601 rm
= (modrm
& 7) | REX_B(s
);
3602 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[rm
]));
3603 gen_helper_pmovmskb_xmm(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3606 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3607 gen_helper_pmovmskb_mmx(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3609 reg
= ((modrm
>> 3) & 7) | rex_r
;
3610 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
3616 if ((b
& 0xf0) == 0xf0) {
3619 modrm
= cpu_ldub_code(env
, s
->pc
++);
3621 reg
= ((modrm
>> 3) & 7) | rex_r
;
3622 mod
= (modrm
>> 6) & 3;
3627 sse_fn_epp
= sse_op_table6
[b
].op
[b1
];
3631 if (!(s
->cpuid_ext_features
& sse_op_table6
[b
].ext_mask
))
3635 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3637 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
3639 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3640 gen_lea_modrm(env
, s
, modrm
);
3642 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3643 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3644 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3645 gen_ldq_env_A0(s
, op2_offset
+
3646 offsetof(ZMMReg
, ZMM_Q(0)));
3648 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3649 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3650 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
3651 s
->mem_index
, MO_LEUL
);
3652 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, op2_offset
+
3653 offsetof(ZMMReg
, ZMM_L(0)));
3655 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3656 tcg_gen_qemu_ld_tl(cpu_tmp0
, cpu_A0
,
3657 s
->mem_index
, MO_LEUW
);
3658 tcg_gen_st16_tl(cpu_tmp0
, cpu_env
, op2_offset
+
3659 offsetof(ZMMReg
, ZMM_W(0)));
3661 case 0x2a: /* movntqda */
3662 gen_ldo_env_A0(s
, op1_offset
);
3665 gen_ldo_env_A0(s
, op2_offset
);
3669 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
3671 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3673 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3674 gen_lea_modrm(env
, s
, modrm
);
3675 gen_ldq_env_A0(s
, op2_offset
);
3678 if (sse_fn_epp
== SSE_SPECIAL
) {
3682 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3683 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3684 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3687 set_cc_op(s
, CC_OP_EFLAGS
);
3694 /* Various integer extensions at 0f 38 f[0-f]. */
3695 b
= modrm
| (b1
<< 8);
3696 modrm
= cpu_ldub_code(env
, s
->pc
++);
3697 reg
= ((modrm
>> 3) & 7) | rex_r
;
3700 case 0x3f0: /* crc32 Gd,Eb */
3701 case 0x3f1: /* crc32 Gd,Ey */
3703 if (!(s
->cpuid_ext_features
& CPUID_EXT_SSE42
)) {
3706 if ((b
& 0xff) == 0xf0) {
3708 } else if (s
->dflag
!= MO_64
) {
3709 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3714 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[reg
]);
3715 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3716 gen_helper_crc32(cpu_T0
, cpu_tmp2_i32
,
3717 cpu_T0
, tcg_const_i32(8 << ot
));
3719 ot
= mo_64_32(s
->dflag
);
3720 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3723 case 0x1f0: /* crc32 or movbe */
3725 /* For these insns, the f3 prefix is supposed to have priority
3726 over the 66 prefix, but that's not what we implement above
3728 if (s
->prefix
& PREFIX_REPNZ
) {
3732 case 0x0f0: /* movbe Gy,My */
3733 case 0x0f1: /* movbe My,Gy */
3734 if (!(s
->cpuid_ext_features
& CPUID_EXT_MOVBE
)) {
3737 if (s
->dflag
!= MO_64
) {
3738 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3743 gen_lea_modrm(env
, s
, modrm
);
3745 tcg_gen_qemu_ld_tl(cpu_T0
, cpu_A0
,
3746 s
->mem_index
, ot
| MO_BE
);
3747 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3749 tcg_gen_qemu_st_tl(cpu_regs
[reg
], cpu_A0
,
3750 s
->mem_index
, ot
| MO_BE
);
3754 case 0x0f2: /* andn Gy, By, Ey */
3755 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3756 || !(s
->prefix
& PREFIX_VEX
)
3760 ot
= mo_64_32(s
->dflag
);
3761 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3762 tcg_gen_andc_tl(cpu_T0
, cpu_regs
[s
->vex_v
], cpu_T0
);
3763 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3764 gen_op_update1_cc();
3765 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3768 case 0x0f7: /* bextr Gy, Ey, By */
3769 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3770 || !(s
->prefix
& PREFIX_VEX
)
3774 ot
= mo_64_32(s
->dflag
);
3778 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3779 /* Extract START, and shift the operand.
3780 Shifts larger than operand size get zeros. */
3781 tcg_gen_ext8u_tl(cpu_A0
, cpu_regs
[s
->vex_v
]);
3782 tcg_gen_shr_tl(cpu_T0
, cpu_T0
, cpu_A0
);
3784 bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3785 zero
= tcg_const_tl(0);
3786 tcg_gen_movcond_tl(TCG_COND_LEU
, cpu_T0
, cpu_A0
, bound
,
3788 tcg_temp_free(zero
);
3790 /* Extract the LEN into a mask. Lengths larger than
3791 operand size get all ones. */
3792 tcg_gen_extract_tl(cpu_A0
, cpu_regs
[s
->vex_v
], 8, 8);
3793 tcg_gen_movcond_tl(TCG_COND_LEU
, cpu_A0
, cpu_A0
, bound
,
3795 tcg_temp_free(bound
);
3796 tcg_gen_movi_tl(cpu_T1
, 1);
3797 tcg_gen_shl_tl(cpu_T1
, cpu_T1
, cpu_A0
);
3798 tcg_gen_subi_tl(cpu_T1
, cpu_T1
, 1);
3799 tcg_gen_and_tl(cpu_T0
, cpu_T0
, cpu_T1
);
3801 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3802 gen_op_update1_cc();
3803 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3807 case 0x0f5: /* bzhi Gy, Ey, By */
3808 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3809 || !(s
->prefix
& PREFIX_VEX
)
3813 ot
= mo_64_32(s
->dflag
);
3814 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3815 tcg_gen_ext8u_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3817 TCGv bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3818 /* Note that since we're using BMILG (in order to get O
3819 cleared) we need to store the inverse into C. */
3820 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_cc_src
,
3822 tcg_gen_movcond_tl(TCG_COND_GT
, cpu_T1
, cpu_T1
,
3823 bound
, bound
, cpu_T1
);
3824 tcg_temp_free(bound
);
3826 tcg_gen_movi_tl(cpu_A0
, -1);
3827 tcg_gen_shl_tl(cpu_A0
, cpu_A0
, cpu_T1
);
3828 tcg_gen_andc_tl(cpu_T0
, cpu_T0
, cpu_A0
);
3829 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
3830 gen_op_update1_cc();
3831 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
3834 case 0x3f6: /* mulx By, Gy, rdx, Ey */
3835 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3836 || !(s
->prefix
& PREFIX_VEX
)
3840 ot
= mo_64_32(s
->dflag
);
3841 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3844 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
3845 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EDX
]);
3846 tcg_gen_mulu2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
3847 cpu_tmp2_i32
, cpu_tmp3_i32
);
3848 tcg_gen_extu_i32_tl(cpu_regs
[s
->vex_v
], cpu_tmp2_i32
);
3849 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp3_i32
);
3851 #ifdef TARGET_X86_64
3853 tcg_gen_mulu2_i64(cpu_T0
, cpu_T1
,
3854 cpu_T0
, cpu_regs
[R_EDX
]);
3855 tcg_gen_mov_i64(cpu_regs
[s
->vex_v
], cpu_T0
);
3856 tcg_gen_mov_i64(cpu_regs
[reg
], cpu_T1
);
3862 case 0x3f5: /* pdep Gy, By, Ey */
3863 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3864 || !(s
->prefix
& PREFIX_VEX
)
3868 ot
= mo_64_32(s
->dflag
);
3869 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3870 /* Note that by zero-extending the mask operand, we
3871 automatically handle zero-extending the result. */
3873 tcg_gen_mov_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3875 tcg_gen_ext32u_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3877 gen_helper_pdep(cpu_regs
[reg
], cpu_T0
, cpu_T1
);
3880 case 0x2f5: /* pext Gy, By, Ey */
3881 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3882 || !(s
->prefix
& PREFIX_VEX
)
3886 ot
= mo_64_32(s
->dflag
);
3887 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3888 /* Note that by zero-extending the mask operand, we
3889 automatically handle zero-extending the result. */
3891 tcg_gen_mov_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3893 tcg_gen_ext32u_tl(cpu_T1
, cpu_regs
[s
->vex_v
]);
3895 gen_helper_pext(cpu_regs
[reg
], cpu_T0
, cpu_T1
);
3898 case 0x1f6: /* adcx Gy, Ey */
3899 case 0x2f6: /* adox Gy, Ey */
3900 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_ADX
)) {
3903 TCGv carry_in
, carry_out
, zero
;
3906 ot
= mo_64_32(s
->dflag
);
3907 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3909 /* Re-use the carry-out from a previous round. */
3910 TCGV_UNUSED(carry_in
);
3911 carry_out
= (b
== 0x1f6 ? cpu_cc_dst
: cpu_cc_src2
);
3915 carry_in
= cpu_cc_dst
;
3916 end_op
= CC_OP_ADCX
;
3918 end_op
= CC_OP_ADCOX
;
3923 end_op
= CC_OP_ADCOX
;
3925 carry_in
= cpu_cc_src2
;
3926 end_op
= CC_OP_ADOX
;
3930 end_op
= CC_OP_ADCOX
;
3931 carry_in
= carry_out
;
3934 end_op
= (b
== 0x1f6 ? CC_OP_ADCX
: CC_OP_ADOX
);
3937 /* If we can't reuse carry-out, get it out of EFLAGS. */
3938 if (TCGV_IS_UNUSED(carry_in
)) {
3939 if (s
->cc_op
!= CC_OP_ADCX
&& s
->cc_op
!= CC_OP_ADOX
) {
3940 gen_compute_eflags(s
);
3942 carry_in
= cpu_tmp0
;
3943 tcg_gen_extract_tl(carry_in
, cpu_cc_src
,
3944 ctz32(b
== 0x1f6 ? CC_C
: CC_O
), 1);
3948 #ifdef TARGET_X86_64
3950 /* If we know TL is 64-bit, and we want a 32-bit
3951 result, just do everything in 64-bit arithmetic. */
3952 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_regs
[reg
]);
3953 tcg_gen_ext32u_i64(cpu_T0
, cpu_T0
);
3954 tcg_gen_add_i64(cpu_T0
, cpu_T0
, cpu_regs
[reg
]);
3955 tcg_gen_add_i64(cpu_T0
, cpu_T0
, carry_in
);
3956 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_T0
);
3957 tcg_gen_shri_i64(carry_out
, cpu_T0
, 32);
3961 /* Otherwise compute the carry-out in two steps. */
3962 zero
= tcg_const_tl(0);
3963 tcg_gen_add2_tl(cpu_T0
, carry_out
,
3966 tcg_gen_add2_tl(cpu_regs
[reg
], carry_out
,
3967 cpu_regs
[reg
], carry_out
,
3969 tcg_temp_free(zero
);
3972 set_cc_op(s
, end_op
);
3976 case 0x1f7: /* shlx Gy, Ey, By */
3977 case 0x2f7: /* sarx Gy, Ey, By */
3978 case 0x3f7: /* shrx Gy, Ey, By */
3979 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3980 || !(s
->prefix
& PREFIX_VEX
)
3984 ot
= mo_64_32(s
->dflag
);
3985 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3987 tcg_gen_andi_tl(cpu_T1
, cpu_regs
[s
->vex_v
], 63);
3989 tcg_gen_andi_tl(cpu_T1
, cpu_regs
[s
->vex_v
], 31);
3992 tcg_gen_shl_tl(cpu_T0
, cpu_T0
, cpu_T1
);
3993 } else if (b
== 0x2f7) {
3995 tcg_gen_ext32s_tl(cpu_T0
, cpu_T0
);
3997 tcg_gen_sar_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4000 tcg_gen_ext32u_tl(cpu_T0
, cpu_T0
);
4002 tcg_gen_shr_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4004 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
4010 case 0x3f3: /* Group 17 */
4011 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
4012 || !(s
->prefix
& PREFIX_VEX
)
4016 ot
= mo_64_32(s
->dflag
);
4017 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4020 case 1: /* blsr By,Ey */
4021 tcg_gen_neg_tl(cpu_T1
, cpu_T0
);
4022 tcg_gen_and_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4023 gen_op_mov_reg_v(ot
, s
->vex_v
, cpu_T0
);
4024 gen_op_update2_cc();
4025 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4028 case 2: /* blsmsk By,Ey */
4029 tcg_gen_mov_tl(cpu_cc_src
, cpu_T0
);
4030 tcg_gen_subi_tl(cpu_T0
, cpu_T0
, 1);
4031 tcg_gen_xor_tl(cpu_T0
, cpu_T0
, cpu_cc_src
);
4032 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
4033 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4036 case 3: /* blsi By, Ey */
4037 tcg_gen_mov_tl(cpu_cc_src
, cpu_T0
);
4038 tcg_gen_subi_tl(cpu_T0
, cpu_T0
, 1);
4039 tcg_gen_and_tl(cpu_T0
, cpu_T0
, cpu_cc_src
);
4040 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
4041 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4057 modrm
= cpu_ldub_code(env
, s
->pc
++);
4059 reg
= ((modrm
>> 3) & 7) | rex_r
;
4060 mod
= (modrm
>> 6) & 3;
4065 sse_fn_eppi
= sse_op_table7
[b
].op
[b1
];
4069 if (!(s
->cpuid_ext_features
& sse_op_table7
[b
].ext_mask
))
4074 if (sse_fn_eppi
== SSE_SPECIAL
) {
4075 ot
= mo_64_32(s
->dflag
);
4076 rm
= (modrm
& 7) | REX_B(s
);
4078 gen_lea_modrm(env
, s
, modrm
);
4079 reg
= ((modrm
>> 3) & 7) | rex_r
;
4080 val
= cpu_ldub_code(env
, s
->pc
++);
4082 case 0x14: /* pextrb */
4083 tcg_gen_ld8u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,
4084 xmm_regs
[reg
].ZMM_B(val
& 15)));
4086 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
4088 tcg_gen_qemu_st_tl(cpu_T0
, cpu_A0
,
4089 s
->mem_index
, MO_UB
);
4092 case 0x15: /* pextrw */
4093 tcg_gen_ld16u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,
4094 xmm_regs
[reg
].ZMM_W(val
& 7)));
4096 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
4098 tcg_gen_qemu_st_tl(cpu_T0
, cpu_A0
,
4099 s
->mem_index
, MO_LEUW
);
4103 if (ot
== MO_32
) { /* pextrd */
4104 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4105 offsetof(CPUX86State
,
4106 xmm_regs
[reg
].ZMM_L(val
& 3)));
4108 tcg_gen_extu_i32_tl(cpu_regs
[rm
], cpu_tmp2_i32
);
4110 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
4111 s
->mem_index
, MO_LEUL
);
4113 } else { /* pextrq */
4114 #ifdef TARGET_X86_64
4115 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
4116 offsetof(CPUX86State
,
4117 xmm_regs
[reg
].ZMM_Q(val
& 1)));
4119 tcg_gen_mov_i64(cpu_regs
[rm
], cpu_tmp1_i64
);
4121 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
4122 s
->mem_index
, MO_LEQ
);
4129 case 0x17: /* extractps */
4130 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,
4131 xmm_regs
[reg
].ZMM_L(val
& 3)));
4133 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
4135 tcg_gen_qemu_st_tl(cpu_T0
, cpu_A0
,
4136 s
->mem_index
, MO_LEUL
);
4139 case 0x20: /* pinsrb */
4141 gen_op_mov_v_reg(MO_32
, cpu_T0
, rm
);
4143 tcg_gen_qemu_ld_tl(cpu_T0
, cpu_A0
,
4144 s
->mem_index
, MO_UB
);
4146 tcg_gen_st8_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
,
4147 xmm_regs
[reg
].ZMM_B(val
& 15)));
4149 case 0x21: /* insertps */
4151 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4152 offsetof(CPUX86State
,xmm_regs
[rm
]
4153 .ZMM_L((val
>> 6) & 3)));
4155 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
4156 s
->mem_index
, MO_LEUL
);
4158 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4159 offsetof(CPUX86State
,xmm_regs
[reg
]
4160 .ZMM_L((val
>> 4) & 3)));
4162 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4163 cpu_env
, offsetof(CPUX86State
,
4164 xmm_regs
[reg
].ZMM_L(0)));
4166 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4167 cpu_env
, offsetof(CPUX86State
,
4168 xmm_regs
[reg
].ZMM_L(1)));
4170 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4171 cpu_env
, offsetof(CPUX86State
,
4172 xmm_regs
[reg
].ZMM_L(2)));
4174 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4175 cpu_env
, offsetof(CPUX86State
,
4176 xmm_regs
[reg
].ZMM_L(3)));
4179 if (ot
== MO_32
) { /* pinsrd */
4181 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[rm
]);
4183 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
4184 s
->mem_index
, MO_LEUL
);
4186 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4187 offsetof(CPUX86State
,
4188 xmm_regs
[reg
].ZMM_L(val
& 3)));
4189 } else { /* pinsrq */
4190 #ifdef TARGET_X86_64
4192 gen_op_mov_v_reg(ot
, cpu_tmp1_i64
, rm
);
4194 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
4195 s
->mem_index
, MO_LEQ
);
4197 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
4198 offsetof(CPUX86State
,
4199 xmm_regs
[reg
].ZMM_Q(val
& 1)));
4210 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4212 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
4214 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4215 gen_lea_modrm(env
, s
, modrm
);
4216 gen_ldo_env_A0(s
, op2_offset
);
4219 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4221 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4223 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4224 gen_lea_modrm(env
, s
, modrm
);
4225 gen_ldq_env_A0(s
, op2_offset
);
4228 val
= cpu_ldub_code(env
, s
->pc
++);
4230 if ((b
& 0xfc) == 0x60) { /* pcmpXstrX */
4231 set_cc_op(s
, CC_OP_EFLAGS
);
4233 if (s
->dflag
== MO_64
) {
4234 /* The helper must use entire 64-bit gp registers */
4239 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4240 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4241 sse_fn_eppi(cpu_env
, cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4245 /* Various integer extensions at 0f 3a f[0-f]. */
4246 b
= modrm
| (b1
<< 8);
4247 modrm
= cpu_ldub_code(env
, s
->pc
++);
4248 reg
= ((modrm
>> 3) & 7) | rex_r
;
4251 case 0x3f0: /* rorx Gy,Ey, Ib */
4252 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4253 || !(s
->prefix
& PREFIX_VEX
)
4257 ot
= mo_64_32(s
->dflag
);
4258 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4259 b
= cpu_ldub_code(env
, s
->pc
++);
4261 tcg_gen_rotri_tl(cpu_T0
, cpu_T0
, b
& 63);
4263 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
4264 tcg_gen_rotri_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, b
& 31);
4265 tcg_gen_extu_i32_tl(cpu_T0
, cpu_tmp2_i32
);
4267 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
4277 gen_unknown_opcode(env
, s
);
4281 /* generic MMX or SSE operation */
4283 case 0x70: /* pshufx insn */
4284 case 0xc6: /* pshufx insn */
4285 case 0xc2: /* compare insns */
4292 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4296 gen_lea_modrm(env
, s
, modrm
);
4297 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4303 /* Most sse scalar operations. */
4306 } else if (b1
== 3) {
4311 case 0x2e: /* ucomis[sd] */
4312 case 0x2f: /* comis[sd] */
4324 gen_op_ld_v(s
, MO_32
, cpu_T0
, cpu_A0
);
4325 tcg_gen_st32_tl(cpu_T0
, cpu_env
,
4326 offsetof(CPUX86State
,xmm_t0
.ZMM_L(0)));
4330 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.ZMM_D(0)));
4333 /* 128 bit access */
4334 gen_ldo_env_A0(s
, op2_offset
);
4338 rm
= (modrm
& 7) | REX_B(s
);
4339 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
4342 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4344 gen_lea_modrm(env
, s
, modrm
);
4345 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4346 gen_ldq_env_A0(s
, op2_offset
);
4349 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4353 case 0x0f: /* 3DNow! data insns */
4354 val
= cpu_ldub_code(env
, s
->pc
++);
4355 sse_fn_epp
= sse_op_table5
[val
];
4359 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
)) {
4362 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4363 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4364 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4366 case 0x70: /* pshufx insn */
4367 case 0xc6: /* pshufx insn */
4368 val
= cpu_ldub_code(env
, s
->pc
++);
4369 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4370 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4371 /* XXX: introduce a new table? */
4372 sse_fn_ppi
= (SSEFunc_0_ppi
)sse_fn_epp
;
4373 sse_fn_ppi(cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4377 val
= cpu_ldub_code(env
, s
->pc
++);
4380 sse_fn_epp
= sse_op_table4
[val
][b1
];
4382 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4383 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4384 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4387 /* maskmov : we must prepare A0 */
4390 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EDI
]);
4391 gen_extu(s
->aflag
, cpu_A0
);
4392 gen_add_A0_ds_seg(s
);
4394 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4395 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4396 /* XXX: introduce a new table? */
4397 sse_fn_eppt
= (SSEFunc_0_eppt
)sse_fn_epp
;
4398 sse_fn_eppt(cpu_env
, cpu_ptr0
, cpu_ptr1
, cpu_A0
);
4401 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4402 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4403 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4406 if (b
== 0x2e || b
== 0x2f) {
4407 set_cc_op(s
, CC_OP_EFLAGS
);
4412 /* convert one instruction. s->base.is_jmp is set if the translation must
4413 be stopped. Return the next pc value */
4414 static target_ulong
disas_insn(DisasContext
*s
, CPUState
*cpu
)
4416 CPUX86State
*env
= cpu
->env_ptr
;
4419 TCGMemOp ot
, aflag
, dflag
;
4420 int modrm
, reg
, rm
, mod
, op
, opreg
, val
;
4421 target_ulong next_eip
, tval
;
4423 target_ulong pc_start
= s
->base
.pc_next
;
4425 s
->pc_start
= s
->pc
= pc_start
;
4430 #ifdef TARGET_X86_64
4435 s
->rip_offset
= 0; /* for relative ip address */
4439 /* x86 has an upper limit of 15 bytes for an instruction. Since we
4440 * do not want to decode and generate IR for an illegal
4441 * instruction, the following check limits the instruction size to
4442 * 25 bytes: 14 prefix + 1 opc + 6 (modrm+sib+ofs) + 4 imm */
4443 if (s
->pc
- pc_start
> 14) {
4446 b
= cpu_ldub_code(env
, s
->pc
);
4448 /* Collect prefixes. */
4451 prefixes
|= PREFIX_REPZ
;
4454 prefixes
|= PREFIX_REPNZ
;
4457 prefixes
|= PREFIX_LOCK
;
4478 prefixes
|= PREFIX_DATA
;
4481 prefixes
|= PREFIX_ADR
;
4483 #ifdef TARGET_X86_64
4487 rex_w
= (b
>> 3) & 1;
4488 rex_r
= (b
& 0x4) << 1;
4489 s
->rex_x
= (b
& 0x2) << 2;
4490 REX_B(s
) = (b
& 0x1) << 3;
4491 x86_64_hregs
= 1; /* select uniform byte register addressing */
4496 case 0xc5: /* 2-byte VEX */
4497 case 0xc4: /* 3-byte VEX */
4498 /* VEX prefixes cannot be used except in 32-bit mode.
4499 Otherwise the instruction is LES or LDS. */
4500 if (s
->code32
&& !s
->vm86
) {
4501 static const int pp_prefix
[4] = {
4502 0, PREFIX_DATA
, PREFIX_REPZ
, PREFIX_REPNZ
4504 int vex3
, vex2
= cpu_ldub_code(env
, s
->pc
);
4506 if (!CODE64(s
) && (vex2
& 0xc0) != 0xc0) {
4507 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4508 otherwise the instruction is LES or LDS. */
4513 /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
4514 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
4515 | PREFIX_LOCK
| PREFIX_DATA
)) {
4518 #ifdef TARGET_X86_64
4523 rex_r
= (~vex2
>> 4) & 8;
4526 b
= cpu_ldub_code(env
, s
->pc
++);
4528 #ifdef TARGET_X86_64
4529 s
->rex_x
= (~vex2
>> 3) & 8;
4530 s
->rex_b
= (~vex2
>> 2) & 8;
4532 vex3
= cpu_ldub_code(env
, s
->pc
++);
4533 rex_w
= (vex3
>> 7) & 1;
4534 switch (vex2
& 0x1f) {
4535 case 0x01: /* Implied 0f leading opcode bytes. */
4536 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4538 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4541 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4544 default: /* Reserved for future use. */
4548 s
->vex_v
= (~vex3
>> 3) & 0xf;
4549 s
->vex_l
= (vex3
>> 2) & 1;
4550 prefixes
|= pp_prefix
[vex3
& 3] | PREFIX_VEX
;
4555 /* Post-process prefixes. */
4557 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit
4558 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4559 over 0x66 if both are present. */
4560 dflag
= (rex_w
> 0 ? MO_64
: prefixes
& PREFIX_DATA
? MO_16
: MO_32
);
4561 /* In 64-bit mode, 0x67 selects 32-bit addressing. */
4562 aflag
= (prefixes
& PREFIX_ADR
? MO_32
: MO_64
);
4564 /* In 16/32-bit mode, 0x66 selects the opposite data size. */
4565 if (s
->code32
^ ((prefixes
& PREFIX_DATA
) != 0)) {
4570 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */
4571 if (s
->code32
^ ((prefixes
& PREFIX_ADR
) != 0)) {
4578 s
->prefix
= prefixes
;
4582 /* now check op code */
4586 /**************************/
4587 /* extended op code */
4588 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4591 /**************************/
4606 ot
= mo_b_d(b
, dflag
);
4609 case 0: /* OP Ev, Gv */
4610 modrm
= cpu_ldub_code(env
, s
->pc
++);
4611 reg
= ((modrm
>> 3) & 7) | rex_r
;
4612 mod
= (modrm
>> 6) & 3;
4613 rm
= (modrm
& 7) | REX_B(s
);
4615 gen_lea_modrm(env
, s
, modrm
);
4617 } else if (op
== OP_XORL
&& rm
== reg
) {
4619 /* xor reg, reg optimisation */
4620 set_cc_op(s
, CC_OP_CLR
);
4621 tcg_gen_movi_tl(cpu_T0
, 0);
4622 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
4627 gen_op_mov_v_reg(ot
, cpu_T1
, reg
);
4628 gen_op(s
, op
, ot
, opreg
);
4630 case 1: /* OP Gv, Ev */
4631 modrm
= cpu_ldub_code(env
, s
->pc
++);
4632 mod
= (modrm
>> 6) & 3;
4633 reg
= ((modrm
>> 3) & 7) | rex_r
;
4634 rm
= (modrm
& 7) | REX_B(s
);
4636 gen_lea_modrm(env
, s
, modrm
);
4637 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
4638 } else if (op
== OP_XORL
&& rm
== reg
) {
4641 gen_op_mov_v_reg(ot
, cpu_T1
, rm
);
4643 gen_op(s
, op
, ot
, reg
);
4645 case 2: /* OP A, Iv */
4646 val
= insn_get(env
, s
, ot
);
4647 tcg_gen_movi_tl(cpu_T1
, val
);
4648 gen_op(s
, op
, ot
, OR_EAX
);
4657 case 0x80: /* GRP1 */
4663 ot
= mo_b_d(b
, dflag
);
4665 modrm
= cpu_ldub_code(env
, s
->pc
++);
4666 mod
= (modrm
>> 6) & 3;
4667 rm
= (modrm
& 7) | REX_B(s
);
4668 op
= (modrm
>> 3) & 7;
4674 s
->rip_offset
= insn_const_size(ot
);
4675 gen_lea_modrm(env
, s
, modrm
);
4686 val
= insn_get(env
, s
, ot
);
4689 val
= (int8_t)insn_get(env
, s
, MO_8
);
4692 tcg_gen_movi_tl(cpu_T1
, val
);
4693 gen_op(s
, op
, ot
, opreg
);
4697 /**************************/
4698 /* inc, dec, and other misc arith */
4699 case 0x40 ... 0x47: /* inc Gv */
4701 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), 1);
4703 case 0x48 ... 0x4f: /* dec Gv */
4705 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), -1);
4707 case 0xf6: /* GRP3 */
4709 ot
= mo_b_d(b
, dflag
);
4711 modrm
= cpu_ldub_code(env
, s
->pc
++);
4712 mod
= (modrm
>> 6) & 3;
4713 rm
= (modrm
& 7) | REX_B(s
);
4714 op
= (modrm
>> 3) & 7;
4717 s
->rip_offset
= insn_const_size(ot
);
4719 gen_lea_modrm(env
, s
, modrm
);
4720 /* For those below that handle locked memory, don't load here. */
4721 if (!(s
->prefix
& PREFIX_LOCK
)
4723 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
4726 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
4731 val
= insn_get(env
, s
, ot
);
4732 tcg_gen_movi_tl(cpu_T1
, val
);
4733 gen_op_testl_T0_T1_cc();
4734 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4737 if (s
->prefix
& PREFIX_LOCK
) {
4741 tcg_gen_movi_tl(cpu_T0
, ~0);
4742 tcg_gen_atomic_xor_fetch_tl(cpu_T0
, cpu_A0
, cpu_T0
,
4743 s
->mem_index
, ot
| MO_LE
);
4745 tcg_gen_not_tl(cpu_T0
, cpu_T0
);
4747 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
4749 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
4754 if (s
->prefix
& PREFIX_LOCK
) {
4756 TCGv a0
, t0
, t1
, t2
;
4761 a0
= tcg_temp_local_new();
4762 t0
= tcg_temp_local_new();
4763 label1
= gen_new_label();
4765 tcg_gen_mov_tl(a0
, cpu_A0
);
4766 tcg_gen_mov_tl(t0
, cpu_T0
);
4768 gen_set_label(label1
);
4769 t1
= tcg_temp_new();
4770 t2
= tcg_temp_new();
4771 tcg_gen_mov_tl(t2
, t0
);
4772 tcg_gen_neg_tl(t1
, t0
);
4773 tcg_gen_atomic_cmpxchg_tl(t0
, a0
, t0
, t1
,
4774 s
->mem_index
, ot
| MO_LE
);
4776 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t2
, label1
);
4780 tcg_gen_mov_tl(cpu_T0
, t0
);
4783 tcg_gen_neg_tl(cpu_T0
, cpu_T0
);
4785 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
4787 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
4790 gen_op_update_neg_cc();
4791 set_cc_op(s
, CC_OP_SUBB
+ ot
);
4796 gen_op_mov_v_reg(MO_8
, cpu_T1
, R_EAX
);
4797 tcg_gen_ext8u_tl(cpu_T0
, cpu_T0
);
4798 tcg_gen_ext8u_tl(cpu_T1
, cpu_T1
);
4799 /* XXX: use 32 bit mul which could be faster */
4800 tcg_gen_mul_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4801 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
4802 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
4803 tcg_gen_andi_tl(cpu_cc_src
, cpu_T0
, 0xff00);
4804 set_cc_op(s
, CC_OP_MULB
);
4807 gen_op_mov_v_reg(MO_16
, cpu_T1
, R_EAX
);
4808 tcg_gen_ext16u_tl(cpu_T0
, cpu_T0
);
4809 tcg_gen_ext16u_tl(cpu_T1
, cpu_T1
);
4810 /* XXX: use 32 bit mul which could be faster */
4811 tcg_gen_mul_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4812 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
4813 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
4814 tcg_gen_shri_tl(cpu_T0
, cpu_T0
, 16);
4815 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T0
);
4816 tcg_gen_mov_tl(cpu_cc_src
, cpu_T0
);
4817 set_cc_op(s
, CC_OP_MULW
);
4821 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
4822 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
4823 tcg_gen_mulu2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4824 cpu_tmp2_i32
, cpu_tmp3_i32
);
4825 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
4826 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
4827 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4828 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4829 set_cc_op(s
, CC_OP_MULL
);
4831 #ifdef TARGET_X86_64
4833 tcg_gen_mulu2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4834 cpu_T0
, cpu_regs
[R_EAX
]);
4835 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4836 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4837 set_cc_op(s
, CC_OP_MULQ
);
4845 gen_op_mov_v_reg(MO_8
, cpu_T1
, R_EAX
);
4846 tcg_gen_ext8s_tl(cpu_T0
, cpu_T0
);
4847 tcg_gen_ext8s_tl(cpu_T1
, cpu_T1
);
4848 /* XXX: use 32 bit mul which could be faster */
4849 tcg_gen_mul_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4850 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
4851 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
4852 tcg_gen_ext8s_tl(cpu_tmp0
, cpu_T0
);
4853 tcg_gen_sub_tl(cpu_cc_src
, cpu_T0
, cpu_tmp0
);
4854 set_cc_op(s
, CC_OP_MULB
);
4857 gen_op_mov_v_reg(MO_16
, cpu_T1
, R_EAX
);
4858 tcg_gen_ext16s_tl(cpu_T0
, cpu_T0
);
4859 tcg_gen_ext16s_tl(cpu_T1
, cpu_T1
);
4860 /* XXX: use 32 bit mul which could be faster */
4861 tcg_gen_mul_tl(cpu_T0
, cpu_T0
, cpu_T1
);
4862 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
4863 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
4864 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T0
);
4865 tcg_gen_sub_tl(cpu_cc_src
, cpu_T0
, cpu_tmp0
);
4866 tcg_gen_shri_tl(cpu_T0
, cpu_T0
, 16);
4867 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T0
);
4868 set_cc_op(s
, CC_OP_MULW
);
4872 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
4873 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
4874 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4875 cpu_tmp2_i32
, cpu_tmp3_i32
);
4876 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
4877 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
4878 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
4879 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4880 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
4881 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
4882 set_cc_op(s
, CC_OP_MULL
);
4884 #ifdef TARGET_X86_64
4886 tcg_gen_muls2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4887 cpu_T0
, cpu_regs
[R_EAX
]);
4888 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4889 tcg_gen_sari_tl(cpu_cc_src
, cpu_regs
[R_EAX
], 63);
4890 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_regs
[R_EDX
]);
4891 set_cc_op(s
, CC_OP_MULQ
);
4899 gen_helper_divb_AL(cpu_env
, cpu_T0
);
4902 gen_helper_divw_AX(cpu_env
, cpu_T0
);
4906 gen_helper_divl_EAX(cpu_env
, cpu_T0
);
4908 #ifdef TARGET_X86_64
4910 gen_helper_divq_EAX(cpu_env
, cpu_T0
);
4918 gen_helper_idivb_AL(cpu_env
, cpu_T0
);
4921 gen_helper_idivw_AX(cpu_env
, cpu_T0
);
4925 gen_helper_idivl_EAX(cpu_env
, cpu_T0
);
4927 #ifdef TARGET_X86_64
4929 gen_helper_idivq_EAX(cpu_env
, cpu_T0
);
4939 case 0xfe: /* GRP4 */
4940 case 0xff: /* GRP5 */
4941 ot
= mo_b_d(b
, dflag
);
4943 modrm
= cpu_ldub_code(env
, s
->pc
++);
4944 mod
= (modrm
>> 6) & 3;
4945 rm
= (modrm
& 7) | REX_B(s
);
4946 op
= (modrm
>> 3) & 7;
4947 if (op
>= 2 && b
== 0xfe) {
4951 if (op
== 2 || op
== 4) {
4952 /* operand size for jumps is 64 bit */
4954 } else if (op
== 3 || op
== 5) {
4955 ot
= dflag
!= MO_16
? MO_32
+ (rex_w
== 1) : MO_16
;
4956 } else if (op
== 6) {
4957 /* default push size is 64 bit */
4958 ot
= mo_pushpop(s
, dflag
);
4962 gen_lea_modrm(env
, s
, modrm
);
4963 if (op
>= 2 && op
!= 3 && op
!= 5)
4964 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
4966 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
4970 case 0: /* inc Ev */
4975 gen_inc(s
, ot
, opreg
, 1);
4977 case 1: /* dec Ev */
4982 gen_inc(s
, ot
, opreg
, -1);
4984 case 2: /* call Ev */
4985 /* XXX: optimize if memory (no 'and' is necessary) */
4986 if (dflag
== MO_16
) {
4987 tcg_gen_ext16u_tl(cpu_T0
, cpu_T0
);
4989 next_eip
= s
->pc
- s
->cs_base
;
4990 tcg_gen_movi_tl(cpu_T1
, next_eip
);
4991 gen_push_v(s
, cpu_T1
);
4992 gen_op_jmp_v(cpu_T0
);
4996 case 3: /* lcall Ev */
4997 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
4998 gen_add_A0_im(s
, 1 << ot
);
4999 gen_op_ld_v(s
, MO_16
, cpu_T0
, cpu_A0
);
5001 if (s
->pe
&& !s
->vm86
) {
5002 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
5003 gen_helper_lcall_protected(cpu_env
, cpu_tmp2_i32
, cpu_T1
,
5004 tcg_const_i32(dflag
- 1),
5005 tcg_const_tl(s
->pc
- s
->cs_base
));
5007 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
5008 gen_helper_lcall_real(cpu_env
, cpu_tmp2_i32
, cpu_T1
,
5009 tcg_const_i32(dflag
- 1),
5010 tcg_const_i32(s
->pc
- s
->cs_base
));
5012 tcg_gen_ld_tl(cpu_tmp4
, cpu_env
, offsetof(CPUX86State
, eip
));
5013 gen_jr(s
, cpu_tmp4
);
5015 case 4: /* jmp Ev */
5016 if (dflag
== MO_16
) {
5017 tcg_gen_ext16u_tl(cpu_T0
, cpu_T0
);
5019 gen_op_jmp_v(cpu_T0
);
5023 case 5: /* ljmp Ev */
5024 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
5025 gen_add_A0_im(s
, 1 << ot
);
5026 gen_op_ld_v(s
, MO_16
, cpu_T0
, cpu_A0
);
5028 if (s
->pe
&& !s
->vm86
) {
5029 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
5030 gen_helper_ljmp_protected(cpu_env
, cpu_tmp2_i32
, cpu_T1
,
5031 tcg_const_tl(s
->pc
- s
->cs_base
));
5033 gen_op_movl_seg_T0_vm(R_CS
);
5034 gen_op_jmp_v(cpu_T1
);
5036 tcg_gen_ld_tl(cpu_tmp4
, cpu_env
, offsetof(CPUX86State
, eip
));
5037 gen_jr(s
, cpu_tmp4
);
5039 case 6: /* push Ev */
5040 gen_push_v(s
, cpu_T0
);
5047 case 0x84: /* test Ev, Gv */
5049 ot
= mo_b_d(b
, dflag
);
5051 modrm
= cpu_ldub_code(env
, s
->pc
++);
5052 reg
= ((modrm
>> 3) & 7) | rex_r
;
5054 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5055 gen_op_mov_v_reg(ot
, cpu_T1
, reg
);
5056 gen_op_testl_T0_T1_cc();
5057 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5060 case 0xa8: /* test eAX, Iv */
5062 ot
= mo_b_d(b
, dflag
);
5063 val
= insn_get(env
, s
, ot
);
5065 gen_op_mov_v_reg(ot
, cpu_T0
, OR_EAX
);
5066 tcg_gen_movi_tl(cpu_T1
, val
);
5067 gen_op_testl_T0_T1_cc();
5068 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5071 case 0x98: /* CWDE/CBW */
5073 #ifdef TARGET_X86_64
5075 gen_op_mov_v_reg(MO_32
, cpu_T0
, R_EAX
);
5076 tcg_gen_ext32s_tl(cpu_T0
, cpu_T0
);
5077 gen_op_mov_reg_v(MO_64
, R_EAX
, cpu_T0
);
5081 gen_op_mov_v_reg(MO_16
, cpu_T0
, R_EAX
);
5082 tcg_gen_ext16s_tl(cpu_T0
, cpu_T0
);
5083 gen_op_mov_reg_v(MO_32
, R_EAX
, cpu_T0
);
5086 gen_op_mov_v_reg(MO_8
, cpu_T0
, R_EAX
);
5087 tcg_gen_ext8s_tl(cpu_T0
, cpu_T0
);
5088 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
5094 case 0x99: /* CDQ/CWD */
5096 #ifdef TARGET_X86_64
5098 gen_op_mov_v_reg(MO_64
, cpu_T0
, R_EAX
);
5099 tcg_gen_sari_tl(cpu_T0
, cpu_T0
, 63);
5100 gen_op_mov_reg_v(MO_64
, R_EDX
, cpu_T0
);
5104 gen_op_mov_v_reg(MO_32
, cpu_T0
, R_EAX
);
5105 tcg_gen_ext32s_tl(cpu_T0
, cpu_T0
);
5106 tcg_gen_sari_tl(cpu_T0
, cpu_T0
, 31);
5107 gen_op_mov_reg_v(MO_32
, R_EDX
, cpu_T0
);
5110 gen_op_mov_v_reg(MO_16
, cpu_T0
, R_EAX
);
5111 tcg_gen_ext16s_tl(cpu_T0
, cpu_T0
);
5112 tcg_gen_sari_tl(cpu_T0
, cpu_T0
, 15);
5113 gen_op_mov_reg_v(MO_16
, R_EDX
, cpu_T0
);
5119 case 0x1af: /* imul Gv, Ev */
5120 case 0x69: /* imul Gv, Ev, I */
5123 modrm
= cpu_ldub_code(env
, s
->pc
++);
5124 reg
= ((modrm
>> 3) & 7) | rex_r
;
5126 s
->rip_offset
= insn_const_size(ot
);
5129 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5131 val
= insn_get(env
, s
, ot
);
5132 tcg_gen_movi_tl(cpu_T1
, val
);
5133 } else if (b
== 0x6b) {
5134 val
= (int8_t)insn_get(env
, s
, MO_8
);
5135 tcg_gen_movi_tl(cpu_T1
, val
);
5137 gen_op_mov_v_reg(ot
, cpu_T1
, reg
);
5140 #ifdef TARGET_X86_64
5142 tcg_gen_muls2_i64(cpu_regs
[reg
], cpu_T1
, cpu_T0
, cpu_T1
);
5143 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5144 tcg_gen_sari_tl(cpu_cc_src
, cpu_cc_dst
, 63);
5145 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_T1
);
5149 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
5150 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T1
);
5151 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
5152 cpu_tmp2_i32
, cpu_tmp3_i32
);
5153 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
5154 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
5155 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5156 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
5157 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
5160 tcg_gen_ext16s_tl(cpu_T0
, cpu_T0
);
5161 tcg_gen_ext16s_tl(cpu_T1
, cpu_T1
);
5162 /* XXX: use 32 bit mul which could be faster */
5163 tcg_gen_mul_tl(cpu_T0
, cpu_T0
, cpu_T1
);
5164 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
5165 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T0
);
5166 tcg_gen_sub_tl(cpu_cc_src
, cpu_T0
, cpu_tmp0
);
5167 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
5170 set_cc_op(s
, CC_OP_MULB
+ ot
);
5173 case 0x1c1: /* xadd Ev, Gv */
5174 ot
= mo_b_d(b
, dflag
);
5175 modrm
= cpu_ldub_code(env
, s
->pc
++);
5176 reg
= ((modrm
>> 3) & 7) | rex_r
;
5177 mod
= (modrm
>> 6) & 3;
5178 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
5180 rm
= (modrm
& 7) | REX_B(s
);
5181 gen_op_mov_v_reg(ot
, cpu_T1
, rm
);
5182 tcg_gen_add_tl(cpu_T0
, cpu_T0
, cpu_T1
);
5183 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
5184 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
5186 gen_lea_modrm(env
, s
, modrm
);
5187 if (s
->prefix
& PREFIX_LOCK
) {
5188 tcg_gen_atomic_fetch_add_tl(cpu_T1
, cpu_A0
, cpu_T0
,
5189 s
->mem_index
, ot
| MO_LE
);
5190 tcg_gen_add_tl(cpu_T0
, cpu_T0
, cpu_T1
);
5192 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
5193 tcg_gen_add_tl(cpu_T0
, cpu_T0
, cpu_T1
);
5194 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
5196 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
5198 gen_op_update2_cc();
5199 set_cc_op(s
, CC_OP_ADDB
+ ot
);
5202 case 0x1b1: /* cmpxchg Ev, Gv */
5204 TCGv oldv
, newv
, cmpv
;
5206 ot
= mo_b_d(b
, dflag
);
5207 modrm
= cpu_ldub_code(env
, s
->pc
++);
5208 reg
= ((modrm
>> 3) & 7) | rex_r
;
5209 mod
= (modrm
>> 6) & 3;
5210 oldv
= tcg_temp_new();
5211 newv
= tcg_temp_new();
5212 cmpv
= tcg_temp_new();
5213 gen_op_mov_v_reg(ot
, newv
, reg
);
5214 tcg_gen_mov_tl(cmpv
, cpu_regs
[R_EAX
]);
5216 if (s
->prefix
& PREFIX_LOCK
) {
5220 gen_lea_modrm(env
, s
, modrm
);
5221 tcg_gen_atomic_cmpxchg_tl(oldv
, cpu_A0
, cmpv
, newv
,
5222 s
->mem_index
, ot
| MO_LE
);
5223 gen_op_mov_reg_v(ot
, R_EAX
, oldv
);
5226 rm
= (modrm
& 7) | REX_B(s
);
5227 gen_op_mov_v_reg(ot
, oldv
, rm
);
5229 gen_lea_modrm(env
, s
, modrm
);
5230 gen_op_ld_v(s
, ot
, oldv
, cpu_A0
);
5231 rm
= 0; /* avoid warning */
5235 /* store value = (old == cmp ? new : old); */
5236 tcg_gen_movcond_tl(TCG_COND_EQ
, newv
, oldv
, cmpv
, newv
, oldv
);
5238 gen_op_mov_reg_v(ot
, R_EAX
, oldv
);
5239 gen_op_mov_reg_v(ot
, rm
, newv
);
5241 /* Perform an unconditional store cycle like physical cpu;
5242 must be before changing accumulator to ensure
5243 idempotency if the store faults and the instruction
5245 gen_op_st_v(s
, ot
, newv
, cpu_A0
);
5246 gen_op_mov_reg_v(ot
, R_EAX
, oldv
);
5249 tcg_gen_mov_tl(cpu_cc_src
, oldv
);
5250 tcg_gen_mov_tl(cpu_cc_srcT
, cmpv
);
5251 tcg_gen_sub_tl(cpu_cc_dst
, cmpv
, oldv
);
5252 set_cc_op(s
, CC_OP_SUBB
+ ot
);
5253 tcg_temp_free(oldv
);
5254 tcg_temp_free(newv
);
5255 tcg_temp_free(cmpv
);
5258 case 0x1c7: /* cmpxchg8b */
5259 modrm
= cpu_ldub_code(env
, s
->pc
++);
5260 mod
= (modrm
>> 6) & 3;
5261 if ((mod
== 3) || ((modrm
& 0x38) != 0x8))
5263 #ifdef TARGET_X86_64
5264 if (dflag
== MO_64
) {
5265 if (!(s
->cpuid_ext_features
& CPUID_EXT_CX16
))
5267 gen_lea_modrm(env
, s
, modrm
);
5268 if ((s
->prefix
& PREFIX_LOCK
) && parallel_cpus
) {
5269 gen_helper_cmpxchg16b(cpu_env
, cpu_A0
);
5271 gen_helper_cmpxchg16b_unlocked(cpu_env
, cpu_A0
);
5276 if (!(s
->cpuid_features
& CPUID_CX8
))
5278 gen_lea_modrm(env
, s
, modrm
);
5279 if ((s
->prefix
& PREFIX_LOCK
) && parallel_cpus
) {
5280 gen_helper_cmpxchg8b(cpu_env
, cpu_A0
);
5282 gen_helper_cmpxchg8b_unlocked(cpu_env
, cpu_A0
);
5285 set_cc_op(s
, CC_OP_EFLAGS
);
5288 /**************************/
5290 case 0x50 ... 0x57: /* push */
5291 gen_op_mov_v_reg(MO_32
, cpu_T0
, (b
& 7) | REX_B(s
));
5292 gen_push_v(s
, cpu_T0
);
5294 case 0x58 ... 0x5f: /* pop */
5296 /* NOTE: order is important for pop %sp */
5297 gen_pop_update(s
, ot
);
5298 gen_op_mov_reg_v(ot
, (b
& 7) | REX_B(s
), cpu_T0
);
5300 case 0x60: /* pusha */
5305 case 0x61: /* popa */
5310 case 0x68: /* push Iv */
5312 ot
= mo_pushpop(s
, dflag
);
5314 val
= insn_get(env
, s
, ot
);
5316 val
= (int8_t)insn_get(env
, s
, MO_8
);
5317 tcg_gen_movi_tl(cpu_T0
, val
);
5318 gen_push_v(s
, cpu_T0
);
5320 case 0x8f: /* pop Ev */
5321 modrm
= cpu_ldub_code(env
, s
->pc
++);
5322 mod
= (modrm
>> 6) & 3;
5325 /* NOTE: order is important for pop %sp */
5326 gen_pop_update(s
, ot
);
5327 rm
= (modrm
& 7) | REX_B(s
);
5328 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
5330 /* NOTE: order is important too for MMU exceptions */
5331 s
->popl_esp_hack
= 1 << ot
;
5332 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5333 s
->popl_esp_hack
= 0;
5334 gen_pop_update(s
, ot
);
5337 case 0xc8: /* enter */
5340 val
= cpu_lduw_code(env
, s
->pc
);
5342 level
= cpu_ldub_code(env
, s
->pc
++);
5343 gen_enter(s
, val
, level
);
5346 case 0xc9: /* leave */
5349 case 0x06: /* push es */
5350 case 0x0e: /* push cs */
5351 case 0x16: /* push ss */
5352 case 0x1e: /* push ds */
5355 gen_op_movl_T0_seg(b
>> 3);
5356 gen_push_v(s
, cpu_T0
);
5358 case 0x1a0: /* push fs */
5359 case 0x1a8: /* push gs */
5360 gen_op_movl_T0_seg((b
>> 3) & 7);
5361 gen_push_v(s
, cpu_T0
);
5363 case 0x07: /* pop es */
5364 case 0x17: /* pop ss */
5365 case 0x1f: /* pop ds */
5370 gen_movl_seg_T0(s
, reg
);
5371 gen_pop_update(s
, ot
);
5372 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5373 if (s
->base
.is_jmp
) {
5374 gen_jmp_im(s
->pc
- s
->cs_base
);
5377 gen_eob_inhibit_irq(s
, true);
5383 case 0x1a1: /* pop fs */
5384 case 0x1a9: /* pop gs */
5386 gen_movl_seg_T0(s
, (b
>> 3) & 7);
5387 gen_pop_update(s
, ot
);
5388 if (s
->base
.is_jmp
) {
5389 gen_jmp_im(s
->pc
- s
->cs_base
);
5394 /**************************/
5397 case 0x89: /* mov Gv, Ev */
5398 ot
= mo_b_d(b
, dflag
);
5399 modrm
= cpu_ldub_code(env
, s
->pc
++);
5400 reg
= ((modrm
>> 3) & 7) | rex_r
;
5402 /* generate a generic store */
5403 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
5406 case 0xc7: /* mov Ev, Iv */
5407 ot
= mo_b_d(b
, dflag
);
5408 modrm
= cpu_ldub_code(env
, s
->pc
++);
5409 mod
= (modrm
>> 6) & 3;
5411 s
->rip_offset
= insn_const_size(ot
);
5412 gen_lea_modrm(env
, s
, modrm
);
5414 val
= insn_get(env
, s
, ot
);
5415 tcg_gen_movi_tl(cpu_T0
, val
);
5417 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
5419 gen_op_mov_reg_v(ot
, (modrm
& 7) | REX_B(s
), cpu_T0
);
5423 case 0x8b: /* mov Ev, Gv */
5424 ot
= mo_b_d(b
, dflag
);
5425 modrm
= cpu_ldub_code(env
, s
->pc
++);
5426 reg
= ((modrm
>> 3) & 7) | rex_r
;
5428 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5429 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
5431 case 0x8e: /* mov seg, Gv */
5432 modrm
= cpu_ldub_code(env
, s
->pc
++);
5433 reg
= (modrm
>> 3) & 7;
5434 if (reg
>= 6 || reg
== R_CS
)
5436 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
5437 gen_movl_seg_T0(s
, reg
);
5438 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5439 if (s
->base
.is_jmp
) {
5440 gen_jmp_im(s
->pc
- s
->cs_base
);
5443 gen_eob_inhibit_irq(s
, true);
5449 case 0x8c: /* mov Gv, seg */
5450 modrm
= cpu_ldub_code(env
, s
->pc
++);
5451 reg
= (modrm
>> 3) & 7;
5452 mod
= (modrm
>> 6) & 3;
5455 gen_op_movl_T0_seg(reg
);
5456 ot
= mod
== 3 ? dflag
: MO_16
;
5457 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5460 case 0x1b6: /* movzbS Gv, Eb */
5461 case 0x1b7: /* movzwS Gv, Eb */
5462 case 0x1be: /* movsbS Gv, Eb */
5463 case 0x1bf: /* movswS Gv, Eb */
5468 /* d_ot is the size of destination */
5470 /* ot is the size of source */
5471 ot
= (b
& 1) + MO_8
;
5472 /* s_ot is the sign+size of source */
5473 s_ot
= b
& 8 ? MO_SIGN
| ot
: ot
;
5475 modrm
= cpu_ldub_code(env
, s
->pc
++);
5476 reg
= ((modrm
>> 3) & 7) | rex_r
;
5477 mod
= (modrm
>> 6) & 3;
5478 rm
= (modrm
& 7) | REX_B(s
);
5481 if (s_ot
== MO_SB
&& byte_reg_is_xH(rm
)) {
5482 tcg_gen_sextract_tl(cpu_T0
, cpu_regs
[rm
- 4], 8, 8);
5484 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
5487 tcg_gen_ext8u_tl(cpu_T0
, cpu_T0
);
5490 tcg_gen_ext8s_tl(cpu_T0
, cpu_T0
);
5493 tcg_gen_ext16u_tl(cpu_T0
, cpu_T0
);
5497 tcg_gen_ext16s_tl(cpu_T0
, cpu_T0
);
5501 gen_op_mov_reg_v(d_ot
, reg
, cpu_T0
);
5503 gen_lea_modrm(env
, s
, modrm
);
5504 gen_op_ld_v(s
, s_ot
, cpu_T0
, cpu_A0
);
5505 gen_op_mov_reg_v(d_ot
, reg
, cpu_T0
);
5510 case 0x8d: /* lea */
5511 modrm
= cpu_ldub_code(env
, s
->pc
++);
5512 mod
= (modrm
>> 6) & 3;
5515 reg
= ((modrm
>> 3) & 7) | rex_r
;
5517 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
5518 TCGv ea
= gen_lea_modrm_1(a
);
5519 gen_lea_v_seg(s
, s
->aflag
, ea
, -1, -1);
5520 gen_op_mov_reg_v(dflag
, reg
, cpu_A0
);
5524 case 0xa0: /* mov EAX, Ov */
5526 case 0xa2: /* mov Ov, EAX */
5529 target_ulong offset_addr
;
5531 ot
= mo_b_d(b
, dflag
);
5533 #ifdef TARGET_X86_64
5535 offset_addr
= cpu_ldq_code(env
, s
->pc
);
5540 offset_addr
= insn_get(env
, s
, s
->aflag
);
5543 tcg_gen_movi_tl(cpu_A0
, offset_addr
);
5544 gen_add_A0_ds_seg(s
);
5546 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
5547 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T0
);
5549 gen_op_mov_v_reg(ot
, cpu_T0
, R_EAX
);
5550 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
5554 case 0xd7: /* xlat */
5555 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EBX
]);
5556 tcg_gen_ext8u_tl(cpu_T0
, cpu_regs
[R_EAX
]);
5557 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_T0
);
5558 gen_extu(s
->aflag
, cpu_A0
);
5559 gen_add_A0_ds_seg(s
);
5560 gen_op_ld_v(s
, MO_8
, cpu_T0
, cpu_A0
);
5561 gen_op_mov_reg_v(MO_8
, R_EAX
, cpu_T0
);
5563 case 0xb0 ... 0xb7: /* mov R, Ib */
5564 val
= insn_get(env
, s
, MO_8
);
5565 tcg_gen_movi_tl(cpu_T0
, val
);
5566 gen_op_mov_reg_v(MO_8
, (b
& 7) | REX_B(s
), cpu_T0
);
5568 case 0xb8 ... 0xbf: /* mov R, Iv */
5569 #ifdef TARGET_X86_64
5570 if (dflag
== MO_64
) {
5573 tmp
= cpu_ldq_code(env
, s
->pc
);
5575 reg
= (b
& 7) | REX_B(s
);
5576 tcg_gen_movi_tl(cpu_T0
, tmp
);
5577 gen_op_mov_reg_v(MO_64
, reg
, cpu_T0
);
5582 val
= insn_get(env
, s
, ot
);
5583 reg
= (b
& 7) | REX_B(s
);
5584 tcg_gen_movi_tl(cpu_T0
, val
);
5585 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
5589 case 0x91 ... 0x97: /* xchg R, EAX */
5592 reg
= (b
& 7) | REX_B(s
);
5596 case 0x87: /* xchg Ev, Gv */
5597 ot
= mo_b_d(b
, dflag
);
5598 modrm
= cpu_ldub_code(env
, s
->pc
++);
5599 reg
= ((modrm
>> 3) & 7) | rex_r
;
5600 mod
= (modrm
>> 6) & 3;
5602 rm
= (modrm
& 7) | REX_B(s
);
5604 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
5605 gen_op_mov_v_reg(ot
, cpu_T1
, rm
);
5606 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
5607 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
5609 gen_lea_modrm(env
, s
, modrm
);
5610 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
5611 /* for xchg, lock is implicit */
5612 tcg_gen_atomic_xchg_tl(cpu_T1
, cpu_A0
, cpu_T0
,
5613 s
->mem_index
, ot
| MO_LE
);
5614 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
5617 case 0xc4: /* les Gv */
5618 /* In CODE64 this is VEX3; see above. */
5621 case 0xc5: /* lds Gv */
5622 /* In CODE64 this is VEX2; see above. */
5625 case 0x1b2: /* lss Gv */
5628 case 0x1b4: /* lfs Gv */
5631 case 0x1b5: /* lgs Gv */
5634 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
5635 modrm
= cpu_ldub_code(env
, s
->pc
++);
5636 reg
= ((modrm
>> 3) & 7) | rex_r
;
5637 mod
= (modrm
>> 6) & 3;
5640 gen_lea_modrm(env
, s
, modrm
);
5641 gen_op_ld_v(s
, ot
, cpu_T1
, cpu_A0
);
5642 gen_add_A0_im(s
, 1 << ot
);
5643 /* load the segment first to handle exceptions properly */
5644 gen_op_ld_v(s
, MO_16
, cpu_T0
, cpu_A0
);
5645 gen_movl_seg_T0(s
, op
);
5646 /* then put the data */
5647 gen_op_mov_reg_v(ot
, reg
, cpu_T1
);
5648 if (s
->base
.is_jmp
) {
5649 gen_jmp_im(s
->pc
- s
->cs_base
);
5654 /************************/
5662 ot
= mo_b_d(b
, dflag
);
5663 modrm
= cpu_ldub_code(env
, s
->pc
++);
5664 mod
= (modrm
>> 6) & 3;
5665 op
= (modrm
>> 3) & 7;
5671 gen_lea_modrm(env
, s
, modrm
);
5674 opreg
= (modrm
& 7) | REX_B(s
);
5679 gen_shift(s
, op
, ot
, opreg
, OR_ECX
);
5682 shift
= cpu_ldub_code(env
, s
->pc
++);
5684 gen_shifti(s
, op
, ot
, opreg
, shift
);
5699 case 0x1a4: /* shld imm */
5703 case 0x1a5: /* shld cl */
5707 case 0x1ac: /* shrd imm */
5711 case 0x1ad: /* shrd cl */
5716 modrm
= cpu_ldub_code(env
, s
->pc
++);
5717 mod
= (modrm
>> 6) & 3;
5718 rm
= (modrm
& 7) | REX_B(s
);
5719 reg
= ((modrm
>> 3) & 7) | rex_r
;
5721 gen_lea_modrm(env
, s
, modrm
);
5726 gen_op_mov_v_reg(ot
, cpu_T1
, reg
);
5729 TCGv imm
= tcg_const_tl(cpu_ldub_code(env
, s
->pc
++));
5730 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, imm
);
5733 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, cpu_regs
[R_ECX
]);
5737 /************************/
5740 if (s
->flags
& (HF_EM_MASK
| HF_TS_MASK
)) {
5741 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5742 /* XXX: what to do if illegal op ? */
5743 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
5746 modrm
= cpu_ldub_code(env
, s
->pc
++);
5747 mod
= (modrm
>> 6) & 3;
5749 op
= ((b
& 7) << 3) | ((modrm
>> 3) & 7);
5752 gen_lea_modrm(env
, s
, modrm
);
5754 case 0x00 ... 0x07: /* fxxxs */
5755 case 0x10 ... 0x17: /* fixxxl */
5756 case 0x20 ... 0x27: /* fxxxl */
5757 case 0x30 ... 0x37: /* fixxx */
5764 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5765 s
->mem_index
, MO_LEUL
);
5766 gen_helper_flds_FT0(cpu_env
, cpu_tmp2_i32
);
5769 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5770 s
->mem_index
, MO_LEUL
);
5771 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
5774 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
5775 s
->mem_index
, MO_LEQ
);
5776 gen_helper_fldl_FT0(cpu_env
, cpu_tmp1_i64
);
5780 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5781 s
->mem_index
, MO_LESW
);
5782 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
5786 gen_helper_fp_arith_ST0_FT0(op1
);
5788 /* fcomp needs pop */
5789 gen_helper_fpop(cpu_env
);
5793 case 0x08: /* flds */
5794 case 0x0a: /* fsts */
5795 case 0x0b: /* fstps */
5796 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5797 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5798 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5803 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5804 s
->mem_index
, MO_LEUL
);
5805 gen_helper_flds_ST0(cpu_env
, cpu_tmp2_i32
);
5808 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5809 s
->mem_index
, MO_LEUL
);
5810 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
5813 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
5814 s
->mem_index
, MO_LEQ
);
5815 gen_helper_fldl_ST0(cpu_env
, cpu_tmp1_i64
);
5819 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5820 s
->mem_index
, MO_LESW
);
5821 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
5826 /* XXX: the corresponding CPUID bit must be tested ! */
5829 gen_helper_fisttl_ST0(cpu_tmp2_i32
, cpu_env
);
5830 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5831 s
->mem_index
, MO_LEUL
);
5834 gen_helper_fisttll_ST0(cpu_tmp1_i64
, cpu_env
);
5835 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
5836 s
->mem_index
, MO_LEQ
);
5840 gen_helper_fistt_ST0(cpu_tmp2_i32
, cpu_env
);
5841 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5842 s
->mem_index
, MO_LEUW
);
5845 gen_helper_fpop(cpu_env
);
5850 gen_helper_fsts_ST0(cpu_tmp2_i32
, cpu_env
);
5851 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5852 s
->mem_index
, MO_LEUL
);
5855 gen_helper_fistl_ST0(cpu_tmp2_i32
, cpu_env
);
5856 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5857 s
->mem_index
, MO_LEUL
);
5860 gen_helper_fstl_ST0(cpu_tmp1_i64
, cpu_env
);
5861 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
5862 s
->mem_index
, MO_LEQ
);
5866 gen_helper_fist_ST0(cpu_tmp2_i32
, cpu_env
);
5867 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5868 s
->mem_index
, MO_LEUW
);
5872 gen_helper_fpop(cpu_env
);
5876 case 0x0c: /* fldenv mem */
5877 gen_helper_fldenv(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5879 case 0x0d: /* fldcw mem */
5880 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
5881 s
->mem_index
, MO_LEUW
);
5882 gen_helper_fldcw(cpu_env
, cpu_tmp2_i32
);
5884 case 0x0e: /* fnstenv mem */
5885 gen_helper_fstenv(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5887 case 0x0f: /* fnstcw mem */
5888 gen_helper_fnstcw(cpu_tmp2_i32
, cpu_env
);
5889 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5890 s
->mem_index
, MO_LEUW
);
5892 case 0x1d: /* fldt mem */
5893 gen_helper_fldt_ST0(cpu_env
, cpu_A0
);
5895 case 0x1f: /* fstpt mem */
5896 gen_helper_fstt_ST0(cpu_env
, cpu_A0
);
5897 gen_helper_fpop(cpu_env
);
5899 case 0x2c: /* frstor mem */
5900 gen_helper_frstor(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5902 case 0x2e: /* fnsave mem */
5903 gen_helper_fsave(cpu_env
, cpu_A0
, tcg_const_i32(dflag
- 1));
5905 case 0x2f: /* fnstsw mem */
5906 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
5907 tcg_gen_qemu_st_i32(cpu_tmp2_i32
, cpu_A0
,
5908 s
->mem_index
, MO_LEUW
);
5910 case 0x3c: /* fbld */
5911 gen_helper_fbld_ST0(cpu_env
, cpu_A0
);
5913 case 0x3e: /* fbstp */
5914 gen_helper_fbst_ST0(cpu_env
, cpu_A0
);
5915 gen_helper_fpop(cpu_env
);
5917 case 0x3d: /* fildll */
5918 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
5919 gen_helper_fildll_ST0(cpu_env
, cpu_tmp1_i64
);
5921 case 0x3f: /* fistpll */
5922 gen_helper_fistll_ST0(cpu_tmp1_i64
, cpu_env
);
5923 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
5924 gen_helper_fpop(cpu_env
);
5930 /* register float ops */
5934 case 0x08: /* fld sti */
5935 gen_helper_fpush(cpu_env
);
5936 gen_helper_fmov_ST0_STN(cpu_env
,
5937 tcg_const_i32((opreg
+ 1) & 7));
5939 case 0x09: /* fxchg sti */
5940 case 0x29: /* fxchg4 sti, undocumented op */
5941 case 0x39: /* fxchg7 sti, undocumented op */
5942 gen_helper_fxchg_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
5944 case 0x0a: /* grp d9/2 */
5947 /* check exceptions (FreeBSD FPU probe) */
5948 gen_helper_fwait(cpu_env
);
5954 case 0x0c: /* grp d9/4 */
5957 gen_helper_fchs_ST0(cpu_env
);
5960 gen_helper_fabs_ST0(cpu_env
);
5963 gen_helper_fldz_FT0(cpu_env
);
5964 gen_helper_fcom_ST0_FT0(cpu_env
);
5967 gen_helper_fxam_ST0(cpu_env
);
5973 case 0x0d: /* grp d9/5 */
5977 gen_helper_fpush(cpu_env
);
5978 gen_helper_fld1_ST0(cpu_env
);
5981 gen_helper_fpush(cpu_env
);
5982 gen_helper_fldl2t_ST0(cpu_env
);
5985 gen_helper_fpush(cpu_env
);
5986 gen_helper_fldl2e_ST0(cpu_env
);
5989 gen_helper_fpush(cpu_env
);
5990 gen_helper_fldpi_ST0(cpu_env
);
5993 gen_helper_fpush(cpu_env
);
5994 gen_helper_fldlg2_ST0(cpu_env
);
5997 gen_helper_fpush(cpu_env
);
5998 gen_helper_fldln2_ST0(cpu_env
);
6001 gen_helper_fpush(cpu_env
);
6002 gen_helper_fldz_ST0(cpu_env
);
6009 case 0x0e: /* grp d9/6 */
6012 gen_helper_f2xm1(cpu_env
);
6015 gen_helper_fyl2x(cpu_env
);
6018 gen_helper_fptan(cpu_env
);
6020 case 3: /* fpatan */
6021 gen_helper_fpatan(cpu_env
);
6023 case 4: /* fxtract */
6024 gen_helper_fxtract(cpu_env
);
6026 case 5: /* fprem1 */
6027 gen_helper_fprem1(cpu_env
);
6029 case 6: /* fdecstp */
6030 gen_helper_fdecstp(cpu_env
);
6033 case 7: /* fincstp */
6034 gen_helper_fincstp(cpu_env
);
6038 case 0x0f: /* grp d9/7 */
6041 gen_helper_fprem(cpu_env
);
6043 case 1: /* fyl2xp1 */
6044 gen_helper_fyl2xp1(cpu_env
);
6047 gen_helper_fsqrt(cpu_env
);
6049 case 3: /* fsincos */
6050 gen_helper_fsincos(cpu_env
);
6052 case 5: /* fscale */
6053 gen_helper_fscale(cpu_env
);
6055 case 4: /* frndint */
6056 gen_helper_frndint(cpu_env
);
6059 gen_helper_fsin(cpu_env
);
6063 gen_helper_fcos(cpu_env
);
6067 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6068 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6069 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6075 gen_helper_fp_arith_STN_ST0(op1
, opreg
);
6077 gen_helper_fpop(cpu_env
);
6079 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6080 gen_helper_fp_arith_ST0_FT0(op1
);
6084 case 0x02: /* fcom */
6085 case 0x22: /* fcom2, undocumented op */
6086 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6087 gen_helper_fcom_ST0_FT0(cpu_env
);
6089 case 0x03: /* fcomp */
6090 case 0x23: /* fcomp3, undocumented op */
6091 case 0x32: /* fcomp5, undocumented op */
6092 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6093 gen_helper_fcom_ST0_FT0(cpu_env
);
6094 gen_helper_fpop(cpu_env
);
6096 case 0x15: /* da/5 */
6098 case 1: /* fucompp */
6099 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6100 gen_helper_fucom_ST0_FT0(cpu_env
);
6101 gen_helper_fpop(cpu_env
);
6102 gen_helper_fpop(cpu_env
);
6110 case 0: /* feni (287 only, just do nop here) */
6112 case 1: /* fdisi (287 only, just do nop here) */
6115 gen_helper_fclex(cpu_env
);
6117 case 3: /* fninit */
6118 gen_helper_fninit(cpu_env
);
6120 case 4: /* fsetpm (287 only, just do nop here) */
6126 case 0x1d: /* fucomi */
6127 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6130 gen_update_cc_op(s
);
6131 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6132 gen_helper_fucomi_ST0_FT0(cpu_env
);
6133 set_cc_op(s
, CC_OP_EFLAGS
);
6135 case 0x1e: /* fcomi */
6136 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6139 gen_update_cc_op(s
);
6140 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6141 gen_helper_fcomi_ST0_FT0(cpu_env
);
6142 set_cc_op(s
, CC_OP_EFLAGS
);
6144 case 0x28: /* ffree sti */
6145 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6147 case 0x2a: /* fst sti */
6148 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6150 case 0x2b: /* fstp sti */
6151 case 0x0b: /* fstp1 sti, undocumented op */
6152 case 0x3a: /* fstp8 sti, undocumented op */
6153 case 0x3b: /* fstp9 sti, undocumented op */
6154 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6155 gen_helper_fpop(cpu_env
);
6157 case 0x2c: /* fucom st(i) */
6158 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6159 gen_helper_fucom_ST0_FT0(cpu_env
);
6161 case 0x2d: /* fucomp st(i) */
6162 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6163 gen_helper_fucom_ST0_FT0(cpu_env
);
6164 gen_helper_fpop(cpu_env
);
6166 case 0x33: /* de/3 */
6168 case 1: /* fcompp */
6169 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6170 gen_helper_fcom_ST0_FT0(cpu_env
);
6171 gen_helper_fpop(cpu_env
);
6172 gen_helper_fpop(cpu_env
);
6178 case 0x38: /* ffreep sti, undocumented op */
6179 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6180 gen_helper_fpop(cpu_env
);
6182 case 0x3c: /* df/4 */
6185 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
6186 tcg_gen_extu_i32_tl(cpu_T0
, cpu_tmp2_i32
);
6187 gen_op_mov_reg_v(MO_16
, R_EAX
, cpu_T0
);
6193 case 0x3d: /* fucomip */
6194 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6197 gen_update_cc_op(s
);
6198 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6199 gen_helper_fucomi_ST0_FT0(cpu_env
);
6200 gen_helper_fpop(cpu_env
);
6201 set_cc_op(s
, CC_OP_EFLAGS
);
6203 case 0x3e: /* fcomip */
6204 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6207 gen_update_cc_op(s
);
6208 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6209 gen_helper_fcomi_ST0_FT0(cpu_env
);
6210 gen_helper_fpop(cpu_env
);
6211 set_cc_op(s
, CC_OP_EFLAGS
);
6213 case 0x10 ... 0x13: /* fcmovxx */
6218 static const uint8_t fcmov_cc
[8] = {
6225 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6228 op1
= fcmov_cc
[op
& 3] | (((op
>> 3) & 1) ^ 1);
6229 l1
= gen_new_label();
6230 gen_jcc1_noeob(s
, op1
, l1
);
6231 gen_helper_fmov_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6240 /************************/
6243 case 0xa4: /* movsS */
6245 ot
= mo_b_d(b
, dflag
);
6246 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6247 gen_repz_movs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6253 case 0xaa: /* stosS */
6255 ot
= mo_b_d(b
, dflag
);
6256 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6257 gen_repz_stos(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6262 case 0xac: /* lodsS */
6264 ot
= mo_b_d(b
, dflag
);
6265 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6266 gen_repz_lods(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6271 case 0xae: /* scasS */
6273 ot
= mo_b_d(b
, dflag
);
6274 if (prefixes
& PREFIX_REPNZ
) {
6275 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6276 } else if (prefixes
& PREFIX_REPZ
) {
6277 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6283 case 0xa6: /* cmpsS */
6285 ot
= mo_b_d(b
, dflag
);
6286 if (prefixes
& PREFIX_REPNZ
) {
6287 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6288 } else if (prefixes
& PREFIX_REPZ
) {
6289 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6294 case 0x6c: /* insS */
6296 ot
= mo_b_d32(b
, dflag
);
6297 tcg_gen_ext16u_tl(cpu_T0
, cpu_regs
[R_EDX
]);
6298 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6299 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
) | 4);
6300 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6301 gen_repz_ins(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6304 if (s
->base
.tb
->cflags
& CF_USE_ICOUNT
) {
6305 gen_jmp(s
, s
->pc
- s
->cs_base
);
6309 case 0x6e: /* outsS */
6311 ot
= mo_b_d32(b
, dflag
);
6312 tcg_gen_ext16u_tl(cpu_T0
, cpu_regs
[R_EDX
]);
6313 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6314 svm_is_rep(prefixes
) | 4);
6315 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6316 gen_repz_outs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6319 if (s
->base
.tb
->cflags
& CF_USE_ICOUNT
) {
6320 gen_jmp(s
, s
->pc
- s
->cs_base
);
6325 /************************/
6330 ot
= mo_b_d32(b
, dflag
);
6331 val
= cpu_ldub_code(env
, s
->pc
++);
6332 tcg_gen_movi_tl(cpu_T0
, val
);
6333 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6334 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6335 if (s
->base
.tb
->cflags
& CF_USE_ICOUNT
) {
6338 tcg_gen_movi_i32(cpu_tmp2_i32
, val
);
6339 gen_helper_in_func(ot
, cpu_T1
, cpu_tmp2_i32
);
6340 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T1
);
6341 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6342 if (s
->base
.tb
->cflags
& CF_USE_ICOUNT
) {
6344 gen_jmp(s
, s
->pc
- s
->cs_base
);
6349 ot
= mo_b_d32(b
, dflag
);
6350 val
= cpu_ldub_code(env
, s
->pc
++);
6351 tcg_gen_movi_tl(cpu_T0
, val
);
6352 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6353 svm_is_rep(prefixes
));
6354 gen_op_mov_v_reg(ot
, cpu_T1
, R_EAX
);
6356 if (s
->base
.tb
->cflags
& CF_USE_ICOUNT
) {
6359 tcg_gen_movi_i32(cpu_tmp2_i32
, val
);
6360 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T1
);
6361 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6362 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6363 if (s
->base
.tb
->cflags
& CF_USE_ICOUNT
) {
6365 gen_jmp(s
, s
->pc
- s
->cs_base
);
6370 ot
= mo_b_d32(b
, dflag
);
6371 tcg_gen_ext16u_tl(cpu_T0
, cpu_regs
[R_EDX
]);
6372 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6373 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6374 if (s
->base
.tb
->cflags
& CF_USE_ICOUNT
) {
6377 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
6378 gen_helper_in_func(ot
, cpu_T1
, cpu_tmp2_i32
);
6379 gen_op_mov_reg_v(ot
, R_EAX
, cpu_T1
);
6380 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6381 if (s
->base
.tb
->cflags
& CF_USE_ICOUNT
) {
6383 gen_jmp(s
, s
->pc
- s
->cs_base
);
6388 ot
= mo_b_d32(b
, dflag
);
6389 tcg_gen_ext16u_tl(cpu_T0
, cpu_regs
[R_EDX
]);
6390 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6391 svm_is_rep(prefixes
));
6392 gen_op_mov_v_reg(ot
, cpu_T1
, R_EAX
);
6394 if (s
->base
.tb
->cflags
& CF_USE_ICOUNT
) {
6397 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
6398 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T1
);
6399 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6400 gen_bpt_io(s
, cpu_tmp2_i32
, ot
);
6401 if (s
->base
.tb
->cflags
& CF_USE_ICOUNT
) {
6403 gen_jmp(s
, s
->pc
- s
->cs_base
);
6407 /************************/
6409 case 0xc2: /* ret im */
6410 val
= cpu_ldsw_code(env
, s
->pc
);
6413 gen_stack_update(s
, val
+ (1 << ot
));
6414 /* Note that gen_pop_T0 uses a zero-extending load. */
6415 gen_op_jmp_v(cpu_T0
);
6419 case 0xc3: /* ret */
6421 gen_pop_update(s
, ot
);
6422 /* Note that gen_pop_T0 uses a zero-extending load. */
6423 gen_op_jmp_v(cpu_T0
);
6427 case 0xca: /* lret im */
6428 val
= cpu_ldsw_code(env
, s
->pc
);
6431 if (s
->pe
&& !s
->vm86
) {
6432 gen_update_cc_op(s
);
6433 gen_jmp_im(pc_start
- s
->cs_base
);
6434 gen_helper_lret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6435 tcg_const_i32(val
));
6439 gen_op_ld_v(s
, dflag
, cpu_T0
, cpu_A0
);
6440 /* NOTE: keeping EIP updated is not a problem in case of
6442 gen_op_jmp_v(cpu_T0
);
6444 gen_add_A0_im(s
, 1 << dflag
);
6445 gen_op_ld_v(s
, dflag
, cpu_T0
, cpu_A0
);
6446 gen_op_movl_seg_T0_vm(R_CS
);
6447 /* add stack offset */
6448 gen_stack_update(s
, val
+ (2 << dflag
));
6452 case 0xcb: /* lret */
6455 case 0xcf: /* iret */
6456 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IRET
);
6459 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6460 set_cc_op(s
, CC_OP_EFLAGS
);
6461 } else if (s
->vm86
) {
6463 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6465 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6466 set_cc_op(s
, CC_OP_EFLAGS
);
6469 gen_helper_iret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6470 tcg_const_i32(s
->pc
- s
->cs_base
));
6471 set_cc_op(s
, CC_OP_EFLAGS
);
6475 case 0xe8: /* call im */
6477 if (dflag
!= MO_16
) {
6478 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6480 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6482 next_eip
= s
->pc
- s
->cs_base
;
6484 if (dflag
== MO_16
) {
6486 } else if (!CODE64(s
)) {
6489 tcg_gen_movi_tl(cpu_T0
, next_eip
);
6490 gen_push_v(s
, cpu_T0
);
6495 case 0x9a: /* lcall im */
6497 unsigned int selector
, offset
;
6502 offset
= insn_get(env
, s
, ot
);
6503 selector
= insn_get(env
, s
, MO_16
);
6505 tcg_gen_movi_tl(cpu_T0
, selector
);
6506 tcg_gen_movi_tl(cpu_T1
, offset
);
6509 case 0xe9: /* jmp im */
6510 if (dflag
!= MO_16
) {
6511 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6513 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6515 tval
+= s
->pc
- s
->cs_base
;
6516 if (dflag
== MO_16
) {
6518 } else if (!CODE64(s
)) {
6524 case 0xea: /* ljmp im */
6526 unsigned int selector
, offset
;
6531 offset
= insn_get(env
, s
, ot
);
6532 selector
= insn_get(env
, s
, MO_16
);
6534 tcg_gen_movi_tl(cpu_T0
, selector
);
6535 tcg_gen_movi_tl(cpu_T1
, offset
);
6538 case 0xeb: /* jmp Jb */
6539 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6540 tval
+= s
->pc
- s
->cs_base
;
6541 if (dflag
== MO_16
) {
6546 case 0x70 ... 0x7f: /* jcc Jb */
6547 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6549 case 0x180 ... 0x18f: /* jcc Jv */
6550 if (dflag
!= MO_16
) {
6551 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6553 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6556 next_eip
= s
->pc
- s
->cs_base
;
6558 if (dflag
== MO_16
) {
6562 gen_jcc(s
, b
, tval
, next_eip
);
6565 case 0x190 ... 0x19f: /* setcc Gv */
6566 modrm
= cpu_ldub_code(env
, s
->pc
++);
6567 gen_setcc1(s
, b
, cpu_T0
);
6568 gen_ldst_modrm(env
, s
, modrm
, MO_8
, OR_TMP0
, 1);
6570 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6571 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6575 modrm
= cpu_ldub_code(env
, s
->pc
++);
6576 reg
= ((modrm
>> 3) & 7) | rex_r
;
6577 gen_cmovcc1(env
, s
, ot
, b
, modrm
, reg
);
6580 /************************/
6582 case 0x9c: /* pushf */
6583 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_PUSHF
);
6584 if (s
->vm86
&& s
->iopl
!= 3) {
6585 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6587 gen_update_cc_op(s
);
6588 gen_helper_read_eflags(cpu_T0
, cpu_env
);
6589 gen_push_v(s
, cpu_T0
);
6592 case 0x9d: /* popf */
6593 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_POPF
);
6594 if (s
->vm86
&& s
->iopl
!= 3) {
6595 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6599 if (dflag
!= MO_16
) {
6600 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6601 tcg_const_i32((TF_MASK
| AC_MASK
|
6606 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6607 tcg_const_i32((TF_MASK
| AC_MASK
|
6609 IF_MASK
| IOPL_MASK
)
6613 if (s
->cpl
<= s
->iopl
) {
6614 if (dflag
!= MO_16
) {
6615 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6616 tcg_const_i32((TF_MASK
|
6622 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6623 tcg_const_i32((TF_MASK
|
6631 if (dflag
!= MO_16
) {
6632 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6633 tcg_const_i32((TF_MASK
| AC_MASK
|
6634 ID_MASK
| NT_MASK
)));
6636 gen_helper_write_eflags(cpu_env
, cpu_T0
,
6637 tcg_const_i32((TF_MASK
| AC_MASK
|
6643 gen_pop_update(s
, ot
);
6644 set_cc_op(s
, CC_OP_EFLAGS
);
6645 /* abort translation because TF/AC flag may change */
6646 gen_jmp_im(s
->pc
- s
->cs_base
);
6650 case 0x9e: /* sahf */
6651 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6653 gen_op_mov_v_reg(MO_8
, cpu_T0
, R_AH
);
6654 gen_compute_eflags(s
);
6655 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, CC_O
);
6656 tcg_gen_andi_tl(cpu_T0
, cpu_T0
, CC_S
| CC_Z
| CC_A
| CC_P
| CC_C
);
6657 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, cpu_T0
);
6659 case 0x9f: /* lahf */
6660 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6662 gen_compute_eflags(s
);
6663 /* Note: gen_compute_eflags() only gives the condition codes */
6664 tcg_gen_ori_tl(cpu_T0
, cpu_cc_src
, 0x02);
6665 gen_op_mov_reg_v(MO_8
, R_AH
, cpu_T0
);
6667 case 0xf5: /* cmc */
6668 gen_compute_eflags(s
);
6669 tcg_gen_xori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6671 case 0xf8: /* clc */
6672 gen_compute_eflags(s
);
6673 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_C
);
6675 case 0xf9: /* stc */
6676 gen_compute_eflags(s
);
6677 tcg_gen_ori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6679 case 0xfc: /* cld */
6680 tcg_gen_movi_i32(cpu_tmp2_i32
, 1);
6681 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6683 case 0xfd: /* std */
6684 tcg_gen_movi_i32(cpu_tmp2_i32
, -1);
6685 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6688 /************************/
6689 /* bit operations */
6690 case 0x1ba: /* bt/bts/btr/btc Gv, im */
6692 modrm
= cpu_ldub_code(env
, s
->pc
++);
6693 op
= (modrm
>> 3) & 7;
6694 mod
= (modrm
>> 6) & 3;
6695 rm
= (modrm
& 7) | REX_B(s
);
6698 gen_lea_modrm(env
, s
, modrm
);
6699 if (!(s
->prefix
& PREFIX_LOCK
)) {
6700 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
6703 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
6706 val
= cpu_ldub_code(env
, s
->pc
++);
6707 tcg_gen_movi_tl(cpu_T1
, val
);
6712 case 0x1a3: /* bt Gv, Ev */
6715 case 0x1ab: /* bts */
6718 case 0x1b3: /* btr */
6721 case 0x1bb: /* btc */
6725 modrm
= cpu_ldub_code(env
, s
->pc
++);
6726 reg
= ((modrm
>> 3) & 7) | rex_r
;
6727 mod
= (modrm
>> 6) & 3;
6728 rm
= (modrm
& 7) | REX_B(s
);
6729 gen_op_mov_v_reg(MO_32
, cpu_T1
, reg
);
6731 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
6732 /* specific case: we need to add a displacement */
6733 gen_exts(ot
, cpu_T1
);
6734 tcg_gen_sari_tl(cpu_tmp0
, cpu_T1
, 3 + ot
);
6735 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, ot
);
6736 tcg_gen_add_tl(cpu_A0
, gen_lea_modrm_1(a
), cpu_tmp0
);
6737 gen_lea_v_seg(s
, s
->aflag
, cpu_A0
, a
.def_seg
, s
->override
);
6738 if (!(s
->prefix
& PREFIX_LOCK
)) {
6739 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
6742 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
6745 tcg_gen_andi_tl(cpu_T1
, cpu_T1
, (1 << (3 + ot
)) - 1);
6746 tcg_gen_movi_tl(cpu_tmp0
, 1);
6747 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T1
);
6748 if (s
->prefix
& PREFIX_LOCK
) {
6751 /* Needs no atomic ops; we surpressed the normal
6752 memory load for LOCK above so do it now. */
6753 gen_op_ld_v(s
, ot
, cpu_T0
, cpu_A0
);
6756 tcg_gen_atomic_fetch_or_tl(cpu_T0
, cpu_A0
, cpu_tmp0
,
6757 s
->mem_index
, ot
| MO_LE
);
6760 tcg_gen_not_tl(cpu_tmp0
, cpu_tmp0
);
6761 tcg_gen_atomic_fetch_and_tl(cpu_T0
, cpu_A0
, cpu_tmp0
,
6762 s
->mem_index
, ot
| MO_LE
);
6766 tcg_gen_atomic_fetch_xor_tl(cpu_T0
, cpu_A0
, cpu_tmp0
,
6767 s
->mem_index
, ot
| MO_LE
);
6770 tcg_gen_shr_tl(cpu_tmp4
, cpu_T0
, cpu_T1
);
6772 tcg_gen_shr_tl(cpu_tmp4
, cpu_T0
, cpu_T1
);
6775 /* Data already loaded; nothing to do. */
6778 tcg_gen_or_tl(cpu_T0
, cpu_T0
, cpu_tmp0
);
6781 tcg_gen_andc_tl(cpu_T0
, cpu_T0
, cpu_tmp0
);
6785 tcg_gen_xor_tl(cpu_T0
, cpu_T0
, cpu_tmp0
);
6790 gen_op_st_v(s
, ot
, cpu_T0
, cpu_A0
);
6792 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
6797 /* Delay all CC updates until after the store above. Note that
6798 C is the result of the test, Z is unchanged, and the others
6799 are all undefined. */
6801 case CC_OP_MULB
... CC_OP_MULQ
:
6802 case CC_OP_ADDB
... CC_OP_ADDQ
:
6803 case CC_OP_ADCB
... CC_OP_ADCQ
:
6804 case CC_OP_SUBB
... CC_OP_SUBQ
:
6805 case CC_OP_SBBB
... CC_OP_SBBQ
:
6806 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
6807 case CC_OP_INCB
... CC_OP_INCQ
:
6808 case CC_OP_DECB
... CC_OP_DECQ
:
6809 case CC_OP_SHLB
... CC_OP_SHLQ
:
6810 case CC_OP_SARB
... CC_OP_SARQ
:
6811 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
6812 /* Z was going to be computed from the non-zero status of CC_DST.
6813 We can get that same Z value (and the new C value) by leaving
6814 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
6816 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
6817 set_cc_op(s
, ((s
->cc_op
- CC_OP_MULB
) & 3) + CC_OP_SARB
);
6820 /* Otherwise, generate EFLAGS and replace the C bit. */
6821 gen_compute_eflags(s
);
6822 tcg_gen_deposit_tl(cpu_cc_src
, cpu_cc_src
, cpu_tmp4
,
6827 case 0x1bc: /* bsf / tzcnt */
6828 case 0x1bd: /* bsr / lzcnt */
6830 modrm
= cpu_ldub_code(env
, s
->pc
++);
6831 reg
= ((modrm
>> 3) & 7) | rex_r
;
6832 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
6833 gen_extu(ot
, cpu_T0
);
6835 /* Note that lzcnt and tzcnt are in different extensions. */
6836 if ((prefixes
& PREFIX_REPZ
)
6838 ? s
->cpuid_ext3_features
& CPUID_EXT3_ABM
6839 : s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)) {
6841 /* For lzcnt/tzcnt, C bit is defined related to the input. */
6842 tcg_gen_mov_tl(cpu_cc_src
, cpu_T0
);
6844 /* For lzcnt, reduce the target_ulong result by the
6845 number of zeros that we expect to find at the top. */
6846 tcg_gen_clzi_tl(cpu_T0
, cpu_T0
, TARGET_LONG_BITS
);
6847 tcg_gen_subi_tl(cpu_T0
, cpu_T0
, TARGET_LONG_BITS
- size
);
6849 /* For tzcnt, a zero input must return the operand size. */
6850 tcg_gen_ctzi_tl(cpu_T0
, cpu_T0
, size
);
6852 /* For lzcnt/tzcnt, Z bit is defined related to the result. */
6853 gen_op_update1_cc();
6854 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
6856 /* For bsr/bsf, only the Z bit is defined and it is related
6857 to the input and not the result. */
6858 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T0
);
6859 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
6861 /* ??? The manual says that the output is undefined when the
6862 input is zero, but real hardware leaves it unchanged, and
6863 real programs appear to depend on that. Accomplish this
6864 by passing the output as the value to return upon zero. */
6866 /* For bsr, return the bit index of the first 1 bit,
6867 not the count of leading zeros. */
6868 tcg_gen_xori_tl(cpu_T1
, cpu_regs
[reg
], TARGET_LONG_BITS
- 1);
6869 tcg_gen_clz_tl(cpu_T0
, cpu_T0
, cpu_T1
);
6870 tcg_gen_xori_tl(cpu_T0
, cpu_T0
, TARGET_LONG_BITS
- 1);
6872 tcg_gen_ctz_tl(cpu_T0
, cpu_T0
, cpu_regs
[reg
]);
6875 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
6877 /************************/
6879 case 0x27: /* daa */
6882 gen_update_cc_op(s
);
6883 gen_helper_daa(cpu_env
);
6884 set_cc_op(s
, CC_OP_EFLAGS
);
6886 case 0x2f: /* das */
6889 gen_update_cc_op(s
);
6890 gen_helper_das(cpu_env
);
6891 set_cc_op(s
, CC_OP_EFLAGS
);
6893 case 0x37: /* aaa */
6896 gen_update_cc_op(s
);
6897 gen_helper_aaa(cpu_env
);
6898 set_cc_op(s
, CC_OP_EFLAGS
);
6900 case 0x3f: /* aas */
6903 gen_update_cc_op(s
);
6904 gen_helper_aas(cpu_env
);
6905 set_cc_op(s
, CC_OP_EFLAGS
);
6907 case 0xd4: /* aam */
6910 val
= cpu_ldub_code(env
, s
->pc
++);
6912 gen_exception(s
, EXCP00_DIVZ
, pc_start
- s
->cs_base
);
6914 gen_helper_aam(cpu_env
, tcg_const_i32(val
));
6915 set_cc_op(s
, CC_OP_LOGICB
);
6918 case 0xd5: /* aad */
6921 val
= cpu_ldub_code(env
, s
->pc
++);
6922 gen_helper_aad(cpu_env
, tcg_const_i32(val
));
6923 set_cc_op(s
, CC_OP_LOGICB
);
6925 /************************/
6927 case 0x90: /* nop */
6928 /* XXX: correct lock test for all insn */
6929 if (prefixes
& PREFIX_LOCK
) {
6932 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
6934 goto do_xchg_reg_eax
;
6936 if (prefixes
& PREFIX_REPZ
) {
6937 gen_update_cc_op(s
);
6938 gen_jmp_im(pc_start
- s
->cs_base
);
6939 gen_helper_pause(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
6940 s
->base
.is_jmp
= DISAS_NORETURN
;
6943 case 0x9b: /* fwait */
6944 if ((s
->flags
& (HF_MP_MASK
| HF_TS_MASK
)) ==
6945 (HF_MP_MASK
| HF_TS_MASK
)) {
6946 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
6948 gen_helper_fwait(cpu_env
);
6951 case 0xcc: /* int3 */
6952 gen_interrupt(s
, EXCP03_INT3
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6954 case 0xcd: /* int N */
6955 val
= cpu_ldub_code(env
, s
->pc
++);
6956 if (s
->vm86
&& s
->iopl
!= 3) {
6957 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6959 gen_interrupt(s
, val
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6962 case 0xce: /* into */
6965 gen_update_cc_op(s
);
6966 gen_jmp_im(pc_start
- s
->cs_base
);
6967 gen_helper_into(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
6970 case 0xf1: /* icebp (undocumented, exits to external debugger) */
6971 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_ICEBP
);
6973 gen_debug(s
, pc_start
- s
->cs_base
);
6976 tb_flush(CPU(x86_env_get_cpu(env
)));
6977 qemu_set_log(CPU_LOG_INT
| CPU_LOG_TB_IN_ASM
);
6981 case 0xfa: /* cli */
6983 if (s
->cpl
<= s
->iopl
) {
6984 gen_helper_cli(cpu_env
);
6986 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6990 gen_helper_cli(cpu_env
);
6992 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6996 case 0xfb: /* sti */
6997 if (s
->vm86
? s
->iopl
== 3 : s
->cpl
<= s
->iopl
) {
6998 gen_helper_sti(cpu_env
);
6999 /* interruptions are enabled only the first insn after sti */
7000 gen_jmp_im(s
->pc
- s
->cs_base
);
7001 gen_eob_inhibit_irq(s
, true);
7003 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7006 case 0x62: /* bound */
7010 modrm
= cpu_ldub_code(env
, s
->pc
++);
7011 reg
= (modrm
>> 3) & 7;
7012 mod
= (modrm
>> 6) & 3;
7015 gen_op_mov_v_reg(ot
, cpu_T0
, reg
);
7016 gen_lea_modrm(env
, s
, modrm
);
7017 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
7019 gen_helper_boundw(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
7021 gen_helper_boundl(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
7024 case 0x1c8 ... 0x1cf: /* bswap reg */
7025 reg
= (b
& 7) | REX_B(s
);
7026 #ifdef TARGET_X86_64
7027 if (dflag
== MO_64
) {
7028 gen_op_mov_v_reg(MO_64
, cpu_T0
, reg
);
7029 tcg_gen_bswap64_i64(cpu_T0
, cpu_T0
);
7030 gen_op_mov_reg_v(MO_64
, reg
, cpu_T0
);
7034 gen_op_mov_v_reg(MO_32
, cpu_T0
, reg
);
7035 tcg_gen_ext32u_tl(cpu_T0
, cpu_T0
);
7036 tcg_gen_bswap32_tl(cpu_T0
, cpu_T0
);
7037 gen_op_mov_reg_v(MO_32
, reg
, cpu_T0
);
7040 case 0xd6: /* salc */
7043 gen_compute_eflags_c(s
, cpu_T0
);
7044 tcg_gen_neg_tl(cpu_T0
, cpu_T0
);
7045 gen_op_mov_reg_v(MO_8
, R_EAX
, cpu_T0
);
7047 case 0xe0: /* loopnz */
7048 case 0xe1: /* loopz */
7049 case 0xe2: /* loop */
7050 case 0xe3: /* jecxz */
7052 TCGLabel
*l1
, *l2
, *l3
;
7054 tval
= (int8_t)insn_get(env
, s
, MO_8
);
7055 next_eip
= s
->pc
- s
->cs_base
;
7057 if (dflag
== MO_16
) {
7061 l1
= gen_new_label();
7062 l2
= gen_new_label();
7063 l3
= gen_new_label();
7066 case 0: /* loopnz */
7068 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
7069 gen_op_jz_ecx(s
->aflag
, l3
);
7070 gen_jcc1(s
, (JCC_Z
<< 1) | (b
^ 1), l1
);
7073 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
7074 gen_op_jnz_ecx(s
->aflag
, l1
);
7078 gen_op_jz_ecx(s
->aflag
, l1
);
7083 gen_jmp_im(next_eip
);
7092 case 0x130: /* wrmsr */
7093 case 0x132: /* rdmsr */
7095 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7097 gen_update_cc_op(s
);
7098 gen_jmp_im(pc_start
- s
->cs_base
);
7100 gen_helper_rdmsr(cpu_env
);
7102 gen_helper_wrmsr(cpu_env
);
7106 case 0x131: /* rdtsc */
7107 gen_update_cc_op(s
);
7108 gen_jmp_im(pc_start
- s
->cs_base
);
7109 if (s
->base
.tb
->cflags
& CF_USE_ICOUNT
) {
7112 gen_helper_rdtsc(cpu_env
);
7113 if (s
->base
.tb
->cflags
& CF_USE_ICOUNT
) {
7115 gen_jmp(s
, s
->pc
- s
->cs_base
);
7118 case 0x133: /* rdpmc */
7119 gen_update_cc_op(s
);
7120 gen_jmp_im(pc_start
- s
->cs_base
);
7121 gen_helper_rdpmc(cpu_env
);
7123 case 0x134: /* sysenter */
7124 /* For Intel SYSENTER is valid on 64-bit */
7125 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7128 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7130 gen_helper_sysenter(cpu_env
);
7134 case 0x135: /* sysexit */
7135 /* For Intel SYSEXIT is valid on 64-bit */
7136 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7139 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7141 gen_helper_sysexit(cpu_env
, tcg_const_i32(dflag
- 1));
7145 #ifdef TARGET_X86_64
7146 case 0x105: /* syscall */
7147 /* XXX: is it usable in real mode ? */
7148 gen_update_cc_op(s
);
7149 gen_jmp_im(pc_start
- s
->cs_base
);
7150 gen_helper_syscall(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7151 /* TF handling for the syscall insn is different. The TF bit is checked
7152 after the syscall insn completes. This allows #DB to not be
7153 generated after one has entered CPL0 if TF is set in FMASK. */
7154 gen_eob_worker(s
, false, true);
7156 case 0x107: /* sysret */
7158 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7160 gen_helper_sysret(cpu_env
, tcg_const_i32(dflag
- 1));
7161 /* condition codes are modified only in long mode */
7163 set_cc_op(s
, CC_OP_EFLAGS
);
7165 /* TF handling for the sysret insn is different. The TF bit is
7166 checked after the sysret insn completes. This allows #DB to be
7167 generated "as if" the syscall insn in userspace has just
7169 gen_eob_worker(s
, false, true);
7173 case 0x1a2: /* cpuid */
7174 gen_update_cc_op(s
);
7175 gen_jmp_im(pc_start
- s
->cs_base
);
7176 gen_helper_cpuid(cpu_env
);
7178 case 0xf4: /* hlt */
7180 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7182 gen_update_cc_op(s
);
7183 gen_jmp_im(pc_start
- s
->cs_base
);
7184 gen_helper_hlt(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7185 s
->base
.is_jmp
= DISAS_NORETURN
;
7189 modrm
= cpu_ldub_code(env
, s
->pc
++);
7190 mod
= (modrm
>> 6) & 3;
7191 op
= (modrm
>> 3) & 7;
7194 if (!s
->pe
|| s
->vm86
)
7196 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_READ
);
7197 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
,
7198 offsetof(CPUX86State
, ldt
.selector
));
7199 ot
= mod
== 3 ? dflag
: MO_16
;
7200 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7203 if (!s
->pe
|| s
->vm86
)
7206 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7208 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_WRITE
);
7209 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7210 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
7211 gen_helper_lldt(cpu_env
, cpu_tmp2_i32
);
7215 if (!s
->pe
|| s
->vm86
)
7217 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_READ
);
7218 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
,
7219 offsetof(CPUX86State
, tr
.selector
));
7220 ot
= mod
== 3 ? dflag
: MO_16
;
7221 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7224 if (!s
->pe
|| s
->vm86
)
7227 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7229 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_WRITE
);
7230 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7231 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T0
);
7232 gen_helper_ltr(cpu_env
, cpu_tmp2_i32
);
7237 if (!s
->pe
|| s
->vm86
)
7239 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7240 gen_update_cc_op(s
);
7242 gen_helper_verr(cpu_env
, cpu_T0
);
7244 gen_helper_verw(cpu_env
, cpu_T0
);
7246 set_cc_op(s
, CC_OP_EFLAGS
);
7254 modrm
= cpu_ldub_code(env
, s
->pc
++);
7256 CASE_MODRM_MEM_OP(0): /* sgdt */
7257 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_READ
);
7258 gen_lea_modrm(env
, s
, modrm
);
7259 tcg_gen_ld32u_tl(cpu_T0
,
7260 cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7261 gen_op_st_v(s
, MO_16
, cpu_T0
, cpu_A0
);
7262 gen_add_A0_im(s
, 2);
7263 tcg_gen_ld_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7264 if (dflag
== MO_16
) {
7265 tcg_gen_andi_tl(cpu_T0
, cpu_T0
, 0xffffff);
7267 gen_op_st_v(s
, CODE64(s
) + MO_32
, cpu_T0
, cpu_A0
);
7270 case 0xc8: /* monitor */
7271 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) || s
->cpl
!= 0) {
7274 gen_update_cc_op(s
);
7275 gen_jmp_im(pc_start
- s
->cs_base
);
7276 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[R_EAX
]);
7277 gen_extu(s
->aflag
, cpu_A0
);
7278 gen_add_A0_ds_seg(s
);
7279 gen_helper_monitor(cpu_env
, cpu_A0
);
7282 case 0xc9: /* mwait */
7283 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) || s
->cpl
!= 0) {
7286 gen_update_cc_op(s
);
7287 gen_jmp_im(pc_start
- s
->cs_base
);
7288 gen_helper_mwait(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7292 case 0xca: /* clac */
7293 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
)
7297 gen_helper_clac(cpu_env
);
7298 gen_jmp_im(s
->pc
- s
->cs_base
);
7302 case 0xcb: /* stac */
7303 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
)
7307 gen_helper_stac(cpu_env
);
7308 gen_jmp_im(s
->pc
- s
->cs_base
);
7312 CASE_MODRM_MEM_OP(1): /* sidt */
7313 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_READ
);
7314 gen_lea_modrm(env
, s
, modrm
);
7315 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7316 gen_op_st_v(s
, MO_16
, cpu_T0
, cpu_A0
);
7317 gen_add_A0_im(s
, 2);
7318 tcg_gen_ld_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, idt
.base
));
7319 if (dflag
== MO_16
) {
7320 tcg_gen_andi_tl(cpu_T0
, cpu_T0
, 0xffffff);
7322 gen_op_st_v(s
, CODE64(s
) + MO_32
, cpu_T0
, cpu_A0
);
7325 case 0xd0: /* xgetbv */
7326 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
7327 || (s
->prefix
& (PREFIX_LOCK
| PREFIX_DATA
7328 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
7331 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_ECX
]);
7332 gen_helper_xgetbv(cpu_tmp1_i64
, cpu_env
, cpu_tmp2_i32
);
7333 tcg_gen_extr_i64_tl(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
], cpu_tmp1_i64
);
7336 case 0xd1: /* xsetbv */
7337 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
7338 || (s
->prefix
& (PREFIX_LOCK
| PREFIX_DATA
7339 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
7343 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7346 tcg_gen_concat_tl_i64(cpu_tmp1_i64
, cpu_regs
[R_EAX
],
7348 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_ECX
]);
7349 gen_helper_xsetbv(cpu_env
, cpu_tmp2_i32
, cpu_tmp1_i64
);
7350 /* End TB because translation flags may change. */
7351 gen_jmp_im(s
->pc
- s
->cs_base
);
7355 case 0xd8: /* VMRUN */
7356 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7360 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7363 gen_update_cc_op(s
);
7364 gen_jmp_im(pc_start
- s
->cs_base
);
7365 gen_helper_vmrun(cpu_env
, tcg_const_i32(s
->aflag
- 1),
7366 tcg_const_i32(s
->pc
- pc_start
));
7368 s
->base
.is_jmp
= DISAS_NORETURN
;
7371 case 0xd9: /* VMMCALL */
7372 if (!(s
->flags
& HF_SVME_MASK
)) {
7375 gen_update_cc_op(s
);
7376 gen_jmp_im(pc_start
- s
->cs_base
);
7377 gen_helper_vmmcall(cpu_env
);
7380 case 0xda: /* VMLOAD */
7381 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7385 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7388 gen_update_cc_op(s
);
7389 gen_jmp_im(pc_start
- s
->cs_base
);
7390 gen_helper_vmload(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7393 case 0xdb: /* VMSAVE */
7394 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7398 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7401 gen_update_cc_op(s
);
7402 gen_jmp_im(pc_start
- s
->cs_base
);
7403 gen_helper_vmsave(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7406 case 0xdc: /* STGI */
7407 if ((!(s
->flags
& HF_SVME_MASK
)
7408 && !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
))
7413 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7416 gen_update_cc_op(s
);
7417 gen_jmp_im(pc_start
- s
->cs_base
);
7418 gen_helper_stgi(cpu_env
);
7421 case 0xdd: /* CLGI */
7422 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7426 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7429 gen_update_cc_op(s
);
7430 gen_jmp_im(pc_start
- s
->cs_base
);
7431 gen_helper_clgi(cpu_env
);
7434 case 0xde: /* SKINIT */
7435 if ((!(s
->flags
& HF_SVME_MASK
)
7436 && !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
))
7440 gen_update_cc_op(s
);
7441 gen_jmp_im(pc_start
- s
->cs_base
);
7442 gen_helper_skinit(cpu_env
);
7445 case 0xdf: /* INVLPGA */
7446 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
) {
7450 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7453 gen_update_cc_op(s
);
7454 gen_jmp_im(pc_start
- s
->cs_base
);
7455 gen_helper_invlpga(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7458 CASE_MODRM_MEM_OP(2): /* lgdt */
7460 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7463 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_WRITE
);
7464 gen_lea_modrm(env
, s
, modrm
);
7465 gen_op_ld_v(s
, MO_16
, cpu_T1
, cpu_A0
);
7466 gen_add_A0_im(s
, 2);
7467 gen_op_ld_v(s
, CODE64(s
) + MO_32
, cpu_T0
, cpu_A0
);
7468 if (dflag
== MO_16
) {
7469 tcg_gen_andi_tl(cpu_T0
, cpu_T0
, 0xffffff);
7471 tcg_gen_st_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7472 tcg_gen_st32_tl(cpu_T1
, cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7475 CASE_MODRM_MEM_OP(3): /* lidt */
7477 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7480 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_WRITE
);
7481 gen_lea_modrm(env
, s
, modrm
);
7482 gen_op_ld_v(s
, MO_16
, cpu_T1
, cpu_A0
);
7483 gen_add_A0_im(s
, 2);
7484 gen_op_ld_v(s
, CODE64(s
) + MO_32
, cpu_T0
, cpu_A0
);
7485 if (dflag
== MO_16
) {
7486 tcg_gen_andi_tl(cpu_T0
, cpu_T0
, 0xffffff);
7488 tcg_gen_st_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, idt
.base
));
7489 tcg_gen_st32_tl(cpu_T1
, cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7492 CASE_MODRM_OP(4): /* smsw */
7493 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_CR0
);
7494 tcg_gen_ld_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, cr
[0]));
7496 mod
= (modrm
>> 6) & 3;
7497 ot
= (mod
!= 3 ? MO_16
: s
->dflag
);
7501 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7503 case 0xee: /* rdpkru */
7504 if (prefixes
& PREFIX_LOCK
) {
7507 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_ECX
]);
7508 gen_helper_rdpkru(cpu_tmp1_i64
, cpu_env
, cpu_tmp2_i32
);
7509 tcg_gen_extr_i64_tl(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
], cpu_tmp1_i64
);
7511 case 0xef: /* wrpkru */
7512 if (prefixes
& PREFIX_LOCK
) {
7515 tcg_gen_concat_tl_i64(cpu_tmp1_i64
, cpu_regs
[R_EAX
],
7517 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_regs
[R_ECX
]);
7518 gen_helper_wrpkru(cpu_env
, cpu_tmp2_i32
, cpu_tmp1_i64
);
7520 CASE_MODRM_OP(6): /* lmsw */
7522 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7525 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7526 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7527 gen_helper_lmsw(cpu_env
, cpu_T0
);
7528 gen_jmp_im(s
->pc
- s
->cs_base
);
7532 CASE_MODRM_MEM_OP(7): /* invlpg */
7534 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7537 gen_update_cc_op(s
);
7538 gen_jmp_im(pc_start
- s
->cs_base
);
7539 gen_lea_modrm(env
, s
, modrm
);
7540 gen_helper_invlpg(cpu_env
, cpu_A0
);
7541 gen_jmp_im(s
->pc
- s
->cs_base
);
7545 case 0xf8: /* swapgs */
7546 #ifdef TARGET_X86_64
7549 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7551 tcg_gen_mov_tl(cpu_T0
, cpu_seg_base
[R_GS
]);
7552 tcg_gen_ld_tl(cpu_seg_base
[R_GS
], cpu_env
,
7553 offsetof(CPUX86State
, kernelgsbase
));
7554 tcg_gen_st_tl(cpu_T0
, cpu_env
,
7555 offsetof(CPUX86State
, kernelgsbase
));
7562 case 0xf9: /* rdtscp */
7563 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_RDTSCP
)) {
7566 gen_update_cc_op(s
);
7567 gen_jmp_im(pc_start
- s
->cs_base
);
7568 if (s
->base
.tb
->cflags
& CF_USE_ICOUNT
) {
7571 gen_helper_rdtscp(cpu_env
);
7572 if (s
->base
.tb
->cflags
& CF_USE_ICOUNT
) {
7574 gen_jmp(s
, s
->pc
- s
->cs_base
);
7583 case 0x108: /* invd */
7584 case 0x109: /* wbinvd */
7586 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7588 gen_svm_check_intercept(s
, pc_start
, (b
& 2) ? SVM_EXIT_INVD
: SVM_EXIT_WBINVD
);
7592 case 0x63: /* arpl or movslS (x86_64) */
7593 #ifdef TARGET_X86_64
7596 /* d_ot is the size of destination */
7599 modrm
= cpu_ldub_code(env
, s
->pc
++);
7600 reg
= ((modrm
>> 3) & 7) | rex_r
;
7601 mod
= (modrm
>> 6) & 3;
7602 rm
= (modrm
& 7) | REX_B(s
);
7605 gen_op_mov_v_reg(MO_32
, cpu_T0
, rm
);
7607 if (d_ot
== MO_64
) {
7608 tcg_gen_ext32s_tl(cpu_T0
, cpu_T0
);
7610 gen_op_mov_reg_v(d_ot
, reg
, cpu_T0
);
7612 gen_lea_modrm(env
, s
, modrm
);
7613 gen_op_ld_v(s
, MO_32
| MO_SIGN
, cpu_T0
, cpu_A0
);
7614 gen_op_mov_reg_v(d_ot
, reg
, cpu_T0
);
7620 TCGv t0
, t1
, t2
, a0
;
7622 if (!s
->pe
|| s
->vm86
)
7624 t0
= tcg_temp_local_new();
7625 t1
= tcg_temp_local_new();
7626 t2
= tcg_temp_local_new();
7628 modrm
= cpu_ldub_code(env
, s
->pc
++);
7629 reg
= (modrm
>> 3) & 7;
7630 mod
= (modrm
>> 6) & 3;
7633 gen_lea_modrm(env
, s
, modrm
);
7634 gen_op_ld_v(s
, ot
, t0
, cpu_A0
);
7635 a0
= tcg_temp_local_new();
7636 tcg_gen_mov_tl(a0
, cpu_A0
);
7638 gen_op_mov_v_reg(ot
, t0
, rm
);
7641 gen_op_mov_v_reg(ot
, t1
, reg
);
7642 tcg_gen_andi_tl(cpu_tmp0
, t0
, 3);
7643 tcg_gen_andi_tl(t1
, t1
, 3);
7644 tcg_gen_movi_tl(t2
, 0);
7645 label1
= gen_new_label();
7646 tcg_gen_brcond_tl(TCG_COND_GE
, cpu_tmp0
, t1
, label1
);
7647 tcg_gen_andi_tl(t0
, t0
, ~3);
7648 tcg_gen_or_tl(t0
, t0
, t1
);
7649 tcg_gen_movi_tl(t2
, CC_Z
);
7650 gen_set_label(label1
);
7652 gen_op_st_v(s
, ot
, t0
, a0
);
7655 gen_op_mov_reg_v(ot
, rm
, t0
);
7657 gen_compute_eflags(s
);
7658 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_Z
);
7659 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, t2
);
7665 case 0x102: /* lar */
7666 case 0x103: /* lsl */
7670 if (!s
->pe
|| s
->vm86
)
7672 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
7673 modrm
= cpu_ldub_code(env
, s
->pc
++);
7674 reg
= ((modrm
>> 3) & 7) | rex_r
;
7675 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7676 t0
= tcg_temp_local_new();
7677 gen_update_cc_op(s
);
7679 gen_helper_lar(t0
, cpu_env
, cpu_T0
);
7681 gen_helper_lsl(t0
, cpu_env
, cpu_T0
);
7683 tcg_gen_andi_tl(cpu_tmp0
, cpu_cc_src
, CC_Z
);
7684 label1
= gen_new_label();
7685 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
7686 gen_op_mov_reg_v(ot
, reg
, t0
);
7687 gen_set_label(label1
);
7688 set_cc_op(s
, CC_OP_EFLAGS
);
7693 modrm
= cpu_ldub_code(env
, s
->pc
++);
7694 mod
= (modrm
>> 6) & 3;
7695 op
= (modrm
>> 3) & 7;
7697 case 0: /* prefetchnta */
7698 case 1: /* prefetchnt0 */
7699 case 2: /* prefetchnt0 */
7700 case 3: /* prefetchnt0 */
7703 gen_nop_modrm(env
, s
, modrm
);
7704 /* nothing more to do */
7706 default: /* nop (multi byte) */
7707 gen_nop_modrm(env
, s
, modrm
);
7712 modrm
= cpu_ldub_code(env
, s
->pc
++);
7713 if (s
->flags
& HF_MPX_EN_MASK
) {
7714 mod
= (modrm
>> 6) & 3;
7715 reg
= ((modrm
>> 3) & 7) | rex_r
;
7716 if (prefixes
& PREFIX_REPZ
) {
7719 || (prefixes
& PREFIX_LOCK
)
7720 || s
->aflag
== MO_16
) {
7723 gen_bndck(env
, s
, modrm
, TCG_COND_LTU
, cpu_bndl
[reg
]);
7724 } else if (prefixes
& PREFIX_REPNZ
) {
7727 || (prefixes
& PREFIX_LOCK
)
7728 || s
->aflag
== MO_16
) {
7731 TCGv_i64 notu
= tcg_temp_new_i64();
7732 tcg_gen_not_i64(notu
, cpu_bndu
[reg
]);
7733 gen_bndck(env
, s
, modrm
, TCG_COND_GTU
, notu
);
7734 tcg_temp_free_i64(notu
);
7735 } else if (prefixes
& PREFIX_DATA
) {
7736 /* bndmov -- from reg/mem */
7737 if (reg
>= 4 || s
->aflag
== MO_16
) {
7741 int reg2
= (modrm
& 7) | REX_B(s
);
7742 if (reg2
>= 4 || (prefixes
& PREFIX_LOCK
)) {
7745 if (s
->flags
& HF_MPX_IU_MASK
) {
7746 tcg_gen_mov_i64(cpu_bndl
[reg
], cpu_bndl
[reg2
]);
7747 tcg_gen_mov_i64(cpu_bndu
[reg
], cpu_bndu
[reg2
]);
7750 gen_lea_modrm(env
, s
, modrm
);
7752 tcg_gen_qemu_ld_i64(cpu_bndl
[reg
], cpu_A0
,
7753 s
->mem_index
, MO_LEQ
);
7754 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, 8);
7755 tcg_gen_qemu_ld_i64(cpu_bndu
[reg
], cpu_A0
,
7756 s
->mem_index
, MO_LEQ
);
7758 tcg_gen_qemu_ld_i64(cpu_bndl
[reg
], cpu_A0
,
7759 s
->mem_index
, MO_LEUL
);
7760 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, 4);
7761 tcg_gen_qemu_ld_i64(cpu_bndu
[reg
], cpu_A0
,
7762 s
->mem_index
, MO_LEUL
);
7764 /* bnd registers are now in-use */
7765 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7767 } else if (mod
!= 3) {
7769 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7771 || (prefixes
& PREFIX_LOCK
)
7772 || s
->aflag
== MO_16
7777 tcg_gen_addi_tl(cpu_A0
, cpu_regs
[a
.base
], a
.disp
);
7779 tcg_gen_movi_tl(cpu_A0
, 0);
7781 gen_lea_v_seg(s
, s
->aflag
, cpu_A0
, a
.def_seg
, s
->override
);
7783 tcg_gen_mov_tl(cpu_T0
, cpu_regs
[a
.index
]);
7785 tcg_gen_movi_tl(cpu_T0
, 0);
7788 gen_helper_bndldx64(cpu_bndl
[reg
], cpu_env
, cpu_A0
, cpu_T0
);
7789 tcg_gen_ld_i64(cpu_bndu
[reg
], cpu_env
,
7790 offsetof(CPUX86State
, mmx_t0
.MMX_Q(0)));
7792 gen_helper_bndldx32(cpu_bndu
[reg
], cpu_env
, cpu_A0
, cpu_T0
);
7793 tcg_gen_ext32u_i64(cpu_bndl
[reg
], cpu_bndu
[reg
]);
7794 tcg_gen_shri_i64(cpu_bndu
[reg
], cpu_bndu
[reg
], 32);
7796 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7799 gen_nop_modrm(env
, s
, modrm
);
7802 modrm
= cpu_ldub_code(env
, s
->pc
++);
7803 if (s
->flags
& HF_MPX_EN_MASK
) {
7804 mod
= (modrm
>> 6) & 3;
7805 reg
= ((modrm
>> 3) & 7) | rex_r
;
7806 if (mod
!= 3 && (prefixes
& PREFIX_REPZ
)) {
7809 || (prefixes
& PREFIX_LOCK
)
7810 || s
->aflag
== MO_16
) {
7813 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7815 tcg_gen_extu_tl_i64(cpu_bndl
[reg
], cpu_regs
[a
.base
]);
7817 tcg_gen_ext32u_i64(cpu_bndl
[reg
], cpu_bndl
[reg
]);
7819 } else if (a
.base
== -1) {
7820 /* no base register has lower bound of 0 */
7821 tcg_gen_movi_i64(cpu_bndl
[reg
], 0);
7823 /* rip-relative generates #ud */
7826 tcg_gen_not_tl(cpu_A0
, gen_lea_modrm_1(a
));
7828 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
7830 tcg_gen_extu_tl_i64(cpu_bndu
[reg
], cpu_A0
);
7831 /* bnd registers are now in-use */
7832 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7834 } else if (prefixes
& PREFIX_REPNZ
) {
7837 || (prefixes
& PREFIX_LOCK
)
7838 || s
->aflag
== MO_16
) {
7841 gen_bndck(env
, s
, modrm
, TCG_COND_GTU
, cpu_bndu
[reg
]);
7842 } else if (prefixes
& PREFIX_DATA
) {
7843 /* bndmov -- to reg/mem */
7844 if (reg
>= 4 || s
->aflag
== MO_16
) {
7848 int reg2
= (modrm
& 7) | REX_B(s
);
7849 if (reg2
>= 4 || (prefixes
& PREFIX_LOCK
)) {
7852 if (s
->flags
& HF_MPX_IU_MASK
) {
7853 tcg_gen_mov_i64(cpu_bndl
[reg2
], cpu_bndl
[reg
]);
7854 tcg_gen_mov_i64(cpu_bndu
[reg2
], cpu_bndu
[reg
]);
7857 gen_lea_modrm(env
, s
, modrm
);
7859 tcg_gen_qemu_st_i64(cpu_bndl
[reg
], cpu_A0
,
7860 s
->mem_index
, MO_LEQ
);
7861 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, 8);
7862 tcg_gen_qemu_st_i64(cpu_bndu
[reg
], cpu_A0
,
7863 s
->mem_index
, MO_LEQ
);
7865 tcg_gen_qemu_st_i64(cpu_bndl
[reg
], cpu_A0
,
7866 s
->mem_index
, MO_LEUL
);
7867 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, 4);
7868 tcg_gen_qemu_st_i64(cpu_bndu
[reg
], cpu_A0
,
7869 s
->mem_index
, MO_LEUL
);
7872 } else if (mod
!= 3) {
7874 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7876 || (prefixes
& PREFIX_LOCK
)
7877 || s
->aflag
== MO_16
7882 tcg_gen_addi_tl(cpu_A0
, cpu_regs
[a
.base
], a
.disp
);
7884 tcg_gen_movi_tl(cpu_A0
, 0);
7886 gen_lea_v_seg(s
, s
->aflag
, cpu_A0
, a
.def_seg
, s
->override
);
7888 tcg_gen_mov_tl(cpu_T0
, cpu_regs
[a
.index
]);
7890 tcg_gen_movi_tl(cpu_T0
, 0);
7893 gen_helper_bndstx64(cpu_env
, cpu_A0
, cpu_T0
,
7894 cpu_bndl
[reg
], cpu_bndu
[reg
]);
7896 gen_helper_bndstx32(cpu_env
, cpu_A0
, cpu_T0
,
7897 cpu_bndl
[reg
], cpu_bndu
[reg
]);
7901 gen_nop_modrm(env
, s
, modrm
);
7903 case 0x119: case 0x11c ... 0x11f: /* nop (multi byte) */
7904 modrm
= cpu_ldub_code(env
, s
->pc
++);
7905 gen_nop_modrm(env
, s
, modrm
);
7907 case 0x120: /* mov reg, crN */
7908 case 0x122: /* mov crN, reg */
7910 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7912 modrm
= cpu_ldub_code(env
, s
->pc
++);
7913 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7914 * AMD documentation (24594.pdf) and testing of
7915 * intel 386 and 486 processors all show that the mod bits
7916 * are assumed to be 1's, regardless of actual values.
7918 rm
= (modrm
& 7) | REX_B(s
);
7919 reg
= ((modrm
>> 3) & 7) | rex_r
;
7924 if ((prefixes
& PREFIX_LOCK
) && (reg
== 0) &&
7925 (s
->cpuid_ext3_features
& CPUID_EXT3_CR8LEG
)) {
7934 gen_update_cc_op(s
);
7935 gen_jmp_im(pc_start
- s
->cs_base
);
7937 if (s
->base
.tb
->cflags
& CF_USE_ICOUNT
) {
7940 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
7941 gen_helper_write_crN(cpu_env
, tcg_const_i32(reg
),
7943 if (s
->base
.tb
->cflags
& CF_USE_ICOUNT
) {
7946 gen_jmp_im(s
->pc
- s
->cs_base
);
7949 if (s
->base
.tb
->cflags
& CF_USE_ICOUNT
) {
7952 gen_helper_read_crN(cpu_T0
, cpu_env
, tcg_const_i32(reg
));
7953 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
7954 if (s
->base
.tb
->cflags
& CF_USE_ICOUNT
) {
7964 case 0x121: /* mov reg, drN */
7965 case 0x123: /* mov drN, reg */
7967 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7969 modrm
= cpu_ldub_code(env
, s
->pc
++);
7970 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7971 * AMD documentation (24594.pdf) and testing of
7972 * intel 386 and 486 processors all show that the mod bits
7973 * are assumed to be 1's, regardless of actual values.
7975 rm
= (modrm
& 7) | REX_B(s
);
7976 reg
= ((modrm
>> 3) & 7) | rex_r
;
7985 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_DR0
+ reg
);
7986 gen_op_mov_v_reg(ot
, cpu_T0
, rm
);
7987 tcg_gen_movi_i32(cpu_tmp2_i32
, reg
);
7988 gen_helper_set_dr(cpu_env
, cpu_tmp2_i32
, cpu_T0
);
7989 gen_jmp_im(s
->pc
- s
->cs_base
);
7992 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_DR0
+ reg
);
7993 tcg_gen_movi_i32(cpu_tmp2_i32
, reg
);
7994 gen_helper_get_dr(cpu_T0
, cpu_env
, cpu_tmp2_i32
);
7995 gen_op_mov_reg_v(ot
, rm
, cpu_T0
);
7999 case 0x106: /* clts */
8001 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
8003 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
8004 gen_helper_clts(cpu_env
);
8005 /* abort block because static cpu state changed */
8006 gen_jmp_im(s
->pc
- s
->cs_base
);
8010 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
8011 case 0x1c3: /* MOVNTI reg, mem */
8012 if (!(s
->cpuid_features
& CPUID_SSE2
))
8014 ot
= mo_64_32(dflag
);
8015 modrm
= cpu_ldub_code(env
, s
->pc
++);
8016 mod
= (modrm
>> 6) & 3;
8019 reg
= ((modrm
>> 3) & 7) | rex_r
;
8020 /* generate a generic store */
8021 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
8024 modrm
= cpu_ldub_code(env
, s
->pc
++);
8026 CASE_MODRM_MEM_OP(0): /* fxsave */
8027 if (!(s
->cpuid_features
& CPUID_FXSR
)
8028 || (prefixes
& PREFIX_LOCK
)) {
8031 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
8032 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8035 gen_lea_modrm(env
, s
, modrm
);
8036 gen_helper_fxsave(cpu_env
, cpu_A0
);
8039 CASE_MODRM_MEM_OP(1): /* fxrstor */
8040 if (!(s
->cpuid_features
& CPUID_FXSR
)
8041 || (prefixes
& PREFIX_LOCK
)) {
8044 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
8045 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8048 gen_lea_modrm(env
, s
, modrm
);
8049 gen_helper_fxrstor(cpu_env
, cpu_A0
);
8052 CASE_MODRM_MEM_OP(2): /* ldmxcsr */
8053 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
)) {
8056 if (s
->flags
& HF_TS_MASK
) {
8057 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8060 gen_lea_modrm(env
, s
, modrm
);
8061 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
, s
->mem_index
, MO_LEUL
);
8062 gen_helper_ldmxcsr(cpu_env
, cpu_tmp2_i32
);
8065 CASE_MODRM_MEM_OP(3): /* stmxcsr */
8066 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
)) {
8069 if (s
->flags
& HF_TS_MASK
) {
8070 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8073 gen_lea_modrm(env
, s
, modrm
);
8074 tcg_gen_ld32u_tl(cpu_T0
, cpu_env
, offsetof(CPUX86State
, mxcsr
));
8075 gen_op_st_v(s
, MO_32
, cpu_T0
, cpu_A0
);
8078 CASE_MODRM_MEM_OP(4): /* xsave */
8079 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8080 || (prefixes
& (PREFIX_LOCK
| PREFIX_DATA
8081 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
8084 gen_lea_modrm(env
, s
, modrm
);
8085 tcg_gen_concat_tl_i64(cpu_tmp1_i64
, cpu_regs
[R_EAX
],
8087 gen_helper_xsave(cpu_env
, cpu_A0
, cpu_tmp1_i64
);
8090 CASE_MODRM_MEM_OP(5): /* xrstor */
8091 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8092 || (prefixes
& (PREFIX_LOCK
| PREFIX_DATA
8093 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
8096 gen_lea_modrm(env
, s
, modrm
);
8097 tcg_gen_concat_tl_i64(cpu_tmp1_i64
, cpu_regs
[R_EAX
],
8099 gen_helper_xrstor(cpu_env
, cpu_A0
, cpu_tmp1_i64
);
8100 /* XRSTOR is how MPX is enabled, which changes how
8101 we translate. Thus we need to end the TB. */
8102 gen_update_cc_op(s
);
8103 gen_jmp_im(s
->pc
- s
->cs_base
);
8107 CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */
8108 if (prefixes
& PREFIX_LOCK
) {
8111 if (prefixes
& PREFIX_DATA
) {
8113 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLWB
)) {
8116 gen_nop_modrm(env
, s
, modrm
);
8119 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8120 || (s
->cpuid_xsave_features
& CPUID_XSAVE_XSAVEOPT
) == 0
8121 || (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
))) {
8124 gen_lea_modrm(env
, s
, modrm
);
8125 tcg_gen_concat_tl_i64(cpu_tmp1_i64
, cpu_regs
[R_EAX
],
8127 gen_helper_xsaveopt(cpu_env
, cpu_A0
, cpu_tmp1_i64
);
8131 CASE_MODRM_MEM_OP(7): /* clflush / clflushopt */
8132 if (prefixes
& PREFIX_LOCK
) {
8135 if (prefixes
& PREFIX_DATA
) {
8137 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLFLUSHOPT
)) {
8142 if ((s
->prefix
& (PREFIX_REPZ
| PREFIX_REPNZ
))
8143 || !(s
->cpuid_features
& CPUID_CLFLUSH
)) {
8147 gen_nop_modrm(env
, s
, modrm
);
8150 case 0xc0 ... 0xc7: /* rdfsbase (f3 0f ae /0) */
8151 case 0xc8 ... 0xcf: /* rdgsbase (f3 0f ae /1) */
8152 case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */
8153 case 0xd8 ... 0xdf: /* wrgsbase (f3 0f ae /3) */
8155 && (prefixes
& PREFIX_REPZ
)
8156 && !(prefixes
& PREFIX_LOCK
)
8157 && (s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_FSGSBASE
)) {
8158 TCGv base
, treg
, src
, dst
;
8160 /* Preserve hflags bits by testing CR4 at runtime. */
8161 tcg_gen_movi_i32(cpu_tmp2_i32
, CR4_FSGSBASE_MASK
);
8162 gen_helper_cr4_testbit(cpu_env
, cpu_tmp2_i32
);
8164 base
= cpu_seg_base
[modrm
& 8 ? R_GS
: R_FS
];
8165 treg
= cpu_regs
[(modrm
& 7) | REX_B(s
)];
8169 dst
= base
, src
= treg
;
8172 dst
= treg
, src
= base
;
8175 if (s
->dflag
== MO_32
) {
8176 tcg_gen_ext32u_tl(dst
, src
);
8178 tcg_gen_mov_tl(dst
, src
);
8184 case 0xf8: /* sfence / pcommit */
8185 if (prefixes
& PREFIX_DATA
) {
8187 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_PCOMMIT
)
8188 || (prefixes
& PREFIX_LOCK
)) {
8194 case 0xf9 ... 0xff: /* sfence */
8195 if (!(s
->cpuid_features
& CPUID_SSE
)
8196 || (prefixes
& PREFIX_LOCK
)) {
8199 tcg_gen_mb(TCG_MO_ST_ST
| TCG_BAR_SC
);
8201 case 0xe8 ... 0xef: /* lfence */
8202 if (!(s
->cpuid_features
& CPUID_SSE
)
8203 || (prefixes
& PREFIX_LOCK
)) {
8206 tcg_gen_mb(TCG_MO_LD_LD
| TCG_BAR_SC
);
8208 case 0xf0 ... 0xf7: /* mfence */
8209 if (!(s
->cpuid_features
& CPUID_SSE2
)
8210 || (prefixes
& PREFIX_LOCK
)) {
8213 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8221 case 0x10d: /* 3DNow! prefetch(w) */
8222 modrm
= cpu_ldub_code(env
, s
->pc
++);
8223 mod
= (modrm
>> 6) & 3;
8226 gen_nop_modrm(env
, s
, modrm
);
8228 case 0x1aa: /* rsm */
8229 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_RSM
);
8230 if (!(s
->flags
& HF_SMM_MASK
))
8232 gen_update_cc_op(s
);
8233 gen_jmp_im(s
->pc
- s
->cs_base
);
8234 gen_helper_rsm(cpu_env
);
8237 case 0x1b8: /* SSE4.2 popcnt */
8238 if ((prefixes
& (PREFIX_REPZ
| PREFIX_LOCK
| PREFIX_REPNZ
)) !=
8241 if (!(s
->cpuid_ext_features
& CPUID_EXT_POPCNT
))
8244 modrm
= cpu_ldub_code(env
, s
->pc
++);
8245 reg
= ((modrm
>> 3) & 7) | rex_r
;
8247 if (s
->prefix
& PREFIX_DATA
) {
8250 ot
= mo_64_32(dflag
);
8253 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
8254 gen_extu(ot
, cpu_T0
);
8255 tcg_gen_mov_tl(cpu_cc_src
, cpu_T0
);
8256 tcg_gen_ctpop_tl(cpu_T0
, cpu_T0
);
8257 gen_op_mov_reg_v(ot
, reg
, cpu_T0
);
8259 set_cc_op(s
, CC_OP_POPCNT
);
8261 case 0x10e ... 0x10f:
8262 /* 3DNow! instructions, ignore prefixes */
8263 s
->prefix
&= ~(PREFIX_REPZ
| PREFIX_REPNZ
| PREFIX_DATA
);
8264 case 0x110 ... 0x117:
8265 case 0x128 ... 0x12f:
8266 case 0x138 ... 0x13a:
8267 case 0x150 ... 0x179:
8268 case 0x17c ... 0x17f:
8270 case 0x1c4 ... 0x1c6:
8271 case 0x1d0 ... 0x1fe:
8272 gen_sse(env
, s
, b
, pc_start
, rex_r
);
8279 gen_illegal_opcode(s
);
8282 gen_unknown_opcode(env
, s
);
8286 void tcg_x86_init(void)
8288 static const char reg_names
[CPU_NB_REGS
][4] = {
8289 #ifdef TARGET_X86_64
8317 static const char seg_base_names
[6][8] = {
8325 static const char bnd_regl_names
[4][8] = {
8326 "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb"
8328 static const char bnd_regu_names
[4][8] = {
8329 "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub"
8332 static bool initialized
;
8339 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
8340 tcg_ctx
.tcg_env
= cpu_env
;
8341 cpu_cc_op
= tcg_global_mem_new_i32(cpu_env
,
8342 offsetof(CPUX86State
, cc_op
), "cc_op");
8343 cpu_cc_dst
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_dst
),
8345 cpu_cc_src
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_src
),
8347 cpu_cc_src2
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_src2
),
8350 for (i
= 0; i
< CPU_NB_REGS
; ++i
) {
8351 cpu_regs
[i
] = tcg_global_mem_new(cpu_env
,
8352 offsetof(CPUX86State
, regs
[i
]),
8356 for (i
= 0; i
< 6; ++i
) {
8358 = tcg_global_mem_new(cpu_env
,
8359 offsetof(CPUX86State
, segs
[i
].base
),
8363 for (i
= 0; i
< 4; ++i
) {
8365 = tcg_global_mem_new_i64(cpu_env
,
8366 offsetof(CPUX86State
, bnd_regs
[i
].lb
),
8369 = tcg_global_mem_new_i64(cpu_env
,
8370 offsetof(CPUX86State
, bnd_regs
[i
].ub
),
8375 static int i386_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cpu
,
8378 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8379 CPUX86State
*env
= cpu
->env_ptr
;
8380 uint32_t flags
= dc
->base
.tb
->flags
;
8381 target_ulong cs_base
= dc
->base
.tb
->cs_base
;
8383 dc
->pe
= (flags
>> HF_PE_SHIFT
) & 1;
8384 dc
->code32
= (flags
>> HF_CS32_SHIFT
) & 1;
8385 dc
->ss32
= (flags
>> HF_SS32_SHIFT
) & 1;
8386 dc
->addseg
= (flags
>> HF_ADDSEG_SHIFT
) & 1;
8388 dc
->vm86
= (flags
>> VM_SHIFT
) & 1;
8389 dc
->cpl
= (flags
>> HF_CPL_SHIFT
) & 3;
8390 dc
->iopl
= (flags
>> IOPL_SHIFT
) & 3;
8391 dc
->tf
= (flags
>> TF_SHIFT
) & 1;
8392 dc
->cc_op
= CC_OP_DYNAMIC
;
8393 dc
->cc_op_dirty
= false;
8394 dc
->cs_base
= cs_base
;
8395 dc
->popl_esp_hack
= 0;
8396 /* select memory access functions */
8398 #ifdef CONFIG_SOFTMMU
8399 dc
->mem_index
= cpu_mmu_index(env
, false);
8401 dc
->cpuid_features
= env
->features
[FEAT_1_EDX
];
8402 dc
->cpuid_ext_features
= env
->features
[FEAT_1_ECX
];
8403 dc
->cpuid_ext2_features
= env
->features
[FEAT_8000_0001_EDX
];
8404 dc
->cpuid_ext3_features
= env
->features
[FEAT_8000_0001_ECX
];
8405 dc
->cpuid_7_0_ebx_features
= env
->features
[FEAT_7_0_EBX
];
8406 dc
->cpuid_xsave_features
= env
->features
[FEAT_XSAVE
];
8407 #ifdef TARGET_X86_64
8408 dc
->lma
= (flags
>> HF_LMA_SHIFT
) & 1;
8409 dc
->code64
= (flags
>> HF_CS64_SHIFT
) & 1;
8412 dc
->jmp_opt
= !(dc
->tf
|| dc
->base
.singlestep_enabled
||
8413 (flags
& HF_INHIBIT_IRQ_MASK
));
8414 /* Do not optimize repz jumps at all in icount mode, because
8415 rep movsS instructions are execured with different paths
8416 in !repz_opt and repz_opt modes. The first one was used
8417 always except single step mode. And this setting
8418 disables jumps optimization and control paths become
8419 equivalent in run and single step modes.
8420 Now there will be no jump optimization for repz in
8421 record/replay modes and there will always be an
8422 additional step for ecx=0 when icount is enabled.
8424 dc
->repz_opt
= !dc
->jmp_opt
&& !(dc
->base
.tb
->cflags
& CF_USE_ICOUNT
);
8426 /* check addseg logic */
8427 if (!dc
->addseg
&& (dc
->vm86
|| !dc
->pe
|| !dc
->code32
))
8428 printf("ERROR addseg\n");
8431 cpu_T0
= tcg_temp_new();
8432 cpu_T1
= tcg_temp_new();
8433 cpu_A0
= tcg_temp_new();
8435 cpu_tmp0
= tcg_temp_new();
8436 cpu_tmp1_i64
= tcg_temp_new_i64();
8437 cpu_tmp2_i32
= tcg_temp_new_i32();
8438 cpu_tmp3_i32
= tcg_temp_new_i32();
8439 cpu_tmp4
= tcg_temp_new();
8440 cpu_ptr0
= tcg_temp_new_ptr();
8441 cpu_ptr1
= tcg_temp_new_ptr();
8442 cpu_cc_srcT
= tcg_temp_local_new();
8447 static void i386_tr_tb_start(DisasContextBase
*db
, CPUState
*cpu
)
8451 static void i386_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
8453 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8455 tcg_gen_insn_start(dc
->base
.pc_next
, dc
->cc_op
);
8458 static bool i386_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cpu
,
8459 const CPUBreakpoint
*bp
)
8461 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8462 /* If RF is set, suppress an internally generated breakpoint. */
8463 int flags
= dc
->base
.tb
->flags
& HF_RF_MASK
? BP_GDB
: BP_ANY
;
8464 if (bp
->flags
& flags
) {
8465 gen_debug(dc
, dc
->base
.pc_next
- dc
->cs_base
);
8466 dc
->base
.is_jmp
= DISAS_NORETURN
;
8467 /* The address covered by the breakpoint must be included in
8468 [tb->pc, tb->pc + tb->size) in order to for it to be
8469 properly cleared -- thus we increment the PC here so that
8470 the generic logic setting tb->size later does the right thing. */
8471 dc
->base
.pc_next
+= 1;
8478 static void i386_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
8480 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8481 target_ulong pc_next
= disas_insn(dc
, cpu
);
8483 if (dc
->tf
|| (dc
->base
.tb
->flags
& HF_INHIBIT_IRQ_MASK
)) {
8484 /* if single step mode, we generate only one instruction and
8485 generate an exception */
8486 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
8487 the flag and abort the translation to give the irqs a
8489 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
8490 } else if ((dc
->base
.tb
->cflags
& CF_USE_ICOUNT
)
8491 && ((dc
->base
.pc_next
& TARGET_PAGE_MASK
)
8492 != ((dc
->base
.pc_next
+ TARGET_MAX_INSN_SIZE
- 1)
8494 || (dc
->base
.pc_next
& ~TARGET_PAGE_MASK
) == 0)) {
8495 /* Do not cross the boundary of the pages in icount mode,
8496 it can cause an exception. Do it only when boundary is
8497 crossed by the first instruction in the block.
8498 If current instruction already crossed the bound - it's ok,
8499 because an exception hasn't stopped this code.
8501 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
8502 } else if ((pc_next
- dc
->base
.pc_first
) >= (TARGET_PAGE_SIZE
- 32)) {
8503 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
8506 dc
->base
.pc_next
= pc_next
;
8509 static void i386_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cpu
)
8511 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8513 if (dc
->base
.is_jmp
== DISAS_TOO_MANY
) {
8514 gen_jmp_im(dc
->base
.pc_next
- dc
->cs_base
);
8519 static void i386_tr_disas_log(const DisasContextBase
*dcbase
,
8522 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8523 int disas_flags
= !dc
->code32
;
8525 qemu_log("IN: %s\n", lookup_symbol(dc
->base
.pc_first
));
8526 #ifdef TARGET_X86_64
8531 log_target_disas(cpu
, dc
->base
.pc_first
, dc
->base
.tb
->size
, disas_flags
);
8534 static const TranslatorOps i386_tr_ops
= {
8535 .init_disas_context
= i386_tr_init_disas_context
,
8536 .tb_start
= i386_tr_tb_start
,
8537 .insn_start
= i386_tr_insn_start
,
8538 .breakpoint_check
= i386_tr_breakpoint_check
,
8539 .translate_insn
= i386_tr_translate_insn
,
8540 .tb_stop
= i386_tr_tb_stop
,
8541 .disas_log
= i386_tr_disas_log
,
8544 /* generate intermediate code for basic block 'tb'. */
8545 void gen_intermediate_code(CPUState
*cpu
, TranslationBlock
*tb
)
8549 translator_loop(&i386_tr_ops
, &dc
.base
, cpu
, tb
);
8552 void restore_state_to_opc(CPUX86State
*env
, TranslationBlock
*tb
,
8555 int cc_op
= data
[1];
8556 env
->eip
= data
[0] - tb
->cs_base
;
8557 if (cc_op
!= CC_OP_DYNAMIC
) {