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.1 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"
25 #include "tcg/tcg-op.h"
26 #include "exec/cpu_ldst.h"
27 #include "exec/translator.h"
29 #include "exec/helper-proto.h"
30 #include "exec/helper-gen.h"
31 #include "helper-tcg.h"
33 #include "trace-tcg.h"
36 #define PREFIX_REPZ 0x01
37 #define PREFIX_REPNZ 0x02
38 #define PREFIX_LOCK 0x04
39 #define PREFIX_DATA 0x08
40 #define PREFIX_ADR 0x10
41 #define PREFIX_VEX 0x20
42 #define PREFIX_REX 0x40
52 /* For a switch indexed by MODRM, match all memory operands for a given OP. */
53 #define CASE_MODRM_MEM_OP(OP) \
54 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
55 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
56 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7
58 #define CASE_MODRM_OP(OP) \
59 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
60 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
61 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7: \
62 case (3 << 6) | (OP << 3) | 0 ... (3 << 6) | (OP << 3) | 7
64 //#define MACRO_TEST 1
66 /* global register indexes */
67 static TCGv cpu_cc_dst
, cpu_cc_src
, cpu_cc_src2
;
68 static TCGv_i32 cpu_cc_op
;
69 static TCGv cpu_regs
[CPU_NB_REGS
];
70 static TCGv cpu_seg_base
[6];
71 static TCGv_i64 cpu_bndl
[4];
72 static TCGv_i64 cpu_bndu
[4];
74 #include "exec/gen-icount.h"
76 typedef struct DisasContext
{
77 DisasContextBase base
;
79 target_ulong pc
; /* pc = eip + cs_base */
80 target_ulong pc_start
; /* pc at TB entry */
81 target_ulong cs_base
; /* base of CS segment */
86 int8_t override
; /* -1 if no override, else R_CS, R_DS, etc */
89 #ifndef CONFIG_USER_ONLY
90 uint8_t cpl
; /* code priv level */
91 uint8_t iopl
; /* i/o priv level */
93 uint8_t vex_l
; /* vex vector length */
94 uint8_t vex_v
; /* vex vvvv register, without 1's complement. */
95 uint8_t popl_esp_hack
; /* for correct popl with esp base handling */
96 uint8_t rip_offset
; /* only used in x86_64, but left for simplicity */
104 bool jmp_opt
; /* use direct block chaining for direct jumps */
105 bool repz_opt
; /* optimize jumps within repz instructions */
108 CCOp cc_op
; /* current CC operation */
109 int mem_index
; /* select memory access functions */
110 uint32_t flags
; /* all execution flags */
112 int cpuid_ext_features
;
113 int cpuid_ext2_features
;
114 int cpuid_ext3_features
;
115 int cpuid_7_0_ebx_features
;
116 int cpuid_xsave_features
;
118 /* TCG local temps */
124 /* TCG local register indexes (only used inside old micro ops) */
136 /* The environment in which user-only runs is constrained. */
137 #ifdef CONFIG_USER_ONLY
141 #define SVME(S) false
142 #define GUEST(S) false
144 #define PE(S) (((S)->flags & HF_PE_MASK) != 0)
145 #define CPL(S) ((S)->cpl)
146 #define IOPL(S) ((S)->iopl)
147 #define SVME(S) (((S)->flags & HF_SVME_MASK) != 0)
148 #define GUEST(S) (((S)->flags & HF_GUEST_MASK) != 0)
150 #if defined(CONFIG_USER_ONLY) && defined(TARGET_X86_64)
151 #define VM86(S) false
152 #define CODE32(S) true
154 #define ADDSEG(S) false
156 #define VM86(S) (((S)->flags & HF_VM_MASK) != 0)
157 #define CODE32(S) (((S)->flags & HF_CS32_MASK) != 0)
158 #define SS32(S) (((S)->flags & HF_SS32_MASK) != 0)
159 #define ADDSEG(S) (((S)->flags & HF_ADDSEG_MASK) != 0)
161 #if !defined(TARGET_X86_64)
162 #define CODE64(S) false
164 #elif defined(CONFIG_USER_ONLY)
165 #define CODE64(S) true
168 #define CODE64(S) (((S)->flags & HF_CS64_MASK) != 0)
169 #define LMA(S) (((S)->flags & HF_LMA_MASK) != 0)
173 #define REX_PREFIX(S) (((S)->prefix & PREFIX_REX) != 0)
174 #define REX_W(S) ((S)->rex_w)
175 #define REX_R(S) ((S)->rex_r + 0)
176 #define REX_X(S) ((S)->rex_x + 0)
177 #define REX_B(S) ((S)->rex_b + 0)
179 #define REX_PREFIX(S) false
180 #define REX_W(S) false
187 * Many sysemu-only helpers are not reachable for user-only.
188 * Define stub generators here, so that we need not either sprinkle
189 * ifdefs through the translator, nor provide the helper function.
191 #define STUB_HELPER(NAME, ...) \
192 static inline void gen_helper_##NAME(__VA_ARGS__) \
193 { qemu_build_not_reached(); }
195 #ifdef CONFIG_USER_ONLY
196 STUB_HELPER(clgi
, TCGv_env env
)
197 STUB_HELPER(flush_page
, TCGv_env env
, TCGv addr
)
198 STUB_HELPER(hlt
, TCGv_env env
, TCGv_i32 pc_ofs
)
199 STUB_HELPER(inb
, TCGv ret
, TCGv_env env
, TCGv_i32 port
)
200 STUB_HELPER(inw
, TCGv ret
, TCGv_env env
, TCGv_i32 port
)
201 STUB_HELPER(inl
, TCGv ret
, TCGv_env env
, TCGv_i32 port
)
202 STUB_HELPER(monitor
, TCGv_env env
, TCGv addr
)
203 STUB_HELPER(mwait
, TCGv_env env
, TCGv_i32 pc_ofs
)
204 STUB_HELPER(outb
, TCGv_env env
, TCGv_i32 port
, TCGv_i32 val
)
205 STUB_HELPER(outw
, TCGv_env env
, TCGv_i32 port
, TCGv_i32 val
)
206 STUB_HELPER(outl
, TCGv_env env
, TCGv_i32 port
, TCGv_i32 val
)
207 STUB_HELPER(rdmsr
, TCGv_env env
)
208 STUB_HELPER(read_crN
, TCGv ret
, TCGv_env env
, TCGv_i32 reg
)
209 STUB_HELPER(set_dr
, TCGv_env env
, TCGv_i32 reg
, TCGv val
)
210 STUB_HELPER(stgi
, TCGv_env env
)
211 STUB_HELPER(svm_check_intercept
, TCGv_env env
, TCGv_i32 type
)
212 STUB_HELPER(vmload
, TCGv_env env
, TCGv_i32 aflag
)
213 STUB_HELPER(vmmcall
, TCGv_env env
)
214 STUB_HELPER(vmrun
, TCGv_env env
, TCGv_i32 aflag
, TCGv_i32 pc_ofs
)
215 STUB_HELPER(vmsave
, TCGv_env env
, TCGv_i32 aflag
)
216 STUB_HELPER(write_crN
, TCGv_env env
, TCGv_i32 reg
, TCGv val
)
217 STUB_HELPER(wrmsr
, TCGv_env env
)
220 static void gen_eob(DisasContext
*s
);
221 static void gen_jr(DisasContext
*s
, TCGv dest
);
222 static void gen_jmp(DisasContext
*s
, target_ulong eip
);
223 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
);
224 static void gen_op(DisasContext
*s1
, int op
, MemOp ot
, int d
);
225 static void gen_exception_gpf(DisasContext
*s
);
227 /* i386 arith/logic operations */
247 OP_SHL1
, /* undocumented */
263 /* I386 int registers */
264 OR_EAX
, /* MUST be even numbered */
273 OR_TMP0
= 16, /* temporary operand register */
275 OR_A0
, /* temporary register used when doing address evaluation */
285 /* Bit set if the global variable is live after setting CC_OP to X. */
286 static const uint8_t cc_op_live
[CC_OP_NB
] = {
287 [CC_OP_DYNAMIC
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
288 [CC_OP_EFLAGS
] = USES_CC_SRC
,
289 [CC_OP_MULB
... CC_OP_MULQ
] = USES_CC_DST
| USES_CC_SRC
,
290 [CC_OP_ADDB
... CC_OP_ADDQ
] = USES_CC_DST
| USES_CC_SRC
,
291 [CC_OP_ADCB
... CC_OP_ADCQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
292 [CC_OP_SUBB
... CC_OP_SUBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRCT
,
293 [CC_OP_SBBB
... CC_OP_SBBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
294 [CC_OP_LOGICB
... CC_OP_LOGICQ
] = USES_CC_DST
,
295 [CC_OP_INCB
... CC_OP_INCQ
] = USES_CC_DST
| USES_CC_SRC
,
296 [CC_OP_DECB
... CC_OP_DECQ
] = USES_CC_DST
| USES_CC_SRC
,
297 [CC_OP_SHLB
... CC_OP_SHLQ
] = USES_CC_DST
| USES_CC_SRC
,
298 [CC_OP_SARB
... CC_OP_SARQ
] = USES_CC_DST
| USES_CC_SRC
,
299 [CC_OP_BMILGB
... CC_OP_BMILGQ
] = USES_CC_DST
| USES_CC_SRC
,
300 [CC_OP_ADCX
] = USES_CC_DST
| USES_CC_SRC
,
301 [CC_OP_ADOX
] = USES_CC_SRC
| USES_CC_SRC2
,
302 [CC_OP_ADCOX
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
304 [CC_OP_POPCNT
] = USES_CC_SRC
,
307 static void set_cc_op(DisasContext
*s
, CCOp op
)
311 if (s
->cc_op
== op
) {
315 /* Discard CC computation that will no longer be used. */
316 dead
= cc_op_live
[s
->cc_op
] & ~cc_op_live
[op
];
317 if (dead
& USES_CC_DST
) {
318 tcg_gen_discard_tl(cpu_cc_dst
);
320 if (dead
& USES_CC_SRC
) {
321 tcg_gen_discard_tl(cpu_cc_src
);
323 if (dead
& USES_CC_SRC2
) {
324 tcg_gen_discard_tl(cpu_cc_src2
);
326 if (dead
& USES_CC_SRCT
) {
327 tcg_gen_discard_tl(s
->cc_srcT
);
330 if (op
== CC_OP_DYNAMIC
) {
331 /* The DYNAMIC setting is translator only, and should never be
332 stored. Thus we always consider it clean. */
333 s
->cc_op_dirty
= false;
335 /* Discard any computed CC_OP value (see shifts). */
336 if (s
->cc_op
== CC_OP_DYNAMIC
) {
337 tcg_gen_discard_i32(cpu_cc_op
);
339 s
->cc_op_dirty
= true;
344 static void gen_update_cc_op(DisasContext
*s
)
346 if (s
->cc_op_dirty
) {
347 tcg_gen_movi_i32(cpu_cc_op
, s
->cc_op
);
348 s
->cc_op_dirty
= false;
354 #define NB_OP_SIZES 4
356 #else /* !TARGET_X86_64 */
358 #define NB_OP_SIZES 3
360 #endif /* !TARGET_X86_64 */
362 #if defined(HOST_WORDS_BIGENDIAN)
363 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
364 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
365 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
366 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
367 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
369 #define REG_B_OFFSET 0
370 #define REG_H_OFFSET 1
371 #define REG_W_OFFSET 0
372 #define REG_L_OFFSET 0
373 #define REG_LH_OFFSET 4
376 /* In instruction encodings for byte register accesses the
377 * register number usually indicates "low 8 bits of register N";
378 * however there are some special cases where N 4..7 indicates
379 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
380 * true for this special case, false otherwise.
382 static inline bool byte_reg_is_xH(DisasContext
*s
, int reg
)
384 /* Any time the REX prefix is present, byte registers are uniform */
385 if (reg
< 4 || REX_PREFIX(s
)) {
391 /* Select the size of a push/pop operation. */
392 static inline MemOp
mo_pushpop(DisasContext
*s
, MemOp ot
)
395 return ot
== MO_16
? MO_16
: MO_64
;
401 /* Select the size of the stack pointer. */
402 static inline MemOp
mo_stacksize(DisasContext
*s
)
404 return CODE64(s
) ? MO_64
: SS32(s
) ? MO_32
: MO_16
;
407 /* Select only size 64 else 32. Used for SSE operand sizes. */
408 static inline MemOp
mo_64_32(MemOp ot
)
411 return ot
== MO_64
? MO_64
: MO_32
;
417 /* Select size 8 if lsb of B is clear, else OT. Used for decoding
418 byte vs word opcodes. */
419 static inline MemOp
mo_b_d(int b
, MemOp ot
)
421 return b
& 1 ? ot
: MO_8
;
424 /* Select size 8 if lsb of B is clear, else OT capped at 32.
425 Used for decoding operand size of port opcodes. */
426 static inline MemOp
mo_b_d32(int b
, MemOp ot
)
428 return b
& 1 ? (ot
== MO_16
? MO_16
: MO_32
) : MO_8
;
431 static void gen_op_mov_reg_v(DisasContext
*s
, MemOp ot
, int reg
, TCGv t0
)
435 if (!byte_reg_is_xH(s
, reg
)) {
436 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 8);
438 tcg_gen_deposit_tl(cpu_regs
[reg
- 4], cpu_regs
[reg
- 4], t0
, 8, 8);
442 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 16);
445 /* For x86_64, this sets the higher half of register to zero.
446 For i386, this is equivalent to a mov. */
447 tcg_gen_ext32u_tl(cpu_regs
[reg
], t0
);
451 tcg_gen_mov_tl(cpu_regs
[reg
], t0
);
460 void gen_op_mov_v_reg(DisasContext
*s
, MemOp ot
, TCGv t0
, int reg
)
462 if (ot
== MO_8
&& byte_reg_is_xH(s
, reg
)) {
463 tcg_gen_extract_tl(t0
, cpu_regs
[reg
- 4], 8, 8);
465 tcg_gen_mov_tl(t0
, cpu_regs
[reg
]);
469 static void gen_add_A0_im(DisasContext
*s
, int val
)
471 tcg_gen_addi_tl(s
->A0
, s
->A0
, val
);
473 tcg_gen_ext32u_tl(s
->A0
, s
->A0
);
477 static inline void gen_op_jmp_v(TCGv dest
)
479 tcg_gen_st_tl(dest
, cpu_env
, offsetof(CPUX86State
, eip
));
483 void gen_op_add_reg_im(DisasContext
*s
, MemOp size
, int reg
, int32_t val
)
485 tcg_gen_addi_tl(s
->tmp0
, cpu_regs
[reg
], val
);
486 gen_op_mov_reg_v(s
, size
, reg
, s
->tmp0
);
489 static inline void gen_op_add_reg_T0(DisasContext
*s
, MemOp size
, int reg
)
491 tcg_gen_add_tl(s
->tmp0
, cpu_regs
[reg
], s
->T0
);
492 gen_op_mov_reg_v(s
, size
, reg
, s
->tmp0
);
495 static inline void gen_op_ld_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
497 tcg_gen_qemu_ld_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
500 static inline void gen_op_st_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
502 tcg_gen_qemu_st_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
505 static inline void gen_op_st_rm_T0_A0(DisasContext
*s
, int idx
, int d
)
508 gen_op_st_v(s
, idx
, s
->T0
, s
->A0
);
510 gen_op_mov_reg_v(s
, idx
, d
, s
->T0
);
514 static inline void gen_jmp_im(DisasContext
*s
, target_ulong pc
)
516 tcg_gen_movi_tl(s
->tmp0
, pc
);
517 gen_op_jmp_v(s
->tmp0
);
520 /* Compute SEG:REG into A0. SEG is selected from the override segment
521 (OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to
522 indicate no override. */
523 static void gen_lea_v_seg(DisasContext
*s
, MemOp aflag
, TCGv a0
,
524 int def_seg
, int ovr_seg
)
530 tcg_gen_mov_tl(s
->A0
, a0
);
537 if (ovr_seg
< 0 && ADDSEG(s
)) {
541 tcg_gen_ext32u_tl(s
->A0
, a0
);
547 tcg_gen_ext16u_tl(s
->A0
, a0
);
562 TCGv seg
= cpu_seg_base
[ovr_seg
];
564 if (aflag
== MO_64
) {
565 tcg_gen_add_tl(s
->A0
, a0
, seg
);
566 } else if (CODE64(s
)) {
567 tcg_gen_ext32u_tl(s
->A0
, a0
);
568 tcg_gen_add_tl(s
->A0
, s
->A0
, seg
);
570 tcg_gen_add_tl(s
->A0
, a0
, seg
);
571 tcg_gen_ext32u_tl(s
->A0
, s
->A0
);
576 static inline void gen_string_movl_A0_ESI(DisasContext
*s
)
578 gen_lea_v_seg(s
, s
->aflag
, cpu_regs
[R_ESI
], R_DS
, s
->override
);
581 static inline void gen_string_movl_A0_EDI(DisasContext
*s
)
583 gen_lea_v_seg(s
, s
->aflag
, cpu_regs
[R_EDI
], R_ES
, -1);
586 static inline void gen_op_movl_T0_Dshift(DisasContext
*s
, MemOp ot
)
588 tcg_gen_ld32s_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, df
));
589 tcg_gen_shli_tl(s
->T0
, s
->T0
, ot
);
592 static TCGv
gen_ext_tl(TCGv dst
, TCGv src
, MemOp size
, bool sign
)
597 tcg_gen_ext8s_tl(dst
, src
);
599 tcg_gen_ext8u_tl(dst
, src
);
604 tcg_gen_ext16s_tl(dst
, src
);
606 tcg_gen_ext16u_tl(dst
, src
);
612 tcg_gen_ext32s_tl(dst
, src
);
614 tcg_gen_ext32u_tl(dst
, src
);
623 static void gen_extu(MemOp ot
, TCGv reg
)
625 gen_ext_tl(reg
, reg
, ot
, false);
628 static void gen_exts(MemOp ot
, TCGv reg
)
630 gen_ext_tl(reg
, reg
, ot
, true);
634 void gen_op_jnz_ecx(DisasContext
*s
, MemOp size
, TCGLabel
*label1
)
636 tcg_gen_mov_tl(s
->tmp0
, cpu_regs
[R_ECX
]);
637 gen_extu(size
, s
->tmp0
);
638 tcg_gen_brcondi_tl(TCG_COND_NE
, s
->tmp0
, 0, label1
);
642 void gen_op_jz_ecx(DisasContext
*s
, MemOp size
, TCGLabel
*label1
)
644 tcg_gen_mov_tl(s
->tmp0
, cpu_regs
[R_ECX
]);
645 gen_extu(size
, s
->tmp0
);
646 tcg_gen_brcondi_tl(TCG_COND_EQ
, s
->tmp0
, 0, label1
);
649 static void gen_helper_in_func(MemOp ot
, TCGv v
, TCGv_i32 n
)
653 gen_helper_inb(v
, cpu_env
, n
);
656 gen_helper_inw(v
, cpu_env
, n
);
659 gen_helper_inl(v
, cpu_env
, n
);
666 static void gen_helper_out_func(MemOp ot
, TCGv_i32 v
, TCGv_i32 n
)
670 gen_helper_outb(cpu_env
, v
, n
);
673 gen_helper_outw(cpu_env
, v
, n
);
676 gen_helper_outl(cpu_env
, v
, n
);
684 * Validate that access to [port, port + 1<<ot) is allowed.
685 * Raise #GP, or VMM exit if not.
687 static bool gen_check_io(DisasContext
*s
, MemOp ot
, TCGv_i32 port
,
690 #ifdef CONFIG_USER_ONLY
692 * We do not implement the ioperm(2) syscall, so the TSS check
695 gen_exception_gpf(s
);
698 if (PE(s
) && (CPL(s
) > IOPL(s
) || VM86(s
))) {
699 gen_helper_check_io(cpu_env
, port
, tcg_constant_i32(1 << ot
));
702 target_ulong cur_eip
= s
->base
.pc_next
- s
->cs_base
;
703 target_ulong next_eip
= s
->pc
- s
->cs_base
;
706 gen_jmp_im(s
, cur_eip
);
707 if (s
->prefix
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
708 svm_flags
|= SVM_IOIO_REP_MASK
;
710 svm_flags
|= 1 << (SVM_IOIO_SIZE_SHIFT
+ ot
);
711 gen_helper_svm_check_io(cpu_env
, port
,
712 tcg_constant_i32(svm_flags
),
713 tcg_constant_i32(next_eip
- cur_eip
));
719 static inline void gen_movs(DisasContext
*s
, MemOp ot
)
721 gen_string_movl_A0_ESI(s
);
722 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
723 gen_string_movl_A0_EDI(s
);
724 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
725 gen_op_movl_T0_Dshift(s
, ot
);
726 gen_op_add_reg_T0(s
, s
->aflag
, R_ESI
);
727 gen_op_add_reg_T0(s
, s
->aflag
, R_EDI
);
730 static void gen_op_update1_cc(DisasContext
*s
)
732 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
735 static void gen_op_update2_cc(DisasContext
*s
)
737 tcg_gen_mov_tl(cpu_cc_src
, s
->T1
);
738 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
741 static void gen_op_update3_cc(DisasContext
*s
, TCGv reg
)
743 tcg_gen_mov_tl(cpu_cc_src2
, reg
);
744 tcg_gen_mov_tl(cpu_cc_src
, s
->T1
);
745 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
748 static inline void gen_op_testl_T0_T1_cc(DisasContext
*s
)
750 tcg_gen_and_tl(cpu_cc_dst
, s
->T0
, s
->T1
);
753 static void gen_op_update_neg_cc(DisasContext
*s
)
755 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
756 tcg_gen_neg_tl(cpu_cc_src
, s
->T0
);
757 tcg_gen_movi_tl(s
->cc_srcT
, 0);
760 /* compute all eflags to cc_src */
761 static void gen_compute_eflags(DisasContext
*s
)
763 TCGv zero
, dst
, src1
, src2
;
766 if (s
->cc_op
== CC_OP_EFLAGS
) {
769 if (s
->cc_op
== CC_OP_CLR
) {
770 tcg_gen_movi_tl(cpu_cc_src
, CC_Z
| CC_P
);
771 set_cc_op(s
, CC_OP_EFLAGS
);
780 /* Take care to not read values that are not live. */
781 live
= cc_op_live
[s
->cc_op
] & ~USES_CC_SRCT
;
782 dead
= live
^ (USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
);
784 zero
= tcg_const_tl(0);
785 if (dead
& USES_CC_DST
) {
788 if (dead
& USES_CC_SRC
) {
791 if (dead
& USES_CC_SRC2
) {
797 gen_helper_cc_compute_all(cpu_cc_src
, dst
, src1
, src2
, cpu_cc_op
);
798 set_cc_op(s
, CC_OP_EFLAGS
);
805 typedef struct CCPrepare
{
815 /* compute eflags.C to reg */
816 static CCPrepare
gen_prepare_eflags_c(DisasContext
*s
, TCGv reg
)
822 case CC_OP_SUBB
... CC_OP_SUBQ
:
823 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
824 size
= s
->cc_op
- CC_OP_SUBB
;
825 t1
= gen_ext_tl(s
->tmp0
, cpu_cc_src
, size
, false);
826 /* If no temporary was used, be careful not to alias t1 and t0. */
827 t0
= t1
== cpu_cc_src
? s
->tmp0
: reg
;
828 tcg_gen_mov_tl(t0
, s
->cc_srcT
);
832 case CC_OP_ADDB
... CC_OP_ADDQ
:
833 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
834 size
= s
->cc_op
- CC_OP_ADDB
;
835 t1
= gen_ext_tl(s
->tmp0
, cpu_cc_src
, size
, false);
836 t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
838 return (CCPrepare
) { .cond
= TCG_COND_LTU
, .reg
= t0
,
839 .reg2
= t1
, .mask
= -1, .use_reg2
= true };
841 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
844 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
846 case CC_OP_INCB
... CC_OP_INCQ
:
847 case CC_OP_DECB
... CC_OP_DECQ
:
848 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
849 .mask
= -1, .no_setcond
= true };
851 case CC_OP_SHLB
... CC_OP_SHLQ
:
852 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
853 size
= s
->cc_op
- CC_OP_SHLB
;
854 shift
= (8 << size
) - 1;
855 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
856 .mask
= (target_ulong
)1 << shift
};
858 case CC_OP_MULB
... CC_OP_MULQ
:
859 return (CCPrepare
) { .cond
= TCG_COND_NE
,
860 .reg
= cpu_cc_src
, .mask
= -1 };
862 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
863 size
= s
->cc_op
- CC_OP_BMILGB
;
864 t0
= gen_ext_tl(reg
, cpu_cc_src
, size
, false);
865 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
869 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_dst
,
870 .mask
= -1, .no_setcond
= true };
873 case CC_OP_SARB
... CC_OP_SARQ
:
875 return (CCPrepare
) { .cond
= TCG_COND_NE
,
876 .reg
= cpu_cc_src
, .mask
= CC_C
};
879 /* The need to compute only C from CC_OP_DYNAMIC is important
880 in efficiently implementing e.g. INC at the start of a TB. */
882 gen_helper_cc_compute_c(reg
, cpu_cc_dst
, cpu_cc_src
,
883 cpu_cc_src2
, cpu_cc_op
);
884 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
885 .mask
= -1, .no_setcond
= true };
889 /* compute eflags.P to reg */
890 static CCPrepare
gen_prepare_eflags_p(DisasContext
*s
, TCGv reg
)
892 gen_compute_eflags(s
);
893 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
897 /* compute eflags.S to reg */
898 static CCPrepare
gen_prepare_eflags_s(DisasContext
*s
, TCGv reg
)
902 gen_compute_eflags(s
);
908 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
912 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
915 MemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
916 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, true);
917 return (CCPrepare
) { .cond
= TCG_COND_LT
, .reg
= t0
, .mask
= -1 };
922 /* compute eflags.O to reg */
923 static CCPrepare
gen_prepare_eflags_o(DisasContext
*s
, TCGv reg
)
928 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src2
,
929 .mask
= -1, .no_setcond
= true };
932 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
934 gen_compute_eflags(s
);
935 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
940 /* compute eflags.Z to reg */
941 static CCPrepare
gen_prepare_eflags_z(DisasContext
*s
, TCGv reg
)
945 gen_compute_eflags(s
);
951 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
954 return (CCPrepare
) { .cond
= TCG_COND_ALWAYS
, .mask
= -1 };
956 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= cpu_cc_src
,
960 MemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
961 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
962 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
967 /* perform a conditional store into register 'reg' according to jump opcode
968 value 'b'. In the fast case, T0 is guaranted not to be used. */
969 static CCPrepare
gen_prepare_cc(DisasContext
*s
, int b
, TCGv reg
)
971 int inv
, jcc_op
, cond
;
977 jcc_op
= (b
>> 1) & 7;
980 case CC_OP_SUBB
... CC_OP_SUBQ
:
981 /* We optimize relational operators for the cmp/jcc case. */
982 size
= s
->cc_op
- CC_OP_SUBB
;
985 tcg_gen_mov_tl(s
->tmp4
, s
->cc_srcT
);
986 gen_extu(size
, s
->tmp4
);
987 t0
= gen_ext_tl(s
->tmp0
, cpu_cc_src
, size
, false);
988 cc
= (CCPrepare
) { .cond
= TCG_COND_LEU
, .reg
= s
->tmp4
,
989 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
998 tcg_gen_mov_tl(s
->tmp4
, s
->cc_srcT
);
999 gen_exts(size
, s
->tmp4
);
1000 t0
= gen_ext_tl(s
->tmp0
, cpu_cc_src
, size
, true);
1001 cc
= (CCPrepare
) { .cond
= cond
, .reg
= s
->tmp4
,
1002 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
1012 /* This actually generates good code for JC, JZ and JS. */
1015 cc
= gen_prepare_eflags_o(s
, reg
);
1018 cc
= gen_prepare_eflags_c(s
, reg
);
1021 cc
= gen_prepare_eflags_z(s
, reg
);
1024 gen_compute_eflags(s
);
1025 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
1026 .mask
= CC_Z
| CC_C
};
1029 cc
= gen_prepare_eflags_s(s
, reg
);
1032 cc
= gen_prepare_eflags_p(s
, reg
);
1035 gen_compute_eflags(s
);
1036 if (reg
== cpu_cc_src
) {
1039 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
1040 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
1041 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
1046 gen_compute_eflags(s
);
1047 if (reg
== cpu_cc_src
) {
1050 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
1051 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
1052 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
1053 .mask
= CC_S
| CC_Z
};
1060 cc
.cond
= tcg_invert_cond(cc
.cond
);
1065 static void gen_setcc1(DisasContext
*s
, int b
, TCGv reg
)
1067 CCPrepare cc
= gen_prepare_cc(s
, b
, reg
);
1069 if (cc
.no_setcond
) {
1070 if (cc
.cond
== TCG_COND_EQ
) {
1071 tcg_gen_xori_tl(reg
, cc
.reg
, 1);
1073 tcg_gen_mov_tl(reg
, cc
.reg
);
1078 if (cc
.cond
== TCG_COND_NE
&& !cc
.use_reg2
&& cc
.imm
== 0 &&
1079 cc
.mask
!= 0 && (cc
.mask
& (cc
.mask
- 1)) == 0) {
1080 tcg_gen_shri_tl(reg
, cc
.reg
, ctztl(cc
.mask
));
1081 tcg_gen_andi_tl(reg
, reg
, 1);
1084 if (cc
.mask
!= -1) {
1085 tcg_gen_andi_tl(reg
, cc
.reg
, cc
.mask
);
1089 tcg_gen_setcond_tl(cc
.cond
, reg
, cc
.reg
, cc
.reg2
);
1091 tcg_gen_setcondi_tl(cc
.cond
, reg
, cc
.reg
, cc
.imm
);
1095 static inline void gen_compute_eflags_c(DisasContext
*s
, TCGv reg
)
1097 gen_setcc1(s
, JCC_B
<< 1, reg
);
1100 /* generate a conditional jump to label 'l1' according to jump opcode
1101 value 'b'. In the fast case, T0 is guaranted not to be used. */
1102 static inline void gen_jcc1_noeob(DisasContext
*s
, int b
, TCGLabel
*l1
)
1104 CCPrepare cc
= gen_prepare_cc(s
, b
, s
->T0
);
1106 if (cc
.mask
!= -1) {
1107 tcg_gen_andi_tl(s
->T0
, cc
.reg
, cc
.mask
);
1111 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1113 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1117 /* Generate a conditional jump to label 'l1' according to jump opcode
1118 value 'b'. In the fast case, T0 is guaranted not to be used.
1119 A translation block must end soon. */
1120 static inline void gen_jcc1(DisasContext
*s
, int b
, TCGLabel
*l1
)
1122 CCPrepare cc
= gen_prepare_cc(s
, b
, s
->T0
);
1124 gen_update_cc_op(s
);
1125 if (cc
.mask
!= -1) {
1126 tcg_gen_andi_tl(s
->T0
, cc
.reg
, cc
.mask
);
1129 set_cc_op(s
, CC_OP_DYNAMIC
);
1131 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1133 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1137 /* XXX: does not work with gdbstub "ice" single step - not a
1139 static TCGLabel
*gen_jz_ecx_string(DisasContext
*s
, target_ulong next_eip
)
1141 TCGLabel
*l1
= gen_new_label();
1142 TCGLabel
*l2
= gen_new_label();
1143 gen_op_jnz_ecx(s
, s
->aflag
, l1
);
1145 gen_jmp_tb(s
, next_eip
, 1);
1150 static inline void gen_stos(DisasContext
*s
, MemOp ot
)
1152 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, R_EAX
);
1153 gen_string_movl_A0_EDI(s
);
1154 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
1155 gen_op_movl_T0_Dshift(s
, ot
);
1156 gen_op_add_reg_T0(s
, s
->aflag
, R_EDI
);
1159 static inline void gen_lods(DisasContext
*s
, MemOp ot
)
1161 gen_string_movl_A0_ESI(s
);
1162 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1163 gen_op_mov_reg_v(s
, ot
, R_EAX
, s
->T0
);
1164 gen_op_movl_T0_Dshift(s
, ot
);
1165 gen_op_add_reg_T0(s
, s
->aflag
, R_ESI
);
1168 static inline void gen_scas(DisasContext
*s
, MemOp ot
)
1170 gen_string_movl_A0_EDI(s
);
1171 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
1172 gen_op(s
, OP_CMPL
, ot
, R_EAX
);
1173 gen_op_movl_T0_Dshift(s
, ot
);
1174 gen_op_add_reg_T0(s
, s
->aflag
, R_EDI
);
1177 static inline void gen_cmps(DisasContext
*s
, MemOp ot
)
1179 gen_string_movl_A0_EDI(s
);
1180 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
1181 gen_string_movl_A0_ESI(s
);
1182 gen_op(s
, OP_CMPL
, ot
, OR_TMP0
);
1183 gen_op_movl_T0_Dshift(s
, ot
);
1184 gen_op_add_reg_T0(s
, s
->aflag
, R_ESI
);
1185 gen_op_add_reg_T0(s
, s
->aflag
, R_EDI
);
1188 static void gen_bpt_io(DisasContext
*s
, TCGv_i32 t_port
, int ot
)
1190 if (s
->flags
& HF_IOBPT_MASK
) {
1191 #ifdef CONFIG_USER_ONLY
1192 /* user-mode cpu should not be in IOBPT mode */
1193 g_assert_not_reached();
1195 TCGv_i32 t_size
= tcg_const_i32(1 << ot
);
1196 TCGv t_next
= tcg_const_tl(s
->pc
- s
->cs_base
);
1198 gen_helper_bpt_io(cpu_env
, t_port
, t_size
, t_next
);
1199 tcg_temp_free_i32(t_size
);
1200 tcg_temp_free(t_next
);
1201 #endif /* CONFIG_USER_ONLY */
1205 static inline void gen_ins(DisasContext
*s
, MemOp ot
)
1207 gen_string_movl_A0_EDI(s
);
1208 /* Note: we must do this dummy write first to be restartable in
1209 case of page fault. */
1210 tcg_gen_movi_tl(s
->T0
, 0);
1211 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
1212 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_EDX
]);
1213 tcg_gen_andi_i32(s
->tmp2_i32
, s
->tmp2_i32
, 0xffff);
1214 gen_helper_in_func(ot
, s
->T0
, s
->tmp2_i32
);
1215 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
1216 gen_op_movl_T0_Dshift(s
, ot
);
1217 gen_op_add_reg_T0(s
, s
->aflag
, R_EDI
);
1218 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
1221 static inline void gen_outs(DisasContext
*s
, MemOp ot
)
1223 gen_string_movl_A0_ESI(s
);
1224 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1226 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_EDX
]);
1227 tcg_gen_andi_i32(s
->tmp2_i32
, s
->tmp2_i32
, 0xffff);
1228 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, s
->T0
);
1229 gen_helper_out_func(ot
, s
->tmp2_i32
, s
->tmp3_i32
);
1230 gen_op_movl_T0_Dshift(s
, ot
);
1231 gen_op_add_reg_T0(s
, s
->aflag
, R_ESI
);
1232 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
1235 /* same method as Valgrind : we generate jumps to current or next
1237 #define GEN_REPZ(op) \
1238 static inline void gen_repz_ ## op(DisasContext *s, MemOp ot, \
1239 target_ulong cur_eip, target_ulong next_eip) \
1242 gen_update_cc_op(s); \
1243 l2 = gen_jz_ecx_string(s, next_eip); \
1244 gen_ ## op(s, ot); \
1245 gen_op_add_reg_im(s, s->aflag, R_ECX, -1); \
1246 /* a loop would cause two single step exceptions if ECX = 1 \
1247 before rep string_insn */ \
1249 gen_op_jz_ecx(s, s->aflag, l2); \
1250 gen_jmp(s, cur_eip); \
1253 #define GEN_REPZ2(op) \
1254 static inline void gen_repz_ ## op(DisasContext *s, MemOp ot, \
1255 target_ulong cur_eip, \
1256 target_ulong next_eip, \
1260 gen_update_cc_op(s); \
1261 l2 = gen_jz_ecx_string(s, next_eip); \
1262 gen_ ## op(s, ot); \
1263 gen_op_add_reg_im(s, s->aflag, R_ECX, -1); \
1264 gen_update_cc_op(s); \
1265 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
1267 gen_op_jz_ecx(s, s->aflag, l2); \
1268 gen_jmp(s, cur_eip); \
1279 static void gen_helper_fp_arith_ST0_FT0(int op
)
1283 gen_helper_fadd_ST0_FT0(cpu_env
);
1286 gen_helper_fmul_ST0_FT0(cpu_env
);
1289 gen_helper_fcom_ST0_FT0(cpu_env
);
1292 gen_helper_fcom_ST0_FT0(cpu_env
);
1295 gen_helper_fsub_ST0_FT0(cpu_env
);
1298 gen_helper_fsubr_ST0_FT0(cpu_env
);
1301 gen_helper_fdiv_ST0_FT0(cpu_env
);
1304 gen_helper_fdivr_ST0_FT0(cpu_env
);
1309 /* NOTE the exception in "r" op ordering */
1310 static void gen_helper_fp_arith_STN_ST0(int op
, int opreg
)
1312 TCGv_i32 tmp
= tcg_const_i32(opreg
);
1315 gen_helper_fadd_STN_ST0(cpu_env
, tmp
);
1318 gen_helper_fmul_STN_ST0(cpu_env
, tmp
);
1321 gen_helper_fsubr_STN_ST0(cpu_env
, tmp
);
1324 gen_helper_fsub_STN_ST0(cpu_env
, tmp
);
1327 gen_helper_fdivr_STN_ST0(cpu_env
, tmp
);
1330 gen_helper_fdiv_STN_ST0(cpu_env
, tmp
);
1335 static void gen_exception(DisasContext
*s
, int trapno
, target_ulong cur_eip
)
1337 gen_update_cc_op(s
);
1338 gen_jmp_im(s
, cur_eip
);
1339 gen_helper_raise_exception(cpu_env
, tcg_const_i32(trapno
));
1340 s
->base
.is_jmp
= DISAS_NORETURN
;
1343 /* Generate #UD for the current instruction. The assumption here is that
1344 the instruction is known, but it isn't allowed in the current cpu mode. */
1345 static void gen_illegal_opcode(DisasContext
*s
)
1347 gen_exception(s
, EXCP06_ILLOP
, s
->pc_start
- s
->cs_base
);
1350 /* Generate #GP for the current instruction. */
1351 static void gen_exception_gpf(DisasContext
*s
)
1353 gen_exception(s
, EXCP0D_GPF
, s
->pc_start
- s
->cs_base
);
1356 /* Check for cpl == 0; if not, raise #GP and return false. */
1357 static bool check_cpl0(DisasContext
*s
)
1362 gen_exception_gpf(s
);
1366 /* If vm86, check for iopl == 3; if not, raise #GP and return false. */
1367 static bool check_vm86_iopl(DisasContext
*s
)
1369 if (!VM86(s
) || IOPL(s
) == 3) {
1372 gen_exception_gpf(s
);
1376 /* Check for iopl allowing access; if not, raise #GP and return false. */
1377 static bool check_iopl(DisasContext
*s
)
1379 if (VM86(s
) ? IOPL(s
) == 3 : CPL(s
) <= IOPL(s
)) {
1382 gen_exception_gpf(s
);
1386 /* if d == OR_TMP0, it means memory operand (address in A0) */
1387 static void gen_op(DisasContext
*s1
, int op
, MemOp ot
, int d
)
1390 if (s1
->prefix
& PREFIX_LOCK
) {
1391 /* Lock prefix when destination is not memory. */
1392 gen_illegal_opcode(s1
);
1395 gen_op_mov_v_reg(s1
, ot
, s1
->T0
, d
);
1396 } else if (!(s1
->prefix
& PREFIX_LOCK
)) {
1397 gen_op_ld_v(s1
, ot
, s1
->T0
, s1
->A0
);
1401 gen_compute_eflags_c(s1
, s1
->tmp4
);
1402 if (s1
->prefix
& PREFIX_LOCK
) {
1403 tcg_gen_add_tl(s1
->T0
, s1
->tmp4
, s1
->T1
);
1404 tcg_gen_atomic_add_fetch_tl(s1
->T0
, s1
->A0
, s1
->T0
,
1405 s1
->mem_index
, ot
| MO_LE
);
1407 tcg_gen_add_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1408 tcg_gen_add_tl(s1
->T0
, s1
->T0
, s1
->tmp4
);
1409 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1411 gen_op_update3_cc(s1
, s1
->tmp4
);
1412 set_cc_op(s1
, CC_OP_ADCB
+ ot
);
1415 gen_compute_eflags_c(s1
, s1
->tmp4
);
1416 if (s1
->prefix
& PREFIX_LOCK
) {
1417 tcg_gen_add_tl(s1
->T0
, s1
->T1
, s1
->tmp4
);
1418 tcg_gen_neg_tl(s1
->T0
, s1
->T0
);
1419 tcg_gen_atomic_add_fetch_tl(s1
->T0
, s1
->A0
, s1
->T0
,
1420 s1
->mem_index
, ot
| MO_LE
);
1422 tcg_gen_sub_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1423 tcg_gen_sub_tl(s1
->T0
, s1
->T0
, s1
->tmp4
);
1424 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1426 gen_op_update3_cc(s1
, s1
->tmp4
);
1427 set_cc_op(s1
, CC_OP_SBBB
+ ot
);
1430 if (s1
->prefix
& PREFIX_LOCK
) {
1431 tcg_gen_atomic_add_fetch_tl(s1
->T0
, s1
->A0
, s1
->T1
,
1432 s1
->mem_index
, ot
| MO_LE
);
1434 tcg_gen_add_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1435 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1437 gen_op_update2_cc(s1
);
1438 set_cc_op(s1
, CC_OP_ADDB
+ ot
);
1441 if (s1
->prefix
& PREFIX_LOCK
) {
1442 tcg_gen_neg_tl(s1
->T0
, s1
->T1
);
1443 tcg_gen_atomic_fetch_add_tl(s1
->cc_srcT
, s1
->A0
, s1
->T0
,
1444 s1
->mem_index
, ot
| MO_LE
);
1445 tcg_gen_sub_tl(s1
->T0
, s1
->cc_srcT
, s1
->T1
);
1447 tcg_gen_mov_tl(s1
->cc_srcT
, s1
->T0
);
1448 tcg_gen_sub_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1449 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1451 gen_op_update2_cc(s1
);
1452 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1456 if (s1
->prefix
& PREFIX_LOCK
) {
1457 tcg_gen_atomic_and_fetch_tl(s1
->T0
, s1
->A0
, s1
->T1
,
1458 s1
->mem_index
, ot
| MO_LE
);
1460 tcg_gen_and_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1461 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1463 gen_op_update1_cc(s1
);
1464 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1467 if (s1
->prefix
& PREFIX_LOCK
) {
1468 tcg_gen_atomic_or_fetch_tl(s1
->T0
, s1
->A0
, s1
->T1
,
1469 s1
->mem_index
, ot
| MO_LE
);
1471 tcg_gen_or_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1472 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1474 gen_op_update1_cc(s1
);
1475 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1478 if (s1
->prefix
& PREFIX_LOCK
) {
1479 tcg_gen_atomic_xor_fetch_tl(s1
->T0
, s1
->A0
, s1
->T1
,
1480 s1
->mem_index
, ot
| MO_LE
);
1482 tcg_gen_xor_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1483 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1485 gen_op_update1_cc(s1
);
1486 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1489 tcg_gen_mov_tl(cpu_cc_src
, s1
->T1
);
1490 tcg_gen_mov_tl(s1
->cc_srcT
, s1
->T0
);
1491 tcg_gen_sub_tl(cpu_cc_dst
, s1
->T0
, s1
->T1
);
1492 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1497 /* if d == OR_TMP0, it means memory operand (address in A0) */
1498 static void gen_inc(DisasContext
*s1
, MemOp ot
, int d
, int c
)
1500 if (s1
->prefix
& PREFIX_LOCK
) {
1502 /* Lock prefix when destination is not memory */
1503 gen_illegal_opcode(s1
);
1506 tcg_gen_movi_tl(s1
->T0
, c
> 0 ? 1 : -1);
1507 tcg_gen_atomic_add_fetch_tl(s1
->T0
, s1
->A0
, s1
->T0
,
1508 s1
->mem_index
, ot
| MO_LE
);
1511 gen_op_mov_v_reg(s1
, ot
, s1
->T0
, d
);
1513 gen_op_ld_v(s1
, ot
, s1
->T0
, s1
->A0
);
1515 tcg_gen_addi_tl(s1
->T0
, s1
->T0
, (c
> 0 ? 1 : -1));
1516 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1519 gen_compute_eflags_c(s1
, cpu_cc_src
);
1520 tcg_gen_mov_tl(cpu_cc_dst
, s1
->T0
);
1521 set_cc_op(s1
, (c
> 0 ? CC_OP_INCB
: CC_OP_DECB
) + ot
);
1524 static void gen_shift_flags(DisasContext
*s
, MemOp ot
, TCGv result
,
1525 TCGv shm1
, TCGv count
, bool is_right
)
1527 TCGv_i32 z32
, s32
, oldop
;
1530 /* Store the results into the CC variables. If we know that the
1531 variable must be dead, store unconditionally. Otherwise we'll
1532 need to not disrupt the current contents. */
1533 z_tl
= tcg_const_tl(0);
1534 if (cc_op_live
[s
->cc_op
] & USES_CC_DST
) {
1535 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_dst
, count
, z_tl
,
1536 result
, cpu_cc_dst
);
1538 tcg_gen_mov_tl(cpu_cc_dst
, result
);
1540 if (cc_op_live
[s
->cc_op
] & USES_CC_SRC
) {
1541 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_src
, count
, z_tl
,
1544 tcg_gen_mov_tl(cpu_cc_src
, shm1
);
1546 tcg_temp_free(z_tl
);
1548 /* Get the two potential CC_OP values into temporaries. */
1549 tcg_gen_movi_i32(s
->tmp2_i32
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1550 if (s
->cc_op
== CC_OP_DYNAMIC
) {
1553 tcg_gen_movi_i32(s
->tmp3_i32
, s
->cc_op
);
1554 oldop
= s
->tmp3_i32
;
1557 /* Conditionally store the CC_OP value. */
1558 z32
= tcg_const_i32(0);
1559 s32
= tcg_temp_new_i32();
1560 tcg_gen_trunc_tl_i32(s32
, count
);
1561 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, s32
, z32
, s
->tmp2_i32
, oldop
);
1562 tcg_temp_free_i32(z32
);
1563 tcg_temp_free_i32(s32
);
1565 /* The CC_OP value is no longer predictable. */
1566 set_cc_op(s
, CC_OP_DYNAMIC
);
1569 static void gen_shift_rm_T1(DisasContext
*s
, MemOp ot
, int op1
,
1570 int is_right
, int is_arith
)
1572 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1575 if (op1
== OR_TMP0
) {
1576 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1578 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1581 tcg_gen_andi_tl(s
->T1
, s
->T1
, mask
);
1582 tcg_gen_subi_tl(s
->tmp0
, s
->T1
, 1);
1586 gen_exts(ot
, s
->T0
);
1587 tcg_gen_sar_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1588 tcg_gen_sar_tl(s
->T0
, s
->T0
, s
->T1
);
1590 gen_extu(ot
, s
->T0
);
1591 tcg_gen_shr_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1592 tcg_gen_shr_tl(s
->T0
, s
->T0
, s
->T1
);
1595 tcg_gen_shl_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1596 tcg_gen_shl_tl(s
->T0
, s
->T0
, s
->T1
);
1600 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1602 gen_shift_flags(s
, ot
, s
->T0
, s
->tmp0
, s
->T1
, is_right
);
1605 static void gen_shift_rm_im(DisasContext
*s
, MemOp ot
, int op1
, int op2
,
1606 int is_right
, int is_arith
)
1608 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1612 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1614 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1620 gen_exts(ot
, s
->T0
);
1621 tcg_gen_sari_tl(s
->tmp4
, s
->T0
, op2
- 1);
1622 tcg_gen_sari_tl(s
->T0
, s
->T0
, op2
);
1624 gen_extu(ot
, s
->T0
);
1625 tcg_gen_shri_tl(s
->tmp4
, s
->T0
, op2
- 1);
1626 tcg_gen_shri_tl(s
->T0
, s
->T0
, op2
);
1629 tcg_gen_shli_tl(s
->tmp4
, s
->T0
, op2
- 1);
1630 tcg_gen_shli_tl(s
->T0
, s
->T0
, op2
);
1635 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1637 /* update eflags if non zero shift */
1639 tcg_gen_mov_tl(cpu_cc_src
, s
->tmp4
);
1640 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
1641 set_cc_op(s
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1645 static void gen_rot_rm_T1(DisasContext
*s
, MemOp ot
, int op1
, int is_right
)
1647 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1651 if (op1
== OR_TMP0
) {
1652 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1654 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1657 tcg_gen_andi_tl(s
->T1
, s
->T1
, mask
);
1661 /* Replicate the 8-bit input so that a 32-bit rotate works. */
1662 tcg_gen_ext8u_tl(s
->T0
, s
->T0
);
1663 tcg_gen_muli_tl(s
->T0
, s
->T0
, 0x01010101);
1666 /* Replicate the 16-bit input so that a 32-bit rotate works. */
1667 tcg_gen_deposit_tl(s
->T0
, s
->T0
, s
->T0
, 16, 16);
1670 #ifdef TARGET_X86_64
1672 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
1673 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, s
->T1
);
1675 tcg_gen_rotr_i32(s
->tmp2_i32
, s
->tmp2_i32
, s
->tmp3_i32
);
1677 tcg_gen_rotl_i32(s
->tmp2_i32
, s
->tmp2_i32
, s
->tmp3_i32
);
1679 tcg_gen_extu_i32_tl(s
->T0
, s
->tmp2_i32
);
1684 tcg_gen_rotr_tl(s
->T0
, s
->T0
, s
->T1
);
1686 tcg_gen_rotl_tl(s
->T0
, s
->T0
, s
->T1
);
1692 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1694 /* We'll need the flags computed into CC_SRC. */
1695 gen_compute_eflags(s
);
1697 /* The value that was "rotated out" is now present at the other end
1698 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1699 since we've computed the flags into CC_SRC, these variables are
1702 tcg_gen_shri_tl(cpu_cc_src2
, s
->T0
, mask
- 1);
1703 tcg_gen_shri_tl(cpu_cc_dst
, s
->T0
, mask
);
1704 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1706 tcg_gen_shri_tl(cpu_cc_src2
, s
->T0
, mask
);
1707 tcg_gen_andi_tl(cpu_cc_dst
, s
->T0
, 1);
1709 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1710 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1712 /* Now conditionally store the new CC_OP value. If the shift count
1713 is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1714 Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1715 exactly as we computed above. */
1716 t0
= tcg_const_i32(0);
1717 t1
= tcg_temp_new_i32();
1718 tcg_gen_trunc_tl_i32(t1
, s
->T1
);
1719 tcg_gen_movi_i32(s
->tmp2_i32
, CC_OP_ADCOX
);
1720 tcg_gen_movi_i32(s
->tmp3_i32
, CC_OP_EFLAGS
);
1721 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, t1
, t0
,
1722 s
->tmp2_i32
, s
->tmp3_i32
);
1723 tcg_temp_free_i32(t0
);
1724 tcg_temp_free_i32(t1
);
1726 /* The CC_OP value is no longer predictable. */
1727 set_cc_op(s
, CC_OP_DYNAMIC
);
1730 static void gen_rot_rm_im(DisasContext
*s
, MemOp ot
, int op1
, int op2
,
1733 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1737 if (op1
== OR_TMP0
) {
1738 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1740 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1746 #ifdef TARGET_X86_64
1748 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
1750 tcg_gen_rotri_i32(s
->tmp2_i32
, s
->tmp2_i32
, op2
);
1752 tcg_gen_rotli_i32(s
->tmp2_i32
, s
->tmp2_i32
, op2
);
1754 tcg_gen_extu_i32_tl(s
->T0
, s
->tmp2_i32
);
1759 tcg_gen_rotri_tl(s
->T0
, s
->T0
, op2
);
1761 tcg_gen_rotli_tl(s
->T0
, s
->T0
, op2
);
1772 shift
= mask
+ 1 - shift
;
1774 gen_extu(ot
, s
->T0
);
1775 tcg_gen_shli_tl(s
->tmp0
, s
->T0
, shift
);
1776 tcg_gen_shri_tl(s
->T0
, s
->T0
, mask
+ 1 - shift
);
1777 tcg_gen_or_tl(s
->T0
, s
->T0
, s
->tmp0
);
1783 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1786 /* Compute the flags into CC_SRC. */
1787 gen_compute_eflags(s
);
1789 /* The value that was "rotated out" is now present at the other end
1790 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1791 since we've computed the flags into CC_SRC, these variables are
1794 tcg_gen_shri_tl(cpu_cc_src2
, s
->T0
, mask
- 1);
1795 tcg_gen_shri_tl(cpu_cc_dst
, s
->T0
, mask
);
1796 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1798 tcg_gen_shri_tl(cpu_cc_src2
, s
->T0
, mask
);
1799 tcg_gen_andi_tl(cpu_cc_dst
, s
->T0
, 1);
1801 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1802 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1803 set_cc_op(s
, CC_OP_ADCOX
);
1807 /* XXX: add faster immediate = 1 case */
1808 static void gen_rotc_rm_T1(DisasContext
*s
, MemOp ot
, int op1
,
1811 gen_compute_eflags(s
);
1812 assert(s
->cc_op
== CC_OP_EFLAGS
);
1816 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1818 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1823 gen_helper_rcrb(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1826 gen_helper_rcrw(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1829 gen_helper_rcrl(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1831 #ifdef TARGET_X86_64
1833 gen_helper_rcrq(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1842 gen_helper_rclb(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1845 gen_helper_rclw(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1848 gen_helper_rcll(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1850 #ifdef TARGET_X86_64
1852 gen_helper_rclq(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1860 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1863 /* XXX: add faster immediate case */
1864 static void gen_shiftd_rm_T1(DisasContext
*s
, MemOp ot
, int op1
,
1865 bool is_right
, TCGv count_in
)
1867 target_ulong mask
= (ot
== MO_64
? 63 : 31);
1871 if (op1
== OR_TMP0
) {
1872 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1874 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1877 count
= tcg_temp_new();
1878 tcg_gen_andi_tl(count
, count_in
, mask
);
1882 /* Note: we implement the Intel behaviour for shift count > 16.
1883 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A
1884 portion by constructing it as a 32-bit value. */
1886 tcg_gen_deposit_tl(s
->tmp0
, s
->T0
, s
->T1
, 16, 16);
1887 tcg_gen_mov_tl(s
->T1
, s
->T0
);
1888 tcg_gen_mov_tl(s
->T0
, s
->tmp0
);
1890 tcg_gen_deposit_tl(s
->T1
, s
->T0
, s
->T1
, 16, 16);
1893 * If TARGET_X86_64 defined then fall through into MO_32 case,
1894 * otherwise fall through default case.
1897 #ifdef TARGET_X86_64
1898 /* Concatenate the two 32-bit values and use a 64-bit shift. */
1899 tcg_gen_subi_tl(s
->tmp0
, count
, 1);
1901 tcg_gen_concat_tl_i64(s
->T0
, s
->T0
, s
->T1
);
1902 tcg_gen_shr_i64(s
->tmp0
, s
->T0
, s
->tmp0
);
1903 tcg_gen_shr_i64(s
->T0
, s
->T0
, count
);
1905 tcg_gen_concat_tl_i64(s
->T0
, s
->T1
, s
->T0
);
1906 tcg_gen_shl_i64(s
->tmp0
, s
->T0
, s
->tmp0
);
1907 tcg_gen_shl_i64(s
->T0
, s
->T0
, count
);
1908 tcg_gen_shri_i64(s
->tmp0
, s
->tmp0
, 32);
1909 tcg_gen_shri_i64(s
->T0
, s
->T0
, 32);
1914 tcg_gen_subi_tl(s
->tmp0
, count
, 1);
1916 tcg_gen_shr_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1918 tcg_gen_subfi_tl(s
->tmp4
, mask
+ 1, count
);
1919 tcg_gen_shr_tl(s
->T0
, s
->T0
, count
);
1920 tcg_gen_shl_tl(s
->T1
, s
->T1
, s
->tmp4
);
1922 tcg_gen_shl_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1924 /* Only needed if count > 16, for Intel behaviour. */
1925 tcg_gen_subfi_tl(s
->tmp4
, 33, count
);
1926 tcg_gen_shr_tl(s
->tmp4
, s
->T1
, s
->tmp4
);
1927 tcg_gen_or_tl(s
->tmp0
, s
->tmp0
, s
->tmp4
);
1930 tcg_gen_subfi_tl(s
->tmp4
, mask
+ 1, count
);
1931 tcg_gen_shl_tl(s
->T0
, s
->T0
, count
);
1932 tcg_gen_shr_tl(s
->T1
, s
->T1
, s
->tmp4
);
1934 tcg_gen_movi_tl(s
->tmp4
, 0);
1935 tcg_gen_movcond_tl(TCG_COND_EQ
, s
->T1
, count
, s
->tmp4
,
1937 tcg_gen_or_tl(s
->T0
, s
->T0
, s
->T1
);
1942 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1944 gen_shift_flags(s
, ot
, s
->T0
, s
->tmp0
, count
, is_right
);
1945 tcg_temp_free(count
);
1948 static void gen_shift(DisasContext
*s1
, int op
, MemOp ot
, int d
, int s
)
1951 gen_op_mov_v_reg(s1
, ot
, s1
->T1
, s
);
1954 gen_rot_rm_T1(s1
, ot
, d
, 0);
1957 gen_rot_rm_T1(s1
, ot
, d
, 1);
1961 gen_shift_rm_T1(s1
, ot
, d
, 0, 0);
1964 gen_shift_rm_T1(s1
, ot
, d
, 1, 0);
1967 gen_shift_rm_T1(s1
, ot
, d
, 1, 1);
1970 gen_rotc_rm_T1(s1
, ot
, d
, 0);
1973 gen_rotc_rm_T1(s1
, ot
, d
, 1);
1978 static void gen_shifti(DisasContext
*s1
, int op
, MemOp ot
, int d
, int c
)
1982 gen_rot_rm_im(s1
, ot
, d
, c
, 0);
1985 gen_rot_rm_im(s1
, ot
, d
, c
, 1);
1989 gen_shift_rm_im(s1
, ot
, d
, c
, 0, 0);
1992 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 0);
1995 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 1);
1998 /* currently not optimized */
1999 tcg_gen_movi_tl(s1
->T1
, c
);
2000 gen_shift(s1
, op
, ot
, d
, OR_TMP1
);
2005 #define X86_MAX_INSN_LENGTH 15
2007 static uint64_t advance_pc(CPUX86State
*env
, DisasContext
*s
, int num_bytes
)
2009 uint64_t pc
= s
->pc
;
2012 if (unlikely(s
->pc
- s
->pc_start
> X86_MAX_INSN_LENGTH
)) {
2013 /* If the instruction's 16th byte is on a different page than the 1st, a
2014 * page fault on the second page wins over the general protection fault
2015 * caused by the instruction being too long.
2016 * This can happen even if the operand is only one byte long!
2018 if (((s
->pc
- 1) ^ (pc
- 1)) & TARGET_PAGE_MASK
) {
2019 volatile uint8_t unused
=
2020 cpu_ldub_code(env
, (s
->pc
- 1) & TARGET_PAGE_MASK
);
2023 siglongjmp(s
->jmpbuf
, 1);
2029 static inline uint8_t x86_ldub_code(CPUX86State
*env
, DisasContext
*s
)
2031 return translator_ldub(env
, advance_pc(env
, s
, 1));
2034 static inline int16_t x86_ldsw_code(CPUX86State
*env
, DisasContext
*s
)
2036 return translator_ldsw(env
, advance_pc(env
, s
, 2));
2039 static inline uint16_t x86_lduw_code(CPUX86State
*env
, DisasContext
*s
)
2041 return translator_lduw(env
, advance_pc(env
, s
, 2));
2044 static inline uint32_t x86_ldl_code(CPUX86State
*env
, DisasContext
*s
)
2046 return translator_ldl(env
, advance_pc(env
, s
, 4));
2049 #ifdef TARGET_X86_64
2050 static inline uint64_t x86_ldq_code(CPUX86State
*env
, DisasContext
*s
)
2052 return translator_ldq(env
, advance_pc(env
, s
, 8));
2056 /* Decompose an address. */
2058 typedef struct AddressParts
{
2066 static AddressParts
gen_lea_modrm_0(CPUX86State
*env
, DisasContext
*s
,
2069 int def_seg
, base
, index
, scale
, mod
, rm
;
2078 mod
= (modrm
>> 6) & 3;
2080 base
= rm
| REX_B(s
);
2083 /* Normally filtered out earlier, but including this path
2084 simplifies multi-byte nop, as well as bndcl, bndcu, bndcn. */
2093 int code
= x86_ldub_code(env
, s
);
2094 scale
= (code
>> 6) & 3;
2095 index
= ((code
>> 3) & 7) | REX_X(s
);
2097 index
= -1; /* no index */
2099 base
= (code
& 7) | REX_B(s
);
2105 if ((base
& 7) == 5) {
2107 disp
= (int32_t)x86_ldl_code(env
, s
);
2108 if (CODE64(s
) && !havesib
) {
2110 disp
+= s
->pc
+ s
->rip_offset
;
2115 disp
= (int8_t)x86_ldub_code(env
, s
);
2119 disp
= (int32_t)x86_ldl_code(env
, s
);
2123 /* For correct popl handling with esp. */
2124 if (base
== R_ESP
&& s
->popl_esp_hack
) {
2125 disp
+= s
->popl_esp_hack
;
2127 if (base
== R_EBP
|| base
== R_ESP
) {
2136 disp
= x86_lduw_code(env
, s
);
2139 } else if (mod
== 1) {
2140 disp
= (int8_t)x86_ldub_code(env
, s
);
2142 disp
= (int16_t)x86_lduw_code(env
, s
);
2186 return (AddressParts
){ def_seg
, base
, index
, scale
, disp
};
2189 /* Compute the address, with a minimum number of TCG ops. */
2190 static TCGv
gen_lea_modrm_1(DisasContext
*s
, AddressParts a
)
2196 ea
= cpu_regs
[a
.index
];
2198 tcg_gen_shli_tl(s
->A0
, cpu_regs
[a
.index
], a
.scale
);
2202 tcg_gen_add_tl(s
->A0
, ea
, cpu_regs
[a
.base
]);
2205 } else if (a
.base
>= 0) {
2206 ea
= cpu_regs
[a
.base
];
2209 tcg_gen_movi_tl(s
->A0
, a
.disp
);
2211 } else if (a
.disp
!= 0) {
2212 tcg_gen_addi_tl(s
->A0
, ea
, a
.disp
);
2219 static void gen_lea_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2221 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
2222 TCGv ea
= gen_lea_modrm_1(s
, a
);
2223 gen_lea_v_seg(s
, s
->aflag
, ea
, a
.def_seg
, s
->override
);
2226 static void gen_nop_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2228 (void)gen_lea_modrm_0(env
, s
, modrm
);
2231 /* Used for BNDCL, BNDCU, BNDCN. */
2232 static void gen_bndck(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2233 TCGCond cond
, TCGv_i64 bndv
)
2235 TCGv ea
= gen_lea_modrm_1(s
, gen_lea_modrm_0(env
, s
, modrm
));
2237 tcg_gen_extu_tl_i64(s
->tmp1_i64
, ea
);
2239 tcg_gen_ext32u_i64(s
->tmp1_i64
, s
->tmp1_i64
);
2241 tcg_gen_setcond_i64(cond
, s
->tmp1_i64
, s
->tmp1_i64
, bndv
);
2242 tcg_gen_extrl_i64_i32(s
->tmp2_i32
, s
->tmp1_i64
);
2243 gen_helper_bndck(cpu_env
, s
->tmp2_i32
);
2246 /* used for LEA and MOV AX, mem */
2247 static void gen_add_A0_ds_seg(DisasContext
*s
)
2249 gen_lea_v_seg(s
, s
->aflag
, s
->A0
, R_DS
, s
->override
);
2252 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2254 static void gen_ldst_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2255 MemOp ot
, int reg
, int is_store
)
2259 mod
= (modrm
>> 6) & 3;
2260 rm
= (modrm
& 7) | REX_B(s
);
2264 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
2265 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
2267 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
2269 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
2272 gen_lea_modrm(env
, s
, modrm
);
2275 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
2276 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
2278 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
2280 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
2285 static inline uint32_t insn_get(CPUX86State
*env
, DisasContext
*s
, MemOp ot
)
2291 ret
= x86_ldub_code(env
, s
);
2294 ret
= x86_lduw_code(env
, s
);
2297 #ifdef TARGET_X86_64
2300 ret
= x86_ldl_code(env
, s
);
2308 static inline int insn_const_size(MemOp ot
)
2317 static inline bool use_goto_tb(DisasContext
*s
, target_ulong pc
)
2319 #ifndef CONFIG_USER_ONLY
2320 return (pc
& TARGET_PAGE_MASK
) == (s
->base
.tb
->pc
& TARGET_PAGE_MASK
) ||
2321 (pc
& TARGET_PAGE_MASK
) == (s
->pc_start
& TARGET_PAGE_MASK
);
2327 static inline void gen_goto_tb(DisasContext
*s
, int tb_num
, target_ulong eip
)
2329 target_ulong pc
= s
->cs_base
+ eip
;
2331 if (use_goto_tb(s
, pc
)) {
2332 /* jump to same page: we can use a direct jump */
2333 tcg_gen_goto_tb(tb_num
);
2335 tcg_gen_exit_tb(s
->base
.tb
, tb_num
);
2336 s
->base
.is_jmp
= DISAS_NORETURN
;
2338 /* jump to another page */
2344 static inline void gen_jcc(DisasContext
*s
, int b
,
2345 target_ulong val
, target_ulong next_eip
)
2350 l1
= gen_new_label();
2353 gen_goto_tb(s
, 0, next_eip
);
2356 gen_goto_tb(s
, 1, val
);
2358 l1
= gen_new_label();
2359 l2
= gen_new_label();
2362 gen_jmp_im(s
, next_eip
);
2372 static void gen_cmovcc1(CPUX86State
*env
, DisasContext
*s
, MemOp ot
, int b
,
2377 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
2379 cc
= gen_prepare_cc(s
, b
, s
->T1
);
2380 if (cc
.mask
!= -1) {
2381 TCGv t0
= tcg_temp_new();
2382 tcg_gen_andi_tl(t0
, cc
.reg
, cc
.mask
);
2386 cc
.reg2
= tcg_const_tl(cc
.imm
);
2389 tcg_gen_movcond_tl(cc
.cond
, s
->T0
, cc
.reg
, cc
.reg2
,
2390 s
->T0
, cpu_regs
[reg
]);
2391 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
2393 if (cc
.mask
!= -1) {
2394 tcg_temp_free(cc
.reg
);
2397 tcg_temp_free(cc
.reg2
);
2401 static inline void gen_op_movl_T0_seg(DisasContext
*s
, X86Seg seg_reg
)
2403 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
2404 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2407 static inline void gen_op_movl_seg_T0_vm(DisasContext
*s
, X86Seg seg_reg
)
2409 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
2410 tcg_gen_st32_tl(s
->T0
, cpu_env
,
2411 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2412 tcg_gen_shli_tl(cpu_seg_base
[seg_reg
], s
->T0
, 4);
2415 /* move T0 to seg_reg and compute if the CPU state may change. Never
2416 call this function with seg_reg == R_CS */
2417 static void gen_movl_seg_T0(DisasContext
*s
, X86Seg seg_reg
)
2419 if (PE(s
) && !VM86(s
)) {
2420 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
2421 gen_helper_load_seg(cpu_env
, tcg_const_i32(seg_reg
), s
->tmp2_i32
);
2422 /* abort translation because the addseg value may change or
2423 because ss32 may change. For R_SS, translation must always
2424 stop as a special handling must be done to disable hardware
2425 interrupts for the next instruction */
2426 if (seg_reg
== R_SS
|| (CODE32(s
) && seg_reg
< R_FS
)) {
2427 s
->base
.is_jmp
= DISAS_TOO_MANY
;
2430 gen_op_movl_seg_T0_vm(s
, seg_reg
);
2431 if (seg_reg
== R_SS
) {
2432 s
->base
.is_jmp
= DISAS_TOO_MANY
;
2437 static void gen_svm_check_intercept(DisasContext
*s
, uint32_t type
)
2439 /* no SVM activated; fast case */
2440 if (likely(!GUEST(s
))) {
2443 gen_helper_svm_check_intercept(cpu_env
, tcg_constant_i32(type
));
2446 static inline void gen_stack_update(DisasContext
*s
, int addend
)
2448 gen_op_add_reg_im(s
, mo_stacksize(s
), R_ESP
, addend
);
2451 /* Generate a push. It depends on ss32, addseg and dflag. */
2452 static void gen_push_v(DisasContext
*s
, TCGv val
)
2454 MemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2455 MemOp a_ot
= mo_stacksize(s
);
2456 int size
= 1 << d_ot
;
2457 TCGv new_esp
= s
->A0
;
2459 tcg_gen_subi_tl(s
->A0
, cpu_regs
[R_ESP
], size
);
2464 tcg_gen_mov_tl(new_esp
, s
->A0
);
2466 gen_lea_v_seg(s
, a_ot
, s
->A0
, R_SS
, -1);
2469 gen_op_st_v(s
, d_ot
, val
, s
->A0
);
2470 gen_op_mov_reg_v(s
, a_ot
, R_ESP
, new_esp
);
2473 /* two step pop is necessary for precise exceptions */
2474 static MemOp
gen_pop_T0(DisasContext
*s
)
2476 MemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2478 gen_lea_v_seg(s
, mo_stacksize(s
), cpu_regs
[R_ESP
], R_SS
, -1);
2479 gen_op_ld_v(s
, d_ot
, s
->T0
, s
->A0
);
2484 static inline void gen_pop_update(DisasContext
*s
, MemOp ot
)
2486 gen_stack_update(s
, 1 << ot
);
2489 static inline void gen_stack_A0(DisasContext
*s
)
2491 gen_lea_v_seg(s
, SS32(s
) ? MO_32
: MO_16
, cpu_regs
[R_ESP
], R_SS
, -1);
2494 static void gen_pusha(DisasContext
*s
)
2496 MemOp s_ot
= SS32(s
) ? MO_32
: MO_16
;
2497 MemOp d_ot
= s
->dflag
;
2498 int size
= 1 << d_ot
;
2501 for (i
= 0; i
< 8; i
++) {
2502 tcg_gen_addi_tl(s
->A0
, cpu_regs
[R_ESP
], (i
- 8) * size
);
2503 gen_lea_v_seg(s
, s_ot
, s
->A0
, R_SS
, -1);
2504 gen_op_st_v(s
, d_ot
, cpu_regs
[7 - i
], s
->A0
);
2507 gen_stack_update(s
, -8 * size
);
2510 static void gen_popa(DisasContext
*s
)
2512 MemOp s_ot
= SS32(s
) ? MO_32
: MO_16
;
2513 MemOp d_ot
= s
->dflag
;
2514 int size
= 1 << d_ot
;
2517 for (i
= 0; i
< 8; i
++) {
2518 /* ESP is not reloaded */
2519 if (7 - i
== R_ESP
) {
2522 tcg_gen_addi_tl(s
->A0
, cpu_regs
[R_ESP
], i
* size
);
2523 gen_lea_v_seg(s
, s_ot
, s
->A0
, R_SS
, -1);
2524 gen_op_ld_v(s
, d_ot
, s
->T0
, s
->A0
);
2525 gen_op_mov_reg_v(s
, d_ot
, 7 - i
, s
->T0
);
2528 gen_stack_update(s
, 8 * size
);
2531 static void gen_enter(DisasContext
*s
, int esp_addend
, int level
)
2533 MemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2534 MemOp a_ot
= CODE64(s
) ? MO_64
: SS32(s
) ? MO_32
: MO_16
;
2535 int size
= 1 << d_ot
;
2537 /* Push BP; compute FrameTemp into T1. */
2538 tcg_gen_subi_tl(s
->T1
, cpu_regs
[R_ESP
], size
);
2539 gen_lea_v_seg(s
, a_ot
, s
->T1
, R_SS
, -1);
2540 gen_op_st_v(s
, d_ot
, cpu_regs
[R_EBP
], s
->A0
);
2546 /* Copy level-1 pointers from the previous frame. */
2547 for (i
= 1; i
< level
; ++i
) {
2548 tcg_gen_subi_tl(s
->A0
, cpu_regs
[R_EBP
], size
* i
);
2549 gen_lea_v_seg(s
, a_ot
, s
->A0
, R_SS
, -1);
2550 gen_op_ld_v(s
, d_ot
, s
->tmp0
, s
->A0
);
2552 tcg_gen_subi_tl(s
->A0
, s
->T1
, size
* i
);
2553 gen_lea_v_seg(s
, a_ot
, s
->A0
, R_SS
, -1);
2554 gen_op_st_v(s
, d_ot
, s
->tmp0
, s
->A0
);
2557 /* Push the current FrameTemp as the last level. */
2558 tcg_gen_subi_tl(s
->A0
, s
->T1
, size
* level
);
2559 gen_lea_v_seg(s
, a_ot
, s
->A0
, R_SS
, -1);
2560 gen_op_st_v(s
, d_ot
, s
->T1
, s
->A0
);
2563 /* Copy the FrameTemp value to EBP. */
2564 gen_op_mov_reg_v(s
, a_ot
, R_EBP
, s
->T1
);
2566 /* Compute the final value of ESP. */
2567 tcg_gen_subi_tl(s
->T1
, s
->T1
, esp_addend
+ size
* level
);
2568 gen_op_mov_reg_v(s
, a_ot
, R_ESP
, s
->T1
);
2571 static void gen_leave(DisasContext
*s
)
2573 MemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2574 MemOp a_ot
= mo_stacksize(s
);
2576 gen_lea_v_seg(s
, a_ot
, cpu_regs
[R_EBP
], R_SS
, -1);
2577 gen_op_ld_v(s
, d_ot
, s
->T0
, s
->A0
);
2579 tcg_gen_addi_tl(s
->T1
, cpu_regs
[R_EBP
], 1 << d_ot
);
2581 gen_op_mov_reg_v(s
, d_ot
, R_EBP
, s
->T0
);
2582 gen_op_mov_reg_v(s
, a_ot
, R_ESP
, s
->T1
);
2585 /* Similarly, except that the assumption here is that we don't decode
2586 the instruction at all -- either a missing opcode, an unimplemented
2587 feature, or just a bogus instruction stream. */
2588 static void gen_unknown_opcode(CPUX86State
*env
, DisasContext
*s
)
2590 gen_illegal_opcode(s
);
2592 if (qemu_loglevel_mask(LOG_UNIMP
)) {
2593 FILE *logfile
= qemu_log_lock();
2594 target_ulong pc
= s
->pc_start
, end
= s
->pc
;
2596 qemu_log("ILLOPC: " TARGET_FMT_lx
":", pc
);
2597 for (; pc
< end
; ++pc
) {
2598 qemu_log(" %02x", cpu_ldub_code(env
, pc
));
2601 qemu_log_unlock(logfile
);
2605 /* an interrupt is different from an exception because of the
2607 static void gen_interrupt(DisasContext
*s
, int intno
,
2608 target_ulong cur_eip
, target_ulong next_eip
)
2610 gen_update_cc_op(s
);
2611 gen_jmp_im(s
, cur_eip
);
2612 gen_helper_raise_interrupt(cpu_env
, tcg_const_i32(intno
),
2613 tcg_const_i32(next_eip
- cur_eip
));
2614 s
->base
.is_jmp
= DISAS_NORETURN
;
2617 static void gen_debug(DisasContext
*s
)
2619 gen_update_cc_op(s
);
2620 gen_jmp_im(s
, s
->base
.pc_next
- s
->cs_base
);
2621 gen_helper_debug(cpu_env
);
2622 s
->base
.is_jmp
= DISAS_NORETURN
;
2625 static void gen_set_hflag(DisasContext
*s
, uint32_t mask
)
2627 if ((s
->flags
& mask
) == 0) {
2628 TCGv_i32 t
= tcg_temp_new_i32();
2629 tcg_gen_ld_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2630 tcg_gen_ori_i32(t
, t
, mask
);
2631 tcg_gen_st_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2632 tcg_temp_free_i32(t
);
2637 static void gen_reset_hflag(DisasContext
*s
, uint32_t mask
)
2639 if (s
->flags
& mask
) {
2640 TCGv_i32 t
= tcg_temp_new_i32();
2641 tcg_gen_ld_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2642 tcg_gen_andi_i32(t
, t
, ~mask
);
2643 tcg_gen_st_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2644 tcg_temp_free_i32(t
);
2649 /* Clear BND registers during legacy branches. */
2650 static void gen_bnd_jmp(DisasContext
*s
)
2652 /* Clear the registers only if BND prefix is missing, MPX is enabled,
2653 and if the BNDREGs are known to be in use (non-zero) already.
2654 The helper itself will check BNDPRESERVE at runtime. */
2655 if ((s
->prefix
& PREFIX_REPNZ
) == 0
2656 && (s
->flags
& HF_MPX_EN_MASK
) != 0
2657 && (s
->flags
& HF_MPX_IU_MASK
) != 0) {
2658 gen_helper_bnd_jmp(cpu_env
);
2662 /* Generate an end of block. Trace exception is also generated if needed.
2663 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set.
2664 If RECHECK_TF, emit a rechecking helper for #DB, ignoring the state of
2665 S->TF. This is used by the syscall/sysret insns. */
2667 do_gen_eob_worker(DisasContext
*s
, bool inhibit
, bool recheck_tf
, bool jr
)
2669 gen_update_cc_op(s
);
2671 /* If several instructions disable interrupts, only the first does it. */
2672 if (inhibit
&& !(s
->flags
& HF_INHIBIT_IRQ_MASK
)) {
2673 gen_set_hflag(s
, HF_INHIBIT_IRQ_MASK
);
2675 gen_reset_hflag(s
, HF_INHIBIT_IRQ_MASK
);
2678 if (s
->base
.tb
->flags
& HF_RF_MASK
) {
2679 gen_helper_reset_rf(cpu_env
);
2681 if (s
->base
.singlestep_enabled
) {
2682 gen_helper_debug(cpu_env
);
2683 } else if (recheck_tf
) {
2684 gen_helper_rechecking_single_step(cpu_env
);
2685 tcg_gen_exit_tb(NULL
, 0);
2686 } else if (s
->flags
& HF_TF_MASK
) {
2687 gen_helper_single_step(cpu_env
);
2689 tcg_gen_lookup_and_goto_ptr();
2691 tcg_gen_exit_tb(NULL
, 0);
2693 s
->base
.is_jmp
= DISAS_NORETURN
;
2697 gen_eob_worker(DisasContext
*s
, bool inhibit
, bool recheck_tf
)
2699 do_gen_eob_worker(s
, inhibit
, recheck_tf
, false);
2703 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set. */
2704 static void gen_eob_inhibit_irq(DisasContext
*s
, bool inhibit
)
2706 gen_eob_worker(s
, inhibit
, false);
2709 /* End of block, resetting the inhibit irq flag. */
2710 static void gen_eob(DisasContext
*s
)
2712 gen_eob_worker(s
, false, false);
2715 /* Jump to register */
2716 static void gen_jr(DisasContext
*s
, TCGv dest
)
2718 do_gen_eob_worker(s
, false, false, true);
2721 /* generate a jump to eip. No segment change must happen before as a
2722 direct call to the next block may occur */
2723 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
)
2725 gen_update_cc_op(s
);
2726 set_cc_op(s
, CC_OP_DYNAMIC
);
2728 gen_goto_tb(s
, tb_num
, eip
);
2735 static void gen_jmp(DisasContext
*s
, target_ulong eip
)
2737 gen_jmp_tb(s
, eip
, 0);
2740 static inline void gen_ldq_env_A0(DisasContext
*s
, int offset
)
2742 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
, s
->mem_index
, MO_LEQ
);
2743 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, offset
);
2746 static inline void gen_stq_env_A0(DisasContext
*s
, int offset
)
2748 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, offset
);
2749 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
, s
->mem_index
, MO_LEQ
);
2752 static inline void gen_ldo_env_A0(DisasContext
*s
, int offset
)
2754 int mem_index
= s
->mem_index
;
2755 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
, mem_index
, MO_LEQ
);
2756 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2757 tcg_gen_addi_tl(s
->tmp0
, s
->A0
, 8);
2758 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->tmp0
, mem_index
, MO_LEQ
);
2759 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2762 static inline void gen_sto_env_A0(DisasContext
*s
, int offset
)
2764 int mem_index
= s
->mem_index
;
2765 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2766 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
, mem_index
, MO_LEQ
);
2767 tcg_gen_addi_tl(s
->tmp0
, s
->A0
, 8);
2768 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2769 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->tmp0
, mem_index
, MO_LEQ
);
2772 static inline void gen_op_movo(DisasContext
*s
, int d_offset
, int s_offset
)
2774 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, s_offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2775 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, d_offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2776 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, s_offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2777 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, d_offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2780 static inline void gen_op_movq(DisasContext
*s
, int d_offset
, int s_offset
)
2782 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, s_offset
);
2783 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, d_offset
);
2786 static inline void gen_op_movl(DisasContext
*s
, int d_offset
, int s_offset
)
2788 tcg_gen_ld_i32(s
->tmp2_i32
, cpu_env
, s_offset
);
2789 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
, d_offset
);
2792 static inline void gen_op_movq_env_0(DisasContext
*s
, int d_offset
)
2794 tcg_gen_movi_i64(s
->tmp1_i64
, 0);
2795 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, d_offset
);
2798 typedef void (*SSEFunc_i_ep
)(TCGv_i32 val
, TCGv_ptr env
, TCGv_ptr reg
);
2799 typedef void (*SSEFunc_l_ep
)(TCGv_i64 val
, TCGv_ptr env
, TCGv_ptr reg
);
2800 typedef void (*SSEFunc_0_epi
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i32 val
);
2801 typedef void (*SSEFunc_0_epl
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i64 val
);
2802 typedef void (*SSEFunc_0_epp
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
);
2803 typedef void (*SSEFunc_0_eppi
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2805 typedef void (*SSEFunc_0_ppi
)(TCGv_ptr reg_a
, TCGv_ptr reg_b
, TCGv_i32 val
);
2806 typedef void (*SSEFunc_0_eppt
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2809 #define SSE_SPECIAL ((void *)1)
2810 #define SSE_DUMMY ((void *)2)
2812 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2813 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2814 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2816 static const SSEFunc_0_epp sse_op_table1
[256][4] = {
2817 /* 3DNow! extensions */
2818 [0x0e] = { SSE_DUMMY
}, /* femms */
2819 [0x0f] = { SSE_DUMMY
}, /* pf... */
2820 /* pure SSE operations */
2821 [0x10] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2822 [0x11] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2823 [0x12] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd, movsldup, movddup */
2824 [0x13] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd */
2825 [0x14] = { gen_helper_punpckldq_xmm
, gen_helper_punpcklqdq_xmm
},
2826 [0x15] = { gen_helper_punpckhdq_xmm
, gen_helper_punpckhqdq_xmm
},
2827 [0x16] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd, movshdup */
2828 [0x17] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd */
2830 [0x28] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2831 [0x29] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2832 [0x2a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2833 [0x2b] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movntps, movntpd, movntss, movntsd */
2834 [0x2c] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2835 [0x2d] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2836 [0x2e] = { gen_helper_ucomiss
, gen_helper_ucomisd
},
2837 [0x2f] = { gen_helper_comiss
, gen_helper_comisd
},
2838 [0x50] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movmskps, movmskpd */
2839 [0x51] = SSE_FOP(sqrt
),
2840 [0x52] = { gen_helper_rsqrtps
, NULL
, gen_helper_rsqrtss
, NULL
},
2841 [0x53] = { gen_helper_rcpps
, NULL
, gen_helper_rcpss
, NULL
},
2842 [0x54] = { gen_helper_pand_xmm
, gen_helper_pand_xmm
}, /* andps, andpd */
2843 [0x55] = { gen_helper_pandn_xmm
, gen_helper_pandn_xmm
}, /* andnps, andnpd */
2844 [0x56] = { gen_helper_por_xmm
, gen_helper_por_xmm
}, /* orps, orpd */
2845 [0x57] = { gen_helper_pxor_xmm
, gen_helper_pxor_xmm
}, /* xorps, xorpd */
2846 [0x58] = SSE_FOP(add
),
2847 [0x59] = SSE_FOP(mul
),
2848 [0x5a] = { gen_helper_cvtps2pd
, gen_helper_cvtpd2ps
,
2849 gen_helper_cvtss2sd
, gen_helper_cvtsd2ss
},
2850 [0x5b] = { gen_helper_cvtdq2ps
, gen_helper_cvtps2dq
, gen_helper_cvttps2dq
},
2851 [0x5c] = SSE_FOP(sub
),
2852 [0x5d] = SSE_FOP(min
),
2853 [0x5e] = SSE_FOP(div
),
2854 [0x5f] = SSE_FOP(max
),
2856 [0xc2] = SSE_FOP(cmpeq
),
2857 [0xc6] = { (SSEFunc_0_epp
)gen_helper_shufps
,
2858 (SSEFunc_0_epp
)gen_helper_shufpd
}, /* XXX: casts */
2860 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */
2861 [0x38] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2862 [0x3a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2864 /* MMX ops and their SSE extensions */
2865 [0x60] = MMX_OP2(punpcklbw
),
2866 [0x61] = MMX_OP2(punpcklwd
),
2867 [0x62] = MMX_OP2(punpckldq
),
2868 [0x63] = MMX_OP2(packsswb
),
2869 [0x64] = MMX_OP2(pcmpgtb
),
2870 [0x65] = MMX_OP2(pcmpgtw
),
2871 [0x66] = MMX_OP2(pcmpgtl
),
2872 [0x67] = MMX_OP2(packuswb
),
2873 [0x68] = MMX_OP2(punpckhbw
),
2874 [0x69] = MMX_OP2(punpckhwd
),
2875 [0x6a] = MMX_OP2(punpckhdq
),
2876 [0x6b] = MMX_OP2(packssdw
),
2877 [0x6c] = { NULL
, gen_helper_punpcklqdq_xmm
},
2878 [0x6d] = { NULL
, gen_helper_punpckhqdq_xmm
},
2879 [0x6e] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movd mm, ea */
2880 [0x6f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, , movqdu */
2881 [0x70] = { (SSEFunc_0_epp
)gen_helper_pshufw_mmx
,
2882 (SSEFunc_0_epp
)gen_helper_pshufd_xmm
,
2883 (SSEFunc_0_epp
)gen_helper_pshufhw_xmm
,
2884 (SSEFunc_0_epp
)gen_helper_pshuflw_xmm
}, /* XXX: casts */
2885 [0x71] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftw */
2886 [0x72] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftd */
2887 [0x73] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftq */
2888 [0x74] = MMX_OP2(pcmpeqb
),
2889 [0x75] = MMX_OP2(pcmpeqw
),
2890 [0x76] = MMX_OP2(pcmpeql
),
2891 [0x77] = { SSE_DUMMY
}, /* emms */
2892 [0x78] = { NULL
, SSE_SPECIAL
, NULL
, SSE_SPECIAL
}, /* extrq_i, insertq_i */
2893 [0x79] = { NULL
, gen_helper_extrq_r
, NULL
, gen_helper_insertq_r
},
2894 [0x7c] = { NULL
, gen_helper_haddpd
, NULL
, gen_helper_haddps
},
2895 [0x7d] = { NULL
, gen_helper_hsubpd
, NULL
, gen_helper_hsubps
},
2896 [0x7e] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movd, movd, , movq */
2897 [0x7f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, movdqu */
2898 [0xc4] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pinsrw */
2899 [0xc5] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pextrw */
2900 [0xd0] = { NULL
, gen_helper_addsubpd
, NULL
, gen_helper_addsubps
},
2901 [0xd1] = MMX_OP2(psrlw
),
2902 [0xd2] = MMX_OP2(psrld
),
2903 [0xd3] = MMX_OP2(psrlq
),
2904 [0xd4] = MMX_OP2(paddq
),
2905 [0xd5] = MMX_OP2(pmullw
),
2906 [0xd6] = { NULL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2907 [0xd7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pmovmskb */
2908 [0xd8] = MMX_OP2(psubusb
),
2909 [0xd9] = MMX_OP2(psubusw
),
2910 [0xda] = MMX_OP2(pminub
),
2911 [0xdb] = MMX_OP2(pand
),
2912 [0xdc] = MMX_OP2(paddusb
),
2913 [0xdd] = MMX_OP2(paddusw
),
2914 [0xde] = MMX_OP2(pmaxub
),
2915 [0xdf] = MMX_OP2(pandn
),
2916 [0xe0] = MMX_OP2(pavgb
),
2917 [0xe1] = MMX_OP2(psraw
),
2918 [0xe2] = MMX_OP2(psrad
),
2919 [0xe3] = MMX_OP2(pavgw
),
2920 [0xe4] = MMX_OP2(pmulhuw
),
2921 [0xe5] = MMX_OP2(pmulhw
),
2922 [0xe6] = { NULL
, gen_helper_cvttpd2dq
, gen_helper_cvtdq2pd
, gen_helper_cvtpd2dq
},
2923 [0xe7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movntq, movntq */
2924 [0xe8] = MMX_OP2(psubsb
),
2925 [0xe9] = MMX_OP2(psubsw
),
2926 [0xea] = MMX_OP2(pminsw
),
2927 [0xeb] = MMX_OP2(por
),
2928 [0xec] = MMX_OP2(paddsb
),
2929 [0xed] = MMX_OP2(paddsw
),
2930 [0xee] = MMX_OP2(pmaxsw
),
2931 [0xef] = MMX_OP2(pxor
),
2932 [0xf0] = { NULL
, NULL
, NULL
, SSE_SPECIAL
}, /* lddqu */
2933 [0xf1] = MMX_OP2(psllw
),
2934 [0xf2] = MMX_OP2(pslld
),
2935 [0xf3] = MMX_OP2(psllq
),
2936 [0xf4] = MMX_OP2(pmuludq
),
2937 [0xf5] = MMX_OP2(pmaddwd
),
2938 [0xf6] = MMX_OP2(psadbw
),
2939 [0xf7] = { (SSEFunc_0_epp
)gen_helper_maskmov_mmx
,
2940 (SSEFunc_0_epp
)gen_helper_maskmov_xmm
}, /* XXX: casts */
2941 [0xf8] = MMX_OP2(psubb
),
2942 [0xf9] = MMX_OP2(psubw
),
2943 [0xfa] = MMX_OP2(psubl
),
2944 [0xfb] = MMX_OP2(psubq
),
2945 [0xfc] = MMX_OP2(paddb
),
2946 [0xfd] = MMX_OP2(paddw
),
2947 [0xfe] = MMX_OP2(paddl
),
2950 static const SSEFunc_0_epp sse_op_table2
[3 * 8][2] = {
2951 [0 + 2] = MMX_OP2(psrlw
),
2952 [0 + 4] = MMX_OP2(psraw
),
2953 [0 + 6] = MMX_OP2(psllw
),
2954 [8 + 2] = MMX_OP2(psrld
),
2955 [8 + 4] = MMX_OP2(psrad
),
2956 [8 + 6] = MMX_OP2(pslld
),
2957 [16 + 2] = MMX_OP2(psrlq
),
2958 [16 + 3] = { NULL
, gen_helper_psrldq_xmm
},
2959 [16 + 6] = MMX_OP2(psllq
),
2960 [16 + 7] = { NULL
, gen_helper_pslldq_xmm
},
2963 static const SSEFunc_0_epi sse_op_table3ai
[] = {
2964 gen_helper_cvtsi2ss
,
2968 #ifdef TARGET_X86_64
2969 static const SSEFunc_0_epl sse_op_table3aq
[] = {
2970 gen_helper_cvtsq2ss
,
2975 static const SSEFunc_i_ep sse_op_table3bi
[] = {
2976 gen_helper_cvttss2si
,
2977 gen_helper_cvtss2si
,
2978 gen_helper_cvttsd2si
,
2982 #ifdef TARGET_X86_64
2983 static const SSEFunc_l_ep sse_op_table3bq
[] = {
2984 gen_helper_cvttss2sq
,
2985 gen_helper_cvtss2sq
,
2986 gen_helper_cvttsd2sq
,
2991 static const SSEFunc_0_epp sse_op_table4
[8][4] = {
3002 static const SSEFunc_0_epp sse_op_table5
[256] = {
3003 [0x0c] = gen_helper_pi2fw
,
3004 [0x0d] = gen_helper_pi2fd
,
3005 [0x1c] = gen_helper_pf2iw
,
3006 [0x1d] = gen_helper_pf2id
,
3007 [0x8a] = gen_helper_pfnacc
,
3008 [0x8e] = gen_helper_pfpnacc
,
3009 [0x90] = gen_helper_pfcmpge
,
3010 [0x94] = gen_helper_pfmin
,
3011 [0x96] = gen_helper_pfrcp
,
3012 [0x97] = gen_helper_pfrsqrt
,
3013 [0x9a] = gen_helper_pfsub
,
3014 [0x9e] = gen_helper_pfadd
,
3015 [0xa0] = gen_helper_pfcmpgt
,
3016 [0xa4] = gen_helper_pfmax
,
3017 [0xa6] = gen_helper_movq
, /* pfrcpit1; no need to actually increase precision */
3018 [0xa7] = gen_helper_movq
, /* pfrsqit1 */
3019 [0xaa] = gen_helper_pfsubr
,
3020 [0xae] = gen_helper_pfacc
,
3021 [0xb0] = gen_helper_pfcmpeq
,
3022 [0xb4] = gen_helper_pfmul
,
3023 [0xb6] = gen_helper_movq
, /* pfrcpit2 */
3024 [0xb7] = gen_helper_pmulhrw_mmx
,
3025 [0xbb] = gen_helper_pswapd
,
3026 [0xbf] = gen_helper_pavgb_mmx
/* pavgusb */
3029 struct SSEOpHelper_epp
{
3030 SSEFunc_0_epp op
[2];
3034 struct SSEOpHelper_eppi
{
3035 SSEFunc_0_eppi op
[2];
3039 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
3040 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
3041 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
3042 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
3043 #define PCLMULQDQ_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, \
3044 CPUID_EXT_PCLMULQDQ }
3045 #define AESNI_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_AES }
3047 static const struct SSEOpHelper_epp sse_op_table6
[256] = {
3048 [0x00] = SSSE3_OP(pshufb
),
3049 [0x01] = SSSE3_OP(phaddw
),
3050 [0x02] = SSSE3_OP(phaddd
),
3051 [0x03] = SSSE3_OP(phaddsw
),
3052 [0x04] = SSSE3_OP(pmaddubsw
),
3053 [0x05] = SSSE3_OP(phsubw
),
3054 [0x06] = SSSE3_OP(phsubd
),
3055 [0x07] = SSSE3_OP(phsubsw
),
3056 [0x08] = SSSE3_OP(psignb
),
3057 [0x09] = SSSE3_OP(psignw
),
3058 [0x0a] = SSSE3_OP(psignd
),
3059 [0x0b] = SSSE3_OP(pmulhrsw
),
3060 [0x10] = SSE41_OP(pblendvb
),
3061 [0x14] = SSE41_OP(blendvps
),
3062 [0x15] = SSE41_OP(blendvpd
),
3063 [0x17] = SSE41_OP(ptest
),
3064 [0x1c] = SSSE3_OP(pabsb
),
3065 [0x1d] = SSSE3_OP(pabsw
),
3066 [0x1e] = SSSE3_OP(pabsd
),
3067 [0x20] = SSE41_OP(pmovsxbw
),
3068 [0x21] = SSE41_OP(pmovsxbd
),
3069 [0x22] = SSE41_OP(pmovsxbq
),
3070 [0x23] = SSE41_OP(pmovsxwd
),
3071 [0x24] = SSE41_OP(pmovsxwq
),
3072 [0x25] = SSE41_OP(pmovsxdq
),
3073 [0x28] = SSE41_OP(pmuldq
),
3074 [0x29] = SSE41_OP(pcmpeqq
),
3075 [0x2a] = SSE41_SPECIAL
, /* movntqda */
3076 [0x2b] = SSE41_OP(packusdw
),
3077 [0x30] = SSE41_OP(pmovzxbw
),
3078 [0x31] = SSE41_OP(pmovzxbd
),
3079 [0x32] = SSE41_OP(pmovzxbq
),
3080 [0x33] = SSE41_OP(pmovzxwd
),
3081 [0x34] = SSE41_OP(pmovzxwq
),
3082 [0x35] = SSE41_OP(pmovzxdq
),
3083 [0x37] = SSE42_OP(pcmpgtq
),
3084 [0x38] = SSE41_OP(pminsb
),
3085 [0x39] = SSE41_OP(pminsd
),
3086 [0x3a] = SSE41_OP(pminuw
),
3087 [0x3b] = SSE41_OP(pminud
),
3088 [0x3c] = SSE41_OP(pmaxsb
),
3089 [0x3d] = SSE41_OP(pmaxsd
),
3090 [0x3e] = SSE41_OP(pmaxuw
),
3091 [0x3f] = SSE41_OP(pmaxud
),
3092 [0x40] = SSE41_OP(pmulld
),
3093 [0x41] = SSE41_OP(phminposuw
),
3094 [0xdb] = AESNI_OP(aesimc
),
3095 [0xdc] = AESNI_OP(aesenc
),
3096 [0xdd] = AESNI_OP(aesenclast
),
3097 [0xde] = AESNI_OP(aesdec
),
3098 [0xdf] = AESNI_OP(aesdeclast
),
3101 static const struct SSEOpHelper_eppi sse_op_table7
[256] = {
3102 [0x08] = SSE41_OP(roundps
),
3103 [0x09] = SSE41_OP(roundpd
),
3104 [0x0a] = SSE41_OP(roundss
),
3105 [0x0b] = SSE41_OP(roundsd
),
3106 [0x0c] = SSE41_OP(blendps
),
3107 [0x0d] = SSE41_OP(blendpd
),
3108 [0x0e] = SSE41_OP(pblendw
),
3109 [0x0f] = SSSE3_OP(palignr
),
3110 [0x14] = SSE41_SPECIAL
, /* pextrb */
3111 [0x15] = SSE41_SPECIAL
, /* pextrw */
3112 [0x16] = SSE41_SPECIAL
, /* pextrd/pextrq */
3113 [0x17] = SSE41_SPECIAL
, /* extractps */
3114 [0x20] = SSE41_SPECIAL
, /* pinsrb */
3115 [0x21] = SSE41_SPECIAL
, /* insertps */
3116 [0x22] = SSE41_SPECIAL
, /* pinsrd/pinsrq */
3117 [0x40] = SSE41_OP(dpps
),
3118 [0x41] = SSE41_OP(dppd
),
3119 [0x42] = SSE41_OP(mpsadbw
),
3120 [0x44] = PCLMULQDQ_OP(pclmulqdq
),
3121 [0x60] = SSE42_OP(pcmpestrm
),
3122 [0x61] = SSE42_OP(pcmpestri
),
3123 [0x62] = SSE42_OP(pcmpistrm
),
3124 [0x63] = SSE42_OP(pcmpistri
),
3125 [0xdf] = AESNI_OP(aeskeygenassist
),
3128 static void gen_sse(CPUX86State
*env
, DisasContext
*s
, int b
,
3129 target_ulong pc_start
)
3131 int b1
, op1_offset
, op2_offset
, is_xmm
, val
;
3132 int modrm
, mod
, rm
, reg
;
3133 SSEFunc_0_epp sse_fn_epp
;
3134 SSEFunc_0_eppi sse_fn_eppi
;
3135 SSEFunc_0_ppi sse_fn_ppi
;
3136 SSEFunc_0_eppt sse_fn_eppt
;
3140 if (s
->prefix
& PREFIX_DATA
)
3142 else if (s
->prefix
& PREFIX_REPZ
)
3144 else if (s
->prefix
& PREFIX_REPNZ
)
3148 sse_fn_epp
= sse_op_table1
[b
][b1
];
3152 if ((b
<= 0x5f && b
>= 0x10) || b
== 0xc6 || b
== 0xc2) {
3162 /* simple MMX/SSE operation */
3163 if (s
->flags
& HF_TS_MASK
) {
3164 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
3167 if (s
->flags
& HF_EM_MASK
) {
3169 gen_illegal_opcode(s
);
3173 && !(s
->flags
& HF_OSFXSR_MASK
)
3174 && (b
!= 0x38 && b
!= 0x3a)) {
3178 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
)) {
3179 /* If we were fully decoding this we might use illegal_op. */
3183 gen_helper_emms(cpu_env
);
3188 gen_helper_emms(cpu_env
);
3191 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3192 the static cpu state) */
3194 gen_helper_enter_mmx(cpu_env
);
3197 modrm
= x86_ldub_code(env
, s
);
3198 reg
= ((modrm
>> 3) & 7);
3202 mod
= (modrm
>> 6) & 3;
3203 if (sse_fn_epp
== SSE_SPECIAL
) {
3206 case 0x0e7: /* movntq */
3210 gen_lea_modrm(env
, s
, modrm
);
3211 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3213 case 0x1e7: /* movntdq */
3214 case 0x02b: /* movntps */
3215 case 0x12b: /* movntps */
3218 gen_lea_modrm(env
, s
, modrm
);
3219 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3221 case 0x3f0: /* lddqu */
3224 gen_lea_modrm(env
, s
, modrm
);
3225 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3227 case 0x22b: /* movntss */
3228 case 0x32b: /* movntsd */
3231 gen_lea_modrm(env
, s
, modrm
);
3233 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3234 xmm_regs
[reg
].ZMM_Q(0)));
3236 tcg_gen_ld32u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
3237 xmm_regs
[reg
].ZMM_L(0)));
3238 gen_op_st_v(s
, MO_32
, s
->T0
, s
->A0
);
3241 case 0x6e: /* movd mm, ea */
3242 #ifdef TARGET_X86_64
3243 if (s
->dflag
== MO_64
) {
3244 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3245 tcg_gen_st_tl(s
->T0
, cpu_env
,
3246 offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3250 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3251 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3252 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3253 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
3254 gen_helper_movl_mm_T0_mmx(s
->ptr0
, s
->tmp2_i32
);
3257 case 0x16e: /* movd xmm, ea */
3258 #ifdef TARGET_X86_64
3259 if (s
->dflag
== MO_64
) {
3260 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3261 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3262 offsetof(CPUX86State
,xmm_regs
[reg
]));
3263 gen_helper_movq_mm_T0_xmm(s
->ptr0
, s
->T0
);
3267 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3268 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3269 offsetof(CPUX86State
,xmm_regs
[reg
]));
3270 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
3271 gen_helper_movl_mm_T0_xmm(s
->ptr0
, s
->tmp2_i32
);
3274 case 0x6f: /* movq mm, ea */
3276 gen_lea_modrm(env
, s
, modrm
);
3277 gen_ldq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3280 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
,
3281 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3282 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
,
3283 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3286 case 0x010: /* movups */
3287 case 0x110: /* movupd */
3288 case 0x028: /* movaps */
3289 case 0x128: /* movapd */
3290 case 0x16f: /* movdqa xmm, ea */
3291 case 0x26f: /* movdqu xmm, ea */
3293 gen_lea_modrm(env
, s
, modrm
);
3294 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3296 rm
= (modrm
& 7) | REX_B(s
);
3297 gen_op_movo(s
, offsetof(CPUX86State
, xmm_regs
[reg
]),
3298 offsetof(CPUX86State
,xmm_regs
[rm
]));
3301 case 0x210: /* movss xmm, ea */
3303 gen_lea_modrm(env
, s
, modrm
);
3304 gen_op_ld_v(s
, MO_32
, s
->T0
, s
->A0
);
3305 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3306 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(0)));
3307 tcg_gen_movi_tl(s
->T0
, 0);
3308 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3309 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(1)));
3310 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3311 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(2)));
3312 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3313 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(3)));
3315 rm
= (modrm
& 7) | REX_B(s
);
3316 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(0)),
3317 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)));
3320 case 0x310: /* movsd xmm, ea */
3322 gen_lea_modrm(env
, s
, modrm
);
3323 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3324 xmm_regs
[reg
].ZMM_Q(0)));
3325 tcg_gen_movi_tl(s
->T0
, 0);
3326 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3327 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(2)));
3328 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3329 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(3)));
3331 rm
= (modrm
& 7) | REX_B(s
);
3332 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(0)),
3333 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3336 case 0x012: /* movlps */
3337 case 0x112: /* movlpd */
3339 gen_lea_modrm(env
, s
, modrm
);
3340 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3341 xmm_regs
[reg
].ZMM_Q(0)));
3344 rm
= (modrm
& 7) | REX_B(s
);
3345 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(0)),
3346 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(1)));
3349 case 0x212: /* movsldup */
3351 gen_lea_modrm(env
, s
, modrm
);
3352 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3354 rm
= (modrm
& 7) | REX_B(s
);
3355 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(0)),
3356 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)));
3357 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(2)),
3358 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(2)));
3360 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(1)),
3361 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3362 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(3)),
3363 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)));
3365 case 0x312: /* movddup */
3367 gen_lea_modrm(env
, s
, modrm
);
3368 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3369 xmm_regs
[reg
].ZMM_Q(0)));
3371 rm
= (modrm
& 7) | REX_B(s
);
3372 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(0)),
3373 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3375 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(1)),
3376 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3378 case 0x016: /* movhps */
3379 case 0x116: /* movhpd */
3381 gen_lea_modrm(env
, s
, modrm
);
3382 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3383 xmm_regs
[reg
].ZMM_Q(1)));
3386 rm
= (modrm
& 7) | REX_B(s
);
3387 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(1)),
3388 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3391 case 0x216: /* movshdup */
3393 gen_lea_modrm(env
, s
, modrm
);
3394 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3396 rm
= (modrm
& 7) | REX_B(s
);
3397 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(1)),
3398 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(1)));
3399 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(3)),
3400 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(3)));
3402 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(0)),
3403 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)));
3404 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(2)),
3405 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)));
3410 int bit_index
, field_length
;
3412 if (b1
== 1 && reg
!= 0)
3414 field_length
= x86_ldub_code(env
, s
) & 0x3F;
3415 bit_index
= x86_ldub_code(env
, s
) & 0x3F;
3416 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3417 offsetof(CPUX86State
,xmm_regs
[reg
]));
3419 gen_helper_extrq_i(cpu_env
, s
->ptr0
,
3420 tcg_const_i32(bit_index
),
3421 tcg_const_i32(field_length
));
3423 gen_helper_insertq_i(cpu_env
, s
->ptr0
,
3424 tcg_const_i32(bit_index
),
3425 tcg_const_i32(field_length
));
3428 case 0x7e: /* movd ea, mm */
3429 #ifdef TARGET_X86_64
3430 if (s
->dflag
== MO_64
) {
3431 tcg_gen_ld_i64(s
->T0
, cpu_env
,
3432 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3433 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3437 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
3438 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_L(0)));
3439 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3442 case 0x17e: /* movd ea, xmm */
3443 #ifdef TARGET_X86_64
3444 if (s
->dflag
== MO_64
) {
3445 tcg_gen_ld_i64(s
->T0
, cpu_env
,
3446 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3447 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3451 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
3452 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3453 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3456 case 0x27e: /* movq xmm, ea */
3458 gen_lea_modrm(env
, s
, modrm
);
3459 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3460 xmm_regs
[reg
].ZMM_Q(0)));
3462 rm
= (modrm
& 7) | REX_B(s
);
3463 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(0)),
3464 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3466 gen_op_movq_env_0(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(1)));
3468 case 0x7f: /* movq ea, mm */
3470 gen_lea_modrm(env
, s
, modrm
);
3471 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3474 gen_op_movq(s
, offsetof(CPUX86State
, fpregs
[rm
].mmx
),
3475 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3478 case 0x011: /* movups */
3479 case 0x111: /* movupd */
3480 case 0x029: /* movaps */
3481 case 0x129: /* movapd */
3482 case 0x17f: /* movdqa ea, xmm */
3483 case 0x27f: /* movdqu ea, xmm */
3485 gen_lea_modrm(env
, s
, modrm
);
3486 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3488 rm
= (modrm
& 7) | REX_B(s
);
3489 gen_op_movo(s
, offsetof(CPUX86State
, xmm_regs
[rm
]),
3490 offsetof(CPUX86State
,xmm_regs
[reg
]));
3493 case 0x211: /* movss ea, xmm */
3495 gen_lea_modrm(env
, s
, modrm
);
3496 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
3497 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(0)));
3498 gen_op_st_v(s
, MO_32
, s
->T0
, s
->A0
);
3500 rm
= (modrm
& 7) | REX_B(s
);
3501 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[rm
].ZMM_L(0)),
3502 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3505 case 0x311: /* movsd ea, xmm */
3507 gen_lea_modrm(env
, s
, modrm
);
3508 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3509 xmm_regs
[reg
].ZMM_Q(0)));
3511 rm
= (modrm
& 7) | REX_B(s
);
3512 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[rm
].ZMM_Q(0)),
3513 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3516 case 0x013: /* movlps */
3517 case 0x113: /* movlpd */
3519 gen_lea_modrm(env
, s
, modrm
);
3520 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3521 xmm_regs
[reg
].ZMM_Q(0)));
3526 case 0x017: /* movhps */
3527 case 0x117: /* movhpd */
3529 gen_lea_modrm(env
, s
, modrm
);
3530 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3531 xmm_regs
[reg
].ZMM_Q(1)));
3536 case 0x71: /* shift mm, im */
3539 case 0x171: /* shift xmm, im */
3545 val
= x86_ldub_code(env
, s
);
3547 tcg_gen_movi_tl(s
->T0
, val
);
3548 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3549 offsetof(CPUX86State
, xmm_t0
.ZMM_L(0)));
3550 tcg_gen_movi_tl(s
->T0
, 0);
3551 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3552 offsetof(CPUX86State
, xmm_t0
.ZMM_L(1)));
3553 op1_offset
= offsetof(CPUX86State
,xmm_t0
);
3555 tcg_gen_movi_tl(s
->T0
, val
);
3556 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3557 offsetof(CPUX86State
, mmx_t0
.MMX_L(0)));
3558 tcg_gen_movi_tl(s
->T0
, 0);
3559 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3560 offsetof(CPUX86State
, mmx_t0
.MMX_L(1)));
3561 op1_offset
= offsetof(CPUX86State
,mmx_t0
);
3563 sse_fn_epp
= sse_op_table2
[((b
- 1) & 3) * 8 +
3564 (((modrm
>> 3)) & 7)][b1
];
3569 rm
= (modrm
& 7) | REX_B(s
);
3570 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3573 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3575 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op2_offset
);
3576 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op1_offset
);
3577 sse_fn_epp(cpu_env
, s
->ptr0
, s
->ptr1
);
3579 case 0x050: /* movmskps */
3580 rm
= (modrm
& 7) | REX_B(s
);
3581 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3582 offsetof(CPUX86State
,xmm_regs
[rm
]));
3583 gen_helper_movmskps(s
->tmp2_i32
, cpu_env
, s
->ptr0
);
3584 tcg_gen_extu_i32_tl(cpu_regs
[reg
], s
->tmp2_i32
);
3586 case 0x150: /* movmskpd */
3587 rm
= (modrm
& 7) | REX_B(s
);
3588 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3589 offsetof(CPUX86State
,xmm_regs
[rm
]));
3590 gen_helper_movmskpd(s
->tmp2_i32
, cpu_env
, s
->ptr0
);
3591 tcg_gen_extu_i32_tl(cpu_regs
[reg
], s
->tmp2_i32
);
3593 case 0x02a: /* cvtpi2ps */
3594 case 0x12a: /* cvtpi2pd */
3595 gen_helper_enter_mmx(cpu_env
);
3597 gen_lea_modrm(env
, s
, modrm
);
3598 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3599 gen_ldq_env_A0(s
, op2_offset
);
3602 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3604 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3605 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
3606 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
3609 gen_helper_cvtpi2ps(cpu_env
, s
->ptr0
, s
->ptr1
);
3613 gen_helper_cvtpi2pd(cpu_env
, s
->ptr0
, s
->ptr1
);
3617 case 0x22a: /* cvtsi2ss */
3618 case 0x32a: /* cvtsi2sd */
3619 ot
= mo_64_32(s
->dflag
);
3620 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3621 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3622 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
3624 SSEFunc_0_epi sse_fn_epi
= sse_op_table3ai
[(b
>> 8) & 1];
3625 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
3626 sse_fn_epi(cpu_env
, s
->ptr0
, s
->tmp2_i32
);
3628 #ifdef TARGET_X86_64
3629 SSEFunc_0_epl sse_fn_epl
= sse_op_table3aq
[(b
>> 8) & 1];
3630 sse_fn_epl(cpu_env
, s
->ptr0
, s
->T0
);
3636 case 0x02c: /* cvttps2pi */
3637 case 0x12c: /* cvttpd2pi */
3638 case 0x02d: /* cvtps2pi */
3639 case 0x12d: /* cvtpd2pi */
3640 gen_helper_enter_mmx(cpu_env
);
3642 gen_lea_modrm(env
, s
, modrm
);
3643 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3644 gen_ldo_env_A0(s
, op2_offset
);
3646 rm
= (modrm
& 7) | REX_B(s
);
3647 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3649 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
);
3650 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
3651 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
3654 gen_helper_cvttps2pi(cpu_env
, s
->ptr0
, s
->ptr1
);
3657 gen_helper_cvttpd2pi(cpu_env
, s
->ptr0
, s
->ptr1
);
3660 gen_helper_cvtps2pi(cpu_env
, s
->ptr0
, s
->ptr1
);
3663 gen_helper_cvtpd2pi(cpu_env
, s
->ptr0
, s
->ptr1
);
3667 case 0x22c: /* cvttss2si */
3668 case 0x32c: /* cvttsd2si */
3669 case 0x22d: /* cvtss2si */
3670 case 0x32d: /* cvtsd2si */
3671 ot
= mo_64_32(s
->dflag
);
3673 gen_lea_modrm(env
, s
, modrm
);
3675 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.ZMM_Q(0)));
3677 gen_op_ld_v(s
, MO_32
, s
->T0
, s
->A0
);
3678 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3679 offsetof(CPUX86State
, xmm_t0
.ZMM_L(0)));
3681 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3683 rm
= (modrm
& 7) | REX_B(s
);
3684 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3686 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op2_offset
);
3688 SSEFunc_i_ep sse_fn_i_ep
=
3689 sse_op_table3bi
[((b
>> 7) & 2) | (b
& 1)];
3690 sse_fn_i_ep(s
->tmp2_i32
, cpu_env
, s
->ptr0
);
3691 tcg_gen_extu_i32_tl(s
->T0
, s
->tmp2_i32
);
3693 #ifdef TARGET_X86_64
3694 SSEFunc_l_ep sse_fn_l_ep
=
3695 sse_op_table3bq
[((b
>> 7) & 2) | (b
& 1)];
3696 sse_fn_l_ep(s
->T0
, cpu_env
, s
->ptr0
);
3701 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
3703 case 0xc4: /* pinsrw */
3706 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
3707 val
= x86_ldub_code(env
, s
);
3710 tcg_gen_st16_tl(s
->T0
, cpu_env
,
3711 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_W(val
)));
3714 tcg_gen_st16_tl(s
->T0
, cpu_env
,
3715 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_W(val
)));
3718 case 0xc5: /* pextrw */
3722 ot
= mo_64_32(s
->dflag
);
3723 val
= x86_ldub_code(env
, s
);
3726 rm
= (modrm
& 7) | REX_B(s
);
3727 tcg_gen_ld16u_tl(s
->T0
, cpu_env
,
3728 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_W(val
)));
3732 tcg_gen_ld16u_tl(s
->T0
, cpu_env
,
3733 offsetof(CPUX86State
,fpregs
[rm
].mmx
.MMX_W(val
)));
3735 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
3736 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
3738 case 0x1d6: /* movq ea, xmm */
3740 gen_lea_modrm(env
, s
, modrm
);
3741 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3742 xmm_regs
[reg
].ZMM_Q(0)));
3744 rm
= (modrm
& 7) | REX_B(s
);
3745 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[rm
].ZMM_Q(0)),
3746 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3747 gen_op_movq_env_0(s
,
3748 offsetof(CPUX86State
, xmm_regs
[rm
].ZMM_Q(1)));
3751 case 0x2d6: /* movq2dq */
3752 gen_helper_enter_mmx(cpu_env
);
3754 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(0)),
3755 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3756 gen_op_movq_env_0(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(1)));
3758 case 0x3d6: /* movdq2q */
3759 gen_helper_enter_mmx(cpu_env
);
3760 rm
= (modrm
& 7) | REX_B(s
);
3761 gen_op_movq(s
, offsetof(CPUX86State
, fpregs
[reg
& 7].mmx
),
3762 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3764 case 0xd7: /* pmovmskb */
3769 rm
= (modrm
& 7) | REX_B(s
);
3770 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3771 offsetof(CPUX86State
, xmm_regs
[rm
]));
3772 gen_helper_pmovmskb_xmm(s
->tmp2_i32
, cpu_env
, s
->ptr0
);
3775 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3776 offsetof(CPUX86State
, fpregs
[rm
].mmx
));
3777 gen_helper_pmovmskb_mmx(s
->tmp2_i32
, cpu_env
, s
->ptr0
);
3779 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
3780 tcg_gen_extu_i32_tl(cpu_regs
[reg
], s
->tmp2_i32
);
3786 if ((b
& 0xf0) == 0xf0) {
3789 modrm
= x86_ldub_code(env
, s
);
3791 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
3792 mod
= (modrm
>> 6) & 3;
3797 sse_fn_epp
= sse_op_table6
[b
].op
[b1
];
3801 if (!(s
->cpuid_ext_features
& sse_op_table6
[b
].ext_mask
))
3805 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3807 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
3809 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3810 gen_lea_modrm(env
, s
, modrm
);
3812 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3813 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3814 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3815 gen_ldq_env_A0(s
, op2_offset
+
3816 offsetof(ZMMReg
, ZMM_Q(0)));
3818 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3819 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3820 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
3821 s
->mem_index
, MO_LEUL
);
3822 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
, op2_offset
+
3823 offsetof(ZMMReg
, ZMM_L(0)));
3825 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3826 tcg_gen_qemu_ld_tl(s
->tmp0
, s
->A0
,
3827 s
->mem_index
, MO_LEUW
);
3828 tcg_gen_st16_tl(s
->tmp0
, cpu_env
, op2_offset
+
3829 offsetof(ZMMReg
, ZMM_W(0)));
3831 case 0x2a: /* movntqda */
3832 gen_ldo_env_A0(s
, op1_offset
);
3835 gen_ldo_env_A0(s
, op2_offset
);
3839 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
3841 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3843 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3844 gen_lea_modrm(env
, s
, modrm
);
3845 gen_ldq_env_A0(s
, op2_offset
);
3848 if (sse_fn_epp
== SSE_SPECIAL
) {
3852 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
3853 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
3854 sse_fn_epp(cpu_env
, s
->ptr0
, s
->ptr1
);
3857 set_cc_op(s
, CC_OP_EFLAGS
);
3864 /* Various integer extensions at 0f 38 f[0-f]. */
3865 b
= modrm
| (b1
<< 8);
3866 modrm
= x86_ldub_code(env
, s
);
3867 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
3870 case 0x3f0: /* crc32 Gd,Eb */
3871 case 0x3f1: /* crc32 Gd,Ey */
3873 if (!(s
->cpuid_ext_features
& CPUID_EXT_SSE42
)) {
3876 if ((b
& 0xff) == 0xf0) {
3878 } else if (s
->dflag
!= MO_64
) {
3879 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3884 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[reg
]);
3885 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3886 gen_helper_crc32(s
->T0
, s
->tmp2_i32
,
3887 s
->T0
, tcg_const_i32(8 << ot
));
3889 ot
= mo_64_32(s
->dflag
);
3890 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
3893 case 0x1f0: /* crc32 or movbe */
3895 /* For these insns, the f3 prefix is supposed to have priority
3896 over the 66 prefix, but that's not what we implement above
3898 if (s
->prefix
& PREFIX_REPNZ
) {
3902 case 0x0f0: /* movbe Gy,My */
3903 case 0x0f1: /* movbe My,Gy */
3904 if (!(s
->cpuid_ext_features
& CPUID_EXT_MOVBE
)) {
3907 if (s
->dflag
!= MO_64
) {
3908 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3913 gen_lea_modrm(env
, s
, modrm
);
3915 tcg_gen_qemu_ld_tl(s
->T0
, s
->A0
,
3916 s
->mem_index
, ot
| MO_BE
);
3917 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
3919 tcg_gen_qemu_st_tl(cpu_regs
[reg
], s
->A0
,
3920 s
->mem_index
, ot
| MO_BE
);
3924 case 0x0f2: /* andn Gy, By, Ey */
3925 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3926 || !(s
->prefix
& PREFIX_VEX
)
3930 ot
= mo_64_32(s
->dflag
);
3931 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3932 tcg_gen_andc_tl(s
->T0
, s
->T0
, cpu_regs
[s
->vex_v
]);
3933 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
3934 gen_op_update1_cc(s
);
3935 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3938 case 0x0f7: /* bextr Gy, Ey, By */
3939 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3940 || !(s
->prefix
& PREFIX_VEX
)
3944 ot
= mo_64_32(s
->dflag
);
3948 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3949 /* Extract START, and shift the operand.
3950 Shifts larger than operand size get zeros. */
3951 tcg_gen_ext8u_tl(s
->A0
, cpu_regs
[s
->vex_v
]);
3952 tcg_gen_shr_tl(s
->T0
, s
->T0
, s
->A0
);
3954 bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3955 zero
= tcg_const_tl(0);
3956 tcg_gen_movcond_tl(TCG_COND_LEU
, s
->T0
, s
->A0
, bound
,
3958 tcg_temp_free(zero
);
3960 /* Extract the LEN into a mask. Lengths larger than
3961 operand size get all ones. */
3962 tcg_gen_extract_tl(s
->A0
, cpu_regs
[s
->vex_v
], 8, 8);
3963 tcg_gen_movcond_tl(TCG_COND_LEU
, s
->A0
, s
->A0
, bound
,
3965 tcg_temp_free(bound
);
3966 tcg_gen_movi_tl(s
->T1
, 1);
3967 tcg_gen_shl_tl(s
->T1
, s
->T1
, s
->A0
);
3968 tcg_gen_subi_tl(s
->T1
, s
->T1
, 1);
3969 tcg_gen_and_tl(s
->T0
, s
->T0
, s
->T1
);
3971 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
3972 gen_op_update1_cc(s
);
3973 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3977 case 0x0f5: /* bzhi Gy, Ey, By */
3978 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
3979 || !(s
->prefix
& PREFIX_VEX
)
3983 ot
= mo_64_32(s
->dflag
);
3984 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3985 tcg_gen_ext8u_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
3987 TCGv bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
3988 /* Note that since we're using BMILG (in order to get O
3989 cleared) we need to store the inverse into C. */
3990 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_cc_src
,
3992 tcg_gen_movcond_tl(TCG_COND_GT
, s
->T1
, s
->T1
,
3993 bound
, bound
, s
->T1
);
3994 tcg_temp_free(bound
);
3996 tcg_gen_movi_tl(s
->A0
, -1);
3997 tcg_gen_shl_tl(s
->A0
, s
->A0
, s
->T1
);
3998 tcg_gen_andc_tl(s
->T0
, s
->T0
, s
->A0
);
3999 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
4000 gen_op_update1_cc(s
);
4001 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4004 case 0x3f6: /* mulx By, Gy, rdx, Ey */
4005 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4006 || !(s
->prefix
& PREFIX_VEX
)
4010 ot
= mo_64_32(s
->dflag
);
4011 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4014 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
4015 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, cpu_regs
[R_EDX
]);
4016 tcg_gen_mulu2_i32(s
->tmp2_i32
, s
->tmp3_i32
,
4017 s
->tmp2_i32
, s
->tmp3_i32
);
4018 tcg_gen_extu_i32_tl(cpu_regs
[s
->vex_v
], s
->tmp2_i32
);
4019 tcg_gen_extu_i32_tl(cpu_regs
[reg
], s
->tmp3_i32
);
4021 #ifdef TARGET_X86_64
4023 tcg_gen_mulu2_i64(s
->T0
, s
->T1
,
4024 s
->T0
, cpu_regs
[R_EDX
]);
4025 tcg_gen_mov_i64(cpu_regs
[s
->vex_v
], s
->T0
);
4026 tcg_gen_mov_i64(cpu_regs
[reg
], s
->T1
);
4032 case 0x3f5: /* pdep Gy, By, Ey */
4033 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4034 || !(s
->prefix
& PREFIX_VEX
)
4038 ot
= mo_64_32(s
->dflag
);
4039 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4040 /* Note that by zero-extending the source operand, we
4041 automatically handle zero-extending the result. */
4043 tcg_gen_mov_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
4045 tcg_gen_ext32u_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
4047 gen_helper_pdep(cpu_regs
[reg
], s
->T1
, s
->T0
);
4050 case 0x2f5: /* pext Gy, By, Ey */
4051 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4052 || !(s
->prefix
& PREFIX_VEX
)
4056 ot
= mo_64_32(s
->dflag
);
4057 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4058 /* Note that by zero-extending the source operand, we
4059 automatically handle zero-extending the result. */
4061 tcg_gen_mov_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
4063 tcg_gen_ext32u_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
4065 gen_helper_pext(cpu_regs
[reg
], s
->T1
, s
->T0
);
4068 case 0x1f6: /* adcx Gy, Ey */
4069 case 0x2f6: /* adox Gy, Ey */
4070 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_ADX
)) {
4073 TCGv carry_in
, carry_out
, zero
;
4076 ot
= mo_64_32(s
->dflag
);
4077 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4079 /* Re-use the carry-out from a previous round. */
4081 carry_out
= (b
== 0x1f6 ? cpu_cc_dst
: cpu_cc_src2
);
4085 carry_in
= cpu_cc_dst
;
4086 end_op
= CC_OP_ADCX
;
4088 end_op
= CC_OP_ADCOX
;
4093 end_op
= CC_OP_ADCOX
;
4095 carry_in
= cpu_cc_src2
;
4096 end_op
= CC_OP_ADOX
;
4100 end_op
= CC_OP_ADCOX
;
4101 carry_in
= carry_out
;
4104 end_op
= (b
== 0x1f6 ? CC_OP_ADCX
: CC_OP_ADOX
);
4107 /* If we can't reuse carry-out, get it out of EFLAGS. */
4109 if (s
->cc_op
!= CC_OP_ADCX
&& s
->cc_op
!= CC_OP_ADOX
) {
4110 gen_compute_eflags(s
);
4113 tcg_gen_extract_tl(carry_in
, cpu_cc_src
,
4114 ctz32(b
== 0x1f6 ? CC_C
: CC_O
), 1);
4118 #ifdef TARGET_X86_64
4120 /* If we know TL is 64-bit, and we want a 32-bit
4121 result, just do everything in 64-bit arithmetic. */
4122 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_regs
[reg
]);
4123 tcg_gen_ext32u_i64(s
->T0
, s
->T0
);
4124 tcg_gen_add_i64(s
->T0
, s
->T0
, cpu_regs
[reg
]);
4125 tcg_gen_add_i64(s
->T0
, s
->T0
, carry_in
);
4126 tcg_gen_ext32u_i64(cpu_regs
[reg
], s
->T0
);
4127 tcg_gen_shri_i64(carry_out
, s
->T0
, 32);
4131 /* Otherwise compute the carry-out in two steps. */
4132 zero
= tcg_const_tl(0);
4133 tcg_gen_add2_tl(s
->T0
, carry_out
,
4136 tcg_gen_add2_tl(cpu_regs
[reg
], carry_out
,
4137 cpu_regs
[reg
], carry_out
,
4139 tcg_temp_free(zero
);
4142 set_cc_op(s
, end_op
);
4146 case 0x1f7: /* shlx Gy, Ey, By */
4147 case 0x2f7: /* sarx Gy, Ey, By */
4148 case 0x3f7: /* shrx Gy, Ey, By */
4149 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4150 || !(s
->prefix
& PREFIX_VEX
)
4154 ot
= mo_64_32(s
->dflag
);
4155 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4157 tcg_gen_andi_tl(s
->T1
, cpu_regs
[s
->vex_v
], 63);
4159 tcg_gen_andi_tl(s
->T1
, cpu_regs
[s
->vex_v
], 31);
4162 tcg_gen_shl_tl(s
->T0
, s
->T0
, s
->T1
);
4163 } else if (b
== 0x2f7) {
4165 tcg_gen_ext32s_tl(s
->T0
, s
->T0
);
4167 tcg_gen_sar_tl(s
->T0
, s
->T0
, s
->T1
);
4170 tcg_gen_ext32u_tl(s
->T0
, s
->T0
);
4172 tcg_gen_shr_tl(s
->T0
, s
->T0
, s
->T1
);
4174 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
4180 case 0x3f3: /* Group 17 */
4181 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
4182 || !(s
->prefix
& PREFIX_VEX
)
4186 ot
= mo_64_32(s
->dflag
);
4187 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4189 tcg_gen_mov_tl(cpu_cc_src
, s
->T0
);
4191 case 1: /* blsr By,Ey */
4192 tcg_gen_subi_tl(s
->T1
, s
->T0
, 1);
4193 tcg_gen_and_tl(s
->T0
, s
->T0
, s
->T1
);
4195 case 2: /* blsmsk By,Ey */
4196 tcg_gen_subi_tl(s
->T1
, s
->T0
, 1);
4197 tcg_gen_xor_tl(s
->T0
, s
->T0
, s
->T1
);
4199 case 3: /* blsi By, Ey */
4200 tcg_gen_neg_tl(s
->T1
, s
->T0
);
4201 tcg_gen_and_tl(s
->T0
, s
->T0
, s
->T1
);
4206 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
4207 gen_op_mov_reg_v(s
, ot
, s
->vex_v
, s
->T0
);
4208 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4219 modrm
= x86_ldub_code(env
, s
);
4221 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
4222 mod
= (modrm
>> 6) & 3;
4227 sse_fn_eppi
= sse_op_table7
[b
].op
[b1
];
4231 if (!(s
->cpuid_ext_features
& sse_op_table7
[b
].ext_mask
))
4236 if (sse_fn_eppi
== SSE_SPECIAL
) {
4237 ot
= mo_64_32(s
->dflag
);
4238 rm
= (modrm
& 7) | REX_B(s
);
4240 gen_lea_modrm(env
, s
, modrm
);
4241 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
4242 val
= x86_ldub_code(env
, s
);
4244 case 0x14: /* pextrb */
4245 tcg_gen_ld8u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
4246 xmm_regs
[reg
].ZMM_B(val
& 15)));
4248 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
4250 tcg_gen_qemu_st_tl(s
->T0
, s
->A0
,
4251 s
->mem_index
, MO_UB
);
4254 case 0x15: /* pextrw */
4255 tcg_gen_ld16u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
4256 xmm_regs
[reg
].ZMM_W(val
& 7)));
4258 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
4260 tcg_gen_qemu_st_tl(s
->T0
, s
->A0
,
4261 s
->mem_index
, MO_LEUW
);
4265 if (ot
== MO_32
) { /* pextrd */
4266 tcg_gen_ld_i32(s
->tmp2_i32
, cpu_env
,
4267 offsetof(CPUX86State
,
4268 xmm_regs
[reg
].ZMM_L(val
& 3)));
4270 tcg_gen_extu_i32_tl(cpu_regs
[rm
], s
->tmp2_i32
);
4272 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
4273 s
->mem_index
, MO_LEUL
);
4275 } else { /* pextrq */
4276 #ifdef TARGET_X86_64
4277 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
,
4278 offsetof(CPUX86State
,
4279 xmm_regs
[reg
].ZMM_Q(val
& 1)));
4281 tcg_gen_mov_i64(cpu_regs
[rm
], s
->tmp1_i64
);
4283 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
,
4284 s
->mem_index
, MO_LEQ
);
4291 case 0x17: /* extractps */
4292 tcg_gen_ld32u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
4293 xmm_regs
[reg
].ZMM_L(val
& 3)));
4295 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
4297 tcg_gen_qemu_st_tl(s
->T0
, s
->A0
,
4298 s
->mem_index
, MO_LEUL
);
4301 case 0x20: /* pinsrb */
4303 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, rm
);
4305 tcg_gen_qemu_ld_tl(s
->T0
, s
->A0
,
4306 s
->mem_index
, MO_UB
);
4308 tcg_gen_st8_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
4309 xmm_regs
[reg
].ZMM_B(val
& 15)));
4311 case 0x21: /* insertps */
4313 tcg_gen_ld_i32(s
->tmp2_i32
, cpu_env
,
4314 offsetof(CPUX86State
,xmm_regs
[rm
]
4315 .ZMM_L((val
>> 6) & 3)));
4317 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
4318 s
->mem_index
, MO_LEUL
);
4320 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
,
4321 offsetof(CPUX86State
,xmm_regs
[reg
]
4322 .ZMM_L((val
>> 4) & 3)));
4324 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4325 cpu_env
, offsetof(CPUX86State
,
4326 xmm_regs
[reg
].ZMM_L(0)));
4328 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4329 cpu_env
, offsetof(CPUX86State
,
4330 xmm_regs
[reg
].ZMM_L(1)));
4332 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4333 cpu_env
, offsetof(CPUX86State
,
4334 xmm_regs
[reg
].ZMM_L(2)));
4336 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4337 cpu_env
, offsetof(CPUX86State
,
4338 xmm_regs
[reg
].ZMM_L(3)));
4341 if (ot
== MO_32
) { /* pinsrd */
4343 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[rm
]);
4345 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
4346 s
->mem_index
, MO_LEUL
);
4348 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
,
4349 offsetof(CPUX86State
,
4350 xmm_regs
[reg
].ZMM_L(val
& 3)));
4351 } else { /* pinsrq */
4352 #ifdef TARGET_X86_64
4354 gen_op_mov_v_reg(s
, ot
, s
->tmp1_i64
, rm
);
4356 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
,
4357 s
->mem_index
, MO_LEQ
);
4359 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
,
4360 offsetof(CPUX86State
,
4361 xmm_regs
[reg
].ZMM_Q(val
& 1)));
4372 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4374 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
4376 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4377 gen_lea_modrm(env
, s
, modrm
);
4378 gen_ldo_env_A0(s
, op2_offset
);
4381 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4383 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4385 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4386 gen_lea_modrm(env
, s
, modrm
);
4387 gen_ldq_env_A0(s
, op2_offset
);
4390 val
= x86_ldub_code(env
, s
);
4392 if ((b
& 0xfc) == 0x60) { /* pcmpXstrX */
4393 set_cc_op(s
, CC_OP_EFLAGS
);
4395 if (s
->dflag
== MO_64
) {
4396 /* The helper must use entire 64-bit gp registers */
4401 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
4402 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
4403 sse_fn_eppi(cpu_env
, s
->ptr0
, s
->ptr1
, tcg_const_i32(val
));
4407 /* Various integer extensions at 0f 3a f[0-f]. */
4408 b
= modrm
| (b1
<< 8);
4409 modrm
= x86_ldub_code(env
, s
);
4410 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
4413 case 0x3f0: /* rorx Gy,Ey, Ib */
4414 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4415 || !(s
->prefix
& PREFIX_VEX
)
4419 ot
= mo_64_32(s
->dflag
);
4420 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4421 b
= x86_ldub_code(env
, s
);
4423 tcg_gen_rotri_tl(s
->T0
, s
->T0
, b
& 63);
4425 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
4426 tcg_gen_rotri_i32(s
->tmp2_i32
, s
->tmp2_i32
, b
& 31);
4427 tcg_gen_extu_i32_tl(s
->T0
, s
->tmp2_i32
);
4429 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
4439 gen_unknown_opcode(env
, s
);
4443 /* generic MMX or SSE operation */
4445 case 0x70: /* pshufx insn */
4446 case 0xc6: /* pshufx insn */
4447 case 0xc2: /* compare insns */
4454 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4458 gen_lea_modrm(env
, s
, modrm
);
4459 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4465 /* Most sse scalar operations. */
4468 } else if (b1
== 3) {
4473 case 0x2e: /* ucomis[sd] */
4474 case 0x2f: /* comis[sd] */
4486 gen_op_ld_v(s
, MO_32
, s
->T0
, s
->A0
);
4487 tcg_gen_st32_tl(s
->T0
, cpu_env
,
4488 offsetof(CPUX86State
,xmm_t0
.ZMM_L(0)));
4492 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.ZMM_D(0)));
4495 /* 128 bit access */
4496 gen_ldo_env_A0(s
, op2_offset
);
4500 rm
= (modrm
& 7) | REX_B(s
);
4501 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
4504 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4506 gen_lea_modrm(env
, s
, modrm
);
4507 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4508 gen_ldq_env_A0(s
, op2_offset
);
4511 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4515 case 0x0f: /* 3DNow! data insns */
4516 val
= x86_ldub_code(env
, s
);
4517 sse_fn_epp
= sse_op_table5
[val
];
4521 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
)) {
4524 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
4525 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
4526 sse_fn_epp(cpu_env
, s
->ptr0
, s
->ptr1
);
4528 case 0x70: /* pshufx insn */
4529 case 0xc6: /* pshufx insn */
4530 val
= x86_ldub_code(env
, s
);
4531 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
4532 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
4533 /* XXX: introduce a new table? */
4534 sse_fn_ppi
= (SSEFunc_0_ppi
)sse_fn_epp
;
4535 sse_fn_ppi(s
->ptr0
, s
->ptr1
, tcg_const_i32(val
));
4539 val
= x86_ldub_code(env
, s
);
4542 sse_fn_epp
= sse_op_table4
[val
][b1
];
4544 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
4545 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
4546 sse_fn_epp(cpu_env
, s
->ptr0
, s
->ptr1
);
4549 /* maskmov : we must prepare A0 */
4552 tcg_gen_mov_tl(s
->A0
, cpu_regs
[R_EDI
]);
4553 gen_extu(s
->aflag
, s
->A0
);
4554 gen_add_A0_ds_seg(s
);
4556 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
4557 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
4558 /* XXX: introduce a new table? */
4559 sse_fn_eppt
= (SSEFunc_0_eppt
)sse_fn_epp
;
4560 sse_fn_eppt(cpu_env
, s
->ptr0
, s
->ptr1
, s
->A0
);
4563 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
4564 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
4565 sse_fn_epp(cpu_env
, s
->ptr0
, s
->ptr1
);
4568 if (b
== 0x2e || b
== 0x2f) {
4569 set_cc_op(s
, CC_OP_EFLAGS
);
4574 /* convert one instruction. s->base.is_jmp is set if the translation must
4575 be stopped. Return the next pc value */
4576 static target_ulong
disas_insn(DisasContext
*s
, CPUState
*cpu
)
4578 CPUX86State
*env
= cpu
->env_ptr
;
4581 MemOp ot
, aflag
, dflag
;
4582 int modrm
, reg
, rm
, mod
, op
, opreg
, val
;
4583 target_ulong next_eip
, tval
;
4584 target_ulong pc_start
= s
->base
.pc_next
;
4586 s
->pc_start
= s
->pc
= pc_start
;
4588 #ifdef TARGET_X86_64
4594 s
->rip_offset
= 0; /* for relative ip address */
4597 if (sigsetjmp(s
->jmpbuf
, 0) != 0) {
4598 gen_exception_gpf(s
);
4605 b
= x86_ldub_code(env
, s
);
4606 /* Collect prefixes. */
4609 prefixes
|= PREFIX_REPZ
;
4612 prefixes
|= PREFIX_REPNZ
;
4615 prefixes
|= PREFIX_LOCK
;
4636 prefixes
|= PREFIX_DATA
;
4639 prefixes
|= PREFIX_ADR
;
4641 #ifdef TARGET_X86_64
4645 prefixes
|= PREFIX_REX
;
4646 s
->rex_w
= (b
>> 3) & 1;
4647 s
->rex_r
= (b
& 0x4) << 1;
4648 s
->rex_x
= (b
& 0x2) << 2;
4649 s
->rex_b
= (b
& 0x1) << 3;
4654 case 0xc5: /* 2-byte VEX */
4655 case 0xc4: /* 3-byte VEX */
4656 /* VEX prefixes cannot be used except in 32-bit mode.
4657 Otherwise the instruction is LES or LDS. */
4658 if (CODE32(s
) && !VM86(s
)) {
4659 static const int pp_prefix
[4] = {
4660 0, PREFIX_DATA
, PREFIX_REPZ
, PREFIX_REPNZ
4662 int vex3
, vex2
= x86_ldub_code(env
, s
);
4664 if (!CODE64(s
) && (vex2
& 0xc0) != 0xc0) {
4665 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4666 otherwise the instruction is LES or LDS. */
4667 s
->pc
--; /* rewind the advance_pc() x86_ldub_code() did */
4671 /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
4672 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
4673 | PREFIX_LOCK
| PREFIX_DATA
| PREFIX_REX
)) {
4676 #ifdef TARGET_X86_64
4677 s
->rex_r
= (~vex2
>> 4) & 8;
4680 /* 2-byte VEX prefix: RVVVVlpp, implied 0f leading opcode byte */
4682 b
= x86_ldub_code(env
, s
) | 0x100;
4684 /* 3-byte VEX prefix: RXBmmmmm wVVVVlpp */
4685 vex3
= x86_ldub_code(env
, s
);
4686 #ifdef TARGET_X86_64
4687 s
->rex_x
= (~vex2
>> 3) & 8;
4688 s
->rex_b
= (~vex2
>> 2) & 8;
4689 s
->rex_w
= (vex3
>> 7) & 1;
4691 switch (vex2
& 0x1f) {
4692 case 0x01: /* Implied 0f leading opcode bytes. */
4693 b
= x86_ldub_code(env
, s
) | 0x100;
4695 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4698 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4701 default: /* Reserved for future use. */
4705 s
->vex_v
= (~vex3
>> 3) & 0xf;
4706 s
->vex_l
= (vex3
>> 2) & 1;
4707 prefixes
|= pp_prefix
[vex3
& 3] | PREFIX_VEX
;
4712 /* Post-process prefixes. */
4714 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit
4715 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4716 over 0x66 if both are present. */
4717 dflag
= (REX_W(s
) ? MO_64
: prefixes
& PREFIX_DATA
? MO_16
: MO_32
);
4718 /* In 64-bit mode, 0x67 selects 32-bit addressing. */
4719 aflag
= (prefixes
& PREFIX_ADR
? MO_32
: MO_64
);
4721 /* In 16/32-bit mode, 0x66 selects the opposite data size. */
4722 if (CODE32(s
) ^ ((prefixes
& PREFIX_DATA
) != 0)) {
4727 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */
4728 if (CODE32(s
) ^ ((prefixes
& PREFIX_ADR
) != 0)) {
4735 s
->prefix
= prefixes
;
4739 /* now check op code */
4743 /**************************/
4744 /* extended op code */
4745 b
= x86_ldub_code(env
, s
) | 0x100;
4748 /**************************/
4763 ot
= mo_b_d(b
, dflag
);
4766 case 0: /* OP Ev, Gv */
4767 modrm
= x86_ldub_code(env
, s
);
4768 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
4769 mod
= (modrm
>> 6) & 3;
4770 rm
= (modrm
& 7) | REX_B(s
);
4772 gen_lea_modrm(env
, s
, modrm
);
4774 } else if (op
== OP_XORL
&& rm
== reg
) {
4776 /* xor reg, reg optimisation */
4777 set_cc_op(s
, CC_OP_CLR
);
4778 tcg_gen_movi_tl(s
->T0
, 0);
4779 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
4784 gen_op_mov_v_reg(s
, ot
, s
->T1
, reg
);
4785 gen_op(s
, op
, ot
, opreg
);
4787 case 1: /* OP Gv, Ev */
4788 modrm
= x86_ldub_code(env
, s
);
4789 mod
= (modrm
>> 6) & 3;
4790 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
4791 rm
= (modrm
& 7) | REX_B(s
);
4793 gen_lea_modrm(env
, s
, modrm
);
4794 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
4795 } else if (op
== OP_XORL
&& rm
== reg
) {
4798 gen_op_mov_v_reg(s
, ot
, s
->T1
, rm
);
4800 gen_op(s
, op
, ot
, reg
);
4802 case 2: /* OP A, Iv */
4803 val
= insn_get(env
, s
, ot
);
4804 tcg_gen_movi_tl(s
->T1
, val
);
4805 gen_op(s
, op
, ot
, OR_EAX
);
4815 case 0x80: /* GRP1 */
4821 ot
= mo_b_d(b
, dflag
);
4823 modrm
= x86_ldub_code(env
, s
);
4824 mod
= (modrm
>> 6) & 3;
4825 rm
= (modrm
& 7) | REX_B(s
);
4826 op
= (modrm
>> 3) & 7;
4832 s
->rip_offset
= insn_const_size(ot
);
4833 gen_lea_modrm(env
, s
, modrm
);
4844 val
= insn_get(env
, s
, ot
);
4847 val
= (int8_t)insn_get(env
, s
, MO_8
);
4850 tcg_gen_movi_tl(s
->T1
, val
);
4851 gen_op(s
, op
, ot
, opreg
);
4855 /**************************/
4856 /* inc, dec, and other misc arith */
4857 case 0x40 ... 0x47: /* inc Gv */
4859 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), 1);
4861 case 0x48 ... 0x4f: /* dec Gv */
4863 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), -1);
4865 case 0xf6: /* GRP3 */
4867 ot
= mo_b_d(b
, dflag
);
4869 modrm
= x86_ldub_code(env
, s
);
4870 mod
= (modrm
>> 6) & 3;
4871 rm
= (modrm
& 7) | REX_B(s
);
4872 op
= (modrm
>> 3) & 7;
4875 s
->rip_offset
= insn_const_size(ot
);
4877 gen_lea_modrm(env
, s
, modrm
);
4878 /* For those below that handle locked memory, don't load here. */
4879 if (!(s
->prefix
& PREFIX_LOCK
)
4881 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
4884 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
4889 val
= insn_get(env
, s
, ot
);
4890 tcg_gen_movi_tl(s
->T1
, val
);
4891 gen_op_testl_T0_T1_cc(s
);
4892 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4895 if (s
->prefix
& PREFIX_LOCK
) {
4899 tcg_gen_movi_tl(s
->T0
, ~0);
4900 tcg_gen_atomic_xor_fetch_tl(s
->T0
, s
->A0
, s
->T0
,
4901 s
->mem_index
, ot
| MO_LE
);
4903 tcg_gen_not_tl(s
->T0
, s
->T0
);
4905 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
4907 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
4912 if (s
->prefix
& PREFIX_LOCK
) {
4914 TCGv a0
, t0
, t1
, t2
;
4919 a0
= tcg_temp_local_new();
4920 t0
= tcg_temp_local_new();
4921 label1
= gen_new_label();
4923 tcg_gen_mov_tl(a0
, s
->A0
);
4924 tcg_gen_mov_tl(t0
, s
->T0
);
4926 gen_set_label(label1
);
4927 t1
= tcg_temp_new();
4928 t2
= tcg_temp_new();
4929 tcg_gen_mov_tl(t2
, t0
);
4930 tcg_gen_neg_tl(t1
, t0
);
4931 tcg_gen_atomic_cmpxchg_tl(t0
, a0
, t0
, t1
,
4932 s
->mem_index
, ot
| MO_LE
);
4934 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t2
, label1
);
4938 tcg_gen_mov_tl(s
->T0
, t0
);
4941 tcg_gen_neg_tl(s
->T0
, s
->T0
);
4943 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
4945 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
4948 gen_op_update_neg_cc(s
);
4949 set_cc_op(s
, CC_OP_SUBB
+ ot
);
4954 gen_op_mov_v_reg(s
, MO_8
, s
->T1
, R_EAX
);
4955 tcg_gen_ext8u_tl(s
->T0
, s
->T0
);
4956 tcg_gen_ext8u_tl(s
->T1
, s
->T1
);
4957 /* XXX: use 32 bit mul which could be faster */
4958 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
4959 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
4960 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
4961 tcg_gen_andi_tl(cpu_cc_src
, s
->T0
, 0xff00);
4962 set_cc_op(s
, CC_OP_MULB
);
4965 gen_op_mov_v_reg(s
, MO_16
, s
->T1
, R_EAX
);
4966 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
4967 tcg_gen_ext16u_tl(s
->T1
, s
->T1
);
4968 /* XXX: use 32 bit mul which could be faster */
4969 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
4970 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
4971 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
4972 tcg_gen_shri_tl(s
->T0
, s
->T0
, 16);
4973 gen_op_mov_reg_v(s
, MO_16
, R_EDX
, s
->T0
);
4974 tcg_gen_mov_tl(cpu_cc_src
, s
->T0
);
4975 set_cc_op(s
, CC_OP_MULW
);
4979 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
4980 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, cpu_regs
[R_EAX
]);
4981 tcg_gen_mulu2_i32(s
->tmp2_i32
, s
->tmp3_i32
,
4982 s
->tmp2_i32
, s
->tmp3_i32
);
4983 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], s
->tmp2_i32
);
4984 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], s
->tmp3_i32
);
4985 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4986 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4987 set_cc_op(s
, CC_OP_MULL
);
4989 #ifdef TARGET_X86_64
4991 tcg_gen_mulu2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4992 s
->T0
, cpu_regs
[R_EAX
]);
4993 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4994 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4995 set_cc_op(s
, CC_OP_MULQ
);
5003 gen_op_mov_v_reg(s
, MO_8
, s
->T1
, R_EAX
);
5004 tcg_gen_ext8s_tl(s
->T0
, s
->T0
);
5005 tcg_gen_ext8s_tl(s
->T1
, s
->T1
);
5006 /* XXX: use 32 bit mul which could be faster */
5007 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
5008 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
5009 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
5010 tcg_gen_ext8s_tl(s
->tmp0
, s
->T0
);
5011 tcg_gen_sub_tl(cpu_cc_src
, s
->T0
, s
->tmp0
);
5012 set_cc_op(s
, CC_OP_MULB
);
5015 gen_op_mov_v_reg(s
, MO_16
, s
->T1
, R_EAX
);
5016 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5017 tcg_gen_ext16s_tl(s
->T1
, s
->T1
);
5018 /* XXX: use 32 bit mul which could be faster */
5019 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
5020 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
5021 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
5022 tcg_gen_ext16s_tl(s
->tmp0
, s
->T0
);
5023 tcg_gen_sub_tl(cpu_cc_src
, s
->T0
, s
->tmp0
);
5024 tcg_gen_shri_tl(s
->T0
, s
->T0
, 16);
5025 gen_op_mov_reg_v(s
, MO_16
, R_EDX
, s
->T0
);
5026 set_cc_op(s
, CC_OP_MULW
);
5030 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
5031 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, cpu_regs
[R_EAX
]);
5032 tcg_gen_muls2_i32(s
->tmp2_i32
, s
->tmp3_i32
,
5033 s
->tmp2_i32
, s
->tmp3_i32
);
5034 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], s
->tmp2_i32
);
5035 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], s
->tmp3_i32
);
5036 tcg_gen_sari_i32(s
->tmp2_i32
, s
->tmp2_i32
, 31);
5037 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
5038 tcg_gen_sub_i32(s
->tmp2_i32
, s
->tmp2_i32
, s
->tmp3_i32
);
5039 tcg_gen_extu_i32_tl(cpu_cc_src
, s
->tmp2_i32
);
5040 set_cc_op(s
, CC_OP_MULL
);
5042 #ifdef TARGET_X86_64
5044 tcg_gen_muls2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
5045 s
->T0
, cpu_regs
[R_EAX
]);
5046 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
5047 tcg_gen_sari_tl(cpu_cc_src
, cpu_regs
[R_EAX
], 63);
5048 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_regs
[R_EDX
]);
5049 set_cc_op(s
, CC_OP_MULQ
);
5057 gen_helper_divb_AL(cpu_env
, s
->T0
);
5060 gen_helper_divw_AX(cpu_env
, s
->T0
);
5064 gen_helper_divl_EAX(cpu_env
, s
->T0
);
5066 #ifdef TARGET_X86_64
5068 gen_helper_divq_EAX(cpu_env
, s
->T0
);
5076 gen_helper_idivb_AL(cpu_env
, s
->T0
);
5079 gen_helper_idivw_AX(cpu_env
, s
->T0
);
5083 gen_helper_idivl_EAX(cpu_env
, s
->T0
);
5085 #ifdef TARGET_X86_64
5087 gen_helper_idivq_EAX(cpu_env
, s
->T0
);
5097 case 0xfe: /* GRP4 */
5098 case 0xff: /* GRP5 */
5099 ot
= mo_b_d(b
, dflag
);
5101 modrm
= x86_ldub_code(env
, s
);
5102 mod
= (modrm
>> 6) & 3;
5103 rm
= (modrm
& 7) | REX_B(s
);
5104 op
= (modrm
>> 3) & 7;
5105 if (op
>= 2 && b
== 0xfe) {
5109 if (op
== 2 || op
== 4) {
5110 /* operand size for jumps is 64 bit */
5112 } else if (op
== 3 || op
== 5) {
5113 ot
= dflag
!= MO_16
? MO_32
+ REX_W(s
) : MO_16
;
5114 } else if (op
== 6) {
5115 /* default push size is 64 bit */
5116 ot
= mo_pushpop(s
, dflag
);
5120 gen_lea_modrm(env
, s
, modrm
);
5121 if (op
>= 2 && op
!= 3 && op
!= 5)
5122 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
5124 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
5128 case 0: /* inc Ev */
5133 gen_inc(s
, ot
, opreg
, 1);
5135 case 1: /* dec Ev */
5140 gen_inc(s
, ot
, opreg
, -1);
5142 case 2: /* call Ev */
5143 /* XXX: optimize if memory (no 'and' is necessary) */
5144 if (dflag
== MO_16
) {
5145 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
5147 next_eip
= s
->pc
- s
->cs_base
;
5148 tcg_gen_movi_tl(s
->T1
, next_eip
);
5149 gen_push_v(s
, s
->T1
);
5150 gen_op_jmp_v(s
->T0
);
5154 case 3: /* lcall Ev */
5158 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
5159 gen_add_A0_im(s
, 1 << ot
);
5160 gen_op_ld_v(s
, MO_16
, s
->T0
, s
->A0
);
5162 if (PE(s
) && !VM86(s
)) {
5163 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
5164 gen_helper_lcall_protected(cpu_env
, s
->tmp2_i32
, s
->T1
,
5165 tcg_const_i32(dflag
- 1),
5166 tcg_const_tl(s
->pc
- s
->cs_base
));
5168 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
5169 gen_helper_lcall_real(cpu_env
, s
->tmp2_i32
, s
->T1
,
5170 tcg_const_i32(dflag
- 1),
5171 tcg_const_i32(s
->pc
- s
->cs_base
));
5173 tcg_gen_ld_tl(s
->tmp4
, cpu_env
, offsetof(CPUX86State
, eip
));
5176 case 4: /* jmp Ev */
5177 if (dflag
== MO_16
) {
5178 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
5180 gen_op_jmp_v(s
->T0
);
5184 case 5: /* ljmp Ev */
5188 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
5189 gen_add_A0_im(s
, 1 << ot
);
5190 gen_op_ld_v(s
, MO_16
, s
->T0
, s
->A0
);
5192 if (PE(s
) && !VM86(s
)) {
5193 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
5194 gen_helper_ljmp_protected(cpu_env
, s
->tmp2_i32
, s
->T1
,
5195 tcg_const_tl(s
->pc
- s
->cs_base
));
5197 gen_op_movl_seg_T0_vm(s
, R_CS
);
5198 gen_op_jmp_v(s
->T1
);
5200 tcg_gen_ld_tl(s
->tmp4
, cpu_env
, offsetof(CPUX86State
, eip
));
5203 case 6: /* push Ev */
5204 gen_push_v(s
, s
->T0
);
5211 case 0x84: /* test Ev, Gv */
5213 ot
= mo_b_d(b
, dflag
);
5215 modrm
= x86_ldub_code(env
, s
);
5216 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5218 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5219 gen_op_mov_v_reg(s
, ot
, s
->T1
, reg
);
5220 gen_op_testl_T0_T1_cc(s
);
5221 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5224 case 0xa8: /* test eAX, Iv */
5226 ot
= mo_b_d(b
, dflag
);
5227 val
= insn_get(env
, s
, ot
);
5229 gen_op_mov_v_reg(s
, ot
, s
->T0
, OR_EAX
);
5230 tcg_gen_movi_tl(s
->T1
, val
);
5231 gen_op_testl_T0_T1_cc(s
);
5232 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5235 case 0x98: /* CWDE/CBW */
5237 #ifdef TARGET_X86_64
5239 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, R_EAX
);
5240 tcg_gen_ext32s_tl(s
->T0
, s
->T0
);
5241 gen_op_mov_reg_v(s
, MO_64
, R_EAX
, s
->T0
);
5245 gen_op_mov_v_reg(s
, MO_16
, s
->T0
, R_EAX
);
5246 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5247 gen_op_mov_reg_v(s
, MO_32
, R_EAX
, s
->T0
);
5250 gen_op_mov_v_reg(s
, MO_8
, s
->T0
, R_EAX
);
5251 tcg_gen_ext8s_tl(s
->T0
, s
->T0
);
5252 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
5258 case 0x99: /* CDQ/CWD */
5260 #ifdef TARGET_X86_64
5262 gen_op_mov_v_reg(s
, MO_64
, s
->T0
, R_EAX
);
5263 tcg_gen_sari_tl(s
->T0
, s
->T0
, 63);
5264 gen_op_mov_reg_v(s
, MO_64
, R_EDX
, s
->T0
);
5268 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, R_EAX
);
5269 tcg_gen_ext32s_tl(s
->T0
, s
->T0
);
5270 tcg_gen_sari_tl(s
->T0
, s
->T0
, 31);
5271 gen_op_mov_reg_v(s
, MO_32
, R_EDX
, s
->T0
);
5274 gen_op_mov_v_reg(s
, MO_16
, s
->T0
, R_EAX
);
5275 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5276 tcg_gen_sari_tl(s
->T0
, s
->T0
, 15);
5277 gen_op_mov_reg_v(s
, MO_16
, R_EDX
, s
->T0
);
5283 case 0x1af: /* imul Gv, Ev */
5284 case 0x69: /* imul Gv, Ev, I */
5287 modrm
= x86_ldub_code(env
, s
);
5288 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5290 s
->rip_offset
= insn_const_size(ot
);
5293 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5295 val
= insn_get(env
, s
, ot
);
5296 tcg_gen_movi_tl(s
->T1
, val
);
5297 } else if (b
== 0x6b) {
5298 val
= (int8_t)insn_get(env
, s
, MO_8
);
5299 tcg_gen_movi_tl(s
->T1
, val
);
5301 gen_op_mov_v_reg(s
, ot
, s
->T1
, reg
);
5304 #ifdef TARGET_X86_64
5306 tcg_gen_muls2_i64(cpu_regs
[reg
], s
->T1
, s
->T0
, s
->T1
);
5307 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5308 tcg_gen_sari_tl(cpu_cc_src
, cpu_cc_dst
, 63);
5309 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, s
->T1
);
5313 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
5314 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, s
->T1
);
5315 tcg_gen_muls2_i32(s
->tmp2_i32
, s
->tmp3_i32
,
5316 s
->tmp2_i32
, s
->tmp3_i32
);
5317 tcg_gen_extu_i32_tl(cpu_regs
[reg
], s
->tmp2_i32
);
5318 tcg_gen_sari_i32(s
->tmp2_i32
, s
->tmp2_i32
, 31);
5319 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5320 tcg_gen_sub_i32(s
->tmp2_i32
, s
->tmp2_i32
, s
->tmp3_i32
);
5321 tcg_gen_extu_i32_tl(cpu_cc_src
, s
->tmp2_i32
);
5324 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5325 tcg_gen_ext16s_tl(s
->T1
, s
->T1
);
5326 /* XXX: use 32 bit mul which could be faster */
5327 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
5328 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
5329 tcg_gen_ext16s_tl(s
->tmp0
, s
->T0
);
5330 tcg_gen_sub_tl(cpu_cc_src
, s
->T0
, s
->tmp0
);
5331 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
5334 set_cc_op(s
, CC_OP_MULB
+ ot
);
5337 case 0x1c1: /* xadd Ev, Gv */
5338 ot
= mo_b_d(b
, dflag
);
5339 modrm
= x86_ldub_code(env
, s
);
5340 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5341 mod
= (modrm
>> 6) & 3;
5342 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
5344 rm
= (modrm
& 7) | REX_B(s
);
5345 gen_op_mov_v_reg(s
, ot
, s
->T1
, rm
);
5346 tcg_gen_add_tl(s
->T0
, s
->T0
, s
->T1
);
5347 gen_op_mov_reg_v(s
, ot
, reg
, s
->T1
);
5348 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
5350 gen_lea_modrm(env
, s
, modrm
);
5351 if (s
->prefix
& PREFIX_LOCK
) {
5352 tcg_gen_atomic_fetch_add_tl(s
->T1
, s
->A0
, s
->T0
,
5353 s
->mem_index
, ot
| MO_LE
);
5354 tcg_gen_add_tl(s
->T0
, s
->T0
, s
->T1
);
5356 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
5357 tcg_gen_add_tl(s
->T0
, s
->T0
, s
->T1
);
5358 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
5360 gen_op_mov_reg_v(s
, ot
, reg
, s
->T1
);
5362 gen_op_update2_cc(s
);
5363 set_cc_op(s
, CC_OP_ADDB
+ ot
);
5366 case 0x1b1: /* cmpxchg Ev, Gv */
5368 TCGv oldv
, newv
, cmpv
;
5370 ot
= mo_b_d(b
, dflag
);
5371 modrm
= x86_ldub_code(env
, s
);
5372 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5373 mod
= (modrm
>> 6) & 3;
5374 oldv
= tcg_temp_new();
5375 newv
= tcg_temp_new();
5376 cmpv
= tcg_temp_new();
5377 gen_op_mov_v_reg(s
, ot
, newv
, reg
);
5378 tcg_gen_mov_tl(cmpv
, cpu_regs
[R_EAX
]);
5380 if (s
->prefix
& PREFIX_LOCK
) {
5384 gen_lea_modrm(env
, s
, modrm
);
5385 tcg_gen_atomic_cmpxchg_tl(oldv
, s
->A0
, cmpv
, newv
,
5386 s
->mem_index
, ot
| MO_LE
);
5387 gen_op_mov_reg_v(s
, ot
, R_EAX
, oldv
);
5390 rm
= (modrm
& 7) | REX_B(s
);
5391 gen_op_mov_v_reg(s
, ot
, oldv
, rm
);
5393 gen_lea_modrm(env
, s
, modrm
);
5394 gen_op_ld_v(s
, ot
, oldv
, s
->A0
);
5395 rm
= 0; /* avoid warning */
5399 /* store value = (old == cmp ? new : old); */
5400 tcg_gen_movcond_tl(TCG_COND_EQ
, newv
, oldv
, cmpv
, newv
, oldv
);
5402 gen_op_mov_reg_v(s
, ot
, R_EAX
, oldv
);
5403 gen_op_mov_reg_v(s
, ot
, rm
, newv
);
5405 /* Perform an unconditional store cycle like physical cpu;
5406 must be before changing accumulator to ensure
5407 idempotency if the store faults and the instruction
5409 gen_op_st_v(s
, ot
, newv
, s
->A0
);
5410 gen_op_mov_reg_v(s
, ot
, R_EAX
, oldv
);
5413 tcg_gen_mov_tl(cpu_cc_src
, oldv
);
5414 tcg_gen_mov_tl(s
->cc_srcT
, cmpv
);
5415 tcg_gen_sub_tl(cpu_cc_dst
, cmpv
, oldv
);
5416 set_cc_op(s
, CC_OP_SUBB
+ ot
);
5417 tcg_temp_free(oldv
);
5418 tcg_temp_free(newv
);
5419 tcg_temp_free(cmpv
);
5422 case 0x1c7: /* cmpxchg8b */
5423 modrm
= x86_ldub_code(env
, s
);
5424 mod
= (modrm
>> 6) & 3;
5425 switch ((modrm
>> 3) & 7) {
5426 case 1: /* CMPXCHG8, CMPXCHG16 */
5430 #ifdef TARGET_X86_64
5431 if (dflag
== MO_64
) {
5432 if (!(s
->cpuid_ext_features
& CPUID_EXT_CX16
)) {
5435 gen_lea_modrm(env
, s
, modrm
);
5436 if ((s
->prefix
& PREFIX_LOCK
) &&
5437 (tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
5438 gen_helper_cmpxchg16b(cpu_env
, s
->A0
);
5440 gen_helper_cmpxchg16b_unlocked(cpu_env
, s
->A0
);
5442 set_cc_op(s
, CC_OP_EFLAGS
);
5446 if (!(s
->cpuid_features
& CPUID_CX8
)) {
5449 gen_lea_modrm(env
, s
, modrm
);
5450 if ((s
->prefix
& PREFIX_LOCK
) &&
5451 (tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
5452 gen_helper_cmpxchg8b(cpu_env
, s
->A0
);
5454 gen_helper_cmpxchg8b_unlocked(cpu_env
, s
->A0
);
5456 set_cc_op(s
, CC_OP_EFLAGS
);
5459 case 7: /* RDSEED */
5460 case 6: /* RDRAND */
5462 (s
->prefix
& (PREFIX_LOCK
| PREFIX_REPZ
| PREFIX_REPNZ
)) ||
5463 !(s
->cpuid_ext_features
& CPUID_EXT_RDRAND
)) {
5466 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
5469 gen_helper_rdrand(s
->T0
, cpu_env
);
5470 rm
= (modrm
& 7) | REX_B(s
);
5471 gen_op_mov_reg_v(s
, dflag
, rm
, s
->T0
);
5472 set_cc_op(s
, CC_OP_EFLAGS
);
5473 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
5474 gen_jmp(s
, s
->pc
- s
->cs_base
);
5483 /**************************/
5485 case 0x50 ... 0x57: /* push */
5486 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, (b
& 7) | REX_B(s
));
5487 gen_push_v(s
, s
->T0
);
5489 case 0x58 ... 0x5f: /* pop */
5491 /* NOTE: order is important for pop %sp */
5492 gen_pop_update(s
, ot
);
5493 gen_op_mov_reg_v(s
, ot
, (b
& 7) | REX_B(s
), s
->T0
);
5495 case 0x60: /* pusha */
5500 case 0x61: /* popa */
5505 case 0x68: /* push Iv */
5507 ot
= mo_pushpop(s
, dflag
);
5509 val
= insn_get(env
, s
, ot
);
5511 val
= (int8_t)insn_get(env
, s
, MO_8
);
5512 tcg_gen_movi_tl(s
->T0
, val
);
5513 gen_push_v(s
, s
->T0
);
5515 case 0x8f: /* pop Ev */
5516 modrm
= x86_ldub_code(env
, s
);
5517 mod
= (modrm
>> 6) & 3;
5520 /* NOTE: order is important for pop %sp */
5521 gen_pop_update(s
, ot
);
5522 rm
= (modrm
& 7) | REX_B(s
);
5523 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
5525 /* NOTE: order is important too for MMU exceptions */
5526 s
->popl_esp_hack
= 1 << ot
;
5527 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5528 s
->popl_esp_hack
= 0;
5529 gen_pop_update(s
, ot
);
5532 case 0xc8: /* enter */
5535 val
= x86_lduw_code(env
, s
);
5536 level
= x86_ldub_code(env
, s
);
5537 gen_enter(s
, val
, level
);
5540 case 0xc9: /* leave */
5543 case 0x06: /* push es */
5544 case 0x0e: /* push cs */
5545 case 0x16: /* push ss */
5546 case 0x1e: /* push ds */
5549 gen_op_movl_T0_seg(s
, b
>> 3);
5550 gen_push_v(s
, s
->T0
);
5552 case 0x1a0: /* push fs */
5553 case 0x1a8: /* push gs */
5554 gen_op_movl_T0_seg(s
, (b
>> 3) & 7);
5555 gen_push_v(s
, s
->T0
);
5557 case 0x07: /* pop es */
5558 case 0x17: /* pop ss */
5559 case 0x1f: /* pop ds */
5564 gen_movl_seg_T0(s
, reg
);
5565 gen_pop_update(s
, ot
);
5566 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5567 if (s
->base
.is_jmp
) {
5568 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
5570 s
->flags
&= ~HF_TF_MASK
;
5571 gen_eob_inhibit_irq(s
, true);
5577 case 0x1a1: /* pop fs */
5578 case 0x1a9: /* pop gs */
5580 gen_movl_seg_T0(s
, (b
>> 3) & 7);
5581 gen_pop_update(s
, ot
);
5582 if (s
->base
.is_jmp
) {
5583 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
5588 /**************************/
5591 case 0x89: /* mov Gv, Ev */
5592 ot
= mo_b_d(b
, dflag
);
5593 modrm
= x86_ldub_code(env
, s
);
5594 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5596 /* generate a generic store */
5597 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
5600 case 0xc7: /* mov Ev, Iv */
5601 ot
= mo_b_d(b
, dflag
);
5602 modrm
= x86_ldub_code(env
, s
);
5603 mod
= (modrm
>> 6) & 3;
5605 s
->rip_offset
= insn_const_size(ot
);
5606 gen_lea_modrm(env
, s
, modrm
);
5608 val
= insn_get(env
, s
, ot
);
5609 tcg_gen_movi_tl(s
->T0
, val
);
5611 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
5613 gen_op_mov_reg_v(s
, ot
, (modrm
& 7) | REX_B(s
), s
->T0
);
5617 case 0x8b: /* mov Ev, Gv */
5618 ot
= mo_b_d(b
, dflag
);
5619 modrm
= x86_ldub_code(env
, s
);
5620 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5622 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5623 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
5625 case 0x8e: /* mov seg, Gv */
5626 modrm
= x86_ldub_code(env
, s
);
5627 reg
= (modrm
>> 3) & 7;
5628 if (reg
>= 6 || reg
== R_CS
)
5630 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
5631 gen_movl_seg_T0(s
, reg
);
5632 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5633 if (s
->base
.is_jmp
) {
5634 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
5636 s
->flags
&= ~HF_TF_MASK
;
5637 gen_eob_inhibit_irq(s
, true);
5643 case 0x8c: /* mov Gv, seg */
5644 modrm
= x86_ldub_code(env
, s
);
5645 reg
= (modrm
>> 3) & 7;
5646 mod
= (modrm
>> 6) & 3;
5649 gen_op_movl_T0_seg(s
, reg
);
5650 ot
= mod
== 3 ? dflag
: MO_16
;
5651 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5654 case 0x1b6: /* movzbS Gv, Eb */
5655 case 0x1b7: /* movzwS Gv, Eb */
5656 case 0x1be: /* movsbS Gv, Eb */
5657 case 0x1bf: /* movswS Gv, Eb */
5662 /* d_ot is the size of destination */
5664 /* ot is the size of source */
5665 ot
= (b
& 1) + MO_8
;
5666 /* s_ot is the sign+size of source */
5667 s_ot
= b
& 8 ? MO_SIGN
| ot
: ot
;
5669 modrm
= x86_ldub_code(env
, s
);
5670 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5671 mod
= (modrm
>> 6) & 3;
5672 rm
= (modrm
& 7) | REX_B(s
);
5675 if (s_ot
== MO_SB
&& byte_reg_is_xH(s
, rm
)) {
5676 tcg_gen_sextract_tl(s
->T0
, cpu_regs
[rm
- 4], 8, 8);
5678 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
5681 tcg_gen_ext8u_tl(s
->T0
, s
->T0
);
5684 tcg_gen_ext8s_tl(s
->T0
, s
->T0
);
5687 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
5691 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5695 gen_op_mov_reg_v(s
, d_ot
, reg
, s
->T0
);
5697 gen_lea_modrm(env
, s
, modrm
);
5698 gen_op_ld_v(s
, s_ot
, s
->T0
, s
->A0
);
5699 gen_op_mov_reg_v(s
, d_ot
, reg
, s
->T0
);
5704 case 0x8d: /* lea */
5705 modrm
= x86_ldub_code(env
, s
);
5706 mod
= (modrm
>> 6) & 3;
5709 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5711 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
5712 TCGv ea
= gen_lea_modrm_1(s
, a
);
5713 gen_lea_v_seg(s
, s
->aflag
, ea
, -1, -1);
5714 gen_op_mov_reg_v(s
, dflag
, reg
, s
->A0
);
5718 case 0xa0: /* mov EAX, Ov */
5720 case 0xa2: /* mov Ov, EAX */
5723 target_ulong offset_addr
;
5725 ot
= mo_b_d(b
, dflag
);
5727 #ifdef TARGET_X86_64
5729 offset_addr
= x86_ldq_code(env
, s
);
5733 offset_addr
= insn_get(env
, s
, s
->aflag
);
5736 tcg_gen_movi_tl(s
->A0
, offset_addr
);
5737 gen_add_A0_ds_seg(s
);
5739 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
5740 gen_op_mov_reg_v(s
, ot
, R_EAX
, s
->T0
);
5742 gen_op_mov_v_reg(s
, ot
, s
->T0
, R_EAX
);
5743 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
5747 case 0xd7: /* xlat */
5748 tcg_gen_mov_tl(s
->A0
, cpu_regs
[R_EBX
]);
5749 tcg_gen_ext8u_tl(s
->T0
, cpu_regs
[R_EAX
]);
5750 tcg_gen_add_tl(s
->A0
, s
->A0
, s
->T0
);
5751 gen_extu(s
->aflag
, s
->A0
);
5752 gen_add_A0_ds_seg(s
);
5753 gen_op_ld_v(s
, MO_8
, s
->T0
, s
->A0
);
5754 gen_op_mov_reg_v(s
, MO_8
, R_EAX
, s
->T0
);
5756 case 0xb0 ... 0xb7: /* mov R, Ib */
5757 val
= insn_get(env
, s
, MO_8
);
5758 tcg_gen_movi_tl(s
->T0
, val
);
5759 gen_op_mov_reg_v(s
, MO_8
, (b
& 7) | REX_B(s
), s
->T0
);
5761 case 0xb8 ... 0xbf: /* mov R, Iv */
5762 #ifdef TARGET_X86_64
5763 if (dflag
== MO_64
) {
5766 tmp
= x86_ldq_code(env
, s
);
5767 reg
= (b
& 7) | REX_B(s
);
5768 tcg_gen_movi_tl(s
->T0
, tmp
);
5769 gen_op_mov_reg_v(s
, MO_64
, reg
, s
->T0
);
5774 val
= insn_get(env
, s
, ot
);
5775 reg
= (b
& 7) | REX_B(s
);
5776 tcg_gen_movi_tl(s
->T0
, val
);
5777 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
5781 case 0x91 ... 0x97: /* xchg R, EAX */
5784 reg
= (b
& 7) | REX_B(s
);
5788 case 0x87: /* xchg Ev, Gv */
5789 ot
= mo_b_d(b
, dflag
);
5790 modrm
= x86_ldub_code(env
, s
);
5791 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5792 mod
= (modrm
>> 6) & 3;
5794 rm
= (modrm
& 7) | REX_B(s
);
5796 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
5797 gen_op_mov_v_reg(s
, ot
, s
->T1
, rm
);
5798 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
5799 gen_op_mov_reg_v(s
, ot
, reg
, s
->T1
);
5801 gen_lea_modrm(env
, s
, modrm
);
5802 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
5803 /* for xchg, lock is implicit */
5804 tcg_gen_atomic_xchg_tl(s
->T1
, s
->A0
, s
->T0
,
5805 s
->mem_index
, ot
| MO_LE
);
5806 gen_op_mov_reg_v(s
, ot
, reg
, s
->T1
);
5809 case 0xc4: /* les Gv */
5810 /* In CODE64 this is VEX3; see above. */
5813 case 0xc5: /* lds Gv */
5814 /* In CODE64 this is VEX2; see above. */
5817 case 0x1b2: /* lss Gv */
5820 case 0x1b4: /* lfs Gv */
5823 case 0x1b5: /* lgs Gv */
5826 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
5827 modrm
= x86_ldub_code(env
, s
);
5828 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5829 mod
= (modrm
>> 6) & 3;
5832 gen_lea_modrm(env
, s
, modrm
);
5833 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
5834 gen_add_A0_im(s
, 1 << ot
);
5835 /* load the segment first to handle exceptions properly */
5836 gen_op_ld_v(s
, MO_16
, s
->T0
, s
->A0
);
5837 gen_movl_seg_T0(s
, op
);
5838 /* then put the data */
5839 gen_op_mov_reg_v(s
, ot
, reg
, s
->T1
);
5840 if (s
->base
.is_jmp
) {
5841 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
5846 /************************/
5854 ot
= mo_b_d(b
, dflag
);
5855 modrm
= x86_ldub_code(env
, s
);
5856 mod
= (modrm
>> 6) & 3;
5857 op
= (modrm
>> 3) & 7;
5863 gen_lea_modrm(env
, s
, modrm
);
5866 opreg
= (modrm
& 7) | REX_B(s
);
5871 gen_shift(s
, op
, ot
, opreg
, OR_ECX
);
5874 shift
= x86_ldub_code(env
, s
);
5876 gen_shifti(s
, op
, ot
, opreg
, shift
);
5891 case 0x1a4: /* shld imm */
5895 case 0x1a5: /* shld cl */
5899 case 0x1ac: /* shrd imm */
5903 case 0x1ad: /* shrd cl */
5908 modrm
= x86_ldub_code(env
, s
);
5909 mod
= (modrm
>> 6) & 3;
5910 rm
= (modrm
& 7) | REX_B(s
);
5911 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5913 gen_lea_modrm(env
, s
, modrm
);
5918 gen_op_mov_v_reg(s
, ot
, s
->T1
, reg
);
5921 TCGv imm
= tcg_const_tl(x86_ldub_code(env
, s
));
5922 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, imm
);
5925 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, cpu_regs
[R_ECX
]);
5929 /************************/
5932 if (s
->flags
& (HF_EM_MASK
| HF_TS_MASK
)) {
5933 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5934 /* XXX: what to do if illegal op ? */
5935 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
5938 modrm
= x86_ldub_code(env
, s
);
5939 mod
= (modrm
>> 6) & 3;
5941 op
= ((b
& 7) << 3) | ((modrm
>> 3) & 7);
5944 gen_lea_modrm(env
, s
, modrm
);
5946 case 0x00 ... 0x07: /* fxxxs */
5947 case 0x10 ... 0x17: /* fixxxl */
5948 case 0x20 ... 0x27: /* fxxxl */
5949 case 0x30 ... 0x37: /* fixxx */
5956 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
5957 s
->mem_index
, MO_LEUL
);
5958 gen_helper_flds_FT0(cpu_env
, s
->tmp2_i32
);
5961 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
5962 s
->mem_index
, MO_LEUL
);
5963 gen_helper_fildl_FT0(cpu_env
, s
->tmp2_i32
);
5966 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
,
5967 s
->mem_index
, MO_LEQ
);
5968 gen_helper_fldl_FT0(cpu_env
, s
->tmp1_i64
);
5972 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
5973 s
->mem_index
, MO_LESW
);
5974 gen_helper_fildl_FT0(cpu_env
, s
->tmp2_i32
);
5978 gen_helper_fp_arith_ST0_FT0(op1
);
5980 /* fcomp needs pop */
5981 gen_helper_fpop(cpu_env
);
5985 case 0x08: /* flds */
5986 case 0x0a: /* fsts */
5987 case 0x0b: /* fstps */
5988 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5989 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5990 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5995 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
5996 s
->mem_index
, MO_LEUL
);
5997 gen_helper_flds_ST0(cpu_env
, s
->tmp2_i32
);
6000 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
6001 s
->mem_index
, MO_LEUL
);
6002 gen_helper_fildl_ST0(cpu_env
, s
->tmp2_i32
);
6005 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
,
6006 s
->mem_index
, MO_LEQ
);
6007 gen_helper_fldl_ST0(cpu_env
, s
->tmp1_i64
);
6011 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
6012 s
->mem_index
, MO_LESW
);
6013 gen_helper_fildl_ST0(cpu_env
, s
->tmp2_i32
);
6018 /* XXX: the corresponding CPUID bit must be tested ! */
6021 gen_helper_fisttl_ST0(s
->tmp2_i32
, cpu_env
);
6022 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
6023 s
->mem_index
, MO_LEUL
);
6026 gen_helper_fisttll_ST0(s
->tmp1_i64
, cpu_env
);
6027 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
,
6028 s
->mem_index
, MO_LEQ
);
6032 gen_helper_fistt_ST0(s
->tmp2_i32
, cpu_env
);
6033 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
6034 s
->mem_index
, MO_LEUW
);
6037 gen_helper_fpop(cpu_env
);
6042 gen_helper_fsts_ST0(s
->tmp2_i32
, cpu_env
);
6043 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
6044 s
->mem_index
, MO_LEUL
);
6047 gen_helper_fistl_ST0(s
->tmp2_i32
, cpu_env
);
6048 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
6049 s
->mem_index
, MO_LEUL
);
6052 gen_helper_fstl_ST0(s
->tmp1_i64
, cpu_env
);
6053 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
,
6054 s
->mem_index
, MO_LEQ
);
6058 gen_helper_fist_ST0(s
->tmp2_i32
, cpu_env
);
6059 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
6060 s
->mem_index
, MO_LEUW
);
6064 gen_helper_fpop(cpu_env
);
6068 case 0x0c: /* fldenv mem */
6069 gen_helper_fldenv(cpu_env
, s
->A0
, tcg_const_i32(dflag
- 1));
6071 case 0x0d: /* fldcw mem */
6072 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
6073 s
->mem_index
, MO_LEUW
);
6074 gen_helper_fldcw(cpu_env
, s
->tmp2_i32
);
6076 case 0x0e: /* fnstenv mem */
6077 gen_helper_fstenv(cpu_env
, s
->A0
, tcg_const_i32(dflag
- 1));
6079 case 0x0f: /* fnstcw mem */
6080 gen_helper_fnstcw(s
->tmp2_i32
, cpu_env
);
6081 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
6082 s
->mem_index
, MO_LEUW
);
6084 case 0x1d: /* fldt mem */
6085 gen_helper_fldt_ST0(cpu_env
, s
->A0
);
6087 case 0x1f: /* fstpt mem */
6088 gen_helper_fstt_ST0(cpu_env
, s
->A0
);
6089 gen_helper_fpop(cpu_env
);
6091 case 0x2c: /* frstor mem */
6092 gen_helper_frstor(cpu_env
, s
->A0
, tcg_const_i32(dflag
- 1));
6094 case 0x2e: /* fnsave mem */
6095 gen_helper_fsave(cpu_env
, s
->A0
, tcg_const_i32(dflag
- 1));
6097 case 0x2f: /* fnstsw mem */
6098 gen_helper_fnstsw(s
->tmp2_i32
, cpu_env
);
6099 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
6100 s
->mem_index
, MO_LEUW
);
6102 case 0x3c: /* fbld */
6103 gen_helper_fbld_ST0(cpu_env
, s
->A0
);
6105 case 0x3e: /* fbstp */
6106 gen_helper_fbst_ST0(cpu_env
, s
->A0
);
6107 gen_helper_fpop(cpu_env
);
6109 case 0x3d: /* fildll */
6110 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
, s
->mem_index
, MO_LEQ
);
6111 gen_helper_fildll_ST0(cpu_env
, s
->tmp1_i64
);
6113 case 0x3f: /* fistpll */
6114 gen_helper_fistll_ST0(s
->tmp1_i64
, cpu_env
);
6115 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
, s
->mem_index
, MO_LEQ
);
6116 gen_helper_fpop(cpu_env
);
6122 /* register float ops */
6126 case 0x08: /* fld sti */
6127 gen_helper_fpush(cpu_env
);
6128 gen_helper_fmov_ST0_STN(cpu_env
,
6129 tcg_const_i32((opreg
+ 1) & 7));
6131 case 0x09: /* fxchg sti */
6132 case 0x29: /* fxchg4 sti, undocumented op */
6133 case 0x39: /* fxchg7 sti, undocumented op */
6134 gen_helper_fxchg_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6136 case 0x0a: /* grp d9/2 */
6139 /* check exceptions (FreeBSD FPU probe) */
6140 gen_helper_fwait(cpu_env
);
6146 case 0x0c: /* grp d9/4 */
6149 gen_helper_fchs_ST0(cpu_env
);
6152 gen_helper_fabs_ST0(cpu_env
);
6155 gen_helper_fldz_FT0(cpu_env
);
6156 gen_helper_fcom_ST0_FT0(cpu_env
);
6159 gen_helper_fxam_ST0(cpu_env
);
6165 case 0x0d: /* grp d9/5 */
6169 gen_helper_fpush(cpu_env
);
6170 gen_helper_fld1_ST0(cpu_env
);
6173 gen_helper_fpush(cpu_env
);
6174 gen_helper_fldl2t_ST0(cpu_env
);
6177 gen_helper_fpush(cpu_env
);
6178 gen_helper_fldl2e_ST0(cpu_env
);
6181 gen_helper_fpush(cpu_env
);
6182 gen_helper_fldpi_ST0(cpu_env
);
6185 gen_helper_fpush(cpu_env
);
6186 gen_helper_fldlg2_ST0(cpu_env
);
6189 gen_helper_fpush(cpu_env
);
6190 gen_helper_fldln2_ST0(cpu_env
);
6193 gen_helper_fpush(cpu_env
);
6194 gen_helper_fldz_ST0(cpu_env
);
6201 case 0x0e: /* grp d9/6 */
6204 gen_helper_f2xm1(cpu_env
);
6207 gen_helper_fyl2x(cpu_env
);
6210 gen_helper_fptan(cpu_env
);
6212 case 3: /* fpatan */
6213 gen_helper_fpatan(cpu_env
);
6215 case 4: /* fxtract */
6216 gen_helper_fxtract(cpu_env
);
6218 case 5: /* fprem1 */
6219 gen_helper_fprem1(cpu_env
);
6221 case 6: /* fdecstp */
6222 gen_helper_fdecstp(cpu_env
);
6225 case 7: /* fincstp */
6226 gen_helper_fincstp(cpu_env
);
6230 case 0x0f: /* grp d9/7 */
6233 gen_helper_fprem(cpu_env
);
6235 case 1: /* fyl2xp1 */
6236 gen_helper_fyl2xp1(cpu_env
);
6239 gen_helper_fsqrt(cpu_env
);
6241 case 3: /* fsincos */
6242 gen_helper_fsincos(cpu_env
);
6244 case 5: /* fscale */
6245 gen_helper_fscale(cpu_env
);
6247 case 4: /* frndint */
6248 gen_helper_frndint(cpu_env
);
6251 gen_helper_fsin(cpu_env
);
6255 gen_helper_fcos(cpu_env
);
6259 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6260 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6261 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6267 gen_helper_fp_arith_STN_ST0(op1
, opreg
);
6269 gen_helper_fpop(cpu_env
);
6271 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6272 gen_helper_fp_arith_ST0_FT0(op1
);
6276 case 0x02: /* fcom */
6277 case 0x22: /* fcom2, undocumented op */
6278 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6279 gen_helper_fcom_ST0_FT0(cpu_env
);
6281 case 0x03: /* fcomp */
6282 case 0x23: /* fcomp3, undocumented op */
6283 case 0x32: /* fcomp5, undocumented op */
6284 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6285 gen_helper_fcom_ST0_FT0(cpu_env
);
6286 gen_helper_fpop(cpu_env
);
6288 case 0x15: /* da/5 */
6290 case 1: /* fucompp */
6291 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6292 gen_helper_fucom_ST0_FT0(cpu_env
);
6293 gen_helper_fpop(cpu_env
);
6294 gen_helper_fpop(cpu_env
);
6302 case 0: /* feni (287 only, just do nop here) */
6304 case 1: /* fdisi (287 only, just do nop here) */
6307 gen_helper_fclex(cpu_env
);
6309 case 3: /* fninit */
6310 gen_helper_fninit(cpu_env
);
6312 case 4: /* fsetpm (287 only, just do nop here) */
6318 case 0x1d: /* fucomi */
6319 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6322 gen_update_cc_op(s
);
6323 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6324 gen_helper_fucomi_ST0_FT0(cpu_env
);
6325 set_cc_op(s
, CC_OP_EFLAGS
);
6327 case 0x1e: /* fcomi */
6328 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6331 gen_update_cc_op(s
);
6332 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6333 gen_helper_fcomi_ST0_FT0(cpu_env
);
6334 set_cc_op(s
, CC_OP_EFLAGS
);
6336 case 0x28: /* ffree sti */
6337 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6339 case 0x2a: /* fst sti */
6340 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6342 case 0x2b: /* fstp sti */
6343 case 0x0b: /* fstp1 sti, undocumented op */
6344 case 0x3a: /* fstp8 sti, undocumented op */
6345 case 0x3b: /* fstp9 sti, undocumented op */
6346 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6347 gen_helper_fpop(cpu_env
);
6349 case 0x2c: /* fucom st(i) */
6350 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6351 gen_helper_fucom_ST0_FT0(cpu_env
);
6353 case 0x2d: /* fucomp st(i) */
6354 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6355 gen_helper_fucom_ST0_FT0(cpu_env
);
6356 gen_helper_fpop(cpu_env
);
6358 case 0x33: /* de/3 */
6360 case 1: /* fcompp */
6361 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6362 gen_helper_fcom_ST0_FT0(cpu_env
);
6363 gen_helper_fpop(cpu_env
);
6364 gen_helper_fpop(cpu_env
);
6370 case 0x38: /* ffreep sti, undocumented op */
6371 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6372 gen_helper_fpop(cpu_env
);
6374 case 0x3c: /* df/4 */
6377 gen_helper_fnstsw(s
->tmp2_i32
, cpu_env
);
6378 tcg_gen_extu_i32_tl(s
->T0
, s
->tmp2_i32
);
6379 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
6385 case 0x3d: /* fucomip */
6386 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6389 gen_update_cc_op(s
);
6390 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6391 gen_helper_fucomi_ST0_FT0(cpu_env
);
6392 gen_helper_fpop(cpu_env
);
6393 set_cc_op(s
, CC_OP_EFLAGS
);
6395 case 0x3e: /* fcomip */
6396 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6399 gen_update_cc_op(s
);
6400 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6401 gen_helper_fcomi_ST0_FT0(cpu_env
);
6402 gen_helper_fpop(cpu_env
);
6403 set_cc_op(s
, CC_OP_EFLAGS
);
6405 case 0x10 ... 0x13: /* fcmovxx */
6410 static const uint8_t fcmov_cc
[8] = {
6417 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6420 op1
= fcmov_cc
[op
& 3] | (((op
>> 3) & 1) ^ 1);
6421 l1
= gen_new_label();
6422 gen_jcc1_noeob(s
, op1
, l1
);
6423 gen_helper_fmov_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6432 /************************/
6435 case 0xa4: /* movsS */
6437 ot
= mo_b_d(b
, dflag
);
6438 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6439 gen_repz_movs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6445 case 0xaa: /* stosS */
6447 ot
= mo_b_d(b
, dflag
);
6448 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6449 gen_repz_stos(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6454 case 0xac: /* lodsS */
6456 ot
= mo_b_d(b
, dflag
);
6457 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6458 gen_repz_lods(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6463 case 0xae: /* scasS */
6465 ot
= mo_b_d(b
, dflag
);
6466 if (prefixes
& PREFIX_REPNZ
) {
6467 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6468 } else if (prefixes
& PREFIX_REPZ
) {
6469 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6475 case 0xa6: /* cmpsS */
6477 ot
= mo_b_d(b
, dflag
);
6478 if (prefixes
& PREFIX_REPNZ
) {
6479 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6480 } else if (prefixes
& PREFIX_REPZ
) {
6481 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6486 case 0x6c: /* insS */
6488 ot
= mo_b_d32(b
, dflag
);
6489 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_EDX
]);
6490 tcg_gen_ext16u_i32(s
->tmp2_i32
, s
->tmp2_i32
);
6491 if (!gen_check_io(s
, ot
, s
->tmp2_i32
,
6492 SVM_IOIO_TYPE_MASK
| SVM_IOIO_STR_MASK
)) {
6495 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6498 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6499 gen_repz_ins(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6500 /* jump generated by gen_repz_ins */
6503 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6504 gen_jmp(s
, s
->pc
- s
->cs_base
);
6508 case 0x6e: /* outsS */
6510 ot
= mo_b_d32(b
, dflag
);
6511 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_EDX
]);
6512 tcg_gen_ext16u_i32(s
->tmp2_i32
, s
->tmp2_i32
);
6513 if (!gen_check_io(s
, ot
, s
->tmp2_i32
, SVM_IOIO_STR_MASK
)) {
6516 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6519 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6520 gen_repz_outs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6521 /* jump generated by gen_repz_outs */
6524 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6525 gen_jmp(s
, s
->pc
- s
->cs_base
);
6530 /************************/
6535 ot
= mo_b_d32(b
, dflag
);
6536 val
= x86_ldub_code(env
, s
);
6537 tcg_gen_movi_i32(s
->tmp2_i32
, val
);
6538 if (!gen_check_io(s
, ot
, s
->tmp2_i32
, SVM_IOIO_TYPE_MASK
)) {
6541 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6544 gen_helper_in_func(ot
, s
->T1
, s
->tmp2_i32
);
6545 gen_op_mov_reg_v(s
, ot
, R_EAX
, s
->T1
);
6546 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
6547 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6548 gen_jmp(s
, s
->pc
- s
->cs_base
);
6553 ot
= mo_b_d32(b
, dflag
);
6554 val
= x86_ldub_code(env
, s
);
6555 tcg_gen_movi_i32(s
->tmp2_i32
, val
);
6556 if (!gen_check_io(s
, ot
, s
->tmp2_i32
, 0)) {
6559 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6562 gen_op_mov_v_reg(s
, ot
, s
->T1
, R_EAX
);
6563 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, s
->T1
);
6564 gen_helper_out_func(ot
, s
->tmp2_i32
, s
->tmp3_i32
);
6565 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
6566 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6567 gen_jmp(s
, s
->pc
- s
->cs_base
);
6572 ot
= mo_b_d32(b
, dflag
);
6573 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_EDX
]);
6574 tcg_gen_ext16u_i32(s
->tmp2_i32
, s
->tmp2_i32
);
6575 if (!gen_check_io(s
, ot
, s
->tmp2_i32
, SVM_IOIO_TYPE_MASK
)) {
6578 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6581 gen_helper_in_func(ot
, s
->T1
, s
->tmp2_i32
);
6582 gen_op_mov_reg_v(s
, ot
, R_EAX
, s
->T1
);
6583 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
6584 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6585 gen_jmp(s
, s
->pc
- s
->cs_base
);
6590 ot
= mo_b_d32(b
, dflag
);
6591 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_EDX
]);
6592 tcg_gen_ext16u_i32(s
->tmp2_i32
, s
->tmp2_i32
);
6593 if (!gen_check_io(s
, ot
, s
->tmp2_i32
, 0)) {
6596 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6599 gen_op_mov_v_reg(s
, ot
, s
->T1
, R_EAX
);
6600 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, s
->T1
);
6601 gen_helper_out_func(ot
, s
->tmp2_i32
, s
->tmp3_i32
);
6602 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
6603 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6604 gen_jmp(s
, s
->pc
- s
->cs_base
);
6608 /************************/
6610 case 0xc2: /* ret im */
6611 val
= x86_ldsw_code(env
, s
);
6613 gen_stack_update(s
, val
+ (1 << ot
));
6614 /* Note that gen_pop_T0 uses a zero-extending load. */
6615 gen_op_jmp_v(s
->T0
);
6619 case 0xc3: /* ret */
6621 gen_pop_update(s
, ot
);
6622 /* Note that gen_pop_T0 uses a zero-extending load. */
6623 gen_op_jmp_v(s
->T0
);
6627 case 0xca: /* lret im */
6628 val
= x86_ldsw_code(env
, s
);
6630 if (PE(s
) && !VM86(s
)) {
6631 gen_update_cc_op(s
);
6632 gen_jmp_im(s
, pc_start
- s
->cs_base
);
6633 gen_helper_lret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6634 tcg_const_i32(val
));
6638 gen_op_ld_v(s
, dflag
, s
->T0
, s
->A0
);
6639 /* NOTE: keeping EIP updated is not a problem in case of
6641 gen_op_jmp_v(s
->T0
);
6643 gen_add_A0_im(s
, 1 << dflag
);
6644 gen_op_ld_v(s
, dflag
, s
->T0
, s
->A0
);
6645 gen_op_movl_seg_T0_vm(s
, R_CS
);
6646 /* add stack offset */
6647 gen_stack_update(s
, val
+ (2 << dflag
));
6651 case 0xcb: /* lret */
6654 case 0xcf: /* iret */
6655 gen_svm_check_intercept(s
, SVM_EXIT_IRET
);
6656 if (!PE(s
) || VM86(s
)) {
6657 /* real mode or vm86 mode */
6658 if (!check_vm86_iopl(s
)) {
6661 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6663 gen_helper_iret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6664 tcg_const_i32(s
->pc
- s
->cs_base
));
6666 set_cc_op(s
, CC_OP_EFLAGS
);
6669 case 0xe8: /* call im */
6671 if (dflag
!= MO_16
) {
6672 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6674 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6676 next_eip
= s
->pc
- s
->cs_base
;
6678 if (dflag
== MO_16
) {
6680 } else if (!CODE64(s
)) {
6683 tcg_gen_movi_tl(s
->T0
, next_eip
);
6684 gen_push_v(s
, s
->T0
);
6689 case 0x9a: /* lcall im */
6691 unsigned int selector
, offset
;
6696 offset
= insn_get(env
, s
, ot
);
6697 selector
= insn_get(env
, s
, MO_16
);
6699 tcg_gen_movi_tl(s
->T0
, selector
);
6700 tcg_gen_movi_tl(s
->T1
, offset
);
6703 case 0xe9: /* jmp im */
6704 if (dflag
!= MO_16
) {
6705 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6707 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6709 tval
+= s
->pc
- s
->cs_base
;
6710 if (dflag
== MO_16
) {
6712 } else if (!CODE64(s
)) {
6718 case 0xea: /* ljmp im */
6720 unsigned int selector
, offset
;
6725 offset
= insn_get(env
, s
, ot
);
6726 selector
= insn_get(env
, s
, MO_16
);
6728 tcg_gen_movi_tl(s
->T0
, selector
);
6729 tcg_gen_movi_tl(s
->T1
, offset
);
6732 case 0xeb: /* jmp Jb */
6733 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6734 tval
+= s
->pc
- s
->cs_base
;
6735 if (dflag
== MO_16
) {
6740 case 0x70 ... 0x7f: /* jcc Jb */
6741 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6743 case 0x180 ... 0x18f: /* jcc Jv */
6744 if (dflag
!= MO_16
) {
6745 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6747 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6750 next_eip
= s
->pc
- s
->cs_base
;
6752 if (dflag
== MO_16
) {
6756 gen_jcc(s
, b
, tval
, next_eip
);
6759 case 0x190 ... 0x19f: /* setcc Gv */
6760 modrm
= x86_ldub_code(env
, s
);
6761 gen_setcc1(s
, b
, s
->T0
);
6762 gen_ldst_modrm(env
, s
, modrm
, MO_8
, OR_TMP0
, 1);
6764 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6765 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6769 modrm
= x86_ldub_code(env
, s
);
6770 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
6771 gen_cmovcc1(env
, s
, ot
, b
, modrm
, reg
);
6774 /************************/
6776 case 0x9c: /* pushf */
6777 gen_svm_check_intercept(s
, SVM_EXIT_PUSHF
);
6778 if (check_vm86_iopl(s
)) {
6779 gen_update_cc_op(s
);
6780 gen_helper_read_eflags(s
->T0
, cpu_env
);
6781 gen_push_v(s
, s
->T0
);
6784 case 0x9d: /* popf */
6785 gen_svm_check_intercept(s
, SVM_EXIT_POPF
);
6786 if (check_vm86_iopl(s
)) {
6789 if (dflag
!= MO_16
) {
6790 gen_helper_write_eflags(cpu_env
, s
->T0
,
6791 tcg_const_i32((TF_MASK
| AC_MASK
|
6796 gen_helper_write_eflags(cpu_env
, s
->T0
,
6797 tcg_const_i32((TF_MASK
| AC_MASK
|
6799 IF_MASK
| IOPL_MASK
)
6803 if (CPL(s
) <= IOPL(s
)) {
6804 if (dflag
!= MO_16
) {
6805 gen_helper_write_eflags(cpu_env
, s
->T0
,
6806 tcg_const_i32((TF_MASK
|
6812 gen_helper_write_eflags(cpu_env
, s
->T0
,
6813 tcg_const_i32((TF_MASK
|
6821 if (dflag
!= MO_16
) {
6822 gen_helper_write_eflags(cpu_env
, s
->T0
,
6823 tcg_const_i32((TF_MASK
| AC_MASK
|
6824 ID_MASK
| NT_MASK
)));
6826 gen_helper_write_eflags(cpu_env
, s
->T0
,
6827 tcg_const_i32((TF_MASK
| AC_MASK
|
6833 gen_pop_update(s
, ot
);
6834 set_cc_op(s
, CC_OP_EFLAGS
);
6835 /* abort translation because TF/AC flag may change */
6836 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
6840 case 0x9e: /* sahf */
6841 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6843 gen_op_mov_v_reg(s
, MO_8
, s
->T0
, R_AH
);
6844 gen_compute_eflags(s
);
6845 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, CC_O
);
6846 tcg_gen_andi_tl(s
->T0
, s
->T0
, CC_S
| CC_Z
| CC_A
| CC_P
| CC_C
);
6847 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, s
->T0
);
6849 case 0x9f: /* lahf */
6850 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6852 gen_compute_eflags(s
);
6853 /* Note: gen_compute_eflags() only gives the condition codes */
6854 tcg_gen_ori_tl(s
->T0
, cpu_cc_src
, 0x02);
6855 gen_op_mov_reg_v(s
, MO_8
, R_AH
, s
->T0
);
6857 case 0xf5: /* cmc */
6858 gen_compute_eflags(s
);
6859 tcg_gen_xori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6861 case 0xf8: /* clc */
6862 gen_compute_eflags(s
);
6863 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_C
);
6865 case 0xf9: /* stc */
6866 gen_compute_eflags(s
);
6867 tcg_gen_ori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6869 case 0xfc: /* cld */
6870 tcg_gen_movi_i32(s
->tmp2_i32
, 1);
6871 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6873 case 0xfd: /* std */
6874 tcg_gen_movi_i32(s
->tmp2_i32
, -1);
6875 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6878 /************************/
6879 /* bit operations */
6880 case 0x1ba: /* bt/bts/btr/btc Gv, im */
6882 modrm
= x86_ldub_code(env
, s
);
6883 op
= (modrm
>> 3) & 7;
6884 mod
= (modrm
>> 6) & 3;
6885 rm
= (modrm
& 7) | REX_B(s
);
6888 gen_lea_modrm(env
, s
, modrm
);
6889 if (!(s
->prefix
& PREFIX_LOCK
)) {
6890 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
6893 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
6896 val
= x86_ldub_code(env
, s
);
6897 tcg_gen_movi_tl(s
->T1
, val
);
6902 case 0x1a3: /* bt Gv, Ev */
6905 case 0x1ab: /* bts */
6908 case 0x1b3: /* btr */
6911 case 0x1bb: /* btc */
6915 modrm
= x86_ldub_code(env
, s
);
6916 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
6917 mod
= (modrm
>> 6) & 3;
6918 rm
= (modrm
& 7) | REX_B(s
);
6919 gen_op_mov_v_reg(s
, MO_32
, s
->T1
, reg
);
6921 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
6922 /* specific case: we need to add a displacement */
6923 gen_exts(ot
, s
->T1
);
6924 tcg_gen_sari_tl(s
->tmp0
, s
->T1
, 3 + ot
);
6925 tcg_gen_shli_tl(s
->tmp0
, s
->tmp0
, ot
);
6926 tcg_gen_add_tl(s
->A0
, gen_lea_modrm_1(s
, a
), s
->tmp0
);
6927 gen_lea_v_seg(s
, s
->aflag
, s
->A0
, a
.def_seg
, s
->override
);
6928 if (!(s
->prefix
& PREFIX_LOCK
)) {
6929 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
6932 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
6935 tcg_gen_andi_tl(s
->T1
, s
->T1
, (1 << (3 + ot
)) - 1);
6936 tcg_gen_movi_tl(s
->tmp0
, 1);
6937 tcg_gen_shl_tl(s
->tmp0
, s
->tmp0
, s
->T1
);
6938 if (s
->prefix
& PREFIX_LOCK
) {
6941 /* Needs no atomic ops; we surpressed the normal
6942 memory load for LOCK above so do it now. */
6943 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
6946 tcg_gen_atomic_fetch_or_tl(s
->T0
, s
->A0
, s
->tmp0
,
6947 s
->mem_index
, ot
| MO_LE
);
6950 tcg_gen_not_tl(s
->tmp0
, s
->tmp0
);
6951 tcg_gen_atomic_fetch_and_tl(s
->T0
, s
->A0
, s
->tmp0
,
6952 s
->mem_index
, ot
| MO_LE
);
6956 tcg_gen_atomic_fetch_xor_tl(s
->T0
, s
->A0
, s
->tmp0
,
6957 s
->mem_index
, ot
| MO_LE
);
6960 tcg_gen_shr_tl(s
->tmp4
, s
->T0
, s
->T1
);
6962 tcg_gen_shr_tl(s
->tmp4
, s
->T0
, s
->T1
);
6965 /* Data already loaded; nothing to do. */
6968 tcg_gen_or_tl(s
->T0
, s
->T0
, s
->tmp0
);
6971 tcg_gen_andc_tl(s
->T0
, s
->T0
, s
->tmp0
);
6975 tcg_gen_xor_tl(s
->T0
, s
->T0
, s
->tmp0
);
6980 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
6982 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
6987 /* Delay all CC updates until after the store above. Note that
6988 C is the result of the test, Z is unchanged, and the others
6989 are all undefined. */
6991 case CC_OP_MULB
... CC_OP_MULQ
:
6992 case CC_OP_ADDB
... CC_OP_ADDQ
:
6993 case CC_OP_ADCB
... CC_OP_ADCQ
:
6994 case CC_OP_SUBB
... CC_OP_SUBQ
:
6995 case CC_OP_SBBB
... CC_OP_SBBQ
:
6996 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
6997 case CC_OP_INCB
... CC_OP_INCQ
:
6998 case CC_OP_DECB
... CC_OP_DECQ
:
6999 case CC_OP_SHLB
... CC_OP_SHLQ
:
7000 case CC_OP_SARB
... CC_OP_SARQ
:
7001 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
7002 /* Z was going to be computed from the non-zero status of CC_DST.
7003 We can get that same Z value (and the new C value) by leaving
7004 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
7006 tcg_gen_mov_tl(cpu_cc_src
, s
->tmp4
);
7007 set_cc_op(s
, ((s
->cc_op
- CC_OP_MULB
) & 3) + CC_OP_SARB
);
7010 /* Otherwise, generate EFLAGS and replace the C bit. */
7011 gen_compute_eflags(s
);
7012 tcg_gen_deposit_tl(cpu_cc_src
, cpu_cc_src
, s
->tmp4
,
7017 case 0x1bc: /* bsf / tzcnt */
7018 case 0x1bd: /* bsr / lzcnt */
7020 modrm
= x86_ldub_code(env
, s
);
7021 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
7022 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
7023 gen_extu(ot
, s
->T0
);
7025 /* Note that lzcnt and tzcnt are in different extensions. */
7026 if ((prefixes
& PREFIX_REPZ
)
7028 ? s
->cpuid_ext3_features
& CPUID_EXT3_ABM
7029 : s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)) {
7031 /* For lzcnt/tzcnt, C bit is defined related to the input. */
7032 tcg_gen_mov_tl(cpu_cc_src
, s
->T0
);
7034 /* For lzcnt, reduce the target_ulong result by the
7035 number of zeros that we expect to find at the top. */
7036 tcg_gen_clzi_tl(s
->T0
, s
->T0
, TARGET_LONG_BITS
);
7037 tcg_gen_subi_tl(s
->T0
, s
->T0
, TARGET_LONG_BITS
- size
);
7039 /* For tzcnt, a zero input must return the operand size. */
7040 tcg_gen_ctzi_tl(s
->T0
, s
->T0
, size
);
7042 /* For lzcnt/tzcnt, Z bit is defined related to the result. */
7043 gen_op_update1_cc(s
);
7044 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
7046 /* For bsr/bsf, only the Z bit is defined and it is related
7047 to the input and not the result. */
7048 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
7049 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
7051 /* ??? The manual says that the output is undefined when the
7052 input is zero, but real hardware leaves it unchanged, and
7053 real programs appear to depend on that. Accomplish this
7054 by passing the output as the value to return upon zero. */
7056 /* For bsr, return the bit index of the first 1 bit,
7057 not the count of leading zeros. */
7058 tcg_gen_xori_tl(s
->T1
, cpu_regs
[reg
], TARGET_LONG_BITS
- 1);
7059 tcg_gen_clz_tl(s
->T0
, s
->T0
, s
->T1
);
7060 tcg_gen_xori_tl(s
->T0
, s
->T0
, TARGET_LONG_BITS
- 1);
7062 tcg_gen_ctz_tl(s
->T0
, s
->T0
, cpu_regs
[reg
]);
7065 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
7067 /************************/
7069 case 0x27: /* daa */
7072 gen_update_cc_op(s
);
7073 gen_helper_daa(cpu_env
);
7074 set_cc_op(s
, CC_OP_EFLAGS
);
7076 case 0x2f: /* das */
7079 gen_update_cc_op(s
);
7080 gen_helper_das(cpu_env
);
7081 set_cc_op(s
, CC_OP_EFLAGS
);
7083 case 0x37: /* aaa */
7086 gen_update_cc_op(s
);
7087 gen_helper_aaa(cpu_env
);
7088 set_cc_op(s
, CC_OP_EFLAGS
);
7090 case 0x3f: /* aas */
7093 gen_update_cc_op(s
);
7094 gen_helper_aas(cpu_env
);
7095 set_cc_op(s
, CC_OP_EFLAGS
);
7097 case 0xd4: /* aam */
7100 val
= x86_ldub_code(env
, s
);
7102 gen_exception(s
, EXCP00_DIVZ
, pc_start
- s
->cs_base
);
7104 gen_helper_aam(cpu_env
, tcg_const_i32(val
));
7105 set_cc_op(s
, CC_OP_LOGICB
);
7108 case 0xd5: /* aad */
7111 val
= x86_ldub_code(env
, s
);
7112 gen_helper_aad(cpu_env
, tcg_const_i32(val
));
7113 set_cc_op(s
, CC_OP_LOGICB
);
7115 /************************/
7117 case 0x90: /* nop */
7118 /* XXX: correct lock test for all insn */
7119 if (prefixes
& PREFIX_LOCK
) {
7122 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
7124 goto do_xchg_reg_eax
;
7126 if (prefixes
& PREFIX_REPZ
) {
7127 gen_update_cc_op(s
);
7128 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7129 gen_helper_pause(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7130 s
->base
.is_jmp
= DISAS_NORETURN
;
7133 case 0x9b: /* fwait */
7134 if ((s
->flags
& (HF_MP_MASK
| HF_TS_MASK
)) ==
7135 (HF_MP_MASK
| HF_TS_MASK
)) {
7136 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7138 gen_helper_fwait(cpu_env
);
7141 case 0xcc: /* int3 */
7142 gen_interrupt(s
, EXCP03_INT3
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
7144 case 0xcd: /* int N */
7145 val
= x86_ldub_code(env
, s
);
7146 if (check_vm86_iopl(s
)) {
7147 gen_interrupt(s
, val
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
7150 case 0xce: /* into */
7153 gen_update_cc_op(s
);
7154 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7155 gen_helper_into(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7158 case 0xf1: /* icebp (undocumented, exits to external debugger) */
7159 gen_svm_check_intercept(s
, SVM_EXIT_ICEBP
);
7163 case 0xfa: /* cli */
7164 if (check_iopl(s
)) {
7165 gen_helper_cli(cpu_env
);
7168 case 0xfb: /* sti */
7169 if (check_iopl(s
)) {
7170 gen_helper_sti(cpu_env
);
7171 /* interruptions are enabled only the first insn after sti */
7172 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7173 gen_eob_inhibit_irq(s
, true);
7176 case 0x62: /* bound */
7180 modrm
= x86_ldub_code(env
, s
);
7181 reg
= (modrm
>> 3) & 7;
7182 mod
= (modrm
>> 6) & 3;
7185 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
7186 gen_lea_modrm(env
, s
, modrm
);
7187 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
7189 gen_helper_boundw(cpu_env
, s
->A0
, s
->tmp2_i32
);
7191 gen_helper_boundl(cpu_env
, s
->A0
, s
->tmp2_i32
);
7194 case 0x1c8 ... 0x1cf: /* bswap reg */
7195 reg
= (b
& 7) | REX_B(s
);
7196 #ifdef TARGET_X86_64
7197 if (dflag
== MO_64
) {
7198 gen_op_mov_v_reg(s
, MO_64
, s
->T0
, reg
);
7199 tcg_gen_bswap64_i64(s
->T0
, s
->T0
);
7200 gen_op_mov_reg_v(s
, MO_64
, reg
, s
->T0
);
7204 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, reg
);
7205 tcg_gen_ext32u_tl(s
->T0
, s
->T0
);
7206 tcg_gen_bswap32_tl(s
->T0
, s
->T0
, TCG_BSWAP_IZ
| TCG_BSWAP_OZ
);
7207 gen_op_mov_reg_v(s
, MO_32
, reg
, s
->T0
);
7210 case 0xd6: /* salc */
7213 gen_compute_eflags_c(s
, s
->T0
);
7214 tcg_gen_neg_tl(s
->T0
, s
->T0
);
7215 gen_op_mov_reg_v(s
, MO_8
, R_EAX
, s
->T0
);
7217 case 0xe0: /* loopnz */
7218 case 0xe1: /* loopz */
7219 case 0xe2: /* loop */
7220 case 0xe3: /* jecxz */
7222 TCGLabel
*l1
, *l2
, *l3
;
7224 tval
= (int8_t)insn_get(env
, s
, MO_8
);
7225 next_eip
= s
->pc
- s
->cs_base
;
7227 if (dflag
== MO_16
) {
7231 l1
= gen_new_label();
7232 l2
= gen_new_label();
7233 l3
= gen_new_label();
7234 gen_update_cc_op(s
);
7237 case 0: /* loopnz */
7239 gen_op_add_reg_im(s
, s
->aflag
, R_ECX
, -1);
7240 gen_op_jz_ecx(s
, s
->aflag
, l3
);
7241 gen_jcc1(s
, (JCC_Z
<< 1) | (b
^ 1), l1
);
7244 gen_op_add_reg_im(s
, s
->aflag
, R_ECX
, -1);
7245 gen_op_jnz_ecx(s
, s
->aflag
, l1
);
7249 gen_op_jz_ecx(s
, s
->aflag
, l1
);
7254 gen_jmp_im(s
, next_eip
);
7258 gen_jmp_im(s
, tval
);
7263 case 0x130: /* wrmsr */
7264 case 0x132: /* rdmsr */
7265 if (check_cpl0(s
)) {
7266 gen_update_cc_op(s
);
7267 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7269 gen_helper_rdmsr(cpu_env
);
7271 gen_helper_wrmsr(cpu_env
);
7272 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7277 case 0x131: /* rdtsc */
7278 gen_update_cc_op(s
);
7279 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7280 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7283 gen_helper_rdtsc(cpu_env
);
7284 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7285 gen_jmp(s
, s
->pc
- s
->cs_base
);
7288 case 0x133: /* rdpmc */
7289 gen_update_cc_op(s
);
7290 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7291 gen_helper_rdpmc(cpu_env
);
7292 s
->base
.is_jmp
= DISAS_NORETURN
;
7294 case 0x134: /* sysenter */
7295 /* For Intel SYSENTER is valid on 64-bit */
7296 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7299 gen_exception_gpf(s
);
7301 gen_helper_sysenter(cpu_env
);
7305 case 0x135: /* sysexit */
7306 /* For Intel SYSEXIT is valid on 64-bit */
7307 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7310 gen_exception_gpf(s
);
7312 gen_helper_sysexit(cpu_env
, tcg_const_i32(dflag
- 1));
7316 #ifdef TARGET_X86_64
7317 case 0x105: /* syscall */
7318 /* XXX: is it usable in real mode ? */
7319 gen_update_cc_op(s
);
7320 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7321 gen_helper_syscall(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7322 /* TF handling for the syscall insn is different. The TF bit is checked
7323 after the syscall insn completes. This allows #DB to not be
7324 generated after one has entered CPL0 if TF is set in FMASK. */
7325 gen_eob_worker(s
, false, true);
7327 case 0x107: /* sysret */
7329 gen_exception_gpf(s
);
7331 gen_helper_sysret(cpu_env
, tcg_const_i32(dflag
- 1));
7332 /* condition codes are modified only in long mode */
7334 set_cc_op(s
, CC_OP_EFLAGS
);
7336 /* TF handling for the sysret insn is different. The TF bit is
7337 checked after the sysret insn completes. This allows #DB to be
7338 generated "as if" the syscall insn in userspace has just
7340 gen_eob_worker(s
, false, true);
7344 case 0x1a2: /* cpuid */
7345 gen_update_cc_op(s
);
7346 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7347 gen_helper_cpuid(cpu_env
);
7349 case 0xf4: /* hlt */
7350 if (check_cpl0(s
)) {
7351 gen_update_cc_op(s
);
7352 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7353 gen_helper_hlt(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7354 s
->base
.is_jmp
= DISAS_NORETURN
;
7358 modrm
= x86_ldub_code(env
, s
);
7359 mod
= (modrm
>> 6) & 3;
7360 op
= (modrm
>> 3) & 7;
7363 if (!PE(s
) || VM86(s
))
7365 gen_svm_check_intercept(s
, SVM_EXIT_LDTR_READ
);
7366 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
7367 offsetof(CPUX86State
, ldt
.selector
));
7368 ot
= mod
== 3 ? dflag
: MO_16
;
7369 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7372 if (!PE(s
) || VM86(s
))
7374 if (check_cpl0(s
)) {
7375 gen_svm_check_intercept(s
, SVM_EXIT_LDTR_WRITE
);
7376 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7377 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
7378 gen_helper_lldt(cpu_env
, s
->tmp2_i32
);
7382 if (!PE(s
) || VM86(s
))
7384 gen_svm_check_intercept(s
, SVM_EXIT_TR_READ
);
7385 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
7386 offsetof(CPUX86State
, tr
.selector
));
7387 ot
= mod
== 3 ? dflag
: MO_16
;
7388 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7391 if (!PE(s
) || VM86(s
))
7393 if (check_cpl0(s
)) {
7394 gen_svm_check_intercept(s
, SVM_EXIT_TR_WRITE
);
7395 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7396 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
7397 gen_helper_ltr(cpu_env
, s
->tmp2_i32
);
7402 if (!PE(s
) || VM86(s
))
7404 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7405 gen_update_cc_op(s
);
7407 gen_helper_verr(cpu_env
, s
->T0
);
7409 gen_helper_verw(cpu_env
, s
->T0
);
7411 set_cc_op(s
, CC_OP_EFLAGS
);
7419 modrm
= x86_ldub_code(env
, s
);
7421 CASE_MODRM_MEM_OP(0): /* sgdt */
7422 gen_svm_check_intercept(s
, SVM_EXIT_GDTR_READ
);
7423 gen_lea_modrm(env
, s
, modrm
);
7424 tcg_gen_ld32u_tl(s
->T0
,
7425 cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7426 gen_op_st_v(s
, MO_16
, s
->T0
, s
->A0
);
7427 gen_add_A0_im(s
, 2);
7428 tcg_gen_ld_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7429 if (dflag
== MO_16
) {
7430 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xffffff);
7432 gen_op_st_v(s
, CODE64(s
) + MO_32
, s
->T0
, s
->A0
);
7435 case 0xc8: /* monitor */
7436 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) || CPL(s
) != 0) {
7439 gen_update_cc_op(s
);
7440 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7441 tcg_gen_mov_tl(s
->A0
, cpu_regs
[R_EAX
]);
7442 gen_extu(s
->aflag
, s
->A0
);
7443 gen_add_A0_ds_seg(s
);
7444 gen_helper_monitor(cpu_env
, s
->A0
);
7447 case 0xc9: /* mwait */
7448 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) || CPL(s
) != 0) {
7451 gen_update_cc_op(s
);
7452 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7453 gen_helper_mwait(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7454 s
->base
.is_jmp
= DISAS_NORETURN
;
7457 case 0xca: /* clac */
7458 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
)
7462 gen_helper_clac(cpu_env
);
7463 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7467 case 0xcb: /* stac */
7468 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
)
7472 gen_helper_stac(cpu_env
);
7473 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7477 CASE_MODRM_MEM_OP(1): /* sidt */
7478 gen_svm_check_intercept(s
, SVM_EXIT_IDTR_READ
);
7479 gen_lea_modrm(env
, s
, modrm
);
7480 tcg_gen_ld32u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7481 gen_op_st_v(s
, MO_16
, s
->T0
, s
->A0
);
7482 gen_add_A0_im(s
, 2);
7483 tcg_gen_ld_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, idt
.base
));
7484 if (dflag
== MO_16
) {
7485 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xffffff);
7487 gen_op_st_v(s
, CODE64(s
) + MO_32
, s
->T0
, s
->A0
);
7490 case 0xd0: /* xgetbv */
7491 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
7492 || (s
->prefix
& (PREFIX_LOCK
| PREFIX_DATA
7493 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
7496 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_ECX
]);
7497 gen_helper_xgetbv(s
->tmp1_i64
, cpu_env
, s
->tmp2_i32
);
7498 tcg_gen_extr_i64_tl(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
], s
->tmp1_i64
);
7501 case 0xd1: /* xsetbv */
7502 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
7503 || (s
->prefix
& (PREFIX_LOCK
| PREFIX_DATA
7504 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
7507 if (!check_cpl0(s
)) {
7510 tcg_gen_concat_tl_i64(s
->tmp1_i64
, cpu_regs
[R_EAX
],
7512 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_ECX
]);
7513 gen_helper_xsetbv(cpu_env
, s
->tmp2_i32
, s
->tmp1_i64
);
7514 /* End TB because translation flags may change. */
7515 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7519 case 0xd8: /* VMRUN */
7520 if (!SVME(s
) || !PE(s
)) {
7523 if (!check_cpl0(s
)) {
7526 gen_update_cc_op(s
);
7527 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7528 gen_helper_vmrun(cpu_env
, tcg_const_i32(s
->aflag
- 1),
7529 tcg_const_i32(s
->pc
- pc_start
));
7530 tcg_gen_exit_tb(NULL
, 0);
7531 s
->base
.is_jmp
= DISAS_NORETURN
;
7534 case 0xd9: /* VMMCALL */
7538 gen_update_cc_op(s
);
7539 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7540 gen_helper_vmmcall(cpu_env
);
7543 case 0xda: /* VMLOAD */
7544 if (!SVME(s
) || !PE(s
)) {
7547 if (!check_cpl0(s
)) {
7550 gen_update_cc_op(s
);
7551 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7552 gen_helper_vmload(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7555 case 0xdb: /* VMSAVE */
7556 if (!SVME(s
) || !PE(s
)) {
7559 if (!check_cpl0(s
)) {
7562 gen_update_cc_op(s
);
7563 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7564 gen_helper_vmsave(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7567 case 0xdc: /* STGI */
7568 if ((!SVME(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
))
7572 if (!check_cpl0(s
)) {
7575 gen_update_cc_op(s
);
7576 gen_helper_stgi(cpu_env
);
7577 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7581 case 0xdd: /* CLGI */
7582 if (!SVME(s
) || !PE(s
)) {
7585 if (!check_cpl0(s
)) {
7588 gen_update_cc_op(s
);
7589 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7590 gen_helper_clgi(cpu_env
);
7593 case 0xde: /* SKINIT */
7594 if ((!SVME(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
))
7598 gen_svm_check_intercept(s
, SVM_EXIT_SKINIT
);
7599 /* If not intercepted, not implemented -- raise #UD. */
7602 case 0xdf: /* INVLPGA */
7603 if (!SVME(s
) || !PE(s
)) {
7606 if (!check_cpl0(s
)) {
7609 gen_svm_check_intercept(s
, SVM_EXIT_INVLPGA
);
7610 if (s
->aflag
== MO_64
) {
7611 tcg_gen_mov_tl(s
->A0
, cpu_regs
[R_EAX
]);
7613 tcg_gen_ext32u_tl(s
->A0
, cpu_regs
[R_EAX
]);
7615 gen_helper_flush_page(cpu_env
, s
->A0
);
7616 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7620 CASE_MODRM_MEM_OP(2): /* lgdt */
7621 if (!check_cpl0(s
)) {
7624 gen_svm_check_intercept(s
, SVM_EXIT_GDTR_WRITE
);
7625 gen_lea_modrm(env
, s
, modrm
);
7626 gen_op_ld_v(s
, MO_16
, s
->T1
, s
->A0
);
7627 gen_add_A0_im(s
, 2);
7628 gen_op_ld_v(s
, CODE64(s
) + MO_32
, s
->T0
, s
->A0
);
7629 if (dflag
== MO_16
) {
7630 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xffffff);
7632 tcg_gen_st_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7633 tcg_gen_st32_tl(s
->T1
, cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7636 CASE_MODRM_MEM_OP(3): /* lidt */
7637 if (!check_cpl0(s
)) {
7640 gen_svm_check_intercept(s
, SVM_EXIT_IDTR_WRITE
);
7641 gen_lea_modrm(env
, s
, modrm
);
7642 gen_op_ld_v(s
, MO_16
, s
->T1
, s
->A0
);
7643 gen_add_A0_im(s
, 2);
7644 gen_op_ld_v(s
, CODE64(s
) + MO_32
, s
->T0
, s
->A0
);
7645 if (dflag
== MO_16
) {
7646 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xffffff);
7648 tcg_gen_st_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, idt
.base
));
7649 tcg_gen_st32_tl(s
->T1
, cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7652 CASE_MODRM_OP(4): /* smsw */
7653 gen_svm_check_intercept(s
, SVM_EXIT_READ_CR0
);
7654 tcg_gen_ld_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, cr
[0]));
7656 * In 32-bit mode, the higher 16 bits of the destination
7657 * register are undefined. In practice CR0[31:0] is stored
7658 * just like in 64-bit mode.
7660 mod
= (modrm
>> 6) & 3;
7661 ot
= (mod
!= 3 ? MO_16
: s
->dflag
);
7662 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7664 case 0xee: /* rdpkru */
7665 if (prefixes
& PREFIX_LOCK
) {
7668 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_ECX
]);
7669 gen_helper_rdpkru(s
->tmp1_i64
, cpu_env
, s
->tmp2_i32
);
7670 tcg_gen_extr_i64_tl(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
], s
->tmp1_i64
);
7672 case 0xef: /* wrpkru */
7673 if (prefixes
& PREFIX_LOCK
) {
7676 tcg_gen_concat_tl_i64(s
->tmp1_i64
, cpu_regs
[R_EAX
],
7678 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_ECX
]);
7679 gen_helper_wrpkru(cpu_env
, s
->tmp2_i32
, s
->tmp1_i64
);
7682 CASE_MODRM_OP(6): /* lmsw */
7683 if (!check_cpl0(s
)) {
7686 gen_svm_check_intercept(s
, SVM_EXIT_WRITE_CR0
);
7687 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7689 * Only the 4 lower bits of CR0 are modified.
7690 * PE cannot be set to zero if already set to one.
7692 tcg_gen_ld_tl(s
->T1
, cpu_env
, offsetof(CPUX86State
, cr
[0]));
7693 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xf);
7694 tcg_gen_andi_tl(s
->T1
, s
->T1
, ~0xe);
7695 tcg_gen_or_tl(s
->T0
, s
->T0
, s
->T1
);
7696 gen_helper_write_crN(cpu_env
, tcg_constant_i32(0), s
->T0
);
7697 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7701 CASE_MODRM_MEM_OP(7): /* invlpg */
7702 if (!check_cpl0(s
)) {
7705 gen_svm_check_intercept(s
, SVM_EXIT_INVLPG
);
7706 gen_lea_modrm(env
, s
, modrm
);
7707 gen_helper_flush_page(cpu_env
, s
->A0
);
7708 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7712 case 0xf8: /* swapgs */
7713 #ifdef TARGET_X86_64
7715 if (check_cpl0(s
)) {
7716 tcg_gen_mov_tl(s
->T0
, cpu_seg_base
[R_GS
]);
7717 tcg_gen_ld_tl(cpu_seg_base
[R_GS
], cpu_env
,
7718 offsetof(CPUX86State
, kernelgsbase
));
7719 tcg_gen_st_tl(s
->T0
, cpu_env
,
7720 offsetof(CPUX86State
, kernelgsbase
));
7727 case 0xf9: /* rdtscp */
7728 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_RDTSCP
)) {
7731 gen_update_cc_op(s
);
7732 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7733 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7736 gen_helper_rdtscp(cpu_env
);
7737 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7738 gen_jmp(s
, s
->pc
- s
->cs_base
);
7747 case 0x108: /* invd */
7748 case 0x109: /* wbinvd */
7749 if (check_cpl0(s
)) {
7750 gen_svm_check_intercept(s
, (b
& 2) ? SVM_EXIT_INVD
: SVM_EXIT_WBINVD
);
7754 case 0x63: /* arpl or movslS (x86_64) */
7755 #ifdef TARGET_X86_64
7758 /* d_ot is the size of destination */
7761 modrm
= x86_ldub_code(env
, s
);
7762 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
7763 mod
= (modrm
>> 6) & 3;
7764 rm
= (modrm
& 7) | REX_B(s
);
7767 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, rm
);
7769 if (d_ot
== MO_64
) {
7770 tcg_gen_ext32s_tl(s
->T0
, s
->T0
);
7772 gen_op_mov_reg_v(s
, d_ot
, reg
, s
->T0
);
7774 gen_lea_modrm(env
, s
, modrm
);
7775 gen_op_ld_v(s
, MO_32
| MO_SIGN
, s
->T0
, s
->A0
);
7776 gen_op_mov_reg_v(s
, d_ot
, reg
, s
->T0
);
7782 TCGv t0
, t1
, t2
, a0
;
7784 if (!PE(s
) || VM86(s
))
7786 t0
= tcg_temp_local_new();
7787 t1
= tcg_temp_local_new();
7788 t2
= tcg_temp_local_new();
7790 modrm
= x86_ldub_code(env
, s
);
7791 reg
= (modrm
>> 3) & 7;
7792 mod
= (modrm
>> 6) & 3;
7795 gen_lea_modrm(env
, s
, modrm
);
7796 gen_op_ld_v(s
, ot
, t0
, s
->A0
);
7797 a0
= tcg_temp_local_new();
7798 tcg_gen_mov_tl(a0
, s
->A0
);
7800 gen_op_mov_v_reg(s
, ot
, t0
, rm
);
7803 gen_op_mov_v_reg(s
, ot
, t1
, reg
);
7804 tcg_gen_andi_tl(s
->tmp0
, t0
, 3);
7805 tcg_gen_andi_tl(t1
, t1
, 3);
7806 tcg_gen_movi_tl(t2
, 0);
7807 label1
= gen_new_label();
7808 tcg_gen_brcond_tl(TCG_COND_GE
, s
->tmp0
, t1
, label1
);
7809 tcg_gen_andi_tl(t0
, t0
, ~3);
7810 tcg_gen_or_tl(t0
, t0
, t1
);
7811 tcg_gen_movi_tl(t2
, CC_Z
);
7812 gen_set_label(label1
);
7814 gen_op_st_v(s
, ot
, t0
, a0
);
7817 gen_op_mov_reg_v(s
, ot
, rm
, t0
);
7819 gen_compute_eflags(s
);
7820 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_Z
);
7821 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, t2
);
7827 case 0x102: /* lar */
7828 case 0x103: /* lsl */
7832 if (!PE(s
) || VM86(s
))
7834 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
7835 modrm
= x86_ldub_code(env
, s
);
7836 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
7837 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7838 t0
= tcg_temp_local_new();
7839 gen_update_cc_op(s
);
7841 gen_helper_lar(t0
, cpu_env
, s
->T0
);
7843 gen_helper_lsl(t0
, cpu_env
, s
->T0
);
7845 tcg_gen_andi_tl(s
->tmp0
, cpu_cc_src
, CC_Z
);
7846 label1
= gen_new_label();
7847 tcg_gen_brcondi_tl(TCG_COND_EQ
, s
->tmp0
, 0, label1
);
7848 gen_op_mov_reg_v(s
, ot
, reg
, t0
);
7849 gen_set_label(label1
);
7850 set_cc_op(s
, CC_OP_EFLAGS
);
7855 modrm
= x86_ldub_code(env
, s
);
7856 mod
= (modrm
>> 6) & 3;
7857 op
= (modrm
>> 3) & 7;
7859 case 0: /* prefetchnta */
7860 case 1: /* prefetchnt0 */
7861 case 2: /* prefetchnt0 */
7862 case 3: /* prefetchnt0 */
7865 gen_nop_modrm(env
, s
, modrm
);
7866 /* nothing more to do */
7868 default: /* nop (multi byte) */
7869 gen_nop_modrm(env
, s
, modrm
);
7874 modrm
= x86_ldub_code(env
, s
);
7875 if (s
->flags
& HF_MPX_EN_MASK
) {
7876 mod
= (modrm
>> 6) & 3;
7877 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
7878 if (prefixes
& PREFIX_REPZ
) {
7881 || (prefixes
& PREFIX_LOCK
)
7882 || s
->aflag
== MO_16
) {
7885 gen_bndck(env
, s
, modrm
, TCG_COND_LTU
, cpu_bndl
[reg
]);
7886 } else if (prefixes
& PREFIX_REPNZ
) {
7889 || (prefixes
& PREFIX_LOCK
)
7890 || s
->aflag
== MO_16
) {
7893 TCGv_i64 notu
= tcg_temp_new_i64();
7894 tcg_gen_not_i64(notu
, cpu_bndu
[reg
]);
7895 gen_bndck(env
, s
, modrm
, TCG_COND_GTU
, notu
);
7896 tcg_temp_free_i64(notu
);
7897 } else if (prefixes
& PREFIX_DATA
) {
7898 /* bndmov -- from reg/mem */
7899 if (reg
>= 4 || s
->aflag
== MO_16
) {
7903 int reg2
= (modrm
& 7) | REX_B(s
);
7904 if (reg2
>= 4 || (prefixes
& PREFIX_LOCK
)) {
7907 if (s
->flags
& HF_MPX_IU_MASK
) {
7908 tcg_gen_mov_i64(cpu_bndl
[reg
], cpu_bndl
[reg2
]);
7909 tcg_gen_mov_i64(cpu_bndu
[reg
], cpu_bndu
[reg2
]);
7912 gen_lea_modrm(env
, s
, modrm
);
7914 tcg_gen_qemu_ld_i64(cpu_bndl
[reg
], s
->A0
,
7915 s
->mem_index
, MO_LEQ
);
7916 tcg_gen_addi_tl(s
->A0
, s
->A0
, 8);
7917 tcg_gen_qemu_ld_i64(cpu_bndu
[reg
], s
->A0
,
7918 s
->mem_index
, MO_LEQ
);
7920 tcg_gen_qemu_ld_i64(cpu_bndl
[reg
], s
->A0
,
7921 s
->mem_index
, MO_LEUL
);
7922 tcg_gen_addi_tl(s
->A0
, s
->A0
, 4);
7923 tcg_gen_qemu_ld_i64(cpu_bndu
[reg
], s
->A0
,
7924 s
->mem_index
, MO_LEUL
);
7926 /* bnd registers are now in-use */
7927 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7929 } else if (mod
!= 3) {
7931 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7933 || (prefixes
& PREFIX_LOCK
)
7934 || s
->aflag
== MO_16
7939 tcg_gen_addi_tl(s
->A0
, cpu_regs
[a
.base
], a
.disp
);
7941 tcg_gen_movi_tl(s
->A0
, 0);
7943 gen_lea_v_seg(s
, s
->aflag
, s
->A0
, a
.def_seg
, s
->override
);
7945 tcg_gen_mov_tl(s
->T0
, cpu_regs
[a
.index
]);
7947 tcg_gen_movi_tl(s
->T0
, 0);
7950 gen_helper_bndldx64(cpu_bndl
[reg
], cpu_env
, s
->A0
, s
->T0
);
7951 tcg_gen_ld_i64(cpu_bndu
[reg
], cpu_env
,
7952 offsetof(CPUX86State
, mmx_t0
.MMX_Q(0)));
7954 gen_helper_bndldx32(cpu_bndu
[reg
], cpu_env
, s
->A0
, s
->T0
);
7955 tcg_gen_ext32u_i64(cpu_bndl
[reg
], cpu_bndu
[reg
]);
7956 tcg_gen_shri_i64(cpu_bndu
[reg
], cpu_bndu
[reg
], 32);
7958 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7961 gen_nop_modrm(env
, s
, modrm
);
7964 modrm
= x86_ldub_code(env
, s
);
7965 if (s
->flags
& HF_MPX_EN_MASK
) {
7966 mod
= (modrm
>> 6) & 3;
7967 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
7968 if (mod
!= 3 && (prefixes
& PREFIX_REPZ
)) {
7971 || (prefixes
& PREFIX_LOCK
)
7972 || s
->aflag
== MO_16
) {
7975 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7977 tcg_gen_extu_tl_i64(cpu_bndl
[reg
], cpu_regs
[a
.base
]);
7979 tcg_gen_ext32u_i64(cpu_bndl
[reg
], cpu_bndl
[reg
]);
7981 } else if (a
.base
== -1) {
7982 /* no base register has lower bound of 0 */
7983 tcg_gen_movi_i64(cpu_bndl
[reg
], 0);
7985 /* rip-relative generates #ud */
7988 tcg_gen_not_tl(s
->A0
, gen_lea_modrm_1(s
, a
));
7990 tcg_gen_ext32u_tl(s
->A0
, s
->A0
);
7992 tcg_gen_extu_tl_i64(cpu_bndu
[reg
], s
->A0
);
7993 /* bnd registers are now in-use */
7994 gen_set_hflag(s
, HF_MPX_IU_MASK
);
7996 } else if (prefixes
& PREFIX_REPNZ
) {
7999 || (prefixes
& PREFIX_LOCK
)
8000 || s
->aflag
== MO_16
) {
8003 gen_bndck(env
, s
, modrm
, TCG_COND_GTU
, cpu_bndu
[reg
]);
8004 } else if (prefixes
& PREFIX_DATA
) {
8005 /* bndmov -- to reg/mem */
8006 if (reg
>= 4 || s
->aflag
== MO_16
) {
8010 int reg2
= (modrm
& 7) | REX_B(s
);
8011 if (reg2
>= 4 || (prefixes
& PREFIX_LOCK
)) {
8014 if (s
->flags
& HF_MPX_IU_MASK
) {
8015 tcg_gen_mov_i64(cpu_bndl
[reg2
], cpu_bndl
[reg
]);
8016 tcg_gen_mov_i64(cpu_bndu
[reg2
], cpu_bndu
[reg
]);
8019 gen_lea_modrm(env
, s
, modrm
);
8021 tcg_gen_qemu_st_i64(cpu_bndl
[reg
], s
->A0
,
8022 s
->mem_index
, MO_LEQ
);
8023 tcg_gen_addi_tl(s
->A0
, s
->A0
, 8);
8024 tcg_gen_qemu_st_i64(cpu_bndu
[reg
], s
->A0
,
8025 s
->mem_index
, MO_LEQ
);
8027 tcg_gen_qemu_st_i64(cpu_bndl
[reg
], s
->A0
,
8028 s
->mem_index
, MO_LEUL
);
8029 tcg_gen_addi_tl(s
->A0
, s
->A0
, 4);
8030 tcg_gen_qemu_st_i64(cpu_bndu
[reg
], s
->A0
,
8031 s
->mem_index
, MO_LEUL
);
8034 } else if (mod
!= 3) {
8036 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
8038 || (prefixes
& PREFIX_LOCK
)
8039 || s
->aflag
== MO_16
8044 tcg_gen_addi_tl(s
->A0
, cpu_regs
[a
.base
], a
.disp
);
8046 tcg_gen_movi_tl(s
->A0
, 0);
8048 gen_lea_v_seg(s
, s
->aflag
, s
->A0
, a
.def_seg
, s
->override
);
8050 tcg_gen_mov_tl(s
->T0
, cpu_regs
[a
.index
]);
8052 tcg_gen_movi_tl(s
->T0
, 0);
8055 gen_helper_bndstx64(cpu_env
, s
->A0
, s
->T0
,
8056 cpu_bndl
[reg
], cpu_bndu
[reg
]);
8058 gen_helper_bndstx32(cpu_env
, s
->A0
, s
->T0
,
8059 cpu_bndl
[reg
], cpu_bndu
[reg
]);
8063 gen_nop_modrm(env
, s
, modrm
);
8065 case 0x119: case 0x11c ... 0x11f: /* nop (multi byte) */
8066 modrm
= x86_ldub_code(env
, s
);
8067 gen_nop_modrm(env
, s
, modrm
);
8070 case 0x120: /* mov reg, crN */
8071 case 0x122: /* mov crN, reg */
8072 if (!check_cpl0(s
)) {
8075 modrm
= x86_ldub_code(env
, s
);
8077 * Ignore the mod bits (assume (modrm&0xc0)==0xc0).
8078 * AMD documentation (24594.pdf) and testing of Intel 386 and 486
8079 * processors all show that the mod bits are assumed to be 1's,
8080 * regardless of actual values.
8082 rm
= (modrm
& 7) | REX_B(s
);
8083 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
8086 if ((prefixes
& PREFIX_LOCK
) &&
8087 (s
->cpuid_ext3_features
& CPUID_EXT3_CR8LEG
)) {
8099 ot
= (CODE64(s
) ? MO_64
: MO_32
);
8101 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
8105 gen_svm_check_intercept(s
, SVM_EXIT_WRITE_CR0
+ reg
);
8106 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
8107 gen_helper_write_crN(cpu_env
, tcg_constant_i32(reg
), s
->T0
);
8108 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8111 gen_svm_check_intercept(s
, SVM_EXIT_READ_CR0
+ reg
);
8112 gen_helper_read_crN(s
->T0
, cpu_env
, tcg_constant_i32(reg
));
8113 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
8114 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
8115 gen_jmp(s
, s
->pc
- s
->cs_base
);
8120 case 0x121: /* mov reg, drN */
8121 case 0x123: /* mov drN, reg */
8122 if (check_cpl0(s
)) {
8123 modrm
= x86_ldub_code(env
, s
);
8124 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
8125 * AMD documentation (24594.pdf) and testing of
8126 * intel 386 and 486 processors all show that the mod bits
8127 * are assumed to be 1's, regardless of actual values.
8129 rm
= (modrm
& 7) | REX_B(s
);
8130 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
8139 gen_svm_check_intercept(s
, SVM_EXIT_WRITE_DR0
+ reg
);
8140 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
8141 tcg_gen_movi_i32(s
->tmp2_i32
, reg
);
8142 gen_helper_set_dr(cpu_env
, s
->tmp2_i32
, s
->T0
);
8143 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8146 gen_svm_check_intercept(s
, SVM_EXIT_READ_DR0
+ reg
);
8147 tcg_gen_movi_i32(s
->tmp2_i32
, reg
);
8148 gen_helper_get_dr(s
->T0
, cpu_env
, s
->tmp2_i32
);
8149 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
8153 case 0x106: /* clts */
8154 if (check_cpl0(s
)) {
8155 gen_svm_check_intercept(s
, SVM_EXIT_WRITE_CR0
);
8156 gen_helper_clts(cpu_env
);
8157 /* abort block because static cpu state changed */
8158 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8162 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
8163 case 0x1c3: /* MOVNTI reg, mem */
8164 if (!(s
->cpuid_features
& CPUID_SSE2
))
8166 ot
= mo_64_32(dflag
);
8167 modrm
= x86_ldub_code(env
, s
);
8168 mod
= (modrm
>> 6) & 3;
8171 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
8172 /* generate a generic store */
8173 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
8176 modrm
= x86_ldub_code(env
, s
);
8178 CASE_MODRM_MEM_OP(0): /* fxsave */
8179 if (!(s
->cpuid_features
& CPUID_FXSR
)
8180 || (prefixes
& PREFIX_LOCK
)) {
8183 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
8184 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8187 gen_lea_modrm(env
, s
, modrm
);
8188 gen_helper_fxsave(cpu_env
, s
->A0
);
8191 CASE_MODRM_MEM_OP(1): /* fxrstor */
8192 if (!(s
->cpuid_features
& CPUID_FXSR
)
8193 || (prefixes
& PREFIX_LOCK
)) {
8196 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
8197 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8200 gen_lea_modrm(env
, s
, modrm
);
8201 gen_helper_fxrstor(cpu_env
, s
->A0
);
8204 CASE_MODRM_MEM_OP(2): /* ldmxcsr */
8205 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
)) {
8208 if (s
->flags
& HF_TS_MASK
) {
8209 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8212 gen_lea_modrm(env
, s
, modrm
);
8213 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
, s
->mem_index
, MO_LEUL
);
8214 gen_helper_ldmxcsr(cpu_env
, s
->tmp2_i32
);
8217 CASE_MODRM_MEM_OP(3): /* stmxcsr */
8218 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
)) {
8221 if (s
->flags
& HF_TS_MASK
) {
8222 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8225 gen_helper_update_mxcsr(cpu_env
);
8226 gen_lea_modrm(env
, s
, modrm
);
8227 tcg_gen_ld32u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, mxcsr
));
8228 gen_op_st_v(s
, MO_32
, s
->T0
, s
->A0
);
8231 CASE_MODRM_MEM_OP(4): /* xsave */
8232 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8233 || (prefixes
& (PREFIX_LOCK
| PREFIX_DATA
8234 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
8237 gen_lea_modrm(env
, s
, modrm
);
8238 tcg_gen_concat_tl_i64(s
->tmp1_i64
, cpu_regs
[R_EAX
],
8240 gen_helper_xsave(cpu_env
, s
->A0
, s
->tmp1_i64
);
8243 CASE_MODRM_MEM_OP(5): /* xrstor */
8244 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8245 || (prefixes
& (PREFIX_LOCK
| PREFIX_DATA
8246 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
8249 gen_lea_modrm(env
, s
, modrm
);
8250 tcg_gen_concat_tl_i64(s
->tmp1_i64
, cpu_regs
[R_EAX
],
8252 gen_helper_xrstor(cpu_env
, s
->A0
, s
->tmp1_i64
);
8253 /* XRSTOR is how MPX is enabled, which changes how
8254 we translate. Thus we need to end the TB. */
8255 gen_update_cc_op(s
);
8256 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8260 CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */
8261 if (prefixes
& PREFIX_LOCK
) {
8264 if (prefixes
& PREFIX_DATA
) {
8266 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLWB
)) {
8269 gen_nop_modrm(env
, s
, modrm
);
8272 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8273 || (s
->cpuid_xsave_features
& CPUID_XSAVE_XSAVEOPT
) == 0
8274 || (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
))) {
8277 gen_lea_modrm(env
, s
, modrm
);
8278 tcg_gen_concat_tl_i64(s
->tmp1_i64
, cpu_regs
[R_EAX
],
8280 gen_helper_xsaveopt(cpu_env
, s
->A0
, s
->tmp1_i64
);
8284 CASE_MODRM_MEM_OP(7): /* clflush / clflushopt */
8285 if (prefixes
& PREFIX_LOCK
) {
8288 if (prefixes
& PREFIX_DATA
) {
8290 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLFLUSHOPT
)) {
8295 if ((s
->prefix
& (PREFIX_REPZ
| PREFIX_REPNZ
))
8296 || !(s
->cpuid_features
& CPUID_CLFLUSH
)) {
8300 gen_nop_modrm(env
, s
, modrm
);
8303 case 0xc0 ... 0xc7: /* rdfsbase (f3 0f ae /0) */
8304 case 0xc8 ... 0xcf: /* rdgsbase (f3 0f ae /1) */
8305 case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */
8306 case 0xd8 ... 0xdf: /* wrgsbase (f3 0f ae /3) */
8308 && (prefixes
& PREFIX_REPZ
)
8309 && !(prefixes
& PREFIX_LOCK
)
8310 && (s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_FSGSBASE
)) {
8311 TCGv base
, treg
, src
, dst
;
8313 /* Preserve hflags bits by testing CR4 at runtime. */
8314 tcg_gen_movi_i32(s
->tmp2_i32
, CR4_FSGSBASE_MASK
);
8315 gen_helper_cr4_testbit(cpu_env
, s
->tmp2_i32
);
8317 base
= cpu_seg_base
[modrm
& 8 ? R_GS
: R_FS
];
8318 treg
= cpu_regs
[(modrm
& 7) | REX_B(s
)];
8322 dst
= base
, src
= treg
;
8325 dst
= treg
, src
= base
;
8328 if (s
->dflag
== MO_32
) {
8329 tcg_gen_ext32u_tl(dst
, src
);
8331 tcg_gen_mov_tl(dst
, src
);
8337 case 0xf8: /* sfence / pcommit */
8338 if (prefixes
& PREFIX_DATA
) {
8340 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_PCOMMIT
)
8341 || (prefixes
& PREFIX_LOCK
)) {
8347 case 0xf9 ... 0xff: /* sfence */
8348 if (!(s
->cpuid_features
& CPUID_SSE
)
8349 || (prefixes
& PREFIX_LOCK
)) {
8352 tcg_gen_mb(TCG_MO_ST_ST
| TCG_BAR_SC
);
8354 case 0xe8 ... 0xef: /* lfence */
8355 if (!(s
->cpuid_features
& CPUID_SSE
)
8356 || (prefixes
& PREFIX_LOCK
)) {
8359 tcg_gen_mb(TCG_MO_LD_LD
| TCG_BAR_SC
);
8361 case 0xf0 ... 0xf7: /* mfence */
8362 if (!(s
->cpuid_features
& CPUID_SSE2
)
8363 || (prefixes
& PREFIX_LOCK
)) {
8366 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8374 case 0x10d: /* 3DNow! prefetch(w) */
8375 modrm
= x86_ldub_code(env
, s
);
8376 mod
= (modrm
>> 6) & 3;
8379 gen_nop_modrm(env
, s
, modrm
);
8381 case 0x1aa: /* rsm */
8382 gen_svm_check_intercept(s
, SVM_EXIT_RSM
);
8383 if (!(s
->flags
& HF_SMM_MASK
))
8385 #ifdef CONFIG_USER_ONLY
8386 /* we should not be in SMM mode */
8387 g_assert_not_reached();
8389 gen_update_cc_op(s
);
8390 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8391 gen_helper_rsm(cpu_env
);
8392 #endif /* CONFIG_USER_ONLY */
8395 case 0x1b8: /* SSE4.2 popcnt */
8396 if ((prefixes
& (PREFIX_REPZ
| PREFIX_LOCK
| PREFIX_REPNZ
)) !=
8399 if (!(s
->cpuid_ext_features
& CPUID_EXT_POPCNT
))
8402 modrm
= x86_ldub_code(env
, s
);
8403 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
8405 if (s
->prefix
& PREFIX_DATA
) {
8408 ot
= mo_64_32(dflag
);
8411 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
8412 gen_extu(ot
, s
->T0
);
8413 tcg_gen_mov_tl(cpu_cc_src
, s
->T0
);
8414 tcg_gen_ctpop_tl(s
->T0
, s
->T0
);
8415 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
8417 set_cc_op(s
, CC_OP_POPCNT
);
8419 case 0x10e ... 0x10f:
8420 /* 3DNow! instructions, ignore prefixes */
8421 s
->prefix
&= ~(PREFIX_REPZ
| PREFIX_REPNZ
| PREFIX_DATA
);
8423 case 0x110 ... 0x117:
8424 case 0x128 ... 0x12f:
8425 case 0x138 ... 0x13a:
8426 case 0x150 ... 0x179:
8427 case 0x17c ... 0x17f:
8429 case 0x1c4 ... 0x1c6:
8430 case 0x1d0 ... 0x1fe:
8431 gen_sse(env
, s
, b
, pc_start
);
8438 gen_illegal_opcode(s
);
8441 gen_unknown_opcode(env
, s
);
8445 void tcg_x86_init(void)
8447 static const char reg_names
[CPU_NB_REGS
][4] = {
8448 #ifdef TARGET_X86_64
8476 static const char seg_base_names
[6][8] = {
8484 static const char bnd_regl_names
[4][8] = {
8485 "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb"
8487 static const char bnd_regu_names
[4][8] = {
8488 "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub"
8492 cpu_cc_op
= tcg_global_mem_new_i32(cpu_env
,
8493 offsetof(CPUX86State
, cc_op
), "cc_op");
8494 cpu_cc_dst
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_dst
),
8496 cpu_cc_src
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_src
),
8498 cpu_cc_src2
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_src2
),
8501 for (i
= 0; i
< CPU_NB_REGS
; ++i
) {
8502 cpu_regs
[i
] = tcg_global_mem_new(cpu_env
,
8503 offsetof(CPUX86State
, regs
[i
]),
8507 for (i
= 0; i
< 6; ++i
) {
8509 = tcg_global_mem_new(cpu_env
,
8510 offsetof(CPUX86State
, segs
[i
].base
),
8514 for (i
= 0; i
< 4; ++i
) {
8516 = tcg_global_mem_new_i64(cpu_env
,
8517 offsetof(CPUX86State
, bnd_regs
[i
].lb
),
8520 = tcg_global_mem_new_i64(cpu_env
,
8521 offsetof(CPUX86State
, bnd_regs
[i
].ub
),
8526 static void i386_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cpu
)
8528 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8529 CPUX86State
*env
= cpu
->env_ptr
;
8530 uint32_t flags
= dc
->base
.tb
->flags
;
8531 int cpl
= (flags
>> HF_CPL_SHIFT
) & 3;
8532 int iopl
= (flags
>> IOPL_SHIFT
) & 3;
8534 dc
->cs_base
= dc
->base
.tb
->cs_base
;
8536 #ifndef CONFIG_USER_ONLY
8541 /* We make some simplifying assumptions; validate they're correct. */
8542 g_assert(PE(dc
) == ((flags
& HF_PE_MASK
) != 0));
8543 g_assert(CPL(dc
) == cpl
);
8544 g_assert(IOPL(dc
) == iopl
);
8545 g_assert(VM86(dc
) == ((flags
& HF_VM_MASK
) != 0));
8546 g_assert(CODE32(dc
) == ((flags
& HF_CS32_MASK
) != 0));
8547 g_assert(CODE64(dc
) == ((flags
& HF_CS64_MASK
) != 0));
8548 g_assert(SS32(dc
) == ((flags
& HF_SS32_MASK
) != 0));
8549 g_assert(LMA(dc
) == ((flags
& HF_LMA_MASK
) != 0));
8550 g_assert(ADDSEG(dc
) == ((flags
& HF_ADDSEG_MASK
) != 0));
8551 g_assert(SVME(dc
) == ((flags
& HF_SVME_MASK
) != 0));
8552 g_assert(GUEST(dc
) == ((flags
& HF_GUEST_MASK
) != 0));
8554 dc
->cc_op
= CC_OP_DYNAMIC
;
8555 dc
->cc_op_dirty
= false;
8556 dc
->popl_esp_hack
= 0;
8557 /* select memory access functions */
8559 #ifdef CONFIG_SOFTMMU
8560 dc
->mem_index
= cpu_mmu_index(env
, false);
8562 dc
->cpuid_features
= env
->features
[FEAT_1_EDX
];
8563 dc
->cpuid_ext_features
= env
->features
[FEAT_1_ECX
];
8564 dc
->cpuid_ext2_features
= env
->features
[FEAT_8000_0001_EDX
];
8565 dc
->cpuid_ext3_features
= env
->features
[FEAT_8000_0001_ECX
];
8566 dc
->cpuid_7_0_ebx_features
= env
->features
[FEAT_7_0_EBX
];
8567 dc
->cpuid_xsave_features
= env
->features
[FEAT_XSAVE
];
8568 dc
->jmp_opt
= !(dc
->base
.singlestep_enabled
||
8569 (flags
& (HF_TF_MASK
| HF_INHIBIT_IRQ_MASK
)));
8571 * If jmp_opt, we want to handle each string instruction individually.
8572 * For icount also disable repz optimization so that each iteration
8573 * is accounted separately.
8575 dc
->repz_opt
= !dc
->jmp_opt
&& !(tb_cflags(dc
->base
.tb
) & CF_USE_ICOUNT
);
8577 dc
->T0
= tcg_temp_new();
8578 dc
->T1
= tcg_temp_new();
8579 dc
->A0
= tcg_temp_new();
8581 dc
->tmp0
= tcg_temp_new();
8582 dc
->tmp1_i64
= tcg_temp_new_i64();
8583 dc
->tmp2_i32
= tcg_temp_new_i32();
8584 dc
->tmp3_i32
= tcg_temp_new_i32();
8585 dc
->tmp4
= tcg_temp_new();
8586 dc
->ptr0
= tcg_temp_new_ptr();
8587 dc
->ptr1
= tcg_temp_new_ptr();
8588 dc
->cc_srcT
= tcg_temp_local_new();
8591 static void i386_tr_tb_start(DisasContextBase
*db
, CPUState
*cpu
)
8595 static void i386_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
8597 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8599 tcg_gen_insn_start(dc
->base
.pc_next
, dc
->cc_op
);
8602 static bool i386_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cpu
,
8603 const CPUBreakpoint
*bp
)
8605 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8606 /* If RF is set, suppress an internally generated breakpoint. */
8607 int flags
= dc
->base
.tb
->flags
& HF_RF_MASK
? BP_GDB
: BP_ANY
;
8608 if (bp
->flags
& flags
) {
8610 /* The address covered by the breakpoint must be included in
8611 [tb->pc, tb->pc + tb->size) in order to for it to be
8612 properly cleared -- thus we increment the PC here so that
8613 the generic logic setting tb->size later does the right thing. */
8614 dc
->base
.pc_next
+= 1;
8621 static void i386_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
8623 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8624 target_ulong pc_next
;
8626 #ifdef TARGET_VSYSCALL_PAGE
8628 * Detect entry into the vsyscall page and invoke the syscall.
8630 if ((dc
->base
.pc_next
& TARGET_PAGE_MASK
) == TARGET_VSYSCALL_PAGE
) {
8631 gen_exception(dc
, EXCP_VSYSCALL
, dc
->base
.pc_next
);
8632 dc
->base
.pc_next
= dc
->pc
+ 1;
8637 pc_next
= disas_insn(dc
, cpu
);
8639 if (dc
->flags
& (HF_TF_MASK
| HF_INHIBIT_IRQ_MASK
)) {
8640 /* if single step mode, we generate only one instruction and
8641 generate an exception */
8642 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
8643 the flag and abort the translation to give the irqs a
8645 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
8646 } else if ((tb_cflags(dc
->base
.tb
) & CF_USE_ICOUNT
)
8647 && ((pc_next
& TARGET_PAGE_MASK
)
8648 != ((pc_next
+ TARGET_MAX_INSN_SIZE
- 1)
8650 || (pc_next
& ~TARGET_PAGE_MASK
) == 0)) {
8651 /* Do not cross the boundary of the pages in icount mode,
8652 it can cause an exception. Do it only when boundary is
8653 crossed by the first instruction in the block.
8654 If current instruction already crossed the bound - it's ok,
8655 because an exception hasn't stopped this code.
8657 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
8658 } else if ((pc_next
- dc
->base
.pc_first
) >= (TARGET_PAGE_SIZE
- 32)) {
8659 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
8662 dc
->base
.pc_next
= pc_next
;
8665 static void i386_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cpu
)
8667 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8669 if (dc
->base
.is_jmp
== DISAS_TOO_MANY
) {
8670 gen_jmp_im(dc
, dc
->base
.pc_next
- dc
->cs_base
);
8675 static void i386_tr_disas_log(const DisasContextBase
*dcbase
,
8678 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8680 qemu_log("IN: %s\n", lookup_symbol(dc
->base
.pc_first
));
8681 log_target_disas(cpu
, dc
->base
.pc_first
, dc
->base
.tb
->size
);
8684 static const TranslatorOps i386_tr_ops
= {
8685 .init_disas_context
= i386_tr_init_disas_context
,
8686 .tb_start
= i386_tr_tb_start
,
8687 .insn_start
= i386_tr_insn_start
,
8688 .breakpoint_check
= i386_tr_breakpoint_check
,
8689 .translate_insn
= i386_tr_translate_insn
,
8690 .tb_stop
= i386_tr_tb_stop
,
8691 .disas_log
= i386_tr_disas_log
,
8694 /* generate intermediate code for basic block 'tb'. */
8695 void gen_intermediate_code(CPUState
*cpu
, TranslationBlock
*tb
, int max_insns
)
8699 translator_loop(&i386_tr_ops
, &dc
.base
, cpu
, tb
, max_insns
);
8702 void restore_state_to_opc(CPUX86State
*env
, TranslationBlock
*tb
,
8705 int cc_op
= data
[1];
8706 env
->eip
= data
[0] - tb
->cs_base
;
8707 if (cc_op
!= CC_OP_DYNAMIC
) {