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"
35 #define PREFIX_REPZ 0x01
36 #define PREFIX_REPNZ 0x02
37 #define PREFIX_LOCK 0x04
38 #define PREFIX_DATA 0x08
39 #define PREFIX_ADR 0x10
40 #define PREFIX_VEX 0x20
41 #define PREFIX_REX 0x40
51 /* For a switch indexed by MODRM, match all memory operands for a given OP. */
52 #define CASE_MODRM_MEM_OP(OP) \
53 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
54 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
55 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7
57 #define CASE_MODRM_OP(OP) \
58 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
59 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
60 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7: \
61 case (3 << 6) | (OP << 3) | 0 ... (3 << 6) | (OP << 3) | 7
63 //#define MACRO_TEST 1
65 /* global register indexes */
66 static TCGv cpu_cc_dst
, cpu_cc_src
, cpu_cc_src2
;
67 static TCGv_i32 cpu_cc_op
;
68 static TCGv cpu_regs
[CPU_NB_REGS
];
69 static TCGv cpu_seg_base
[6];
70 static TCGv_i64 cpu_bndl
[4];
71 static TCGv_i64 cpu_bndu
[4];
73 #include "exec/gen-icount.h"
75 typedef struct DisasContext
{
76 DisasContextBase base
;
78 target_ulong pc
; /* pc = eip + cs_base */
79 target_ulong pc_start
; /* pc at TB entry */
80 target_ulong cs_base
; /* base of CS segment */
85 int8_t override
; /* -1 if no override, else R_CS, R_DS, etc */
88 #ifndef CONFIG_USER_ONLY
89 uint8_t cpl
; /* code priv level */
90 uint8_t iopl
; /* i/o priv level */
92 uint8_t vex_l
; /* vex vector length */
93 uint8_t vex_v
; /* vex vvvv register, without 1's complement. */
94 uint8_t popl_esp_hack
; /* for correct popl with esp base handling */
95 uint8_t rip_offset
; /* only used in x86_64, but left for simplicity */
103 bool jmp_opt
; /* use direct block chaining for direct jumps */
104 bool repz_opt
; /* optimize jumps within repz instructions */
107 CCOp cc_op
; /* current CC operation */
108 int mem_index
; /* select memory access functions */
109 uint32_t flags
; /* all execution flags */
111 int cpuid_ext_features
;
112 int cpuid_ext2_features
;
113 int cpuid_ext3_features
;
114 int cpuid_7_0_ebx_features
;
115 int cpuid_xsave_features
;
117 /* TCG local temps */
123 /* TCG local register indexes (only used inside old micro ops) */
133 TCGOp
*prev_insn_end
;
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(get_dr
, TCGv ret
, TCGv_env env
, TCGv_i32 reg
)
210 STUB_HELPER(set_dr
, TCGv_env env
, TCGv_i32 reg
, TCGv val
)
211 STUB_HELPER(stgi
, TCGv_env env
)
212 STUB_HELPER(svm_check_intercept
, TCGv_env env
, TCGv_i32 type
)
213 STUB_HELPER(vmload
, TCGv_env env
, TCGv_i32 aflag
)
214 STUB_HELPER(vmmcall
, TCGv_env env
)
215 STUB_HELPER(vmrun
, TCGv_env env
, TCGv_i32 aflag
, TCGv_i32 pc_ofs
)
216 STUB_HELPER(vmsave
, TCGv_env env
, TCGv_i32 aflag
)
217 STUB_HELPER(write_crN
, TCGv_env env
, TCGv_i32 reg
, TCGv val
)
218 STUB_HELPER(wrmsr
, TCGv_env env
)
221 static void gen_eob(DisasContext
*s
);
222 static void gen_jr(DisasContext
*s
, TCGv dest
);
223 static void gen_jmp(DisasContext
*s
, target_ulong eip
);
224 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
);
225 static void gen_op(DisasContext
*s1
, int op
, MemOp ot
, int d
);
226 static void gen_exception_gpf(DisasContext
*s
);
228 /* i386 arith/logic operations */
248 OP_SHL1
, /* undocumented */
264 /* I386 int registers */
265 OR_EAX
, /* MUST be even numbered */
274 OR_TMP0
= 16, /* temporary operand register */
276 OR_A0
, /* temporary register used when doing address evaluation */
286 /* Bit set if the global variable is live after setting CC_OP to X. */
287 static const uint8_t cc_op_live
[CC_OP_NB
] = {
288 [CC_OP_DYNAMIC
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
289 [CC_OP_EFLAGS
] = USES_CC_SRC
,
290 [CC_OP_MULB
... CC_OP_MULQ
] = USES_CC_DST
| USES_CC_SRC
,
291 [CC_OP_ADDB
... CC_OP_ADDQ
] = USES_CC_DST
| USES_CC_SRC
,
292 [CC_OP_ADCB
... CC_OP_ADCQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
293 [CC_OP_SUBB
... CC_OP_SUBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRCT
,
294 [CC_OP_SBBB
... CC_OP_SBBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
295 [CC_OP_LOGICB
... CC_OP_LOGICQ
] = USES_CC_DST
,
296 [CC_OP_INCB
... CC_OP_INCQ
] = USES_CC_DST
| USES_CC_SRC
,
297 [CC_OP_DECB
... CC_OP_DECQ
] = USES_CC_DST
| USES_CC_SRC
,
298 [CC_OP_SHLB
... CC_OP_SHLQ
] = USES_CC_DST
| USES_CC_SRC
,
299 [CC_OP_SARB
... CC_OP_SARQ
] = USES_CC_DST
| USES_CC_SRC
,
300 [CC_OP_BMILGB
... CC_OP_BMILGQ
] = USES_CC_DST
| USES_CC_SRC
,
301 [CC_OP_ADCX
] = USES_CC_DST
| USES_CC_SRC
,
302 [CC_OP_ADOX
] = USES_CC_SRC
| USES_CC_SRC2
,
303 [CC_OP_ADCOX
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
305 [CC_OP_POPCNT
] = USES_CC_SRC
,
308 static void set_cc_op(DisasContext
*s
, CCOp op
)
312 if (s
->cc_op
== op
) {
316 /* Discard CC computation that will no longer be used. */
317 dead
= cc_op_live
[s
->cc_op
] & ~cc_op_live
[op
];
318 if (dead
& USES_CC_DST
) {
319 tcg_gen_discard_tl(cpu_cc_dst
);
321 if (dead
& USES_CC_SRC
) {
322 tcg_gen_discard_tl(cpu_cc_src
);
324 if (dead
& USES_CC_SRC2
) {
325 tcg_gen_discard_tl(cpu_cc_src2
);
327 if (dead
& USES_CC_SRCT
) {
328 tcg_gen_discard_tl(s
->cc_srcT
);
331 if (op
== CC_OP_DYNAMIC
) {
332 /* The DYNAMIC setting is translator only, and should never be
333 stored. Thus we always consider it clean. */
334 s
->cc_op_dirty
= false;
336 /* Discard any computed CC_OP value (see shifts). */
337 if (s
->cc_op
== CC_OP_DYNAMIC
) {
338 tcg_gen_discard_i32(cpu_cc_op
);
340 s
->cc_op_dirty
= true;
345 static void gen_update_cc_op(DisasContext
*s
)
347 if (s
->cc_op_dirty
) {
348 tcg_gen_movi_i32(cpu_cc_op
, s
->cc_op
);
349 s
->cc_op_dirty
= false;
355 #define NB_OP_SIZES 4
357 #else /* !TARGET_X86_64 */
359 #define NB_OP_SIZES 3
361 #endif /* !TARGET_X86_64 */
364 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
365 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
366 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
367 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
368 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
370 #define REG_B_OFFSET 0
371 #define REG_H_OFFSET 1
372 #define REG_W_OFFSET 0
373 #define REG_L_OFFSET 0
374 #define REG_LH_OFFSET 4
377 /* In instruction encodings for byte register accesses the
378 * register number usually indicates "low 8 bits of register N";
379 * however there are some special cases where N 4..7 indicates
380 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
381 * true for this special case, false otherwise.
383 static inline bool byte_reg_is_xH(DisasContext
*s
, int reg
)
385 /* Any time the REX prefix is present, byte registers are uniform */
386 if (reg
< 4 || REX_PREFIX(s
)) {
392 /* Select the size of a push/pop operation. */
393 static inline MemOp
mo_pushpop(DisasContext
*s
, MemOp ot
)
396 return ot
== MO_16
? MO_16
: MO_64
;
402 /* Select the size of the stack pointer. */
403 static inline MemOp
mo_stacksize(DisasContext
*s
)
405 return CODE64(s
) ? MO_64
: SS32(s
) ? MO_32
: MO_16
;
408 /* Select only size 64 else 32. Used for SSE operand sizes. */
409 static inline MemOp
mo_64_32(MemOp ot
)
412 return ot
== MO_64
? MO_64
: MO_32
;
418 /* Select size 8 if lsb of B is clear, else OT. Used for decoding
419 byte vs word opcodes. */
420 static inline MemOp
mo_b_d(int b
, MemOp ot
)
422 return b
& 1 ? ot
: MO_8
;
425 /* Select size 8 if lsb of B is clear, else OT capped at 32.
426 Used for decoding operand size of port opcodes. */
427 static inline MemOp
mo_b_d32(int b
, MemOp ot
)
429 return b
& 1 ? (ot
== MO_16
? MO_16
: MO_32
) : MO_8
;
432 static void gen_op_mov_reg_v(DisasContext
*s
, MemOp ot
, int reg
, TCGv t0
)
436 if (!byte_reg_is_xH(s
, reg
)) {
437 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 8);
439 tcg_gen_deposit_tl(cpu_regs
[reg
- 4], cpu_regs
[reg
- 4], t0
, 8, 8);
443 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 16);
446 /* For x86_64, this sets the higher half of register to zero.
447 For i386, this is equivalent to a mov. */
448 tcg_gen_ext32u_tl(cpu_regs
[reg
], t0
);
452 tcg_gen_mov_tl(cpu_regs
[reg
], t0
);
461 void gen_op_mov_v_reg(DisasContext
*s
, MemOp ot
, TCGv t0
, int reg
)
463 if (ot
== MO_8
&& byte_reg_is_xH(s
, reg
)) {
464 tcg_gen_extract_tl(t0
, cpu_regs
[reg
- 4], 8, 8);
466 tcg_gen_mov_tl(t0
, cpu_regs
[reg
]);
470 static void gen_add_A0_im(DisasContext
*s
, int val
)
472 tcg_gen_addi_tl(s
->A0
, s
->A0
, val
);
474 tcg_gen_ext32u_tl(s
->A0
, s
->A0
);
478 static inline void gen_op_jmp_v(TCGv dest
)
480 tcg_gen_st_tl(dest
, cpu_env
, offsetof(CPUX86State
, eip
));
484 void gen_op_add_reg_im(DisasContext
*s
, MemOp size
, int reg
, int32_t val
)
486 tcg_gen_addi_tl(s
->tmp0
, cpu_regs
[reg
], val
);
487 gen_op_mov_reg_v(s
, size
, reg
, s
->tmp0
);
490 static inline void gen_op_add_reg_T0(DisasContext
*s
, MemOp size
, int reg
)
492 tcg_gen_add_tl(s
->tmp0
, cpu_regs
[reg
], s
->T0
);
493 gen_op_mov_reg_v(s
, size
, reg
, s
->tmp0
);
496 static inline void gen_op_ld_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
498 tcg_gen_qemu_ld_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
501 static inline void gen_op_st_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
503 tcg_gen_qemu_st_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
506 static inline void gen_op_st_rm_T0_A0(DisasContext
*s
, int idx
, int d
)
509 gen_op_st_v(s
, idx
, s
->T0
, s
->A0
);
511 gen_op_mov_reg_v(s
, idx
, d
, s
->T0
);
515 static inline void gen_jmp_im(DisasContext
*s
, target_ulong pc
)
517 tcg_gen_movi_tl(s
->tmp0
, pc
);
518 gen_op_jmp_v(s
->tmp0
);
521 /* Compute SEG:REG into A0. SEG is selected from the override segment
522 (OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to
523 indicate no override. */
524 static void gen_lea_v_seg(DisasContext
*s
, MemOp aflag
, TCGv a0
,
525 int def_seg
, int ovr_seg
)
531 tcg_gen_mov_tl(s
->A0
, a0
);
538 if (ovr_seg
< 0 && ADDSEG(s
)) {
542 tcg_gen_ext32u_tl(s
->A0
, a0
);
548 tcg_gen_ext16u_tl(s
->A0
, a0
);
563 TCGv seg
= cpu_seg_base
[ovr_seg
];
565 if (aflag
== MO_64
) {
566 tcg_gen_add_tl(s
->A0
, a0
, seg
);
567 } else if (CODE64(s
)) {
568 tcg_gen_ext32u_tl(s
->A0
, a0
);
569 tcg_gen_add_tl(s
->A0
, s
->A0
, seg
);
571 tcg_gen_add_tl(s
->A0
, a0
, seg
);
572 tcg_gen_ext32u_tl(s
->A0
, s
->A0
);
577 static inline void gen_string_movl_A0_ESI(DisasContext
*s
)
579 gen_lea_v_seg(s
, s
->aflag
, cpu_regs
[R_ESI
], R_DS
, s
->override
);
582 static inline void gen_string_movl_A0_EDI(DisasContext
*s
)
584 gen_lea_v_seg(s
, s
->aflag
, cpu_regs
[R_EDI
], R_ES
, -1);
587 static inline void gen_op_movl_T0_Dshift(DisasContext
*s
, MemOp ot
)
589 tcg_gen_ld32s_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, df
));
590 tcg_gen_shli_tl(s
->T0
, s
->T0
, ot
);
593 static TCGv
gen_ext_tl(TCGv dst
, TCGv src
, MemOp size
, bool sign
)
598 tcg_gen_ext8s_tl(dst
, src
);
600 tcg_gen_ext8u_tl(dst
, src
);
605 tcg_gen_ext16s_tl(dst
, src
);
607 tcg_gen_ext16u_tl(dst
, src
);
613 tcg_gen_ext32s_tl(dst
, src
);
615 tcg_gen_ext32u_tl(dst
, src
);
624 static void gen_extu(MemOp ot
, TCGv reg
)
626 gen_ext_tl(reg
, reg
, ot
, false);
629 static void gen_exts(MemOp ot
, TCGv reg
)
631 gen_ext_tl(reg
, reg
, ot
, true);
635 void gen_op_jnz_ecx(DisasContext
*s
, MemOp size
, TCGLabel
*label1
)
637 tcg_gen_mov_tl(s
->tmp0
, cpu_regs
[R_ECX
]);
638 gen_extu(size
, s
->tmp0
);
639 tcg_gen_brcondi_tl(TCG_COND_NE
, s
->tmp0
, 0, label1
);
643 void gen_op_jz_ecx(DisasContext
*s
, MemOp size
, TCGLabel
*label1
)
645 tcg_gen_mov_tl(s
->tmp0
, cpu_regs
[R_ECX
]);
646 gen_extu(size
, s
->tmp0
);
647 tcg_gen_brcondi_tl(TCG_COND_EQ
, s
->tmp0
, 0, label1
);
650 static void gen_helper_in_func(MemOp ot
, TCGv v
, TCGv_i32 n
)
654 gen_helper_inb(v
, cpu_env
, n
);
657 gen_helper_inw(v
, cpu_env
, n
);
660 gen_helper_inl(v
, cpu_env
, n
);
667 static void gen_helper_out_func(MemOp ot
, TCGv_i32 v
, TCGv_i32 n
)
671 gen_helper_outb(cpu_env
, v
, n
);
674 gen_helper_outw(cpu_env
, v
, n
);
677 gen_helper_outl(cpu_env
, v
, n
);
685 * Validate that access to [port, port + 1<<ot) is allowed.
686 * Raise #GP, or VMM exit if not.
688 static bool gen_check_io(DisasContext
*s
, MemOp ot
, TCGv_i32 port
,
691 #ifdef CONFIG_USER_ONLY
693 * We do not implement the ioperm(2) syscall, so the TSS check
696 gen_exception_gpf(s
);
699 if (PE(s
) && (CPL(s
) > IOPL(s
) || VM86(s
))) {
700 gen_helper_check_io(cpu_env
, port
, tcg_constant_i32(1 << ot
));
703 target_ulong cur_eip
= s
->base
.pc_next
- s
->cs_base
;
704 target_ulong next_eip
= s
->pc
- s
->cs_base
;
707 gen_jmp_im(s
, cur_eip
);
708 if (s
->prefix
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
709 svm_flags
|= SVM_IOIO_REP_MASK
;
711 svm_flags
|= 1 << (SVM_IOIO_SIZE_SHIFT
+ ot
);
712 gen_helper_svm_check_io(cpu_env
, port
,
713 tcg_constant_i32(svm_flags
),
714 tcg_constant_i32(next_eip
- cur_eip
));
720 static inline void gen_movs(DisasContext
*s
, MemOp ot
)
722 gen_string_movl_A0_ESI(s
);
723 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
724 gen_string_movl_A0_EDI(s
);
725 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
726 gen_op_movl_T0_Dshift(s
, ot
);
727 gen_op_add_reg_T0(s
, s
->aflag
, R_ESI
);
728 gen_op_add_reg_T0(s
, s
->aflag
, R_EDI
);
731 static void gen_op_update1_cc(DisasContext
*s
)
733 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
736 static void gen_op_update2_cc(DisasContext
*s
)
738 tcg_gen_mov_tl(cpu_cc_src
, s
->T1
);
739 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
742 static void gen_op_update3_cc(DisasContext
*s
, TCGv reg
)
744 tcg_gen_mov_tl(cpu_cc_src2
, reg
);
745 tcg_gen_mov_tl(cpu_cc_src
, s
->T1
);
746 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
749 static inline void gen_op_testl_T0_T1_cc(DisasContext
*s
)
751 tcg_gen_and_tl(cpu_cc_dst
, s
->T0
, s
->T1
);
754 static void gen_op_update_neg_cc(DisasContext
*s
)
756 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
757 tcg_gen_neg_tl(cpu_cc_src
, s
->T0
);
758 tcg_gen_movi_tl(s
->cc_srcT
, 0);
761 /* compute all eflags to cc_src */
762 static void gen_compute_eflags(DisasContext
*s
)
764 TCGv zero
, dst
, src1
, src2
;
767 if (s
->cc_op
== CC_OP_EFLAGS
) {
770 if (s
->cc_op
== CC_OP_CLR
) {
771 tcg_gen_movi_tl(cpu_cc_src
, CC_Z
| CC_P
);
772 set_cc_op(s
, CC_OP_EFLAGS
);
781 /* Take care to not read values that are not live. */
782 live
= cc_op_live
[s
->cc_op
] & ~USES_CC_SRCT
;
783 dead
= live
^ (USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
);
785 zero
= tcg_const_tl(0);
786 if (dead
& USES_CC_DST
) {
789 if (dead
& USES_CC_SRC
) {
792 if (dead
& USES_CC_SRC2
) {
798 gen_helper_cc_compute_all(cpu_cc_src
, dst
, src1
, src2
, cpu_cc_op
);
799 set_cc_op(s
, CC_OP_EFLAGS
);
806 typedef struct CCPrepare
{
816 /* compute eflags.C to reg */
817 static CCPrepare
gen_prepare_eflags_c(DisasContext
*s
, TCGv reg
)
823 case CC_OP_SUBB
... CC_OP_SUBQ
:
824 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
825 size
= s
->cc_op
- CC_OP_SUBB
;
826 t1
= gen_ext_tl(s
->tmp0
, cpu_cc_src
, size
, false);
827 /* If no temporary was used, be careful not to alias t1 and t0. */
828 t0
= t1
== cpu_cc_src
? s
->tmp0
: reg
;
829 tcg_gen_mov_tl(t0
, s
->cc_srcT
);
833 case CC_OP_ADDB
... CC_OP_ADDQ
:
834 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
835 size
= s
->cc_op
- CC_OP_ADDB
;
836 t1
= gen_ext_tl(s
->tmp0
, cpu_cc_src
, size
, false);
837 t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
839 return (CCPrepare
) { .cond
= TCG_COND_LTU
, .reg
= t0
,
840 .reg2
= t1
, .mask
= -1, .use_reg2
= true };
842 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
845 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
847 case CC_OP_INCB
... CC_OP_INCQ
:
848 case CC_OP_DECB
... CC_OP_DECQ
:
849 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
850 .mask
= -1, .no_setcond
= true };
852 case CC_OP_SHLB
... CC_OP_SHLQ
:
853 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
854 size
= s
->cc_op
- CC_OP_SHLB
;
855 shift
= (8 << size
) - 1;
856 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
857 .mask
= (target_ulong
)1 << shift
};
859 case CC_OP_MULB
... CC_OP_MULQ
:
860 return (CCPrepare
) { .cond
= TCG_COND_NE
,
861 .reg
= cpu_cc_src
, .mask
= -1 };
863 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
864 size
= s
->cc_op
- CC_OP_BMILGB
;
865 t0
= gen_ext_tl(reg
, cpu_cc_src
, size
, false);
866 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
870 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_dst
,
871 .mask
= -1, .no_setcond
= true };
874 case CC_OP_SARB
... CC_OP_SARQ
:
876 return (CCPrepare
) { .cond
= TCG_COND_NE
,
877 .reg
= cpu_cc_src
, .mask
= CC_C
};
880 /* The need to compute only C from CC_OP_DYNAMIC is important
881 in efficiently implementing e.g. INC at the start of a TB. */
883 gen_helper_cc_compute_c(reg
, cpu_cc_dst
, cpu_cc_src
,
884 cpu_cc_src2
, cpu_cc_op
);
885 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
886 .mask
= -1, .no_setcond
= true };
890 /* compute eflags.P to reg */
891 static CCPrepare
gen_prepare_eflags_p(DisasContext
*s
, TCGv reg
)
893 gen_compute_eflags(s
);
894 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
898 /* compute eflags.S to reg */
899 static CCPrepare
gen_prepare_eflags_s(DisasContext
*s
, TCGv reg
)
903 gen_compute_eflags(s
);
909 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
913 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
916 MemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
917 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, true);
918 return (CCPrepare
) { .cond
= TCG_COND_LT
, .reg
= t0
, .mask
= -1 };
923 /* compute eflags.O to reg */
924 static CCPrepare
gen_prepare_eflags_o(DisasContext
*s
, TCGv reg
)
929 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src2
,
930 .mask
= -1, .no_setcond
= true };
933 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
935 gen_compute_eflags(s
);
936 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
941 /* compute eflags.Z to reg */
942 static CCPrepare
gen_prepare_eflags_z(DisasContext
*s
, TCGv reg
)
946 gen_compute_eflags(s
);
952 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
955 return (CCPrepare
) { .cond
= TCG_COND_ALWAYS
, .mask
= -1 };
957 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= cpu_cc_src
,
961 MemOp size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
962 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
963 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
968 /* perform a conditional store into register 'reg' according to jump opcode
969 value 'b'. In the fast case, T0 is guaranted not to be used. */
970 static CCPrepare
gen_prepare_cc(DisasContext
*s
, int b
, TCGv reg
)
972 int inv
, jcc_op
, cond
;
978 jcc_op
= (b
>> 1) & 7;
981 case CC_OP_SUBB
... CC_OP_SUBQ
:
982 /* We optimize relational operators for the cmp/jcc case. */
983 size
= s
->cc_op
- CC_OP_SUBB
;
986 tcg_gen_mov_tl(s
->tmp4
, s
->cc_srcT
);
987 gen_extu(size
, s
->tmp4
);
988 t0
= gen_ext_tl(s
->tmp0
, cpu_cc_src
, size
, false);
989 cc
= (CCPrepare
) { .cond
= TCG_COND_LEU
, .reg
= s
->tmp4
,
990 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
999 tcg_gen_mov_tl(s
->tmp4
, s
->cc_srcT
);
1000 gen_exts(size
, s
->tmp4
);
1001 t0
= gen_ext_tl(s
->tmp0
, cpu_cc_src
, size
, true);
1002 cc
= (CCPrepare
) { .cond
= cond
, .reg
= s
->tmp4
,
1003 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
1013 /* This actually generates good code for JC, JZ and JS. */
1016 cc
= gen_prepare_eflags_o(s
, reg
);
1019 cc
= gen_prepare_eflags_c(s
, reg
);
1022 cc
= gen_prepare_eflags_z(s
, reg
);
1025 gen_compute_eflags(s
);
1026 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
1027 .mask
= CC_Z
| CC_C
};
1030 cc
= gen_prepare_eflags_s(s
, reg
);
1033 cc
= gen_prepare_eflags_p(s
, reg
);
1036 gen_compute_eflags(s
);
1037 if (reg
== cpu_cc_src
) {
1040 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
1041 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
1042 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
1047 gen_compute_eflags(s
);
1048 if (reg
== cpu_cc_src
) {
1051 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
1052 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
1053 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
1054 .mask
= CC_S
| CC_Z
};
1061 cc
.cond
= tcg_invert_cond(cc
.cond
);
1066 static void gen_setcc1(DisasContext
*s
, int b
, TCGv reg
)
1068 CCPrepare cc
= gen_prepare_cc(s
, b
, reg
);
1070 if (cc
.no_setcond
) {
1071 if (cc
.cond
== TCG_COND_EQ
) {
1072 tcg_gen_xori_tl(reg
, cc
.reg
, 1);
1074 tcg_gen_mov_tl(reg
, cc
.reg
);
1079 if (cc
.cond
== TCG_COND_NE
&& !cc
.use_reg2
&& cc
.imm
== 0 &&
1080 cc
.mask
!= 0 && (cc
.mask
& (cc
.mask
- 1)) == 0) {
1081 tcg_gen_shri_tl(reg
, cc
.reg
, ctztl(cc
.mask
));
1082 tcg_gen_andi_tl(reg
, reg
, 1);
1085 if (cc
.mask
!= -1) {
1086 tcg_gen_andi_tl(reg
, cc
.reg
, cc
.mask
);
1090 tcg_gen_setcond_tl(cc
.cond
, reg
, cc
.reg
, cc
.reg2
);
1092 tcg_gen_setcondi_tl(cc
.cond
, reg
, cc
.reg
, cc
.imm
);
1096 static inline void gen_compute_eflags_c(DisasContext
*s
, TCGv reg
)
1098 gen_setcc1(s
, JCC_B
<< 1, reg
);
1101 /* generate a conditional jump to label 'l1' according to jump opcode
1102 value 'b'. In the fast case, T0 is guaranted not to be used. */
1103 static inline void gen_jcc1_noeob(DisasContext
*s
, int b
, TCGLabel
*l1
)
1105 CCPrepare cc
= gen_prepare_cc(s
, b
, s
->T0
);
1107 if (cc
.mask
!= -1) {
1108 tcg_gen_andi_tl(s
->T0
, cc
.reg
, cc
.mask
);
1112 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1114 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1118 /* Generate a conditional jump to label 'l1' according to jump opcode
1119 value 'b'. In the fast case, T0 is guaranted not to be used.
1120 A translation block must end soon. */
1121 static inline void gen_jcc1(DisasContext
*s
, int b
, TCGLabel
*l1
)
1123 CCPrepare cc
= gen_prepare_cc(s
, b
, s
->T0
);
1125 gen_update_cc_op(s
);
1126 if (cc
.mask
!= -1) {
1127 tcg_gen_andi_tl(s
->T0
, cc
.reg
, cc
.mask
);
1130 set_cc_op(s
, CC_OP_DYNAMIC
);
1132 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1134 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1138 /* XXX: does not work with gdbstub "ice" single step - not a
1140 static TCGLabel
*gen_jz_ecx_string(DisasContext
*s
, target_ulong next_eip
)
1142 TCGLabel
*l1
= gen_new_label();
1143 TCGLabel
*l2
= gen_new_label();
1144 gen_op_jnz_ecx(s
, s
->aflag
, l1
);
1146 gen_jmp_tb(s
, next_eip
, 1);
1151 static inline void gen_stos(DisasContext
*s
, MemOp ot
)
1153 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, R_EAX
);
1154 gen_string_movl_A0_EDI(s
);
1155 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
1156 gen_op_movl_T0_Dshift(s
, ot
);
1157 gen_op_add_reg_T0(s
, s
->aflag
, R_EDI
);
1160 static inline void gen_lods(DisasContext
*s
, MemOp ot
)
1162 gen_string_movl_A0_ESI(s
);
1163 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1164 gen_op_mov_reg_v(s
, ot
, R_EAX
, s
->T0
);
1165 gen_op_movl_T0_Dshift(s
, ot
);
1166 gen_op_add_reg_T0(s
, s
->aflag
, R_ESI
);
1169 static inline void gen_scas(DisasContext
*s
, MemOp ot
)
1171 gen_string_movl_A0_EDI(s
);
1172 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
1173 gen_op(s
, OP_CMPL
, ot
, R_EAX
);
1174 gen_op_movl_T0_Dshift(s
, ot
);
1175 gen_op_add_reg_T0(s
, s
->aflag
, R_EDI
);
1178 static inline void gen_cmps(DisasContext
*s
, MemOp ot
)
1180 gen_string_movl_A0_EDI(s
);
1181 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
1182 gen_string_movl_A0_ESI(s
);
1183 gen_op(s
, OP_CMPL
, ot
, OR_TMP0
);
1184 gen_op_movl_T0_Dshift(s
, ot
);
1185 gen_op_add_reg_T0(s
, s
->aflag
, R_ESI
);
1186 gen_op_add_reg_T0(s
, s
->aflag
, R_EDI
);
1189 static void gen_bpt_io(DisasContext
*s
, TCGv_i32 t_port
, int ot
)
1191 if (s
->flags
& HF_IOBPT_MASK
) {
1192 #ifdef CONFIG_USER_ONLY
1193 /* user-mode cpu should not be in IOBPT mode */
1194 g_assert_not_reached();
1196 TCGv_i32 t_size
= tcg_const_i32(1 << ot
);
1197 TCGv t_next
= tcg_const_tl(s
->pc
- s
->cs_base
);
1199 gen_helper_bpt_io(cpu_env
, t_port
, t_size
, t_next
);
1200 tcg_temp_free_i32(t_size
);
1201 tcg_temp_free(t_next
);
1202 #endif /* CONFIG_USER_ONLY */
1206 static inline void gen_ins(DisasContext
*s
, MemOp ot
)
1208 gen_string_movl_A0_EDI(s
);
1209 /* Note: we must do this dummy write first to be restartable in
1210 case of page fault. */
1211 tcg_gen_movi_tl(s
->T0
, 0);
1212 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
1213 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_EDX
]);
1214 tcg_gen_andi_i32(s
->tmp2_i32
, s
->tmp2_i32
, 0xffff);
1215 gen_helper_in_func(ot
, s
->T0
, s
->tmp2_i32
);
1216 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
1217 gen_op_movl_T0_Dshift(s
, ot
);
1218 gen_op_add_reg_T0(s
, s
->aflag
, R_EDI
);
1219 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
1222 static inline void gen_outs(DisasContext
*s
, MemOp ot
)
1224 gen_string_movl_A0_ESI(s
);
1225 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1227 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_EDX
]);
1228 tcg_gen_andi_i32(s
->tmp2_i32
, s
->tmp2_i32
, 0xffff);
1229 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, s
->T0
);
1230 gen_helper_out_func(ot
, s
->tmp2_i32
, s
->tmp3_i32
);
1231 gen_op_movl_T0_Dshift(s
, ot
);
1232 gen_op_add_reg_T0(s
, s
->aflag
, R_ESI
);
1233 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
1236 /* same method as Valgrind : we generate jumps to current or next
1238 #define GEN_REPZ(op) \
1239 static inline void gen_repz_ ## op(DisasContext *s, MemOp ot, \
1240 target_ulong cur_eip, target_ulong next_eip) \
1243 gen_update_cc_op(s); \
1244 l2 = gen_jz_ecx_string(s, next_eip); \
1245 gen_ ## op(s, ot); \
1246 gen_op_add_reg_im(s, s->aflag, R_ECX, -1); \
1247 /* a loop would cause two single step exceptions if ECX = 1 \
1248 before rep string_insn */ \
1250 gen_op_jz_ecx(s, s->aflag, l2); \
1251 gen_jmp(s, cur_eip); \
1254 #define GEN_REPZ2(op) \
1255 static inline void gen_repz_ ## op(DisasContext *s, MemOp ot, \
1256 target_ulong cur_eip, \
1257 target_ulong next_eip, \
1261 gen_update_cc_op(s); \
1262 l2 = gen_jz_ecx_string(s, next_eip); \
1263 gen_ ## op(s, ot); \
1264 gen_op_add_reg_im(s, s->aflag, R_ECX, -1); \
1265 gen_update_cc_op(s); \
1266 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
1268 gen_op_jz_ecx(s, s->aflag, l2); \
1269 gen_jmp(s, cur_eip); \
1280 static void gen_helper_fp_arith_ST0_FT0(int op
)
1284 gen_helper_fadd_ST0_FT0(cpu_env
);
1287 gen_helper_fmul_ST0_FT0(cpu_env
);
1290 gen_helper_fcom_ST0_FT0(cpu_env
);
1293 gen_helper_fcom_ST0_FT0(cpu_env
);
1296 gen_helper_fsub_ST0_FT0(cpu_env
);
1299 gen_helper_fsubr_ST0_FT0(cpu_env
);
1302 gen_helper_fdiv_ST0_FT0(cpu_env
);
1305 gen_helper_fdivr_ST0_FT0(cpu_env
);
1310 /* NOTE the exception in "r" op ordering */
1311 static void gen_helper_fp_arith_STN_ST0(int op
, int opreg
)
1313 TCGv_i32 tmp
= tcg_const_i32(opreg
);
1316 gen_helper_fadd_STN_ST0(cpu_env
, tmp
);
1319 gen_helper_fmul_STN_ST0(cpu_env
, tmp
);
1322 gen_helper_fsubr_STN_ST0(cpu_env
, tmp
);
1325 gen_helper_fsub_STN_ST0(cpu_env
, tmp
);
1328 gen_helper_fdivr_STN_ST0(cpu_env
, tmp
);
1331 gen_helper_fdiv_STN_ST0(cpu_env
, tmp
);
1336 static void gen_exception(DisasContext
*s
, int trapno
, target_ulong cur_eip
)
1338 gen_update_cc_op(s
);
1339 gen_jmp_im(s
, cur_eip
);
1340 gen_helper_raise_exception(cpu_env
, tcg_const_i32(trapno
));
1341 s
->base
.is_jmp
= DISAS_NORETURN
;
1344 /* Generate #UD for the current instruction. The assumption here is that
1345 the instruction is known, but it isn't allowed in the current cpu mode. */
1346 static void gen_illegal_opcode(DisasContext
*s
)
1348 gen_exception(s
, EXCP06_ILLOP
, s
->pc_start
- s
->cs_base
);
1351 /* Generate #GP for the current instruction. */
1352 static void gen_exception_gpf(DisasContext
*s
)
1354 gen_exception(s
, EXCP0D_GPF
, s
->pc_start
- s
->cs_base
);
1357 /* Check for cpl == 0; if not, raise #GP and return false. */
1358 static bool check_cpl0(DisasContext
*s
)
1363 gen_exception_gpf(s
);
1367 /* If vm86, check for iopl == 3; if not, raise #GP and return false. */
1368 static bool check_vm86_iopl(DisasContext
*s
)
1370 if (!VM86(s
) || IOPL(s
) == 3) {
1373 gen_exception_gpf(s
);
1377 /* Check for iopl allowing access; if not, raise #GP and return false. */
1378 static bool check_iopl(DisasContext
*s
)
1380 if (VM86(s
) ? IOPL(s
) == 3 : CPL(s
) <= IOPL(s
)) {
1383 gen_exception_gpf(s
);
1387 /* if d == OR_TMP0, it means memory operand (address in A0) */
1388 static void gen_op(DisasContext
*s1
, int op
, MemOp ot
, int d
)
1391 if (s1
->prefix
& PREFIX_LOCK
) {
1392 /* Lock prefix when destination is not memory. */
1393 gen_illegal_opcode(s1
);
1396 gen_op_mov_v_reg(s1
, ot
, s1
->T0
, d
);
1397 } else if (!(s1
->prefix
& PREFIX_LOCK
)) {
1398 gen_op_ld_v(s1
, ot
, s1
->T0
, s1
->A0
);
1402 gen_compute_eflags_c(s1
, s1
->tmp4
);
1403 if (s1
->prefix
& PREFIX_LOCK
) {
1404 tcg_gen_add_tl(s1
->T0
, s1
->tmp4
, s1
->T1
);
1405 tcg_gen_atomic_add_fetch_tl(s1
->T0
, s1
->A0
, s1
->T0
,
1406 s1
->mem_index
, ot
| MO_LE
);
1408 tcg_gen_add_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1409 tcg_gen_add_tl(s1
->T0
, s1
->T0
, s1
->tmp4
);
1410 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1412 gen_op_update3_cc(s1
, s1
->tmp4
);
1413 set_cc_op(s1
, CC_OP_ADCB
+ ot
);
1416 gen_compute_eflags_c(s1
, s1
->tmp4
);
1417 if (s1
->prefix
& PREFIX_LOCK
) {
1418 tcg_gen_add_tl(s1
->T0
, s1
->T1
, s1
->tmp4
);
1419 tcg_gen_neg_tl(s1
->T0
, s1
->T0
);
1420 tcg_gen_atomic_add_fetch_tl(s1
->T0
, s1
->A0
, s1
->T0
,
1421 s1
->mem_index
, ot
| MO_LE
);
1423 tcg_gen_sub_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1424 tcg_gen_sub_tl(s1
->T0
, s1
->T0
, s1
->tmp4
);
1425 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1427 gen_op_update3_cc(s1
, s1
->tmp4
);
1428 set_cc_op(s1
, CC_OP_SBBB
+ ot
);
1431 if (s1
->prefix
& PREFIX_LOCK
) {
1432 tcg_gen_atomic_add_fetch_tl(s1
->T0
, s1
->A0
, s1
->T1
,
1433 s1
->mem_index
, ot
| MO_LE
);
1435 tcg_gen_add_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1436 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1438 gen_op_update2_cc(s1
);
1439 set_cc_op(s1
, CC_OP_ADDB
+ ot
);
1442 if (s1
->prefix
& PREFIX_LOCK
) {
1443 tcg_gen_neg_tl(s1
->T0
, s1
->T1
);
1444 tcg_gen_atomic_fetch_add_tl(s1
->cc_srcT
, s1
->A0
, s1
->T0
,
1445 s1
->mem_index
, ot
| MO_LE
);
1446 tcg_gen_sub_tl(s1
->T0
, s1
->cc_srcT
, s1
->T1
);
1448 tcg_gen_mov_tl(s1
->cc_srcT
, s1
->T0
);
1449 tcg_gen_sub_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1450 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1452 gen_op_update2_cc(s1
);
1453 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1457 if (s1
->prefix
& PREFIX_LOCK
) {
1458 tcg_gen_atomic_and_fetch_tl(s1
->T0
, s1
->A0
, s1
->T1
,
1459 s1
->mem_index
, ot
| MO_LE
);
1461 tcg_gen_and_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1462 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1464 gen_op_update1_cc(s1
);
1465 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1468 if (s1
->prefix
& PREFIX_LOCK
) {
1469 tcg_gen_atomic_or_fetch_tl(s1
->T0
, s1
->A0
, s1
->T1
,
1470 s1
->mem_index
, ot
| MO_LE
);
1472 tcg_gen_or_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1473 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1475 gen_op_update1_cc(s1
);
1476 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1479 if (s1
->prefix
& PREFIX_LOCK
) {
1480 tcg_gen_atomic_xor_fetch_tl(s1
->T0
, s1
->A0
, s1
->T1
,
1481 s1
->mem_index
, ot
| MO_LE
);
1483 tcg_gen_xor_tl(s1
->T0
, s1
->T0
, s1
->T1
);
1484 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1486 gen_op_update1_cc(s1
);
1487 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1490 tcg_gen_mov_tl(cpu_cc_src
, s1
->T1
);
1491 tcg_gen_mov_tl(s1
->cc_srcT
, s1
->T0
);
1492 tcg_gen_sub_tl(cpu_cc_dst
, s1
->T0
, s1
->T1
);
1493 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1498 /* if d == OR_TMP0, it means memory operand (address in A0) */
1499 static void gen_inc(DisasContext
*s1
, MemOp ot
, int d
, int c
)
1501 if (s1
->prefix
& PREFIX_LOCK
) {
1503 /* Lock prefix when destination is not memory */
1504 gen_illegal_opcode(s1
);
1507 tcg_gen_movi_tl(s1
->T0
, c
> 0 ? 1 : -1);
1508 tcg_gen_atomic_add_fetch_tl(s1
->T0
, s1
->A0
, s1
->T0
,
1509 s1
->mem_index
, ot
| MO_LE
);
1512 gen_op_mov_v_reg(s1
, ot
, s1
->T0
, d
);
1514 gen_op_ld_v(s1
, ot
, s1
->T0
, s1
->A0
);
1516 tcg_gen_addi_tl(s1
->T0
, s1
->T0
, (c
> 0 ? 1 : -1));
1517 gen_op_st_rm_T0_A0(s1
, ot
, d
);
1520 gen_compute_eflags_c(s1
, cpu_cc_src
);
1521 tcg_gen_mov_tl(cpu_cc_dst
, s1
->T0
);
1522 set_cc_op(s1
, (c
> 0 ? CC_OP_INCB
: CC_OP_DECB
) + ot
);
1525 static void gen_shift_flags(DisasContext
*s
, MemOp ot
, TCGv result
,
1526 TCGv shm1
, TCGv count
, bool is_right
)
1528 TCGv_i32 z32
, s32
, oldop
;
1531 /* Store the results into the CC variables. If we know that the
1532 variable must be dead, store unconditionally. Otherwise we'll
1533 need to not disrupt the current contents. */
1534 z_tl
= tcg_const_tl(0);
1535 if (cc_op_live
[s
->cc_op
] & USES_CC_DST
) {
1536 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_dst
, count
, z_tl
,
1537 result
, cpu_cc_dst
);
1539 tcg_gen_mov_tl(cpu_cc_dst
, result
);
1541 if (cc_op_live
[s
->cc_op
] & USES_CC_SRC
) {
1542 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_src
, count
, z_tl
,
1545 tcg_gen_mov_tl(cpu_cc_src
, shm1
);
1547 tcg_temp_free(z_tl
);
1549 /* Get the two potential CC_OP values into temporaries. */
1550 tcg_gen_movi_i32(s
->tmp2_i32
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1551 if (s
->cc_op
== CC_OP_DYNAMIC
) {
1554 tcg_gen_movi_i32(s
->tmp3_i32
, s
->cc_op
);
1555 oldop
= s
->tmp3_i32
;
1558 /* Conditionally store the CC_OP value. */
1559 z32
= tcg_const_i32(0);
1560 s32
= tcg_temp_new_i32();
1561 tcg_gen_trunc_tl_i32(s32
, count
);
1562 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, s32
, z32
, s
->tmp2_i32
, oldop
);
1563 tcg_temp_free_i32(z32
);
1564 tcg_temp_free_i32(s32
);
1566 /* The CC_OP value is no longer predictable. */
1567 set_cc_op(s
, CC_OP_DYNAMIC
);
1570 static void gen_shift_rm_T1(DisasContext
*s
, MemOp ot
, int op1
,
1571 int is_right
, int is_arith
)
1573 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1576 if (op1
== OR_TMP0
) {
1577 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1579 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1582 tcg_gen_andi_tl(s
->T1
, s
->T1
, mask
);
1583 tcg_gen_subi_tl(s
->tmp0
, s
->T1
, 1);
1587 gen_exts(ot
, s
->T0
);
1588 tcg_gen_sar_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1589 tcg_gen_sar_tl(s
->T0
, s
->T0
, s
->T1
);
1591 gen_extu(ot
, s
->T0
);
1592 tcg_gen_shr_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1593 tcg_gen_shr_tl(s
->T0
, s
->T0
, s
->T1
);
1596 tcg_gen_shl_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1597 tcg_gen_shl_tl(s
->T0
, s
->T0
, s
->T1
);
1601 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1603 gen_shift_flags(s
, ot
, s
->T0
, s
->tmp0
, s
->T1
, is_right
);
1606 static void gen_shift_rm_im(DisasContext
*s
, MemOp ot
, int op1
, int op2
,
1607 int is_right
, int is_arith
)
1609 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1613 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1615 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1621 gen_exts(ot
, s
->T0
);
1622 tcg_gen_sari_tl(s
->tmp4
, s
->T0
, op2
- 1);
1623 tcg_gen_sari_tl(s
->T0
, s
->T0
, op2
);
1625 gen_extu(ot
, s
->T0
);
1626 tcg_gen_shri_tl(s
->tmp4
, s
->T0
, op2
- 1);
1627 tcg_gen_shri_tl(s
->T0
, s
->T0
, op2
);
1630 tcg_gen_shli_tl(s
->tmp4
, s
->T0
, op2
- 1);
1631 tcg_gen_shli_tl(s
->T0
, s
->T0
, op2
);
1636 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1638 /* update eflags if non zero shift */
1640 tcg_gen_mov_tl(cpu_cc_src
, s
->tmp4
);
1641 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
1642 set_cc_op(s
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1646 static void gen_rot_rm_T1(DisasContext
*s
, MemOp ot
, int op1
, int is_right
)
1648 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1652 if (op1
== OR_TMP0
) {
1653 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1655 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1658 tcg_gen_andi_tl(s
->T1
, s
->T1
, mask
);
1662 /* Replicate the 8-bit input so that a 32-bit rotate works. */
1663 tcg_gen_ext8u_tl(s
->T0
, s
->T0
);
1664 tcg_gen_muli_tl(s
->T0
, s
->T0
, 0x01010101);
1667 /* Replicate the 16-bit input so that a 32-bit rotate works. */
1668 tcg_gen_deposit_tl(s
->T0
, s
->T0
, s
->T0
, 16, 16);
1671 #ifdef TARGET_X86_64
1673 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
1674 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, s
->T1
);
1676 tcg_gen_rotr_i32(s
->tmp2_i32
, s
->tmp2_i32
, s
->tmp3_i32
);
1678 tcg_gen_rotl_i32(s
->tmp2_i32
, s
->tmp2_i32
, s
->tmp3_i32
);
1680 tcg_gen_extu_i32_tl(s
->T0
, s
->tmp2_i32
);
1685 tcg_gen_rotr_tl(s
->T0
, s
->T0
, s
->T1
);
1687 tcg_gen_rotl_tl(s
->T0
, s
->T0
, s
->T1
);
1693 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1695 /* We'll need the flags computed into CC_SRC. */
1696 gen_compute_eflags(s
);
1698 /* The value that was "rotated out" is now present at the other end
1699 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1700 since we've computed the flags into CC_SRC, these variables are
1703 tcg_gen_shri_tl(cpu_cc_src2
, s
->T0
, mask
- 1);
1704 tcg_gen_shri_tl(cpu_cc_dst
, s
->T0
, mask
);
1705 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1707 tcg_gen_shri_tl(cpu_cc_src2
, s
->T0
, mask
);
1708 tcg_gen_andi_tl(cpu_cc_dst
, s
->T0
, 1);
1710 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1711 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1713 /* Now conditionally store the new CC_OP value. If the shift count
1714 is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1715 Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1716 exactly as we computed above. */
1717 t0
= tcg_const_i32(0);
1718 t1
= tcg_temp_new_i32();
1719 tcg_gen_trunc_tl_i32(t1
, s
->T1
);
1720 tcg_gen_movi_i32(s
->tmp2_i32
, CC_OP_ADCOX
);
1721 tcg_gen_movi_i32(s
->tmp3_i32
, CC_OP_EFLAGS
);
1722 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, t1
, t0
,
1723 s
->tmp2_i32
, s
->tmp3_i32
);
1724 tcg_temp_free_i32(t0
);
1725 tcg_temp_free_i32(t1
);
1727 /* The CC_OP value is no longer predictable. */
1728 set_cc_op(s
, CC_OP_DYNAMIC
);
1731 static void gen_rot_rm_im(DisasContext
*s
, MemOp ot
, int op1
, int op2
,
1734 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1738 if (op1
== OR_TMP0
) {
1739 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1741 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1747 #ifdef TARGET_X86_64
1749 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
1751 tcg_gen_rotri_i32(s
->tmp2_i32
, s
->tmp2_i32
, op2
);
1753 tcg_gen_rotli_i32(s
->tmp2_i32
, s
->tmp2_i32
, op2
);
1755 tcg_gen_extu_i32_tl(s
->T0
, s
->tmp2_i32
);
1760 tcg_gen_rotri_tl(s
->T0
, s
->T0
, op2
);
1762 tcg_gen_rotli_tl(s
->T0
, s
->T0
, op2
);
1773 shift
= mask
+ 1 - shift
;
1775 gen_extu(ot
, s
->T0
);
1776 tcg_gen_shli_tl(s
->tmp0
, s
->T0
, shift
);
1777 tcg_gen_shri_tl(s
->T0
, s
->T0
, mask
+ 1 - shift
);
1778 tcg_gen_or_tl(s
->T0
, s
->T0
, s
->tmp0
);
1784 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1787 /* Compute the flags into CC_SRC. */
1788 gen_compute_eflags(s
);
1790 /* The value that was "rotated out" is now present at the other end
1791 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1792 since we've computed the flags into CC_SRC, these variables are
1795 tcg_gen_shri_tl(cpu_cc_src2
, s
->T0
, mask
- 1);
1796 tcg_gen_shri_tl(cpu_cc_dst
, s
->T0
, mask
);
1797 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1799 tcg_gen_shri_tl(cpu_cc_src2
, s
->T0
, mask
);
1800 tcg_gen_andi_tl(cpu_cc_dst
, s
->T0
, 1);
1802 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1803 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1804 set_cc_op(s
, CC_OP_ADCOX
);
1808 /* XXX: add faster immediate = 1 case */
1809 static void gen_rotc_rm_T1(DisasContext
*s
, MemOp ot
, int op1
,
1812 gen_compute_eflags(s
);
1813 assert(s
->cc_op
== CC_OP_EFLAGS
);
1817 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1819 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1824 gen_helper_rcrb(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1827 gen_helper_rcrw(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1830 gen_helper_rcrl(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1832 #ifdef TARGET_X86_64
1834 gen_helper_rcrq(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1843 gen_helper_rclb(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1846 gen_helper_rclw(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1849 gen_helper_rcll(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1851 #ifdef TARGET_X86_64
1853 gen_helper_rclq(s
->T0
, cpu_env
, s
->T0
, s
->T1
);
1861 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1864 /* XXX: add faster immediate case */
1865 static void gen_shiftd_rm_T1(DisasContext
*s
, MemOp ot
, int op1
,
1866 bool is_right
, TCGv count_in
)
1868 target_ulong mask
= (ot
== MO_64
? 63 : 31);
1872 if (op1
== OR_TMP0
) {
1873 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
1875 gen_op_mov_v_reg(s
, ot
, s
->T0
, op1
);
1878 count
= tcg_temp_new();
1879 tcg_gen_andi_tl(count
, count_in
, mask
);
1883 /* Note: we implement the Intel behaviour for shift count > 16.
1884 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A
1885 portion by constructing it as a 32-bit value. */
1887 tcg_gen_deposit_tl(s
->tmp0
, s
->T0
, s
->T1
, 16, 16);
1888 tcg_gen_mov_tl(s
->T1
, s
->T0
);
1889 tcg_gen_mov_tl(s
->T0
, s
->tmp0
);
1891 tcg_gen_deposit_tl(s
->T1
, s
->T0
, s
->T1
, 16, 16);
1894 * If TARGET_X86_64 defined then fall through into MO_32 case,
1895 * otherwise fall through default case.
1898 #ifdef TARGET_X86_64
1899 /* Concatenate the two 32-bit values and use a 64-bit shift. */
1900 tcg_gen_subi_tl(s
->tmp0
, count
, 1);
1902 tcg_gen_concat_tl_i64(s
->T0
, s
->T0
, s
->T1
);
1903 tcg_gen_shr_i64(s
->tmp0
, s
->T0
, s
->tmp0
);
1904 tcg_gen_shr_i64(s
->T0
, s
->T0
, count
);
1906 tcg_gen_concat_tl_i64(s
->T0
, s
->T1
, s
->T0
);
1907 tcg_gen_shl_i64(s
->tmp0
, s
->T0
, s
->tmp0
);
1908 tcg_gen_shl_i64(s
->T0
, s
->T0
, count
);
1909 tcg_gen_shri_i64(s
->tmp0
, s
->tmp0
, 32);
1910 tcg_gen_shri_i64(s
->T0
, s
->T0
, 32);
1915 tcg_gen_subi_tl(s
->tmp0
, count
, 1);
1917 tcg_gen_shr_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1919 tcg_gen_subfi_tl(s
->tmp4
, mask
+ 1, count
);
1920 tcg_gen_shr_tl(s
->T0
, s
->T0
, count
);
1921 tcg_gen_shl_tl(s
->T1
, s
->T1
, s
->tmp4
);
1923 tcg_gen_shl_tl(s
->tmp0
, s
->T0
, s
->tmp0
);
1925 /* Only needed if count > 16, for Intel behaviour. */
1926 tcg_gen_subfi_tl(s
->tmp4
, 33, count
);
1927 tcg_gen_shr_tl(s
->tmp4
, s
->T1
, s
->tmp4
);
1928 tcg_gen_or_tl(s
->tmp0
, s
->tmp0
, s
->tmp4
);
1931 tcg_gen_subfi_tl(s
->tmp4
, mask
+ 1, count
);
1932 tcg_gen_shl_tl(s
->T0
, s
->T0
, count
);
1933 tcg_gen_shr_tl(s
->T1
, s
->T1
, s
->tmp4
);
1935 tcg_gen_movi_tl(s
->tmp4
, 0);
1936 tcg_gen_movcond_tl(TCG_COND_EQ
, s
->T1
, count
, s
->tmp4
,
1938 tcg_gen_or_tl(s
->T0
, s
->T0
, s
->T1
);
1943 gen_op_st_rm_T0_A0(s
, ot
, op1
);
1945 gen_shift_flags(s
, ot
, s
->T0
, s
->tmp0
, count
, is_right
);
1946 tcg_temp_free(count
);
1949 static void gen_shift(DisasContext
*s1
, int op
, MemOp ot
, int d
, int s
)
1952 gen_op_mov_v_reg(s1
, ot
, s1
->T1
, s
);
1955 gen_rot_rm_T1(s1
, ot
, d
, 0);
1958 gen_rot_rm_T1(s1
, ot
, d
, 1);
1962 gen_shift_rm_T1(s1
, ot
, d
, 0, 0);
1965 gen_shift_rm_T1(s1
, ot
, d
, 1, 0);
1968 gen_shift_rm_T1(s1
, ot
, d
, 1, 1);
1971 gen_rotc_rm_T1(s1
, ot
, d
, 0);
1974 gen_rotc_rm_T1(s1
, ot
, d
, 1);
1979 static void gen_shifti(DisasContext
*s1
, int op
, MemOp ot
, int d
, int c
)
1983 gen_rot_rm_im(s1
, ot
, d
, c
, 0);
1986 gen_rot_rm_im(s1
, ot
, d
, c
, 1);
1990 gen_shift_rm_im(s1
, ot
, d
, c
, 0, 0);
1993 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 0);
1996 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 1);
1999 /* currently not optimized */
2000 tcg_gen_movi_tl(s1
->T1
, c
);
2001 gen_shift(s1
, op
, ot
, d
, OR_TMP1
);
2006 #define X86_MAX_INSN_LENGTH 15
2008 static uint64_t advance_pc(CPUX86State
*env
, DisasContext
*s
, int num_bytes
)
2010 uint64_t pc
= s
->pc
;
2012 /* This is a subsequent insn that crosses a page boundary. */
2013 if (s
->base
.num_insns
> 1 &&
2014 !is_same_page(&s
->base
, s
->pc
+ num_bytes
- 1)) {
2015 siglongjmp(s
->jmpbuf
, 2);
2019 if (unlikely(s
->pc
- s
->pc_start
> X86_MAX_INSN_LENGTH
)) {
2020 /* If the instruction's 16th byte is on a different page than the 1st, a
2021 * page fault on the second page wins over the general protection fault
2022 * caused by the instruction being too long.
2023 * This can happen even if the operand is only one byte long!
2025 if (((s
->pc
- 1) ^ (pc
- 1)) & TARGET_PAGE_MASK
) {
2026 volatile uint8_t unused
=
2027 cpu_ldub_code(env
, (s
->pc
- 1) & TARGET_PAGE_MASK
);
2030 siglongjmp(s
->jmpbuf
, 1);
2036 static inline uint8_t x86_ldub_code(CPUX86State
*env
, DisasContext
*s
)
2038 return translator_ldub(env
, &s
->base
, advance_pc(env
, s
, 1));
2041 static inline int16_t x86_ldsw_code(CPUX86State
*env
, DisasContext
*s
)
2043 return translator_lduw(env
, &s
->base
, advance_pc(env
, s
, 2));
2046 static inline uint16_t x86_lduw_code(CPUX86State
*env
, DisasContext
*s
)
2048 return translator_lduw(env
, &s
->base
, advance_pc(env
, s
, 2));
2051 static inline uint32_t x86_ldl_code(CPUX86State
*env
, DisasContext
*s
)
2053 return translator_ldl(env
, &s
->base
, advance_pc(env
, s
, 4));
2056 #ifdef TARGET_X86_64
2057 static inline uint64_t x86_ldq_code(CPUX86State
*env
, DisasContext
*s
)
2059 return translator_ldq(env
, &s
->base
, advance_pc(env
, s
, 8));
2063 /* Decompose an address. */
2065 typedef struct AddressParts
{
2073 static AddressParts
gen_lea_modrm_0(CPUX86State
*env
, DisasContext
*s
,
2076 int def_seg
, base
, index
, scale
, mod
, rm
;
2085 mod
= (modrm
>> 6) & 3;
2087 base
= rm
| REX_B(s
);
2090 /* Normally filtered out earlier, but including this path
2091 simplifies multi-byte nop, as well as bndcl, bndcu, bndcn. */
2100 int code
= x86_ldub_code(env
, s
);
2101 scale
= (code
>> 6) & 3;
2102 index
= ((code
>> 3) & 7) | REX_X(s
);
2104 index
= -1; /* no index */
2106 base
= (code
& 7) | REX_B(s
);
2112 if ((base
& 7) == 5) {
2114 disp
= (int32_t)x86_ldl_code(env
, s
);
2115 if (CODE64(s
) && !havesib
) {
2117 disp
+= s
->pc
+ s
->rip_offset
;
2122 disp
= (int8_t)x86_ldub_code(env
, s
);
2126 disp
= (int32_t)x86_ldl_code(env
, s
);
2130 /* For correct popl handling with esp. */
2131 if (base
== R_ESP
&& s
->popl_esp_hack
) {
2132 disp
+= s
->popl_esp_hack
;
2134 if (base
== R_EBP
|| base
== R_ESP
) {
2143 disp
= x86_lduw_code(env
, s
);
2146 } else if (mod
== 1) {
2147 disp
= (int8_t)x86_ldub_code(env
, s
);
2149 disp
= (int16_t)x86_lduw_code(env
, s
);
2193 return (AddressParts
){ def_seg
, base
, index
, scale
, disp
};
2196 /* Compute the address, with a minimum number of TCG ops. */
2197 static TCGv
gen_lea_modrm_1(DisasContext
*s
, AddressParts a
)
2203 ea
= cpu_regs
[a
.index
];
2205 tcg_gen_shli_tl(s
->A0
, cpu_regs
[a
.index
], a
.scale
);
2209 tcg_gen_add_tl(s
->A0
, ea
, cpu_regs
[a
.base
]);
2212 } else if (a
.base
>= 0) {
2213 ea
= cpu_regs
[a
.base
];
2216 tcg_gen_movi_tl(s
->A0
, a
.disp
);
2218 } else if (a
.disp
!= 0) {
2219 tcg_gen_addi_tl(s
->A0
, ea
, a
.disp
);
2226 static void gen_lea_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2228 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
2229 TCGv ea
= gen_lea_modrm_1(s
, a
);
2230 gen_lea_v_seg(s
, s
->aflag
, ea
, a
.def_seg
, s
->override
);
2233 static void gen_nop_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2235 (void)gen_lea_modrm_0(env
, s
, modrm
);
2238 /* Used for BNDCL, BNDCU, BNDCN. */
2239 static void gen_bndck(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2240 TCGCond cond
, TCGv_i64 bndv
)
2242 TCGv ea
= gen_lea_modrm_1(s
, gen_lea_modrm_0(env
, s
, modrm
));
2244 tcg_gen_extu_tl_i64(s
->tmp1_i64
, ea
);
2246 tcg_gen_ext32u_i64(s
->tmp1_i64
, s
->tmp1_i64
);
2248 tcg_gen_setcond_i64(cond
, s
->tmp1_i64
, s
->tmp1_i64
, bndv
);
2249 tcg_gen_extrl_i64_i32(s
->tmp2_i32
, s
->tmp1_i64
);
2250 gen_helper_bndck(cpu_env
, s
->tmp2_i32
);
2253 /* used for LEA and MOV AX, mem */
2254 static void gen_add_A0_ds_seg(DisasContext
*s
)
2256 gen_lea_v_seg(s
, s
->aflag
, s
->A0
, R_DS
, s
->override
);
2259 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2261 static void gen_ldst_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2262 MemOp ot
, int reg
, int is_store
)
2266 mod
= (modrm
>> 6) & 3;
2267 rm
= (modrm
& 7) | REX_B(s
);
2271 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
2272 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
2274 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
2276 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
2279 gen_lea_modrm(env
, s
, modrm
);
2282 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
2283 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
2285 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
2287 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
2292 static target_ulong
insn_get_addr(CPUX86State
*env
, DisasContext
*s
, MemOp ot
)
2298 ret
= x86_ldub_code(env
, s
);
2301 ret
= x86_lduw_code(env
, s
);
2304 ret
= x86_ldl_code(env
, s
);
2306 #ifdef TARGET_X86_64
2308 ret
= x86_ldq_code(env
, s
);
2312 g_assert_not_reached();
2317 static inline uint32_t insn_get(CPUX86State
*env
, DisasContext
*s
, MemOp ot
)
2323 ret
= x86_ldub_code(env
, s
);
2326 ret
= x86_lduw_code(env
, s
);
2329 #ifdef TARGET_X86_64
2332 ret
= x86_ldl_code(env
, s
);
2340 static inline int insn_const_size(MemOp ot
)
2349 static void gen_goto_tb(DisasContext
*s
, int tb_num
, target_ulong eip
)
2351 target_ulong pc
= s
->cs_base
+ eip
;
2353 if (translator_use_goto_tb(&s
->base
, pc
)) {
2354 /* jump to same page: we can use a direct jump */
2355 tcg_gen_goto_tb(tb_num
);
2357 tcg_gen_exit_tb(s
->base
.tb
, tb_num
);
2358 s
->base
.is_jmp
= DISAS_NORETURN
;
2360 /* jump to another page */
2366 static inline void gen_jcc(DisasContext
*s
, int b
,
2367 target_ulong val
, target_ulong next_eip
)
2372 l1
= gen_new_label();
2375 gen_goto_tb(s
, 0, next_eip
);
2378 gen_goto_tb(s
, 1, val
);
2380 l1
= gen_new_label();
2381 l2
= gen_new_label();
2384 gen_jmp_im(s
, next_eip
);
2394 static void gen_cmovcc1(CPUX86State
*env
, DisasContext
*s
, MemOp ot
, int b
,
2399 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
2401 cc
= gen_prepare_cc(s
, b
, s
->T1
);
2402 if (cc
.mask
!= -1) {
2403 TCGv t0
= tcg_temp_new();
2404 tcg_gen_andi_tl(t0
, cc
.reg
, cc
.mask
);
2408 cc
.reg2
= tcg_const_tl(cc
.imm
);
2411 tcg_gen_movcond_tl(cc
.cond
, s
->T0
, cc
.reg
, cc
.reg2
,
2412 s
->T0
, cpu_regs
[reg
]);
2413 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
2415 if (cc
.mask
!= -1) {
2416 tcg_temp_free(cc
.reg
);
2419 tcg_temp_free(cc
.reg2
);
2423 static inline void gen_op_movl_T0_seg(DisasContext
*s
, X86Seg seg_reg
)
2425 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
2426 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2429 static inline void gen_op_movl_seg_T0_vm(DisasContext
*s
, X86Seg seg_reg
)
2431 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
2432 tcg_gen_st32_tl(s
->T0
, cpu_env
,
2433 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2434 tcg_gen_shli_tl(cpu_seg_base
[seg_reg
], s
->T0
, 4);
2437 /* move T0 to seg_reg and compute if the CPU state may change. Never
2438 call this function with seg_reg == R_CS */
2439 static void gen_movl_seg_T0(DisasContext
*s
, X86Seg seg_reg
)
2441 if (PE(s
) && !VM86(s
)) {
2442 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
2443 gen_helper_load_seg(cpu_env
, tcg_const_i32(seg_reg
), s
->tmp2_i32
);
2444 /* abort translation because the addseg value may change or
2445 because ss32 may change. For R_SS, translation must always
2446 stop as a special handling must be done to disable hardware
2447 interrupts for the next instruction */
2448 if (seg_reg
== R_SS
|| (CODE32(s
) && seg_reg
< R_FS
)) {
2449 s
->base
.is_jmp
= DISAS_TOO_MANY
;
2452 gen_op_movl_seg_T0_vm(s
, seg_reg
);
2453 if (seg_reg
== R_SS
) {
2454 s
->base
.is_jmp
= DISAS_TOO_MANY
;
2459 static void gen_svm_check_intercept(DisasContext
*s
, uint32_t type
)
2461 /* no SVM activated; fast case */
2462 if (likely(!GUEST(s
))) {
2465 gen_helper_svm_check_intercept(cpu_env
, tcg_constant_i32(type
));
2468 static inline void gen_stack_update(DisasContext
*s
, int addend
)
2470 gen_op_add_reg_im(s
, mo_stacksize(s
), R_ESP
, addend
);
2473 /* Generate a push. It depends on ss32, addseg and dflag. */
2474 static void gen_push_v(DisasContext
*s
, TCGv val
)
2476 MemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2477 MemOp a_ot
= mo_stacksize(s
);
2478 int size
= 1 << d_ot
;
2479 TCGv new_esp
= s
->A0
;
2481 tcg_gen_subi_tl(s
->A0
, cpu_regs
[R_ESP
], size
);
2486 tcg_gen_mov_tl(new_esp
, s
->A0
);
2488 gen_lea_v_seg(s
, a_ot
, s
->A0
, R_SS
, -1);
2491 gen_op_st_v(s
, d_ot
, val
, s
->A0
);
2492 gen_op_mov_reg_v(s
, a_ot
, R_ESP
, new_esp
);
2495 /* two step pop is necessary for precise exceptions */
2496 static MemOp
gen_pop_T0(DisasContext
*s
)
2498 MemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2500 gen_lea_v_seg(s
, mo_stacksize(s
), cpu_regs
[R_ESP
], R_SS
, -1);
2501 gen_op_ld_v(s
, d_ot
, s
->T0
, s
->A0
);
2506 static inline void gen_pop_update(DisasContext
*s
, MemOp ot
)
2508 gen_stack_update(s
, 1 << ot
);
2511 static inline void gen_stack_A0(DisasContext
*s
)
2513 gen_lea_v_seg(s
, SS32(s
) ? MO_32
: MO_16
, cpu_regs
[R_ESP
], R_SS
, -1);
2516 static void gen_pusha(DisasContext
*s
)
2518 MemOp s_ot
= SS32(s
) ? MO_32
: MO_16
;
2519 MemOp d_ot
= s
->dflag
;
2520 int size
= 1 << d_ot
;
2523 for (i
= 0; i
< 8; i
++) {
2524 tcg_gen_addi_tl(s
->A0
, cpu_regs
[R_ESP
], (i
- 8) * size
);
2525 gen_lea_v_seg(s
, s_ot
, s
->A0
, R_SS
, -1);
2526 gen_op_st_v(s
, d_ot
, cpu_regs
[7 - i
], s
->A0
);
2529 gen_stack_update(s
, -8 * size
);
2532 static void gen_popa(DisasContext
*s
)
2534 MemOp s_ot
= SS32(s
) ? MO_32
: MO_16
;
2535 MemOp d_ot
= s
->dflag
;
2536 int size
= 1 << d_ot
;
2539 for (i
= 0; i
< 8; i
++) {
2540 /* ESP is not reloaded */
2541 if (7 - i
== R_ESP
) {
2544 tcg_gen_addi_tl(s
->A0
, cpu_regs
[R_ESP
], i
* size
);
2545 gen_lea_v_seg(s
, s_ot
, s
->A0
, R_SS
, -1);
2546 gen_op_ld_v(s
, d_ot
, s
->T0
, s
->A0
);
2547 gen_op_mov_reg_v(s
, d_ot
, 7 - i
, s
->T0
);
2550 gen_stack_update(s
, 8 * size
);
2553 static void gen_enter(DisasContext
*s
, int esp_addend
, int level
)
2555 MemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2556 MemOp a_ot
= CODE64(s
) ? MO_64
: SS32(s
) ? MO_32
: MO_16
;
2557 int size
= 1 << d_ot
;
2559 /* Push BP; compute FrameTemp into T1. */
2560 tcg_gen_subi_tl(s
->T1
, cpu_regs
[R_ESP
], size
);
2561 gen_lea_v_seg(s
, a_ot
, s
->T1
, R_SS
, -1);
2562 gen_op_st_v(s
, d_ot
, cpu_regs
[R_EBP
], s
->A0
);
2568 /* Copy level-1 pointers from the previous frame. */
2569 for (i
= 1; i
< level
; ++i
) {
2570 tcg_gen_subi_tl(s
->A0
, cpu_regs
[R_EBP
], size
* i
);
2571 gen_lea_v_seg(s
, a_ot
, s
->A0
, R_SS
, -1);
2572 gen_op_ld_v(s
, d_ot
, s
->tmp0
, s
->A0
);
2574 tcg_gen_subi_tl(s
->A0
, s
->T1
, size
* i
);
2575 gen_lea_v_seg(s
, a_ot
, s
->A0
, R_SS
, -1);
2576 gen_op_st_v(s
, d_ot
, s
->tmp0
, s
->A0
);
2579 /* Push the current FrameTemp as the last level. */
2580 tcg_gen_subi_tl(s
->A0
, s
->T1
, size
* level
);
2581 gen_lea_v_seg(s
, a_ot
, s
->A0
, R_SS
, -1);
2582 gen_op_st_v(s
, d_ot
, s
->T1
, s
->A0
);
2585 /* Copy the FrameTemp value to EBP. */
2586 gen_op_mov_reg_v(s
, a_ot
, R_EBP
, s
->T1
);
2588 /* Compute the final value of ESP. */
2589 tcg_gen_subi_tl(s
->T1
, s
->T1
, esp_addend
+ size
* level
);
2590 gen_op_mov_reg_v(s
, a_ot
, R_ESP
, s
->T1
);
2593 static void gen_leave(DisasContext
*s
)
2595 MemOp d_ot
= mo_pushpop(s
, s
->dflag
);
2596 MemOp a_ot
= mo_stacksize(s
);
2598 gen_lea_v_seg(s
, a_ot
, cpu_regs
[R_EBP
], R_SS
, -1);
2599 gen_op_ld_v(s
, d_ot
, s
->T0
, s
->A0
);
2601 tcg_gen_addi_tl(s
->T1
, cpu_regs
[R_EBP
], 1 << d_ot
);
2603 gen_op_mov_reg_v(s
, d_ot
, R_EBP
, s
->T0
);
2604 gen_op_mov_reg_v(s
, a_ot
, R_ESP
, s
->T1
);
2607 /* Similarly, except that the assumption here is that we don't decode
2608 the instruction at all -- either a missing opcode, an unimplemented
2609 feature, or just a bogus instruction stream. */
2610 static void gen_unknown_opcode(CPUX86State
*env
, DisasContext
*s
)
2612 gen_illegal_opcode(s
);
2614 if (qemu_loglevel_mask(LOG_UNIMP
)) {
2615 FILE *logfile
= qemu_log_trylock();
2617 target_ulong pc
= s
->pc_start
, end
= s
->pc
;
2619 fprintf(logfile
, "ILLOPC: " TARGET_FMT_lx
":", pc
);
2620 for (; pc
< end
; ++pc
) {
2621 fprintf(logfile
, " %02x", cpu_ldub_code(env
, pc
));
2623 fprintf(logfile
, "\n");
2624 qemu_log_unlock(logfile
);
2629 /* an interrupt is different from an exception because of the
2631 static void gen_interrupt(DisasContext
*s
, int intno
,
2632 target_ulong cur_eip
, target_ulong next_eip
)
2634 gen_update_cc_op(s
);
2635 gen_jmp_im(s
, cur_eip
);
2636 gen_helper_raise_interrupt(cpu_env
, tcg_const_i32(intno
),
2637 tcg_const_i32(next_eip
- cur_eip
));
2638 s
->base
.is_jmp
= DISAS_NORETURN
;
2641 static void gen_set_hflag(DisasContext
*s
, uint32_t mask
)
2643 if ((s
->flags
& mask
) == 0) {
2644 TCGv_i32 t
= tcg_temp_new_i32();
2645 tcg_gen_ld_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2646 tcg_gen_ori_i32(t
, t
, mask
);
2647 tcg_gen_st_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2648 tcg_temp_free_i32(t
);
2653 static void gen_reset_hflag(DisasContext
*s
, uint32_t mask
)
2655 if (s
->flags
& mask
) {
2656 TCGv_i32 t
= tcg_temp_new_i32();
2657 tcg_gen_ld_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2658 tcg_gen_andi_i32(t
, t
, ~mask
);
2659 tcg_gen_st_i32(t
, cpu_env
, offsetof(CPUX86State
, hflags
));
2660 tcg_temp_free_i32(t
);
2665 /* Clear BND registers during legacy branches. */
2666 static void gen_bnd_jmp(DisasContext
*s
)
2668 /* Clear the registers only if BND prefix is missing, MPX is enabled,
2669 and if the BNDREGs are known to be in use (non-zero) already.
2670 The helper itself will check BNDPRESERVE at runtime. */
2671 if ((s
->prefix
& PREFIX_REPNZ
) == 0
2672 && (s
->flags
& HF_MPX_EN_MASK
) != 0
2673 && (s
->flags
& HF_MPX_IU_MASK
) != 0) {
2674 gen_helper_bnd_jmp(cpu_env
);
2678 /* Generate an end of block. Trace exception is also generated if needed.
2679 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set.
2680 If RECHECK_TF, emit a rechecking helper for #DB, ignoring the state of
2681 S->TF. This is used by the syscall/sysret insns. */
2683 do_gen_eob_worker(DisasContext
*s
, bool inhibit
, bool recheck_tf
, bool jr
)
2685 gen_update_cc_op(s
);
2687 /* If several instructions disable interrupts, only the first does it. */
2688 if (inhibit
&& !(s
->flags
& HF_INHIBIT_IRQ_MASK
)) {
2689 gen_set_hflag(s
, HF_INHIBIT_IRQ_MASK
);
2691 gen_reset_hflag(s
, HF_INHIBIT_IRQ_MASK
);
2694 if (s
->base
.tb
->flags
& HF_RF_MASK
) {
2695 gen_helper_reset_rf(cpu_env
);
2698 gen_helper_rechecking_single_step(cpu_env
);
2699 tcg_gen_exit_tb(NULL
, 0);
2700 } else if (s
->flags
& HF_TF_MASK
) {
2701 gen_helper_single_step(cpu_env
);
2703 tcg_gen_lookup_and_goto_ptr();
2705 tcg_gen_exit_tb(NULL
, 0);
2707 s
->base
.is_jmp
= DISAS_NORETURN
;
2711 gen_eob_worker(DisasContext
*s
, bool inhibit
, bool recheck_tf
)
2713 do_gen_eob_worker(s
, inhibit
, recheck_tf
, false);
2717 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set. */
2718 static void gen_eob_inhibit_irq(DisasContext
*s
, bool inhibit
)
2720 gen_eob_worker(s
, inhibit
, false);
2723 /* End of block, resetting the inhibit irq flag. */
2724 static void gen_eob(DisasContext
*s
)
2726 gen_eob_worker(s
, false, false);
2729 /* Jump to register */
2730 static void gen_jr(DisasContext
*s
, TCGv dest
)
2732 do_gen_eob_worker(s
, false, false, true);
2735 /* generate a jump to eip. No segment change must happen before as a
2736 direct call to the next block may occur */
2737 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
)
2739 gen_update_cc_op(s
);
2740 set_cc_op(s
, CC_OP_DYNAMIC
);
2742 gen_goto_tb(s
, tb_num
, eip
);
2749 static void gen_jmp(DisasContext
*s
, target_ulong eip
)
2751 gen_jmp_tb(s
, eip
, 0);
2754 static inline void gen_ldq_env_A0(DisasContext
*s
, int offset
)
2756 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
, s
->mem_index
, MO_LEUQ
);
2757 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, offset
);
2760 static inline void gen_stq_env_A0(DisasContext
*s
, int offset
)
2762 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, offset
);
2763 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
, s
->mem_index
, MO_LEUQ
);
2766 static inline void gen_ldo_env_A0(DisasContext
*s
, int offset
, bool align
)
2768 int mem_index
= s
->mem_index
;
2769 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
, mem_index
,
2770 MO_LEUQ
| (align
? MO_ALIGN_16
: 0));
2771 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2772 tcg_gen_addi_tl(s
->tmp0
, s
->A0
, 8);
2773 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->tmp0
, mem_index
, MO_LEUQ
);
2774 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2777 static inline void gen_sto_env_A0(DisasContext
*s
, int offset
, bool align
)
2779 int mem_index
= s
->mem_index
;
2780 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2781 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
, mem_index
,
2782 MO_LEUQ
| (align
? MO_ALIGN_16
: 0));
2783 tcg_gen_addi_tl(s
->tmp0
, s
->A0
, 8);
2784 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2785 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->tmp0
, mem_index
, MO_LEUQ
);
2788 static inline void gen_op_movo(DisasContext
*s
, int d_offset
, int s_offset
)
2790 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, s_offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2791 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, d_offset
+ offsetof(ZMMReg
, ZMM_Q(0)));
2792 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, s_offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2793 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, d_offset
+ offsetof(ZMMReg
, ZMM_Q(1)));
2796 static inline void gen_op_movq(DisasContext
*s
, int d_offset
, int s_offset
)
2798 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
, s_offset
);
2799 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, d_offset
);
2802 static inline void gen_op_movl(DisasContext
*s
, int d_offset
, int s_offset
)
2804 tcg_gen_ld_i32(s
->tmp2_i32
, cpu_env
, s_offset
);
2805 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
, d_offset
);
2808 static inline void gen_op_movq_env_0(DisasContext
*s
, int d_offset
)
2810 tcg_gen_movi_i64(s
->tmp1_i64
, 0);
2811 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
, d_offset
);
2814 #define ZMM_OFFSET(reg) offsetof(CPUX86State, xmm_regs[reg])
2816 typedef void (*SSEFunc_i_ep
)(TCGv_i32 val
, TCGv_ptr env
, TCGv_ptr reg
);
2817 typedef void (*SSEFunc_l_ep
)(TCGv_i64 val
, TCGv_ptr env
, TCGv_ptr reg
);
2818 typedef void (*SSEFunc_0_epi
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i32 val
);
2819 typedef void (*SSEFunc_0_epl
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i64 val
);
2820 typedef void (*SSEFunc_0_epp
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
);
2821 typedef void (*SSEFunc_0_eppp
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2823 typedef void (*SSEFunc_0_eppi
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2825 typedef void (*SSEFunc_0_ppi
)(TCGv_ptr reg_a
, TCGv_ptr reg_b
, TCGv_i32 val
);
2826 typedef void (*SSEFunc_0_eppt
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2829 #define SSE_OPF_CMP (1 << 1) /* does not write for first operand */
2830 #define SSE_OPF_SPECIAL (1 << 3) /* magic */
2831 #define SSE_OPF_3DNOW (1 << 4) /* 3DNow! instruction */
2832 #define SSE_OPF_MMX (1 << 5) /* MMX/integer/AVX2 instruction */
2833 #define SSE_OPF_SCALAR (1 << 6) /* Has SSE scalar variants */
2834 #define SSE_OPF_SHUF (1 << 9) /* pshufx/shufpx */
2836 #define OP(op, flags, a, b, c, d) \
2837 {flags, {{.op = a}, {.op = b}, {.op = c}, {.op = d} } }
2839 #define MMX_OP(x) OP(op1, SSE_OPF_MMX, \
2840 gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm, NULL, NULL)
2842 #define SSE_FOP(name) OP(op1, SSE_OPF_SCALAR, \
2843 gen_helper_##name##ps##_xmm, gen_helper_##name##pd##_xmm, \
2844 gen_helper_##name##ss, gen_helper_##name##sd)
2845 #define SSE_OP(sname, dname, op, flags) OP(op, flags, \
2846 gen_helper_##sname##_xmm, gen_helper_##dname##_xmm, NULL, NULL)
2848 typedef union SSEFuncs
{
2851 SSEFunc_0_eppt op1t
;
2854 struct SSEOpHelper_table1
{
2859 #define SSE_3DNOW { SSE_OPF_3DNOW }
2860 #define SSE_SPECIAL { SSE_OPF_SPECIAL }
2862 static const struct SSEOpHelper_table1 sse_op_table1
[256] = {
2863 /* 3DNow! extensions */
2864 [0x0e] = SSE_SPECIAL
, /* femms */
2865 [0x0f] = SSE_3DNOW
, /* pf... (sse_op_table5) */
2866 /* pure SSE operations */
2867 [0x10] = SSE_SPECIAL
, /* movups, movupd, movss, movsd */
2868 [0x11] = SSE_SPECIAL
, /* movups, movupd, movss, movsd */
2869 [0x12] = SSE_SPECIAL
, /* movlps, movlpd, movsldup, movddup */
2870 [0x13] = SSE_SPECIAL
, /* movlps, movlpd */
2871 [0x14] = SSE_OP(punpckldq
, punpcklqdq
, op1
, 0), /* unpcklps, unpcklpd */
2872 [0x15] = SSE_OP(punpckhdq
, punpckhqdq
, op1
, 0), /* unpckhps, unpckhpd */
2873 [0x16] = SSE_SPECIAL
, /* movhps, movhpd, movshdup */
2874 [0x17] = SSE_SPECIAL
, /* movhps, movhpd */
2876 [0x28] = SSE_SPECIAL
, /* movaps, movapd */
2877 [0x29] = SSE_SPECIAL
, /* movaps, movapd */
2878 [0x2a] = SSE_SPECIAL
, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2879 [0x2b] = SSE_SPECIAL
, /* movntps, movntpd, movntss, movntsd */
2880 [0x2c] = SSE_SPECIAL
, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2881 [0x2d] = SSE_SPECIAL
, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2882 [0x2e] = OP(op1
, SSE_OPF_CMP
| SSE_OPF_SCALAR
,
2883 gen_helper_ucomiss
, gen_helper_ucomisd
, NULL
, NULL
),
2884 [0x2f] = OP(op1
, SSE_OPF_CMP
| SSE_OPF_SCALAR
,
2885 gen_helper_comiss
, gen_helper_comisd
, NULL
, NULL
),
2886 [0x50] = SSE_SPECIAL
, /* movmskps, movmskpd */
2887 [0x51] = OP(op1
, SSE_OPF_SCALAR
,
2888 gen_helper_sqrtps_xmm
, gen_helper_sqrtpd_xmm
,
2889 gen_helper_sqrtss
, gen_helper_sqrtsd
),
2890 [0x52] = OP(op1
, SSE_OPF_SCALAR
,
2891 gen_helper_rsqrtps_xmm
, NULL
, gen_helper_rsqrtss
, NULL
),
2892 [0x53] = OP(op1
, SSE_OPF_SCALAR
,
2893 gen_helper_rcpps_xmm
, NULL
, gen_helper_rcpss
, NULL
),
2894 [0x54] = SSE_OP(pand
, pand
, op1
, 0), /* andps, andpd */
2895 [0x55] = SSE_OP(pandn
, pandn
, op1
, 0), /* andnps, andnpd */
2896 [0x56] = SSE_OP(por
, por
, op1
, 0), /* orps, orpd */
2897 [0x57] = SSE_OP(pxor
, pxor
, op1
, 0), /* xorps, xorpd */
2898 [0x58] = SSE_FOP(add
),
2899 [0x59] = SSE_FOP(mul
),
2900 [0x5a] = OP(op1
, SSE_OPF_SCALAR
,
2901 gen_helper_cvtps2pd_xmm
, gen_helper_cvtpd2ps_xmm
,
2902 gen_helper_cvtss2sd
, gen_helper_cvtsd2ss
),
2904 gen_helper_cvtdq2ps_xmm
, gen_helper_cvtps2dq_xmm
,
2905 gen_helper_cvttps2dq_xmm
, NULL
),
2906 [0x5c] = SSE_FOP(sub
),
2907 [0x5d] = SSE_FOP(min
),
2908 [0x5e] = SSE_FOP(div
),
2909 [0x5f] = SSE_FOP(max
),
2911 [0xc2] = SSE_FOP(cmpeq
), /* sse_op_table4 */
2912 [0xc6] = SSE_OP(shufps
, shufpd
, op1i
, SSE_OPF_SHUF
),
2914 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */
2915 [0x38] = SSE_SPECIAL
,
2916 [0x3a] = SSE_SPECIAL
,
2918 /* MMX ops and their SSE extensions */
2919 [0x60] = MMX_OP(punpcklbw
),
2920 [0x61] = MMX_OP(punpcklwd
),
2921 [0x62] = MMX_OP(punpckldq
),
2922 [0x63] = MMX_OP(packsswb
),
2923 [0x64] = MMX_OP(pcmpgtb
),
2924 [0x65] = MMX_OP(pcmpgtw
),
2925 [0x66] = MMX_OP(pcmpgtl
),
2926 [0x67] = MMX_OP(packuswb
),
2927 [0x68] = MMX_OP(punpckhbw
),
2928 [0x69] = MMX_OP(punpckhwd
),
2929 [0x6a] = MMX_OP(punpckhdq
),
2930 [0x6b] = MMX_OP(packssdw
),
2931 [0x6c] = OP(op1
, SSE_OPF_MMX
,
2932 NULL
, gen_helper_punpcklqdq_xmm
, NULL
, NULL
),
2933 [0x6d] = OP(op1
, SSE_OPF_MMX
,
2934 NULL
, gen_helper_punpckhqdq_xmm
, NULL
, NULL
),
2935 [0x6e] = SSE_SPECIAL
, /* movd mm, ea */
2936 [0x6f] = SSE_SPECIAL
, /* movq, movdqa, , movqdu */
2937 [0x70] = OP(op1i
, SSE_OPF_SHUF
| SSE_OPF_MMX
,
2938 gen_helper_pshufw_mmx
, gen_helper_pshufd_xmm
,
2939 gen_helper_pshufhw_xmm
, gen_helper_pshuflw_xmm
),
2940 [0x71] = SSE_SPECIAL
, /* shiftw */
2941 [0x72] = SSE_SPECIAL
, /* shiftd */
2942 [0x73] = SSE_SPECIAL
, /* shiftq */
2943 [0x74] = MMX_OP(pcmpeqb
),
2944 [0x75] = MMX_OP(pcmpeqw
),
2945 [0x76] = MMX_OP(pcmpeql
),
2946 [0x77] = SSE_SPECIAL
, /* emms */
2947 [0x78] = SSE_SPECIAL
, /* extrq_i, insertq_i (sse4a) */
2949 NULL
, gen_helper_extrq_r
, NULL
, gen_helper_insertq_r
),
2951 NULL
, gen_helper_haddpd_xmm
, NULL
, gen_helper_haddps_xmm
),
2953 NULL
, gen_helper_hsubpd_xmm
, NULL
, gen_helper_hsubps_xmm
),
2954 [0x7e] = SSE_SPECIAL
, /* movd, movd, , movq */
2955 [0x7f] = SSE_SPECIAL
, /* movq, movdqa, movdqu */
2956 [0xc4] = SSE_SPECIAL
, /* pinsrw */
2957 [0xc5] = SSE_SPECIAL
, /* pextrw */
2959 NULL
, gen_helper_addsubpd_xmm
, NULL
, gen_helper_addsubps_xmm
),
2960 [0xd1] = MMX_OP(psrlw
),
2961 [0xd2] = MMX_OP(psrld
),
2962 [0xd3] = MMX_OP(psrlq
),
2963 [0xd4] = MMX_OP(paddq
),
2964 [0xd5] = MMX_OP(pmullw
),
2965 [0xd6] = SSE_SPECIAL
,
2966 [0xd7] = SSE_SPECIAL
, /* pmovmskb */
2967 [0xd8] = MMX_OP(psubusb
),
2968 [0xd9] = MMX_OP(psubusw
),
2969 [0xda] = MMX_OP(pminub
),
2970 [0xdb] = MMX_OP(pand
),
2971 [0xdc] = MMX_OP(paddusb
),
2972 [0xdd] = MMX_OP(paddusw
),
2973 [0xde] = MMX_OP(pmaxub
),
2974 [0xdf] = MMX_OP(pandn
),
2975 [0xe0] = MMX_OP(pavgb
),
2976 [0xe1] = MMX_OP(psraw
),
2977 [0xe2] = MMX_OP(psrad
),
2978 [0xe3] = MMX_OP(pavgw
),
2979 [0xe4] = MMX_OP(pmulhuw
),
2980 [0xe5] = MMX_OP(pmulhw
),
2982 NULL
, gen_helper_cvttpd2dq_xmm
,
2983 gen_helper_cvtdq2pd_xmm
, gen_helper_cvtpd2dq_xmm
),
2984 [0xe7] = SSE_SPECIAL
, /* movntq, movntq */
2985 [0xe8] = MMX_OP(psubsb
),
2986 [0xe9] = MMX_OP(psubsw
),
2987 [0xea] = MMX_OP(pminsw
),
2988 [0xeb] = MMX_OP(por
),
2989 [0xec] = MMX_OP(paddsb
),
2990 [0xed] = MMX_OP(paddsw
),
2991 [0xee] = MMX_OP(pmaxsw
),
2992 [0xef] = MMX_OP(pxor
),
2993 [0xf0] = SSE_SPECIAL
, /* lddqu */
2994 [0xf1] = MMX_OP(psllw
),
2995 [0xf2] = MMX_OP(pslld
),
2996 [0xf3] = MMX_OP(psllq
),
2997 [0xf4] = MMX_OP(pmuludq
),
2998 [0xf5] = MMX_OP(pmaddwd
),
2999 [0xf6] = MMX_OP(psadbw
),
3000 [0xf7] = OP(op1t
, SSE_OPF_MMX
,
3001 gen_helper_maskmov_mmx
, gen_helper_maskmov_xmm
, NULL
, NULL
),
3002 [0xf8] = MMX_OP(psubb
),
3003 [0xf9] = MMX_OP(psubw
),
3004 [0xfa] = MMX_OP(psubl
),
3005 [0xfb] = MMX_OP(psubq
),
3006 [0xfc] = MMX_OP(paddb
),
3007 [0xfd] = MMX_OP(paddw
),
3008 [0xfe] = MMX_OP(paddl
),
3016 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
3018 static const SSEFunc_0_epp sse_op_table2
[3 * 8][2] = {
3019 [0 + 2] = MMX_OP2(psrlw
),
3020 [0 + 4] = MMX_OP2(psraw
),
3021 [0 + 6] = MMX_OP2(psllw
),
3022 [8 + 2] = MMX_OP2(psrld
),
3023 [8 + 4] = MMX_OP2(psrad
),
3024 [8 + 6] = MMX_OP2(pslld
),
3025 [16 + 2] = MMX_OP2(psrlq
),
3026 [16 + 3] = { NULL
, gen_helper_psrldq_xmm
},
3027 [16 + 6] = MMX_OP2(psllq
),
3028 [16 + 7] = { NULL
, gen_helper_pslldq_xmm
},
3031 static const SSEFunc_0_epi sse_op_table3ai
[] = {
3032 gen_helper_cvtsi2ss
,
3036 #ifdef TARGET_X86_64
3037 static const SSEFunc_0_epl sse_op_table3aq
[] = {
3038 gen_helper_cvtsq2ss
,
3043 static const SSEFunc_i_ep sse_op_table3bi
[] = {
3044 gen_helper_cvttss2si
,
3045 gen_helper_cvtss2si
,
3046 gen_helper_cvttsd2si
,
3050 #ifdef TARGET_X86_64
3051 static const SSEFunc_l_ep sse_op_table3bq
[] = {
3052 gen_helper_cvttss2sq
,
3053 gen_helper_cvtss2sq
,
3054 gen_helper_cvttsd2sq
,
3059 #define SSE_CMP(x) { \
3060 gen_helper_ ## x ## ps ## _xmm, gen_helper_ ## x ## pd ## _xmm, \
3061 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd}
3062 static const SSEFunc_0_epp sse_op_table4
[8][4] = {
3074 static const SSEFunc_0_epp sse_op_table5
[256] = {
3075 [0x0c] = gen_helper_pi2fw
,
3076 [0x0d] = gen_helper_pi2fd
,
3077 [0x1c] = gen_helper_pf2iw
,
3078 [0x1d] = gen_helper_pf2id
,
3079 [0x8a] = gen_helper_pfnacc
,
3080 [0x8e] = gen_helper_pfpnacc
,
3081 [0x90] = gen_helper_pfcmpge
,
3082 [0x94] = gen_helper_pfmin
,
3083 [0x96] = gen_helper_pfrcp
,
3084 [0x97] = gen_helper_pfrsqrt
,
3085 [0x9a] = gen_helper_pfsub
,
3086 [0x9e] = gen_helper_pfadd
,
3087 [0xa0] = gen_helper_pfcmpgt
,
3088 [0xa4] = gen_helper_pfmax
,
3089 [0xa6] = gen_helper_movq
, /* pfrcpit1; no need to actually increase precision */
3090 [0xa7] = gen_helper_movq
, /* pfrsqit1 */
3091 [0xaa] = gen_helper_pfsubr
,
3092 [0xae] = gen_helper_pfacc
,
3093 [0xb0] = gen_helper_pfcmpeq
,
3094 [0xb4] = gen_helper_pfmul
,
3095 [0xb6] = gen_helper_movq
, /* pfrcpit2 */
3096 [0xb7] = gen_helper_pmulhrw_mmx
,
3097 [0xbb] = gen_helper_pswapd
,
3098 [0xbf] = gen_helper_pavgb_mmx
,
3101 struct SSEOpHelper_table6
{
3107 struct SSEOpHelper_table7
{
3115 #define gen_helper_special_xmm NULL
3117 #define OP(name, op, flags, ext, mmx_name) \
3118 {{{.op = mmx_name}, {.op = gen_helper_ ## name ## _xmm} }, \
3119 CPUID_EXT_ ## ext, flags}
3120 #define BINARY_OP_MMX(name, ext) \
3121 OP(name, op1, SSE_OPF_MMX, ext, gen_helper_ ## name ## _mmx)
3122 #define BINARY_OP(name, ext, flags) \
3123 OP(name, op1, flags, ext, NULL)
3124 #define UNARY_OP_MMX(name, ext) \
3125 OP(name, op1, SSE_OPF_MMX, ext, gen_helper_ ## name ## _mmx)
3126 #define UNARY_OP(name, ext, flags) \
3127 OP(name, op1, flags, ext, NULL)
3128 #define BLENDV_OP(name, ext, flags) OP(name, op1, 0, ext, NULL)
3129 #define CMP_OP(name, ext) OP(name, op1, SSE_OPF_CMP, ext, NULL)
3130 #define SPECIAL_OP(ext) OP(special, op1, SSE_OPF_SPECIAL, ext, NULL)
3132 /* prefix [66] 0f 38 */
3133 static const struct SSEOpHelper_table6 sse_op_table6
[256] = {
3134 [0x00] = BINARY_OP_MMX(pshufb
, SSSE3
),
3135 [0x01] = BINARY_OP_MMX(phaddw
, SSSE3
),
3136 [0x02] = BINARY_OP_MMX(phaddd
, SSSE3
),
3137 [0x03] = BINARY_OP_MMX(phaddsw
, SSSE3
),
3138 [0x04] = BINARY_OP_MMX(pmaddubsw
, SSSE3
),
3139 [0x05] = BINARY_OP_MMX(phsubw
, SSSE3
),
3140 [0x06] = BINARY_OP_MMX(phsubd
, SSSE3
),
3141 [0x07] = BINARY_OP_MMX(phsubsw
, SSSE3
),
3142 [0x08] = BINARY_OP_MMX(psignb
, SSSE3
),
3143 [0x09] = BINARY_OP_MMX(psignw
, SSSE3
),
3144 [0x0a] = BINARY_OP_MMX(psignd
, SSSE3
),
3145 [0x0b] = BINARY_OP_MMX(pmulhrsw
, SSSE3
),
3146 [0x10] = BLENDV_OP(pblendvb
, SSE41
, SSE_OPF_MMX
),
3147 [0x14] = BLENDV_OP(blendvps
, SSE41
, 0),
3148 [0x15] = BLENDV_OP(blendvpd
, SSE41
, 0),
3149 [0x17] = CMP_OP(ptest
, SSE41
),
3150 [0x1c] = UNARY_OP_MMX(pabsb
, SSSE3
),
3151 [0x1d] = UNARY_OP_MMX(pabsw
, SSSE3
),
3152 [0x1e] = UNARY_OP_MMX(pabsd
, SSSE3
),
3153 [0x20] = UNARY_OP(pmovsxbw
, SSE41
, SSE_OPF_MMX
),
3154 [0x21] = UNARY_OP(pmovsxbd
, SSE41
, SSE_OPF_MMX
),
3155 [0x22] = UNARY_OP(pmovsxbq
, SSE41
, SSE_OPF_MMX
),
3156 [0x23] = UNARY_OP(pmovsxwd
, SSE41
, SSE_OPF_MMX
),
3157 [0x24] = UNARY_OP(pmovsxwq
, SSE41
, SSE_OPF_MMX
),
3158 [0x25] = UNARY_OP(pmovsxdq
, SSE41
, SSE_OPF_MMX
),
3159 [0x28] = BINARY_OP(pmuldq
, SSE41
, SSE_OPF_MMX
),
3160 [0x29] = BINARY_OP(pcmpeqq
, SSE41
, SSE_OPF_MMX
),
3161 [0x2a] = SPECIAL_OP(SSE41
), /* movntdqa */
3162 [0x2b] = BINARY_OP(packusdw
, SSE41
, SSE_OPF_MMX
),
3163 [0x30] = UNARY_OP(pmovzxbw
, SSE41
, SSE_OPF_MMX
),
3164 [0x31] = UNARY_OP(pmovzxbd
, SSE41
, SSE_OPF_MMX
),
3165 [0x32] = UNARY_OP(pmovzxbq
, SSE41
, SSE_OPF_MMX
),
3166 [0x33] = UNARY_OP(pmovzxwd
, SSE41
, SSE_OPF_MMX
),
3167 [0x34] = UNARY_OP(pmovzxwq
, SSE41
, SSE_OPF_MMX
),
3168 [0x35] = UNARY_OP(pmovzxdq
, SSE41
, SSE_OPF_MMX
),
3169 [0x37] = BINARY_OP(pcmpgtq
, SSE41
, SSE_OPF_MMX
),
3170 [0x38] = BINARY_OP(pminsb
, SSE41
, SSE_OPF_MMX
),
3171 [0x39] = BINARY_OP(pminsd
, SSE41
, SSE_OPF_MMX
),
3172 [0x3a] = BINARY_OP(pminuw
, SSE41
, SSE_OPF_MMX
),
3173 [0x3b] = BINARY_OP(pminud
, SSE41
, SSE_OPF_MMX
),
3174 [0x3c] = BINARY_OP(pmaxsb
, SSE41
, SSE_OPF_MMX
),
3175 [0x3d] = BINARY_OP(pmaxsd
, SSE41
, SSE_OPF_MMX
),
3176 [0x3e] = BINARY_OP(pmaxuw
, SSE41
, SSE_OPF_MMX
),
3177 [0x3f] = BINARY_OP(pmaxud
, SSE41
, SSE_OPF_MMX
),
3178 [0x40] = BINARY_OP(pmulld
, SSE41
, SSE_OPF_MMX
),
3179 [0x41] = UNARY_OP(phminposuw
, SSE41
, 0),
3180 [0xdb] = UNARY_OP(aesimc
, AES
, 0),
3181 [0xdc] = BINARY_OP(aesenc
, AES
, 0),
3182 [0xdd] = BINARY_OP(aesenclast
, AES
, 0),
3183 [0xde] = BINARY_OP(aesdec
, AES
, 0),
3184 [0xdf] = BINARY_OP(aesdeclast
, AES
, 0),
3187 /* prefix [66] 0f 3a */
3188 static const struct SSEOpHelper_table7 sse_op_table7
[256] = {
3189 [0x08] = UNARY_OP(roundps
, SSE41
, 0),
3190 [0x09] = UNARY_OP(roundpd
, SSE41
, 0),
3191 [0x0a] = UNARY_OP(roundss
, SSE41
, SSE_OPF_SCALAR
),
3192 [0x0b] = UNARY_OP(roundsd
, SSE41
, SSE_OPF_SCALAR
),
3193 [0x0c] = BINARY_OP(blendps
, SSE41
, 0),
3194 [0x0d] = BINARY_OP(blendpd
, SSE41
, 0),
3195 [0x0e] = BINARY_OP(pblendw
, SSE41
, SSE_OPF_MMX
),
3196 [0x0f] = BINARY_OP_MMX(palignr
, SSSE3
),
3197 [0x14] = SPECIAL_OP(SSE41
), /* pextrb */
3198 [0x15] = SPECIAL_OP(SSE41
), /* pextrw */
3199 [0x16] = SPECIAL_OP(SSE41
), /* pextrd/pextrq */
3200 [0x17] = SPECIAL_OP(SSE41
), /* extractps */
3201 [0x20] = SPECIAL_OP(SSE41
), /* pinsrb */
3202 [0x21] = SPECIAL_OP(SSE41
), /* insertps */
3203 [0x22] = SPECIAL_OP(SSE41
), /* pinsrd/pinsrq */
3204 [0x40] = BINARY_OP(dpps
, SSE41
, 0),
3205 [0x41] = BINARY_OP(dppd
, SSE41
, 0),
3206 [0x42] = BINARY_OP(mpsadbw
, SSE41
, SSE_OPF_MMX
),
3207 [0x44] = BINARY_OP(pclmulqdq
, PCLMULQDQ
, 0),
3208 [0x60] = CMP_OP(pcmpestrm
, SSE42
),
3209 [0x61] = CMP_OP(pcmpestri
, SSE42
),
3210 [0x62] = CMP_OP(pcmpistrm
, SSE42
),
3211 [0x63] = CMP_OP(pcmpistri
, SSE42
),
3212 [0xdf] = UNARY_OP(aeskeygenassist
, AES
, 0),
3216 #undef BINARY_OP_MMX
3223 /* VEX prefix not allowed */
3224 #define CHECK_NO_VEX(s) do { \
3225 if (s->prefix & PREFIX_VEX) \
3229 static void gen_sse(CPUX86State
*env
, DisasContext
*s
, int b
,
3230 target_ulong pc_start
)
3232 int b1
, op1_offset
, op2_offset
, is_xmm
, val
;
3233 int modrm
, mod
, rm
, reg
;
3236 const struct SSEOpHelper_table6
*op6
;
3237 const struct SSEOpHelper_table7
*op7
;
3241 if (s
->prefix
& PREFIX_DATA
)
3243 else if (s
->prefix
& PREFIX_REPZ
)
3245 else if (s
->prefix
& PREFIX_REPNZ
)
3249 sse_op_flags
= sse_op_table1
[b
].flags
;
3250 sse_op_fn
= sse_op_table1
[b
].fn
[b1
];
3251 if ((sse_op_flags
& (SSE_OPF_SPECIAL
| SSE_OPF_3DNOW
)) == 0
3252 && !sse_op_fn
.op1
) {
3255 if ((b
<= 0x5f && b
>= 0x10) || b
== 0xc6 || b
== 0xc2) {
3265 if (sse_op_flags
& SSE_OPF_3DNOW
) {
3266 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
)) {
3270 /* simple MMX/SSE operation */
3271 if (s
->flags
& HF_TS_MASK
) {
3272 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
3275 if (s
->flags
& HF_EM_MASK
) {
3277 gen_illegal_opcode(s
);
3281 && !(s
->flags
& HF_OSFXSR_MASK
)
3282 && (b
!= 0x38 && b
!= 0x3a)) {
3286 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
)) {
3287 /* If we were fully decoding this we might use illegal_op. */
3291 gen_helper_emms(cpu_env
);
3296 gen_helper_emms(cpu_env
);
3299 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3300 the static cpu state) */
3302 gen_helper_enter_mmx(cpu_env
);
3305 modrm
= x86_ldub_code(env
, s
);
3306 reg
= ((modrm
>> 3) & 7);
3310 mod
= (modrm
>> 6) & 3;
3311 if (sse_op_flags
& SSE_OPF_SPECIAL
) {
3314 case 0x0e7: /* movntq */
3319 gen_lea_modrm(env
, s
, modrm
);
3320 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3322 case 0x1e7: /* movntdq */
3323 case 0x02b: /* movntps */
3324 case 0x12b: /* movntpd */
3327 gen_lea_modrm(env
, s
, modrm
);
3328 gen_sto_env_A0(s
, ZMM_OFFSET(reg
), true);
3330 case 0x3f0: /* lddqu */
3333 gen_lea_modrm(env
, s
, modrm
);
3334 gen_ldo_env_A0(s
, ZMM_OFFSET(reg
), false);
3336 case 0x22b: /* movntss */
3337 case 0x32b: /* movntsd */
3340 gen_lea_modrm(env
, s
, modrm
);
3342 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3343 xmm_regs
[reg
].ZMM_Q(0)));
3345 tcg_gen_ld32u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
3346 xmm_regs
[reg
].ZMM_L(0)));
3347 gen_op_st_v(s
, MO_32
, s
->T0
, s
->A0
);
3350 case 0x6e: /* movd mm, ea */
3352 #ifdef TARGET_X86_64
3353 if (s
->dflag
== MO_64
) {
3354 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3355 tcg_gen_st_tl(s
->T0
, cpu_env
,
3356 offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3360 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3361 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3362 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3363 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
3364 gen_helper_movl_mm_T0_mmx(s
->ptr0
, s
->tmp2_i32
);
3367 case 0x16e: /* movd xmm, ea */
3368 #ifdef TARGET_X86_64
3369 if (s
->dflag
== MO_64
) {
3370 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3371 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, ZMM_OFFSET(reg
));
3372 gen_helper_movq_mm_T0_xmm(s
->ptr0
, s
->T0
);
3376 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3377 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, ZMM_OFFSET(reg
));
3378 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
3379 gen_helper_movl_mm_T0_xmm(s
->ptr0
, s
->tmp2_i32
);
3382 case 0x6f: /* movq mm, ea */
3385 gen_lea_modrm(env
, s
, modrm
);
3386 gen_ldq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3389 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
,
3390 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3391 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
,
3392 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3395 case 0x010: /* movups */
3396 case 0x110: /* movupd */
3397 case 0x028: /* movaps */
3398 case 0x128: /* movapd */
3399 case 0x16f: /* movdqa xmm, ea */
3400 case 0x26f: /* movdqu xmm, ea */
3402 gen_lea_modrm(env
, s
, modrm
);
3403 gen_ldo_env_A0(s
, ZMM_OFFSET(reg
),
3404 /* movaps, movapd, movdqa */
3405 b
== 0x028 || b
== 0x128 || b
== 0x16f);
3407 rm
= (modrm
& 7) | REX_B(s
);
3408 gen_op_movo(s
, ZMM_OFFSET(reg
), ZMM_OFFSET(rm
));
3411 case 0x210: /* movss xmm, ea */
3413 gen_lea_modrm(env
, s
, modrm
);
3414 gen_op_ld_v(s
, MO_32
, s
->T0
, s
->A0
);
3415 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3416 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(0)));
3417 tcg_gen_movi_tl(s
->T0
, 0);
3418 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3419 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(1)));
3420 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3421 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(2)));
3422 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3423 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(3)));
3425 rm
= (modrm
& 7) | REX_B(s
);
3426 tcg_gen_ld_i32(s
->tmp2_i32
, cpu_env
,
3427 offsetof(CPUX86State
, xmm_regs
[rm
].ZMM_L(0)));
3428 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
,
3429 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(0)));
3432 case 0x310: /* movsd xmm, ea */
3434 gen_lea_modrm(env
, s
, modrm
);
3435 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3436 xmm_regs
[reg
].ZMM_Q(0)));
3437 tcg_gen_movi_tl(s
->T0
, 0);
3438 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3439 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(2)));
3440 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3441 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(3)));
3443 rm
= (modrm
& 7) | REX_B(s
);
3444 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(0)),
3445 offsetof(CPUX86State
, xmm_regs
[rm
].ZMM_Q(0)));
3448 case 0x012: /* movlps */
3449 case 0x112: /* movlpd */
3451 gen_lea_modrm(env
, s
, modrm
);
3452 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3453 xmm_regs
[reg
].ZMM_Q(0)));
3456 rm
= (modrm
& 7) | REX_B(s
);
3457 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(0)),
3458 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(1)));
3461 case 0x212: /* movsldup */
3463 gen_lea_modrm(env
, s
, modrm
);
3464 gen_ldo_env_A0(s
, ZMM_OFFSET(reg
), true);
3466 rm
= (modrm
& 7) | REX_B(s
);
3467 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(0)),
3468 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(0)));
3469 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(2)),
3470 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(2)));
3472 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(1)),
3473 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3474 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(3)),
3475 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(2)));
3477 case 0x312: /* movddup */
3479 gen_lea_modrm(env
, s
, modrm
);
3480 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3481 xmm_regs
[reg
].ZMM_Q(0)));
3483 rm
= (modrm
& 7) | REX_B(s
);
3484 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(0)),
3485 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3487 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(1)),
3488 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3490 case 0x016: /* movhps */
3491 case 0x116: /* movhpd */
3493 gen_lea_modrm(env
, s
, modrm
);
3494 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3495 xmm_regs
[reg
].ZMM_Q(1)));
3498 rm
= (modrm
& 7) | REX_B(s
);
3499 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(1)),
3500 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3503 case 0x216: /* movshdup */
3505 gen_lea_modrm(env
, s
, modrm
);
3506 gen_ldo_env_A0(s
, ZMM_OFFSET(reg
), true);
3508 rm
= (modrm
& 7) | REX_B(s
);
3509 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(1)),
3510 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(1)));
3511 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(3)),
3512 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_L(3)));
3514 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(0)),
3515 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(1)));
3516 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(2)),
3517 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(3)));
3523 int bit_index
, field_length
;
3525 if (b1
== 1 && reg
!= 0)
3527 field_length
= x86_ldub_code(env
, s
) & 0x3F;
3528 bit_index
= x86_ldub_code(env
, s
) & 0x3F;
3529 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, ZMM_OFFSET(reg
));
3531 gen_helper_extrq_i(cpu_env
, s
->ptr0
,
3532 tcg_const_i32(bit_index
),
3533 tcg_const_i32(field_length
));
3536 gen_lea_modrm(env
, s
, modrm
);
3537 op2_offset
= offsetof(CPUX86State
, xmm_t0
);
3538 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.ZMM_D(0)));
3540 rm
= (modrm
& 7) | REX_B(s
);
3541 op2_offset
= ZMM_OFFSET(rm
);
3543 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
3544 gen_helper_insertq_i(cpu_env
, s
->ptr0
, s
->ptr1
,
3545 tcg_const_i32(bit_index
),
3546 tcg_const_i32(field_length
));
3550 case 0x7e: /* movd ea, mm */
3552 #ifdef TARGET_X86_64
3553 if (s
->dflag
== MO_64
) {
3554 tcg_gen_ld_i64(s
->T0
, cpu_env
,
3555 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3556 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3560 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
3561 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_L(0)));
3562 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3565 case 0x17e: /* movd ea, xmm */
3566 #ifdef TARGET_X86_64
3567 if (s
->dflag
== MO_64
) {
3568 tcg_gen_ld_i64(s
->T0
, cpu_env
,
3569 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3570 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3574 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
3575 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3576 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3579 case 0x27e: /* movq xmm, ea */
3581 gen_lea_modrm(env
, s
, modrm
);
3582 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3583 xmm_regs
[reg
].ZMM_Q(0)));
3585 rm
= (modrm
& 7) | REX_B(s
);
3586 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(0)),
3587 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3589 gen_op_movq_env_0(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(1)));
3591 case 0x7f: /* movq ea, mm */
3594 gen_lea_modrm(env
, s
, modrm
);
3595 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3598 gen_op_movq(s
, offsetof(CPUX86State
, fpregs
[rm
].mmx
),
3599 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3602 case 0x011: /* movups */
3603 case 0x111: /* movupd */
3604 case 0x029: /* movaps */
3605 case 0x129: /* movapd */
3606 case 0x17f: /* movdqa ea, xmm */
3607 case 0x27f: /* movdqu ea, xmm */
3609 gen_lea_modrm(env
, s
, modrm
);
3610 gen_sto_env_A0(s
, ZMM_OFFSET(reg
),
3611 /* movaps, movapd, movdqa */
3612 b
== 0x029 || b
== 0x129 || b
== 0x17f);
3614 rm
= (modrm
& 7) | REX_B(s
);
3615 gen_op_movo(s
, ZMM_OFFSET(rm
), ZMM_OFFSET(reg
));
3618 case 0x211: /* movss ea, xmm */
3620 gen_lea_modrm(env
, s
, modrm
);
3621 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
3622 offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_L(0)));
3623 gen_op_st_v(s
, MO_32
, s
->T0
, s
->A0
);
3625 rm
= (modrm
& 7) | REX_B(s
);
3626 gen_op_movl(s
, offsetof(CPUX86State
, xmm_regs
[rm
].ZMM_L(0)),
3627 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_L(0)));
3630 case 0x311: /* movsd ea, xmm */
3632 gen_lea_modrm(env
, s
, modrm
);
3633 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3634 xmm_regs
[reg
].ZMM_Q(0)));
3636 rm
= (modrm
& 7) | REX_B(s
);
3637 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[rm
].ZMM_Q(0)),
3638 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3641 case 0x013: /* movlps */
3642 case 0x113: /* movlpd */
3644 gen_lea_modrm(env
, s
, modrm
);
3645 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3646 xmm_regs
[reg
].ZMM_Q(0)));
3651 case 0x017: /* movhps */
3652 case 0x117: /* movhpd */
3654 gen_lea_modrm(env
, s
, modrm
);
3655 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3656 xmm_regs
[reg
].ZMM_Q(1)));
3661 case 0x71: /* shift mm, im */
3664 case 0x171: /* shift xmm, im */
3667 val
= x86_ldub_code(env
, s
);
3669 tcg_gen_movi_tl(s
->T0
, val
);
3670 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3671 offsetof(CPUX86State
, xmm_t0
.ZMM_L(0)));
3672 tcg_gen_movi_tl(s
->T0
, 0);
3673 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3674 offsetof(CPUX86State
, xmm_t0
.ZMM_L(1)));
3675 op1_offset
= offsetof(CPUX86State
,xmm_t0
);
3678 tcg_gen_movi_tl(s
->T0
, val
);
3679 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3680 offsetof(CPUX86State
, mmx_t0
.MMX_L(0)));
3681 tcg_gen_movi_tl(s
->T0
, 0);
3682 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3683 offsetof(CPUX86State
, mmx_t0
.MMX_L(1)));
3684 op1_offset
= offsetof(CPUX86State
,mmx_t0
);
3687 SSEFunc_0_epp fn
= sse_op_table2
[((b
- 1) & 3) * 8 +
3688 (((modrm
>> 3)) & 7)][b1
];
3693 rm
= (modrm
& 7) | REX_B(s
);
3694 op2_offset
= ZMM_OFFSET(rm
);
3697 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3699 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op2_offset
);
3700 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op1_offset
);
3701 fn(cpu_env
, s
->ptr0
, s
->ptr1
);
3703 case 0x050: /* movmskps */
3704 rm
= (modrm
& 7) | REX_B(s
);
3705 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, ZMM_OFFSET(rm
));
3706 gen_helper_movmskps_xmm(s
->tmp2_i32
, cpu_env
, s
->ptr0
);
3707 tcg_gen_extu_i32_tl(cpu_regs
[reg
], s
->tmp2_i32
);
3709 case 0x150: /* movmskpd */
3710 rm
= (modrm
& 7) | REX_B(s
);
3711 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, ZMM_OFFSET(rm
));
3712 gen_helper_movmskpd_xmm(s
->tmp2_i32
, cpu_env
, s
->ptr0
);
3713 tcg_gen_extu_i32_tl(cpu_regs
[reg
], s
->tmp2_i32
);
3715 case 0x02a: /* cvtpi2ps */
3716 case 0x12a: /* cvtpi2pd */
3718 gen_helper_enter_mmx(cpu_env
);
3720 gen_lea_modrm(env
, s
, modrm
);
3721 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3722 gen_ldq_env_A0(s
, op2_offset
);
3725 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3727 op1_offset
= ZMM_OFFSET(reg
);
3728 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
3729 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
3732 gen_helper_cvtpi2ps(cpu_env
, s
->ptr0
, s
->ptr1
);
3736 gen_helper_cvtpi2pd(cpu_env
, s
->ptr0
, s
->ptr1
);
3740 case 0x22a: /* cvtsi2ss */
3741 case 0x32a: /* cvtsi2sd */
3742 ot
= mo_64_32(s
->dflag
);
3743 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3744 op1_offset
= ZMM_OFFSET(reg
);
3745 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
3747 SSEFunc_0_epi sse_fn_epi
= sse_op_table3ai
[(b
>> 8) & 1];
3748 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
3749 sse_fn_epi(cpu_env
, s
->ptr0
, s
->tmp2_i32
);
3751 #ifdef TARGET_X86_64
3752 SSEFunc_0_epl sse_fn_epl
= sse_op_table3aq
[(b
>> 8) & 1];
3753 sse_fn_epl(cpu_env
, s
->ptr0
, s
->T0
);
3759 case 0x02c: /* cvttps2pi */
3760 case 0x12c: /* cvttpd2pi */
3761 case 0x02d: /* cvtps2pi */
3762 case 0x12d: /* cvtpd2pi */
3764 gen_helper_enter_mmx(cpu_env
);
3766 gen_lea_modrm(env
, s
, modrm
);
3767 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3768 /* FIXME: should be 64-bit access if b1 == 0. */
3769 gen_ldo_env_A0(s
, op2_offset
, !!b1
);
3771 rm
= (modrm
& 7) | REX_B(s
);
3772 op2_offset
= ZMM_OFFSET(rm
);
3774 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
);
3775 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
3776 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
3779 gen_helper_cvttps2pi(cpu_env
, s
->ptr0
, s
->ptr1
);
3782 gen_helper_cvttpd2pi(cpu_env
, s
->ptr0
, s
->ptr1
);
3785 gen_helper_cvtps2pi(cpu_env
, s
->ptr0
, s
->ptr1
);
3788 gen_helper_cvtpd2pi(cpu_env
, s
->ptr0
, s
->ptr1
);
3792 case 0x22c: /* cvttss2si */
3793 case 0x32c: /* cvttsd2si */
3794 case 0x22d: /* cvtss2si */
3795 case 0x32d: /* cvtsd2si */
3796 ot
= mo_64_32(s
->dflag
);
3798 gen_lea_modrm(env
, s
, modrm
);
3800 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.ZMM_Q(0)));
3802 gen_op_ld_v(s
, MO_32
, s
->T0
, s
->A0
);
3803 tcg_gen_st32_tl(s
->T0
, cpu_env
,
3804 offsetof(CPUX86State
, xmm_t0
.ZMM_L(0)));
3806 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3808 rm
= (modrm
& 7) | REX_B(s
);
3809 op2_offset
= ZMM_OFFSET(rm
);
3811 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op2_offset
);
3813 SSEFunc_i_ep sse_fn_i_ep
=
3814 sse_op_table3bi
[((b
>> 7) & 2) | (b
& 1)];
3815 sse_fn_i_ep(s
->tmp2_i32
, cpu_env
, s
->ptr0
);
3816 tcg_gen_extu_i32_tl(s
->T0
, s
->tmp2_i32
);
3818 #ifdef TARGET_X86_64
3819 SSEFunc_l_ep sse_fn_l_ep
=
3820 sse_op_table3bq
[((b
>> 7) & 2) | (b
& 1)];
3821 sse_fn_l_ep(s
->T0
, cpu_env
, s
->ptr0
);
3826 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
3828 case 0xc4: /* pinsrw */
3831 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
3832 val
= x86_ldub_code(env
, s
);
3835 tcg_gen_st16_tl(s
->T0
, cpu_env
,
3836 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_W(val
)));
3840 tcg_gen_st16_tl(s
->T0
, cpu_env
,
3841 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_W(val
)));
3844 case 0xc5: /* pextrw */
3848 ot
= mo_64_32(s
->dflag
);
3849 val
= x86_ldub_code(env
, s
);
3852 rm
= (modrm
& 7) | REX_B(s
);
3853 tcg_gen_ld16u_tl(s
->T0
, cpu_env
,
3854 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_W(val
)));
3858 tcg_gen_ld16u_tl(s
->T0
, cpu_env
,
3859 offsetof(CPUX86State
,fpregs
[rm
].mmx
.MMX_W(val
)));
3861 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
3862 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
3864 case 0x1d6: /* movq ea, xmm */
3866 gen_lea_modrm(env
, s
, modrm
);
3867 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3868 xmm_regs
[reg
].ZMM_Q(0)));
3870 rm
= (modrm
& 7) | REX_B(s
);
3871 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[rm
].ZMM_Q(0)),
3872 offsetof(CPUX86State
,xmm_regs
[reg
].ZMM_Q(0)));
3873 gen_op_movq_env_0(s
,
3874 offsetof(CPUX86State
, xmm_regs
[rm
].ZMM_Q(1)));
3877 case 0x2d6: /* movq2dq */
3879 gen_helper_enter_mmx(cpu_env
);
3881 gen_op_movq(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(0)),
3882 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3883 gen_op_movq_env_0(s
, offsetof(CPUX86State
, xmm_regs
[reg
].ZMM_Q(1)));
3885 case 0x3d6: /* movdq2q */
3887 gen_helper_enter_mmx(cpu_env
);
3888 rm
= (modrm
& 7) | REX_B(s
);
3889 gen_op_movq(s
, offsetof(CPUX86State
, fpregs
[reg
& 7].mmx
),
3890 offsetof(CPUX86State
,xmm_regs
[rm
].ZMM_Q(0)));
3892 case 0xd7: /* pmovmskb */
3897 rm
= (modrm
& 7) | REX_B(s
);
3898 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, ZMM_OFFSET(rm
));
3899 gen_helper_pmovmskb_xmm(s
->tmp2_i32
, cpu_env
, s
->ptr0
);
3903 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
,
3904 offsetof(CPUX86State
, fpregs
[rm
].mmx
));
3905 gen_helper_pmovmskb_mmx(s
->tmp2_i32
, cpu_env
, s
->ptr0
);
3907 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
3908 tcg_gen_extu_i32_tl(cpu_regs
[reg
], s
->tmp2_i32
);
3914 if ((b
& 0xf0) == 0xf0) {
3917 modrm
= x86_ldub_code(env
, s
);
3919 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
3920 mod
= (modrm
>> 6) & 3;
3923 op6
= &sse_op_table6
[b
];
3924 if (op6
->ext_mask
== 0) {
3927 if (!(s
->cpuid_ext_features
& op6
->ext_mask
)) {
3932 op1_offset
= ZMM_OFFSET(reg
);
3934 op2_offset
= ZMM_OFFSET(rm
| REX_B(s
));
3936 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3937 gen_lea_modrm(env
, s
, modrm
);
3939 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3940 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3941 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3942 gen_ldq_env_A0(s
, op2_offset
+
3943 offsetof(ZMMReg
, ZMM_Q(0)));
3945 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3946 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3947 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
3948 s
->mem_index
, MO_LEUL
);
3949 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
, op2_offset
+
3950 offsetof(ZMMReg
, ZMM_L(0)));
3952 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3953 tcg_gen_qemu_ld_tl(s
->tmp0
, s
->A0
,
3954 s
->mem_index
, MO_LEUW
);
3955 tcg_gen_st16_tl(s
->tmp0
, cpu_env
, op2_offset
+
3956 offsetof(ZMMReg
, ZMM_W(0)));
3958 case 0x2a: /* movntdqa */
3959 gen_ldo_env_A0(s
, op1_offset
, true);
3962 gen_ldo_env_A0(s
, op2_offset
, true);
3965 if (!op6
->fn
[b1
].op1
) {
3968 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
3969 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
3970 op6
->fn
[b1
].op1(cpu_env
, s
->ptr0
, s
->ptr1
);
3973 if ((op6
->flags
& SSE_OPF_MMX
) == 0) {
3976 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
3978 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3980 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3981 gen_lea_modrm(env
, s
, modrm
);
3982 gen_ldq_env_A0(s
, op2_offset
);
3984 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
3985 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
3986 op6
->fn
[0].op1(cpu_env
, s
->ptr0
, s
->ptr1
);
3989 if (op6
->flags
& SSE_OPF_CMP
) {
3990 set_cc_op(s
, CC_OP_EFLAGS
);
3997 /* Various integer extensions at 0f 38 f[0-f]. */
3998 b
= modrm
| (b1
<< 8);
3999 modrm
= x86_ldub_code(env
, s
);
4000 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
4003 case 0x3f0: /* crc32 Gd,Eb */
4004 case 0x3f1: /* crc32 Gd,Ey */
4007 if (!(s
->cpuid_ext_features
& CPUID_EXT_SSE42
)) {
4010 if ((b
& 0xff) == 0xf0) {
4012 } else if (s
->dflag
!= MO_64
) {
4013 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
4018 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[reg
]);
4019 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4020 gen_helper_crc32(s
->T0
, s
->tmp2_i32
,
4021 s
->T0
, tcg_const_i32(8 << ot
));
4023 ot
= mo_64_32(s
->dflag
);
4024 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
4027 case 0x1f0: /* crc32 or movbe */
4030 /* For these insns, the f3 prefix is supposed to have priority
4031 over the 66 prefix, but that's not what we implement above
4033 if (s
->prefix
& PREFIX_REPNZ
) {
4037 case 0x0f0: /* movbe Gy,My */
4038 case 0x0f1: /* movbe My,Gy */
4040 if (!(s
->cpuid_ext_features
& CPUID_EXT_MOVBE
)) {
4043 if (s
->dflag
!= MO_64
) {
4044 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
4049 gen_lea_modrm(env
, s
, modrm
);
4051 tcg_gen_qemu_ld_tl(s
->T0
, s
->A0
,
4052 s
->mem_index
, ot
| MO_BE
);
4053 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
4055 tcg_gen_qemu_st_tl(cpu_regs
[reg
], s
->A0
,
4056 s
->mem_index
, ot
| MO_BE
);
4060 case 0x0f2: /* andn Gy, By, Ey */
4061 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
4062 || !(s
->prefix
& PREFIX_VEX
)
4066 ot
= mo_64_32(s
->dflag
);
4067 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4068 tcg_gen_andc_tl(s
->T0
, s
->T0
, cpu_regs
[s
->vex_v
]);
4069 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
4070 gen_op_update1_cc(s
);
4071 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4074 case 0x0f7: /* bextr Gy, Ey, By */
4075 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
4076 || !(s
->prefix
& PREFIX_VEX
)
4080 ot
= mo_64_32(s
->dflag
);
4084 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4085 /* Extract START, and shift the operand.
4086 Shifts larger than operand size get zeros. */
4087 tcg_gen_ext8u_tl(s
->A0
, cpu_regs
[s
->vex_v
]);
4088 tcg_gen_shr_tl(s
->T0
, s
->T0
, s
->A0
);
4090 bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
4091 zero
= tcg_const_tl(0);
4092 tcg_gen_movcond_tl(TCG_COND_LEU
, s
->T0
, s
->A0
, bound
,
4094 tcg_temp_free(zero
);
4096 /* Extract the LEN into a mask. Lengths larger than
4097 operand size get all ones. */
4098 tcg_gen_extract_tl(s
->A0
, cpu_regs
[s
->vex_v
], 8, 8);
4099 tcg_gen_movcond_tl(TCG_COND_LEU
, s
->A0
, s
->A0
, bound
,
4101 tcg_temp_free(bound
);
4102 tcg_gen_movi_tl(s
->T1
, 1);
4103 tcg_gen_shl_tl(s
->T1
, s
->T1
, s
->A0
);
4104 tcg_gen_subi_tl(s
->T1
, s
->T1
, 1);
4105 tcg_gen_and_tl(s
->T0
, s
->T0
, s
->T1
);
4107 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
4108 gen_op_update1_cc(s
);
4109 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4113 case 0x0f5: /* bzhi Gy, Ey, By */
4114 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4115 || !(s
->prefix
& PREFIX_VEX
)
4119 ot
= mo_64_32(s
->dflag
);
4120 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4121 tcg_gen_ext8u_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
4123 TCGv bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
4124 /* Note that since we're using BMILG (in order to get O
4125 cleared) we need to store the inverse into C. */
4126 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_cc_src
,
4128 tcg_gen_movcond_tl(TCG_COND_GT
, s
->T1
, s
->T1
,
4129 bound
, bound
, s
->T1
);
4130 tcg_temp_free(bound
);
4132 tcg_gen_movi_tl(s
->A0
, -1);
4133 tcg_gen_shl_tl(s
->A0
, s
->A0
, s
->T1
);
4134 tcg_gen_andc_tl(s
->T0
, s
->T0
, s
->A0
);
4135 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
4136 gen_op_update1_cc(s
);
4137 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4140 case 0x3f6: /* mulx By, Gy, rdx, Ey */
4141 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4142 || !(s
->prefix
& PREFIX_VEX
)
4146 ot
= mo_64_32(s
->dflag
);
4147 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4150 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
4151 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, cpu_regs
[R_EDX
]);
4152 tcg_gen_mulu2_i32(s
->tmp2_i32
, s
->tmp3_i32
,
4153 s
->tmp2_i32
, s
->tmp3_i32
);
4154 tcg_gen_extu_i32_tl(cpu_regs
[s
->vex_v
], s
->tmp2_i32
);
4155 tcg_gen_extu_i32_tl(cpu_regs
[reg
], s
->tmp3_i32
);
4157 #ifdef TARGET_X86_64
4159 tcg_gen_mulu2_i64(s
->T0
, s
->T1
,
4160 s
->T0
, cpu_regs
[R_EDX
]);
4161 tcg_gen_mov_i64(cpu_regs
[s
->vex_v
], s
->T0
);
4162 tcg_gen_mov_i64(cpu_regs
[reg
], s
->T1
);
4168 case 0x3f5: /* pdep Gy, By, Ey */
4169 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4170 || !(s
->prefix
& PREFIX_VEX
)
4174 ot
= mo_64_32(s
->dflag
);
4175 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4176 /* Note that by zero-extending the source operand, we
4177 automatically handle zero-extending the result. */
4179 tcg_gen_mov_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
4181 tcg_gen_ext32u_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
4183 gen_helper_pdep(cpu_regs
[reg
], s
->T1
, s
->T0
);
4186 case 0x2f5: /* pext Gy, By, Ey */
4187 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4188 || !(s
->prefix
& PREFIX_VEX
)
4192 ot
= mo_64_32(s
->dflag
);
4193 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4194 /* Note that by zero-extending the source operand, we
4195 automatically handle zero-extending the result. */
4197 tcg_gen_mov_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
4199 tcg_gen_ext32u_tl(s
->T1
, cpu_regs
[s
->vex_v
]);
4201 gen_helper_pext(cpu_regs
[reg
], s
->T1
, s
->T0
);
4204 case 0x1f6: /* adcx Gy, Ey */
4205 case 0x2f6: /* adox Gy, Ey */
4207 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_ADX
)) {
4210 TCGv carry_in
, carry_out
, zero
;
4213 ot
= mo_64_32(s
->dflag
);
4214 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4216 /* Re-use the carry-out from a previous round. */
4218 carry_out
= (b
== 0x1f6 ? cpu_cc_dst
: cpu_cc_src2
);
4222 carry_in
= cpu_cc_dst
;
4223 end_op
= CC_OP_ADCX
;
4225 end_op
= CC_OP_ADCOX
;
4230 end_op
= CC_OP_ADCOX
;
4232 carry_in
= cpu_cc_src2
;
4233 end_op
= CC_OP_ADOX
;
4237 end_op
= CC_OP_ADCOX
;
4238 carry_in
= carry_out
;
4241 end_op
= (b
== 0x1f6 ? CC_OP_ADCX
: CC_OP_ADOX
);
4244 /* If we can't reuse carry-out, get it out of EFLAGS. */
4246 if (s
->cc_op
!= CC_OP_ADCX
&& s
->cc_op
!= CC_OP_ADOX
) {
4247 gen_compute_eflags(s
);
4250 tcg_gen_extract_tl(carry_in
, cpu_cc_src
,
4251 ctz32(b
== 0x1f6 ? CC_C
: CC_O
), 1);
4255 #ifdef TARGET_X86_64
4257 /* If we know TL is 64-bit, and we want a 32-bit
4258 result, just do everything in 64-bit arithmetic. */
4259 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_regs
[reg
]);
4260 tcg_gen_ext32u_i64(s
->T0
, s
->T0
);
4261 tcg_gen_add_i64(s
->T0
, s
->T0
, cpu_regs
[reg
]);
4262 tcg_gen_add_i64(s
->T0
, s
->T0
, carry_in
);
4263 tcg_gen_ext32u_i64(cpu_regs
[reg
], s
->T0
);
4264 tcg_gen_shri_i64(carry_out
, s
->T0
, 32);
4268 /* Otherwise compute the carry-out in two steps. */
4269 zero
= tcg_const_tl(0);
4270 tcg_gen_add2_tl(s
->T0
, carry_out
,
4273 tcg_gen_add2_tl(cpu_regs
[reg
], carry_out
,
4274 cpu_regs
[reg
], carry_out
,
4276 tcg_temp_free(zero
);
4279 set_cc_op(s
, end_op
);
4283 case 0x1f7: /* shlx Gy, Ey, By */
4284 case 0x2f7: /* sarx Gy, Ey, By */
4285 case 0x3f7: /* shrx Gy, Ey, By */
4286 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4287 || !(s
->prefix
& PREFIX_VEX
)
4291 ot
= mo_64_32(s
->dflag
);
4292 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4294 tcg_gen_andi_tl(s
->T1
, cpu_regs
[s
->vex_v
], 63);
4296 tcg_gen_andi_tl(s
->T1
, cpu_regs
[s
->vex_v
], 31);
4299 tcg_gen_shl_tl(s
->T0
, s
->T0
, s
->T1
);
4300 } else if (b
== 0x2f7) {
4302 tcg_gen_ext32s_tl(s
->T0
, s
->T0
);
4304 tcg_gen_sar_tl(s
->T0
, s
->T0
, s
->T1
);
4307 tcg_gen_ext32u_tl(s
->T0
, s
->T0
);
4309 tcg_gen_shr_tl(s
->T0
, s
->T0
, s
->T1
);
4311 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
4317 case 0x3f3: /* Group 17 */
4318 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
4319 || !(s
->prefix
& PREFIX_VEX
)
4323 ot
= mo_64_32(s
->dflag
);
4324 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4326 tcg_gen_mov_tl(cpu_cc_src
, s
->T0
);
4328 case 1: /* blsr By,Ey */
4329 tcg_gen_subi_tl(s
->T1
, s
->T0
, 1);
4330 tcg_gen_and_tl(s
->T0
, s
->T0
, s
->T1
);
4332 case 2: /* blsmsk By,Ey */
4333 tcg_gen_subi_tl(s
->T1
, s
->T0
, 1);
4334 tcg_gen_xor_tl(s
->T0
, s
->T0
, s
->T1
);
4336 case 3: /* blsi By, Ey */
4337 tcg_gen_neg_tl(s
->T1
, s
->T0
);
4338 tcg_gen_and_tl(s
->T0
, s
->T0
, s
->T1
);
4343 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
4344 gen_op_mov_reg_v(s
, ot
, s
->vex_v
, s
->T0
);
4345 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4356 modrm
= x86_ldub_code(env
, s
);
4358 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
4359 mod
= (modrm
>> 6) & 3;
4362 op7
= &sse_op_table7
[b
];
4363 if (op7
->ext_mask
== 0) {
4366 if (!(s
->cpuid_ext_features
& op7
->ext_mask
)) {
4372 if (op7
->flags
& SSE_OPF_SPECIAL
) {
4373 /* None of the "special" ops are valid on mmx registers */
4377 ot
= mo_64_32(s
->dflag
);
4378 rm
= (modrm
& 7) | REX_B(s
);
4380 gen_lea_modrm(env
, s
, modrm
);
4381 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
4382 val
= x86_ldub_code(env
, s
);
4384 case 0x14: /* pextrb */
4385 tcg_gen_ld8u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
4386 xmm_regs
[reg
].ZMM_B(val
& 15)));
4388 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
4390 tcg_gen_qemu_st_tl(s
->T0
, s
->A0
,
4391 s
->mem_index
, MO_UB
);
4394 case 0x15: /* pextrw */
4395 tcg_gen_ld16u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
4396 xmm_regs
[reg
].ZMM_W(val
& 7)));
4398 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
4400 tcg_gen_qemu_st_tl(s
->T0
, s
->A0
,
4401 s
->mem_index
, MO_LEUW
);
4405 if (ot
== MO_32
) { /* pextrd */
4406 tcg_gen_ld_i32(s
->tmp2_i32
, cpu_env
,
4407 offsetof(CPUX86State
,
4408 xmm_regs
[reg
].ZMM_L(val
& 3)));
4410 tcg_gen_extu_i32_tl(cpu_regs
[rm
], s
->tmp2_i32
);
4412 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
4413 s
->mem_index
, MO_LEUL
);
4415 } else { /* pextrq */
4416 #ifdef TARGET_X86_64
4417 tcg_gen_ld_i64(s
->tmp1_i64
, cpu_env
,
4418 offsetof(CPUX86State
,
4419 xmm_regs
[reg
].ZMM_Q(val
& 1)));
4421 tcg_gen_mov_i64(cpu_regs
[rm
], s
->tmp1_i64
);
4423 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
,
4424 s
->mem_index
, MO_LEUQ
);
4431 case 0x17: /* extractps */
4432 tcg_gen_ld32u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
4433 xmm_regs
[reg
].ZMM_L(val
& 3)));
4435 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
4437 tcg_gen_qemu_st_tl(s
->T0
, s
->A0
,
4438 s
->mem_index
, MO_LEUL
);
4441 case 0x20: /* pinsrb */
4443 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, rm
);
4445 tcg_gen_qemu_ld_tl(s
->T0
, s
->A0
,
4446 s
->mem_index
, MO_UB
);
4448 tcg_gen_st8_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
,
4449 xmm_regs
[reg
].ZMM_B(val
& 15)));
4451 case 0x21: /* insertps */
4453 tcg_gen_ld_i32(s
->tmp2_i32
, cpu_env
,
4454 offsetof(CPUX86State
,xmm_regs
[rm
]
4455 .ZMM_L((val
>> 6) & 3)));
4457 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
4458 s
->mem_index
, MO_LEUL
);
4460 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
,
4461 offsetof(CPUX86State
,xmm_regs
[reg
]
4462 .ZMM_L((val
>> 4) & 3)));
4464 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4465 cpu_env
, offsetof(CPUX86State
,
4466 xmm_regs
[reg
].ZMM_L(0)));
4468 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4469 cpu_env
, offsetof(CPUX86State
,
4470 xmm_regs
[reg
].ZMM_L(1)));
4472 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4473 cpu_env
, offsetof(CPUX86State
,
4474 xmm_regs
[reg
].ZMM_L(2)));
4476 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4477 cpu_env
, offsetof(CPUX86State
,
4478 xmm_regs
[reg
].ZMM_L(3)));
4481 if (ot
== MO_32
) { /* pinsrd */
4483 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[rm
]);
4485 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
4486 s
->mem_index
, MO_LEUL
);
4488 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
,
4489 offsetof(CPUX86State
,
4490 xmm_regs
[reg
].ZMM_L(val
& 3)));
4491 } else { /* pinsrq */
4492 #ifdef TARGET_X86_64
4494 gen_op_mov_v_reg(s
, ot
, s
->tmp1_i64
, rm
);
4496 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
,
4497 s
->mem_index
, MO_LEUQ
);
4499 tcg_gen_st_i64(s
->tmp1_i64
, cpu_env
,
4500 offsetof(CPUX86State
,
4501 xmm_regs
[reg
].ZMM_Q(val
& 1)));
4514 if ((op7
->flags
& SSE_OPF_MMX
) == 0) {
4517 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4519 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4521 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4522 gen_lea_modrm(env
, s
, modrm
);
4523 gen_ldq_env_A0(s
, op2_offset
);
4525 val
= x86_ldub_code(env
, s
);
4526 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
4527 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
4529 /* We only actually have one MMX instuction (palignr) */
4532 op7
->fn
[0].op1(cpu_env
, s
->ptr0
, s
->ptr1
,
4533 tcg_const_i32(val
));
4538 op1_offset
= ZMM_OFFSET(reg
);
4540 op2_offset
= ZMM_OFFSET(rm
| REX_B(s
));
4542 op2_offset
= offsetof(CPUX86State
, xmm_t0
);
4543 gen_lea_modrm(env
, s
, modrm
);
4544 gen_ldo_env_A0(s
, op2_offset
, true);
4547 val
= x86_ldub_code(env
, s
);
4548 if ((b
& 0xfc) == 0x60) { /* pcmpXstrX */
4549 set_cc_op(s
, CC_OP_EFLAGS
);
4551 if (s
->dflag
== MO_64
) {
4552 /* The helper must use entire 64-bit gp registers */
4557 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
4558 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
4559 op7
->fn
[b1
].op1(cpu_env
, s
->ptr0
, s
->ptr1
, tcg_const_i32(val
));
4560 if (op7
->flags
& SSE_OPF_CMP
) {
4561 set_cc_op(s
, CC_OP_EFLAGS
);
4566 /* Various integer extensions at 0f 3a f[0-f]. */
4567 b
= modrm
| (b1
<< 8);
4568 modrm
= x86_ldub_code(env
, s
);
4569 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
4572 case 0x3f0: /* rorx Gy,Ey, Ib */
4573 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4574 || !(s
->prefix
& PREFIX_VEX
)
4578 ot
= mo_64_32(s
->dflag
);
4579 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4580 b
= x86_ldub_code(env
, s
);
4582 tcg_gen_rotri_tl(s
->T0
, s
->T0
, b
& 63);
4584 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
4585 tcg_gen_rotri_i32(s
->tmp2_i32
, s
->tmp2_i32
, b
& 31);
4586 tcg_gen_extu_i32_tl(s
->T0
, s
->tmp2_i32
);
4588 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
4598 gen_unknown_opcode(env
, s
);
4602 /* generic MMX or SSE operation */
4604 case 0x70: /* pshufx insn */
4605 case 0xc6: /* pshufx insn */
4606 case 0xc2: /* compare insns */
4613 op1_offset
= ZMM_OFFSET(reg
);
4617 gen_lea_modrm(env
, s
, modrm
);
4618 op2_offset
= offsetof(CPUX86State
, xmm_t0
);
4620 if (sse_op_flags
& SSE_OPF_SCALAR
) {
4621 if (sse_op_flags
& SSE_OPF_CMP
) {
4622 /* ucomis[sd], comis[sd] */
4629 /* Most sse scalar operations. */
4632 } else if (b1
== 3) {
4641 gen_op_ld_v(s
, MO_32
, s
->T0
, s
->A0
);
4642 tcg_gen_st32_tl(s
->T0
, cpu_env
,
4643 offsetof(CPUX86State
, xmm_t0
.ZMM_L(0)));
4647 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.ZMM_D(0)));
4650 /* 128 bit access */
4651 gen_ldo_env_A0(s
, op2_offset
, true);
4655 rm
= (modrm
& 7) | REX_B(s
);
4656 op2_offset
= ZMM_OFFSET(rm
);
4660 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4662 gen_lea_modrm(env
, s
, modrm
);
4663 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4664 gen_ldq_env_A0(s
, op2_offset
);
4667 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4669 if (sse_op_flags
& SSE_OPF_3DNOW
) {
4670 /* 3DNow! data insns */
4671 val
= x86_ldub_code(env
, s
);
4672 SSEFunc_0_epp op_3dnow
= sse_op_table5
[val
];
4676 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
4677 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
4678 op_3dnow(cpu_env
, s
->ptr0
, s
->ptr1
);
4682 tcg_gen_addi_ptr(s
->ptr0
, cpu_env
, op1_offset
);
4683 tcg_gen_addi_ptr(s
->ptr1
, cpu_env
, op2_offset
);
4684 if (sse_op_flags
& SSE_OPF_SHUF
) {
4685 val
= x86_ldub_code(env
, s
);
4686 sse_op_fn
.op1i(s
->ptr0
, s
->ptr1
, tcg_const_i32(val
));
4687 } else if (b
== 0xf7) {
4688 /* maskmov : we must prepare A0 */
4692 tcg_gen_mov_tl(s
->A0
, cpu_regs
[R_EDI
]);
4693 gen_extu(s
->aflag
, s
->A0
);
4694 gen_add_A0_ds_seg(s
);
4695 sse_op_fn
.op1t(cpu_env
, s
->ptr0
, s
->ptr1
, s
->A0
);
4696 } else if (b
== 0xc2) {
4697 /* compare insns, bits 7:3 (7:5 for AVX) are ignored */
4698 val
= x86_ldub_code(env
, s
) & 7;
4699 sse_op_table4
[val
][b1
](cpu_env
, s
->ptr0
, s
->ptr1
);
4701 sse_op_fn
.op1(cpu_env
, s
->ptr0
, s
->ptr1
);
4704 if (sse_op_flags
& SSE_OPF_CMP
) {
4705 set_cc_op(s
, CC_OP_EFLAGS
);
4710 /* convert one instruction. s->base.is_jmp is set if the translation must
4711 be stopped. Return the next pc value */
4712 static target_ulong
disas_insn(DisasContext
*s
, CPUState
*cpu
)
4714 CPUX86State
*env
= cpu
->env_ptr
;
4717 MemOp ot
, aflag
, dflag
;
4718 int modrm
, reg
, rm
, mod
, op
, opreg
, val
;
4719 target_ulong next_eip
, tval
;
4720 target_ulong pc_start
= s
->base
.pc_next
;
4721 bool orig_cc_op_dirty
= s
->cc_op_dirty
;
4722 CCOp orig_cc_op
= s
->cc_op
;
4724 s
->pc_start
= s
->pc
= pc_start
;
4726 #ifdef TARGET_X86_64
4732 s
->rip_offset
= 0; /* for relative ip address */
4735 switch (sigsetjmp(s
->jmpbuf
, 0)) {
4739 gen_exception_gpf(s
);
4742 /* Restore state that may affect the next instruction. */
4743 s
->cc_op_dirty
= orig_cc_op_dirty
;
4744 s
->cc_op
= orig_cc_op
;
4745 s
->base
.num_insns
--;
4746 tcg_remove_ops_after(s
->prev_insn_end
);
4747 s
->base
.is_jmp
= DISAS_TOO_MANY
;
4750 g_assert_not_reached();
4756 b
= x86_ldub_code(env
, s
);
4757 /* Collect prefixes. */
4760 prefixes
|= PREFIX_REPZ
;
4761 prefixes
&= ~PREFIX_REPNZ
;
4764 prefixes
|= PREFIX_REPNZ
;
4765 prefixes
&= ~PREFIX_REPZ
;
4768 prefixes
|= PREFIX_LOCK
;
4789 prefixes
|= PREFIX_DATA
;
4792 prefixes
|= PREFIX_ADR
;
4794 #ifdef TARGET_X86_64
4798 prefixes
|= PREFIX_REX
;
4799 s
->rex_w
= (b
>> 3) & 1;
4800 s
->rex_r
= (b
& 0x4) << 1;
4801 s
->rex_x
= (b
& 0x2) << 2;
4802 s
->rex_b
= (b
& 0x1) << 3;
4807 case 0xc5: /* 2-byte VEX */
4808 case 0xc4: /* 3-byte VEX */
4809 /* VEX prefixes cannot be used except in 32-bit mode.
4810 Otherwise the instruction is LES or LDS. */
4811 if (CODE32(s
) && !VM86(s
)) {
4812 static const int pp_prefix
[4] = {
4813 0, PREFIX_DATA
, PREFIX_REPZ
, PREFIX_REPNZ
4815 int vex3
, vex2
= x86_ldub_code(env
, s
);
4817 if (!CODE64(s
) && (vex2
& 0xc0) != 0xc0) {
4818 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4819 otherwise the instruction is LES or LDS. */
4820 s
->pc
--; /* rewind the advance_pc() x86_ldub_code() did */
4824 /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
4825 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
4826 | PREFIX_LOCK
| PREFIX_DATA
| PREFIX_REX
)) {
4829 #ifdef TARGET_X86_64
4830 s
->rex_r
= (~vex2
>> 4) & 8;
4833 /* 2-byte VEX prefix: RVVVVlpp, implied 0f leading opcode byte */
4835 b
= x86_ldub_code(env
, s
) | 0x100;
4837 /* 3-byte VEX prefix: RXBmmmmm wVVVVlpp */
4838 vex3
= x86_ldub_code(env
, s
);
4839 #ifdef TARGET_X86_64
4840 s
->rex_x
= (~vex2
>> 3) & 8;
4841 s
->rex_b
= (~vex2
>> 2) & 8;
4842 s
->rex_w
= (vex3
>> 7) & 1;
4844 switch (vex2
& 0x1f) {
4845 case 0x01: /* Implied 0f leading opcode bytes. */
4846 b
= x86_ldub_code(env
, s
) | 0x100;
4848 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4851 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4854 default: /* Reserved for future use. */
4858 s
->vex_v
= (~vex3
>> 3) & 0xf;
4859 s
->vex_l
= (vex3
>> 2) & 1;
4860 prefixes
|= pp_prefix
[vex3
& 3] | PREFIX_VEX
;
4865 /* Post-process prefixes. */
4867 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit
4868 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4869 over 0x66 if both are present. */
4870 dflag
= (REX_W(s
) ? MO_64
: prefixes
& PREFIX_DATA
? MO_16
: MO_32
);
4871 /* In 64-bit mode, 0x67 selects 32-bit addressing. */
4872 aflag
= (prefixes
& PREFIX_ADR
? MO_32
: MO_64
);
4874 /* In 16/32-bit mode, 0x66 selects the opposite data size. */
4875 if (CODE32(s
) ^ ((prefixes
& PREFIX_DATA
) != 0)) {
4880 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */
4881 if (CODE32(s
) ^ ((prefixes
& PREFIX_ADR
) != 0)) {
4888 s
->prefix
= prefixes
;
4892 /* now check op code */
4896 /**************************/
4897 /* extended op code */
4898 b
= x86_ldub_code(env
, s
) | 0x100;
4901 /**************************/
4916 ot
= mo_b_d(b
, dflag
);
4919 case 0: /* OP Ev, Gv */
4920 modrm
= x86_ldub_code(env
, s
);
4921 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
4922 mod
= (modrm
>> 6) & 3;
4923 rm
= (modrm
& 7) | REX_B(s
);
4925 gen_lea_modrm(env
, s
, modrm
);
4927 } else if (op
== OP_XORL
&& rm
== reg
) {
4929 /* xor reg, reg optimisation */
4930 set_cc_op(s
, CC_OP_CLR
);
4931 tcg_gen_movi_tl(s
->T0
, 0);
4932 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
4937 gen_op_mov_v_reg(s
, ot
, s
->T1
, reg
);
4938 gen_op(s
, op
, ot
, opreg
);
4940 case 1: /* OP Gv, Ev */
4941 modrm
= x86_ldub_code(env
, s
);
4942 mod
= (modrm
>> 6) & 3;
4943 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
4944 rm
= (modrm
& 7) | REX_B(s
);
4946 gen_lea_modrm(env
, s
, modrm
);
4947 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
4948 } else if (op
== OP_XORL
&& rm
== reg
) {
4951 gen_op_mov_v_reg(s
, ot
, s
->T1
, rm
);
4953 gen_op(s
, op
, ot
, reg
);
4955 case 2: /* OP A, Iv */
4956 val
= insn_get(env
, s
, ot
);
4957 tcg_gen_movi_tl(s
->T1
, val
);
4958 gen_op(s
, op
, ot
, OR_EAX
);
4968 case 0x80: /* GRP1 */
4974 ot
= mo_b_d(b
, dflag
);
4976 modrm
= x86_ldub_code(env
, s
);
4977 mod
= (modrm
>> 6) & 3;
4978 rm
= (modrm
& 7) | REX_B(s
);
4979 op
= (modrm
>> 3) & 7;
4985 s
->rip_offset
= insn_const_size(ot
);
4986 gen_lea_modrm(env
, s
, modrm
);
4997 val
= insn_get(env
, s
, ot
);
5000 val
= (int8_t)insn_get(env
, s
, MO_8
);
5003 tcg_gen_movi_tl(s
->T1
, val
);
5004 gen_op(s
, op
, ot
, opreg
);
5008 /**************************/
5009 /* inc, dec, and other misc arith */
5010 case 0x40 ... 0x47: /* inc Gv */
5012 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), 1);
5014 case 0x48 ... 0x4f: /* dec Gv */
5016 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), -1);
5018 case 0xf6: /* GRP3 */
5020 ot
= mo_b_d(b
, dflag
);
5022 modrm
= x86_ldub_code(env
, s
);
5023 mod
= (modrm
>> 6) & 3;
5024 rm
= (modrm
& 7) | REX_B(s
);
5025 op
= (modrm
>> 3) & 7;
5028 s
->rip_offset
= insn_const_size(ot
);
5030 gen_lea_modrm(env
, s
, modrm
);
5031 /* For those below that handle locked memory, don't load here. */
5032 if (!(s
->prefix
& PREFIX_LOCK
)
5034 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
5037 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
5042 val
= insn_get(env
, s
, ot
);
5043 tcg_gen_movi_tl(s
->T1
, val
);
5044 gen_op_testl_T0_T1_cc(s
);
5045 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5048 if (s
->prefix
& PREFIX_LOCK
) {
5052 tcg_gen_movi_tl(s
->T0
, ~0);
5053 tcg_gen_atomic_xor_fetch_tl(s
->T0
, s
->A0
, s
->T0
,
5054 s
->mem_index
, ot
| MO_LE
);
5056 tcg_gen_not_tl(s
->T0
, s
->T0
);
5058 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
5060 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
5065 if (s
->prefix
& PREFIX_LOCK
) {
5067 TCGv a0
, t0
, t1
, t2
;
5072 a0
= tcg_temp_local_new();
5073 t0
= tcg_temp_local_new();
5074 label1
= gen_new_label();
5076 tcg_gen_mov_tl(a0
, s
->A0
);
5077 tcg_gen_mov_tl(t0
, s
->T0
);
5079 gen_set_label(label1
);
5080 t1
= tcg_temp_new();
5081 t2
= tcg_temp_new();
5082 tcg_gen_mov_tl(t2
, t0
);
5083 tcg_gen_neg_tl(t1
, t0
);
5084 tcg_gen_atomic_cmpxchg_tl(t0
, a0
, t0
, t1
,
5085 s
->mem_index
, ot
| MO_LE
);
5087 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t2
, label1
);
5091 tcg_gen_mov_tl(s
->T0
, t0
);
5094 tcg_gen_neg_tl(s
->T0
, s
->T0
);
5096 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
5098 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
5101 gen_op_update_neg_cc(s
);
5102 set_cc_op(s
, CC_OP_SUBB
+ ot
);
5107 gen_op_mov_v_reg(s
, MO_8
, s
->T1
, R_EAX
);
5108 tcg_gen_ext8u_tl(s
->T0
, s
->T0
);
5109 tcg_gen_ext8u_tl(s
->T1
, s
->T1
);
5110 /* XXX: use 32 bit mul which could be faster */
5111 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
5112 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
5113 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
5114 tcg_gen_andi_tl(cpu_cc_src
, s
->T0
, 0xff00);
5115 set_cc_op(s
, CC_OP_MULB
);
5118 gen_op_mov_v_reg(s
, MO_16
, s
->T1
, R_EAX
);
5119 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
5120 tcg_gen_ext16u_tl(s
->T1
, s
->T1
);
5121 /* XXX: use 32 bit mul which could be faster */
5122 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
5123 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
5124 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
5125 tcg_gen_shri_tl(s
->T0
, s
->T0
, 16);
5126 gen_op_mov_reg_v(s
, MO_16
, R_EDX
, s
->T0
);
5127 tcg_gen_mov_tl(cpu_cc_src
, s
->T0
);
5128 set_cc_op(s
, CC_OP_MULW
);
5132 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
5133 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, cpu_regs
[R_EAX
]);
5134 tcg_gen_mulu2_i32(s
->tmp2_i32
, s
->tmp3_i32
,
5135 s
->tmp2_i32
, s
->tmp3_i32
);
5136 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], s
->tmp2_i32
);
5137 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], s
->tmp3_i32
);
5138 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
5139 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
5140 set_cc_op(s
, CC_OP_MULL
);
5142 #ifdef TARGET_X86_64
5144 tcg_gen_mulu2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
5145 s
->T0
, cpu_regs
[R_EAX
]);
5146 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
5147 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
5148 set_cc_op(s
, CC_OP_MULQ
);
5156 gen_op_mov_v_reg(s
, MO_8
, s
->T1
, R_EAX
);
5157 tcg_gen_ext8s_tl(s
->T0
, s
->T0
);
5158 tcg_gen_ext8s_tl(s
->T1
, s
->T1
);
5159 /* XXX: use 32 bit mul which could be faster */
5160 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
5161 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
5162 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
5163 tcg_gen_ext8s_tl(s
->tmp0
, s
->T0
);
5164 tcg_gen_sub_tl(cpu_cc_src
, s
->T0
, s
->tmp0
);
5165 set_cc_op(s
, CC_OP_MULB
);
5168 gen_op_mov_v_reg(s
, MO_16
, s
->T1
, R_EAX
);
5169 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5170 tcg_gen_ext16s_tl(s
->T1
, s
->T1
);
5171 /* XXX: use 32 bit mul which could be faster */
5172 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
5173 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
5174 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
5175 tcg_gen_ext16s_tl(s
->tmp0
, s
->T0
);
5176 tcg_gen_sub_tl(cpu_cc_src
, s
->T0
, s
->tmp0
);
5177 tcg_gen_shri_tl(s
->T0
, s
->T0
, 16);
5178 gen_op_mov_reg_v(s
, MO_16
, R_EDX
, s
->T0
);
5179 set_cc_op(s
, CC_OP_MULW
);
5183 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
5184 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, cpu_regs
[R_EAX
]);
5185 tcg_gen_muls2_i32(s
->tmp2_i32
, s
->tmp3_i32
,
5186 s
->tmp2_i32
, s
->tmp3_i32
);
5187 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], s
->tmp2_i32
);
5188 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], s
->tmp3_i32
);
5189 tcg_gen_sari_i32(s
->tmp2_i32
, s
->tmp2_i32
, 31);
5190 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
5191 tcg_gen_sub_i32(s
->tmp2_i32
, s
->tmp2_i32
, s
->tmp3_i32
);
5192 tcg_gen_extu_i32_tl(cpu_cc_src
, s
->tmp2_i32
);
5193 set_cc_op(s
, CC_OP_MULL
);
5195 #ifdef TARGET_X86_64
5197 tcg_gen_muls2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
5198 s
->T0
, cpu_regs
[R_EAX
]);
5199 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
5200 tcg_gen_sari_tl(cpu_cc_src
, cpu_regs
[R_EAX
], 63);
5201 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_regs
[R_EDX
]);
5202 set_cc_op(s
, CC_OP_MULQ
);
5210 gen_helper_divb_AL(cpu_env
, s
->T0
);
5213 gen_helper_divw_AX(cpu_env
, s
->T0
);
5217 gen_helper_divl_EAX(cpu_env
, s
->T0
);
5219 #ifdef TARGET_X86_64
5221 gen_helper_divq_EAX(cpu_env
, s
->T0
);
5229 gen_helper_idivb_AL(cpu_env
, s
->T0
);
5232 gen_helper_idivw_AX(cpu_env
, s
->T0
);
5236 gen_helper_idivl_EAX(cpu_env
, s
->T0
);
5238 #ifdef TARGET_X86_64
5240 gen_helper_idivq_EAX(cpu_env
, s
->T0
);
5250 case 0xfe: /* GRP4 */
5251 case 0xff: /* GRP5 */
5252 ot
= mo_b_d(b
, dflag
);
5254 modrm
= x86_ldub_code(env
, s
);
5255 mod
= (modrm
>> 6) & 3;
5256 rm
= (modrm
& 7) | REX_B(s
);
5257 op
= (modrm
>> 3) & 7;
5258 if (op
>= 2 && b
== 0xfe) {
5262 if (op
== 2 || op
== 4) {
5263 /* operand size for jumps is 64 bit */
5265 } else if (op
== 3 || op
== 5) {
5266 ot
= dflag
!= MO_16
? MO_32
+ REX_W(s
) : MO_16
;
5267 } else if (op
== 6) {
5268 /* default push size is 64 bit */
5269 ot
= mo_pushpop(s
, dflag
);
5273 gen_lea_modrm(env
, s
, modrm
);
5274 if (op
>= 2 && op
!= 3 && op
!= 5)
5275 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
5277 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
5281 case 0: /* inc Ev */
5286 gen_inc(s
, ot
, opreg
, 1);
5288 case 1: /* dec Ev */
5293 gen_inc(s
, ot
, opreg
, -1);
5295 case 2: /* call Ev */
5296 /* XXX: optimize if memory (no 'and' is necessary) */
5297 if (dflag
== MO_16
) {
5298 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
5300 next_eip
= s
->pc
- s
->cs_base
;
5301 tcg_gen_movi_tl(s
->T1
, next_eip
);
5302 gen_push_v(s
, s
->T1
);
5303 gen_op_jmp_v(s
->T0
);
5307 case 3: /* lcall Ev */
5311 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
5312 gen_add_A0_im(s
, 1 << ot
);
5313 gen_op_ld_v(s
, MO_16
, s
->T0
, s
->A0
);
5315 if (PE(s
) && !VM86(s
)) {
5316 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
5317 gen_helper_lcall_protected(cpu_env
, s
->tmp2_i32
, s
->T1
,
5318 tcg_const_i32(dflag
- 1),
5319 tcg_const_tl(s
->pc
- s
->cs_base
));
5321 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
5322 gen_helper_lcall_real(cpu_env
, s
->tmp2_i32
, s
->T1
,
5323 tcg_const_i32(dflag
- 1),
5324 tcg_const_i32(s
->pc
- s
->cs_base
));
5326 tcg_gen_ld_tl(s
->tmp4
, cpu_env
, offsetof(CPUX86State
, eip
));
5329 case 4: /* jmp Ev */
5330 if (dflag
== MO_16
) {
5331 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
5333 gen_op_jmp_v(s
->T0
);
5337 case 5: /* ljmp Ev */
5341 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
5342 gen_add_A0_im(s
, 1 << ot
);
5343 gen_op_ld_v(s
, MO_16
, s
->T0
, s
->A0
);
5345 if (PE(s
) && !VM86(s
)) {
5346 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
5347 gen_helper_ljmp_protected(cpu_env
, s
->tmp2_i32
, s
->T1
,
5348 tcg_const_tl(s
->pc
- s
->cs_base
));
5350 gen_op_movl_seg_T0_vm(s
, R_CS
);
5351 gen_op_jmp_v(s
->T1
);
5353 tcg_gen_ld_tl(s
->tmp4
, cpu_env
, offsetof(CPUX86State
, eip
));
5356 case 6: /* push Ev */
5357 gen_push_v(s
, s
->T0
);
5364 case 0x84: /* test Ev, Gv */
5366 ot
= mo_b_d(b
, dflag
);
5368 modrm
= x86_ldub_code(env
, s
);
5369 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5371 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5372 gen_op_mov_v_reg(s
, ot
, s
->T1
, reg
);
5373 gen_op_testl_T0_T1_cc(s
);
5374 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5377 case 0xa8: /* test eAX, Iv */
5379 ot
= mo_b_d(b
, dflag
);
5380 val
= insn_get(env
, s
, ot
);
5382 gen_op_mov_v_reg(s
, ot
, s
->T0
, OR_EAX
);
5383 tcg_gen_movi_tl(s
->T1
, val
);
5384 gen_op_testl_T0_T1_cc(s
);
5385 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5388 case 0x98: /* CWDE/CBW */
5390 #ifdef TARGET_X86_64
5392 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, R_EAX
);
5393 tcg_gen_ext32s_tl(s
->T0
, s
->T0
);
5394 gen_op_mov_reg_v(s
, MO_64
, R_EAX
, s
->T0
);
5398 gen_op_mov_v_reg(s
, MO_16
, s
->T0
, R_EAX
);
5399 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5400 gen_op_mov_reg_v(s
, MO_32
, R_EAX
, s
->T0
);
5403 gen_op_mov_v_reg(s
, MO_8
, s
->T0
, R_EAX
);
5404 tcg_gen_ext8s_tl(s
->T0
, s
->T0
);
5405 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
5411 case 0x99: /* CDQ/CWD */
5413 #ifdef TARGET_X86_64
5415 gen_op_mov_v_reg(s
, MO_64
, s
->T0
, R_EAX
);
5416 tcg_gen_sari_tl(s
->T0
, s
->T0
, 63);
5417 gen_op_mov_reg_v(s
, MO_64
, R_EDX
, s
->T0
);
5421 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, R_EAX
);
5422 tcg_gen_ext32s_tl(s
->T0
, s
->T0
);
5423 tcg_gen_sari_tl(s
->T0
, s
->T0
, 31);
5424 gen_op_mov_reg_v(s
, MO_32
, R_EDX
, s
->T0
);
5427 gen_op_mov_v_reg(s
, MO_16
, s
->T0
, R_EAX
);
5428 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5429 tcg_gen_sari_tl(s
->T0
, s
->T0
, 15);
5430 gen_op_mov_reg_v(s
, MO_16
, R_EDX
, s
->T0
);
5436 case 0x1af: /* imul Gv, Ev */
5437 case 0x69: /* imul Gv, Ev, I */
5440 modrm
= x86_ldub_code(env
, s
);
5441 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5443 s
->rip_offset
= insn_const_size(ot
);
5446 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5448 val
= insn_get(env
, s
, ot
);
5449 tcg_gen_movi_tl(s
->T1
, val
);
5450 } else if (b
== 0x6b) {
5451 val
= (int8_t)insn_get(env
, s
, MO_8
);
5452 tcg_gen_movi_tl(s
->T1
, val
);
5454 gen_op_mov_v_reg(s
, ot
, s
->T1
, reg
);
5457 #ifdef TARGET_X86_64
5459 tcg_gen_muls2_i64(cpu_regs
[reg
], s
->T1
, s
->T0
, s
->T1
);
5460 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5461 tcg_gen_sari_tl(cpu_cc_src
, cpu_cc_dst
, 63);
5462 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, s
->T1
);
5466 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
5467 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, s
->T1
);
5468 tcg_gen_muls2_i32(s
->tmp2_i32
, s
->tmp3_i32
,
5469 s
->tmp2_i32
, s
->tmp3_i32
);
5470 tcg_gen_extu_i32_tl(cpu_regs
[reg
], s
->tmp2_i32
);
5471 tcg_gen_sari_i32(s
->tmp2_i32
, s
->tmp2_i32
, 31);
5472 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5473 tcg_gen_sub_i32(s
->tmp2_i32
, s
->tmp2_i32
, s
->tmp3_i32
);
5474 tcg_gen_extu_i32_tl(cpu_cc_src
, s
->tmp2_i32
);
5477 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5478 tcg_gen_ext16s_tl(s
->T1
, s
->T1
);
5479 /* XXX: use 32 bit mul which could be faster */
5480 tcg_gen_mul_tl(s
->T0
, s
->T0
, s
->T1
);
5481 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
5482 tcg_gen_ext16s_tl(s
->tmp0
, s
->T0
);
5483 tcg_gen_sub_tl(cpu_cc_src
, s
->T0
, s
->tmp0
);
5484 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
5487 set_cc_op(s
, CC_OP_MULB
+ ot
);
5490 case 0x1c1: /* xadd Ev, Gv */
5491 ot
= mo_b_d(b
, dflag
);
5492 modrm
= x86_ldub_code(env
, s
);
5493 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5494 mod
= (modrm
>> 6) & 3;
5495 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
5497 rm
= (modrm
& 7) | REX_B(s
);
5498 gen_op_mov_v_reg(s
, ot
, s
->T1
, rm
);
5499 tcg_gen_add_tl(s
->T0
, s
->T0
, s
->T1
);
5500 gen_op_mov_reg_v(s
, ot
, reg
, s
->T1
);
5501 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
5503 gen_lea_modrm(env
, s
, modrm
);
5504 if (s
->prefix
& PREFIX_LOCK
) {
5505 tcg_gen_atomic_fetch_add_tl(s
->T1
, s
->A0
, s
->T0
,
5506 s
->mem_index
, ot
| MO_LE
);
5507 tcg_gen_add_tl(s
->T0
, s
->T0
, s
->T1
);
5509 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
5510 tcg_gen_add_tl(s
->T0
, s
->T0
, s
->T1
);
5511 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
5513 gen_op_mov_reg_v(s
, ot
, reg
, s
->T1
);
5515 gen_op_update2_cc(s
);
5516 set_cc_op(s
, CC_OP_ADDB
+ ot
);
5519 case 0x1b1: /* cmpxchg Ev, Gv */
5521 TCGv oldv
, newv
, cmpv
;
5523 ot
= mo_b_d(b
, dflag
);
5524 modrm
= x86_ldub_code(env
, s
);
5525 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5526 mod
= (modrm
>> 6) & 3;
5527 oldv
= tcg_temp_new();
5528 newv
= tcg_temp_new();
5529 cmpv
= tcg_temp_new();
5530 gen_op_mov_v_reg(s
, ot
, newv
, reg
);
5531 tcg_gen_mov_tl(cmpv
, cpu_regs
[R_EAX
]);
5533 if (s
->prefix
& PREFIX_LOCK
) {
5537 gen_lea_modrm(env
, s
, modrm
);
5538 tcg_gen_atomic_cmpxchg_tl(oldv
, s
->A0
, cmpv
, newv
,
5539 s
->mem_index
, ot
| MO_LE
);
5540 gen_op_mov_reg_v(s
, ot
, R_EAX
, oldv
);
5543 rm
= (modrm
& 7) | REX_B(s
);
5544 gen_op_mov_v_reg(s
, ot
, oldv
, rm
);
5546 gen_lea_modrm(env
, s
, modrm
);
5547 gen_op_ld_v(s
, ot
, oldv
, s
->A0
);
5548 rm
= 0; /* avoid warning */
5552 /* store value = (old == cmp ? new : old); */
5553 tcg_gen_movcond_tl(TCG_COND_EQ
, newv
, oldv
, cmpv
, newv
, oldv
);
5555 gen_op_mov_reg_v(s
, ot
, R_EAX
, oldv
);
5556 gen_op_mov_reg_v(s
, ot
, rm
, newv
);
5558 /* Perform an unconditional store cycle like physical cpu;
5559 must be before changing accumulator to ensure
5560 idempotency if the store faults and the instruction
5562 gen_op_st_v(s
, ot
, newv
, s
->A0
);
5563 gen_op_mov_reg_v(s
, ot
, R_EAX
, oldv
);
5566 tcg_gen_mov_tl(cpu_cc_src
, oldv
);
5567 tcg_gen_mov_tl(s
->cc_srcT
, cmpv
);
5568 tcg_gen_sub_tl(cpu_cc_dst
, cmpv
, oldv
);
5569 set_cc_op(s
, CC_OP_SUBB
+ ot
);
5570 tcg_temp_free(oldv
);
5571 tcg_temp_free(newv
);
5572 tcg_temp_free(cmpv
);
5575 case 0x1c7: /* cmpxchg8b */
5576 modrm
= x86_ldub_code(env
, s
);
5577 mod
= (modrm
>> 6) & 3;
5578 switch ((modrm
>> 3) & 7) {
5579 case 1: /* CMPXCHG8, CMPXCHG16 */
5583 #ifdef TARGET_X86_64
5584 if (dflag
== MO_64
) {
5585 if (!(s
->cpuid_ext_features
& CPUID_EXT_CX16
)) {
5588 gen_lea_modrm(env
, s
, modrm
);
5589 if ((s
->prefix
& PREFIX_LOCK
) &&
5590 (tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
5591 gen_helper_cmpxchg16b(cpu_env
, s
->A0
);
5593 gen_helper_cmpxchg16b_unlocked(cpu_env
, s
->A0
);
5595 set_cc_op(s
, CC_OP_EFLAGS
);
5599 if (!(s
->cpuid_features
& CPUID_CX8
)) {
5602 gen_lea_modrm(env
, s
, modrm
);
5603 if ((s
->prefix
& PREFIX_LOCK
) &&
5604 (tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
5605 gen_helper_cmpxchg8b(cpu_env
, s
->A0
);
5607 gen_helper_cmpxchg8b_unlocked(cpu_env
, s
->A0
);
5609 set_cc_op(s
, CC_OP_EFLAGS
);
5612 case 7: /* RDSEED */
5613 case 6: /* RDRAND */
5615 (s
->prefix
& (PREFIX_LOCK
| PREFIX_REPZ
| PREFIX_REPNZ
)) ||
5616 !(s
->cpuid_ext_features
& CPUID_EXT_RDRAND
)) {
5619 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
5622 gen_helper_rdrand(s
->T0
, cpu_env
);
5623 rm
= (modrm
& 7) | REX_B(s
);
5624 gen_op_mov_reg_v(s
, dflag
, rm
, s
->T0
);
5625 set_cc_op(s
, CC_OP_EFLAGS
);
5626 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
5627 gen_jmp(s
, s
->pc
- s
->cs_base
);
5636 /**************************/
5638 case 0x50 ... 0x57: /* push */
5639 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, (b
& 7) | REX_B(s
));
5640 gen_push_v(s
, s
->T0
);
5642 case 0x58 ... 0x5f: /* pop */
5644 /* NOTE: order is important for pop %sp */
5645 gen_pop_update(s
, ot
);
5646 gen_op_mov_reg_v(s
, ot
, (b
& 7) | REX_B(s
), s
->T0
);
5648 case 0x60: /* pusha */
5653 case 0x61: /* popa */
5658 case 0x68: /* push Iv */
5660 ot
= mo_pushpop(s
, dflag
);
5662 val
= insn_get(env
, s
, ot
);
5664 val
= (int8_t)insn_get(env
, s
, MO_8
);
5665 tcg_gen_movi_tl(s
->T0
, val
);
5666 gen_push_v(s
, s
->T0
);
5668 case 0x8f: /* pop Ev */
5669 modrm
= x86_ldub_code(env
, s
);
5670 mod
= (modrm
>> 6) & 3;
5673 /* NOTE: order is important for pop %sp */
5674 gen_pop_update(s
, ot
);
5675 rm
= (modrm
& 7) | REX_B(s
);
5676 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
5678 /* NOTE: order is important too for MMU exceptions */
5679 s
->popl_esp_hack
= 1 << ot
;
5680 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5681 s
->popl_esp_hack
= 0;
5682 gen_pop_update(s
, ot
);
5685 case 0xc8: /* enter */
5688 val
= x86_lduw_code(env
, s
);
5689 level
= x86_ldub_code(env
, s
);
5690 gen_enter(s
, val
, level
);
5693 case 0xc9: /* leave */
5696 case 0x06: /* push es */
5697 case 0x0e: /* push cs */
5698 case 0x16: /* push ss */
5699 case 0x1e: /* push ds */
5702 gen_op_movl_T0_seg(s
, b
>> 3);
5703 gen_push_v(s
, s
->T0
);
5705 case 0x1a0: /* push fs */
5706 case 0x1a8: /* push gs */
5707 gen_op_movl_T0_seg(s
, (b
>> 3) & 7);
5708 gen_push_v(s
, s
->T0
);
5710 case 0x07: /* pop es */
5711 case 0x17: /* pop ss */
5712 case 0x1f: /* pop ds */
5717 gen_movl_seg_T0(s
, reg
);
5718 gen_pop_update(s
, ot
);
5719 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5720 if (s
->base
.is_jmp
) {
5721 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
5723 s
->flags
&= ~HF_TF_MASK
;
5724 gen_eob_inhibit_irq(s
, true);
5730 case 0x1a1: /* pop fs */
5731 case 0x1a9: /* pop gs */
5733 gen_movl_seg_T0(s
, (b
>> 3) & 7);
5734 gen_pop_update(s
, ot
);
5735 if (s
->base
.is_jmp
) {
5736 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
5741 /**************************/
5744 case 0x89: /* mov Gv, Ev */
5745 ot
= mo_b_d(b
, dflag
);
5746 modrm
= x86_ldub_code(env
, s
);
5747 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5749 /* generate a generic store */
5750 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
5753 case 0xc7: /* mov Ev, Iv */
5754 ot
= mo_b_d(b
, dflag
);
5755 modrm
= x86_ldub_code(env
, s
);
5756 mod
= (modrm
>> 6) & 3;
5758 s
->rip_offset
= insn_const_size(ot
);
5759 gen_lea_modrm(env
, s
, modrm
);
5761 val
= insn_get(env
, s
, ot
);
5762 tcg_gen_movi_tl(s
->T0
, val
);
5764 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
5766 gen_op_mov_reg_v(s
, ot
, (modrm
& 7) | REX_B(s
), s
->T0
);
5770 case 0x8b: /* mov Ev, Gv */
5771 ot
= mo_b_d(b
, dflag
);
5772 modrm
= x86_ldub_code(env
, s
);
5773 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5775 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5776 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
5778 case 0x8e: /* mov seg, Gv */
5779 modrm
= x86_ldub_code(env
, s
);
5780 reg
= (modrm
>> 3) & 7;
5781 if (reg
>= 6 || reg
== R_CS
)
5783 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
5784 gen_movl_seg_T0(s
, reg
);
5785 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5786 if (s
->base
.is_jmp
) {
5787 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
5789 s
->flags
&= ~HF_TF_MASK
;
5790 gen_eob_inhibit_irq(s
, true);
5796 case 0x8c: /* mov Gv, seg */
5797 modrm
= x86_ldub_code(env
, s
);
5798 reg
= (modrm
>> 3) & 7;
5799 mod
= (modrm
>> 6) & 3;
5802 gen_op_movl_T0_seg(s
, reg
);
5803 ot
= mod
== 3 ? dflag
: MO_16
;
5804 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5807 case 0x1b6: /* movzbS Gv, Eb */
5808 case 0x1b7: /* movzwS Gv, Eb */
5809 case 0x1be: /* movsbS Gv, Eb */
5810 case 0x1bf: /* movswS Gv, Eb */
5815 /* d_ot is the size of destination */
5817 /* ot is the size of source */
5818 ot
= (b
& 1) + MO_8
;
5819 /* s_ot is the sign+size of source */
5820 s_ot
= b
& 8 ? MO_SIGN
| ot
: ot
;
5822 modrm
= x86_ldub_code(env
, s
);
5823 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5824 mod
= (modrm
>> 6) & 3;
5825 rm
= (modrm
& 7) | REX_B(s
);
5828 if (s_ot
== MO_SB
&& byte_reg_is_xH(s
, rm
)) {
5829 tcg_gen_sextract_tl(s
->T0
, cpu_regs
[rm
- 4], 8, 8);
5831 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
5834 tcg_gen_ext8u_tl(s
->T0
, s
->T0
);
5837 tcg_gen_ext8s_tl(s
->T0
, s
->T0
);
5840 tcg_gen_ext16u_tl(s
->T0
, s
->T0
);
5844 tcg_gen_ext16s_tl(s
->T0
, s
->T0
);
5848 gen_op_mov_reg_v(s
, d_ot
, reg
, s
->T0
);
5850 gen_lea_modrm(env
, s
, modrm
);
5851 gen_op_ld_v(s
, s_ot
, s
->T0
, s
->A0
);
5852 gen_op_mov_reg_v(s
, d_ot
, reg
, s
->T0
);
5857 case 0x8d: /* lea */
5858 modrm
= x86_ldub_code(env
, s
);
5859 mod
= (modrm
>> 6) & 3;
5862 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5864 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
5865 TCGv ea
= gen_lea_modrm_1(s
, a
);
5866 gen_lea_v_seg(s
, s
->aflag
, ea
, -1, -1);
5867 gen_op_mov_reg_v(s
, dflag
, reg
, s
->A0
);
5871 case 0xa0: /* mov EAX, Ov */
5873 case 0xa2: /* mov Ov, EAX */
5876 target_ulong offset_addr
;
5878 ot
= mo_b_d(b
, dflag
);
5879 offset_addr
= insn_get_addr(env
, s
, s
->aflag
);
5880 tcg_gen_movi_tl(s
->A0
, offset_addr
);
5881 gen_add_A0_ds_seg(s
);
5883 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
5884 gen_op_mov_reg_v(s
, ot
, R_EAX
, s
->T0
);
5886 gen_op_mov_v_reg(s
, ot
, s
->T0
, R_EAX
);
5887 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
5891 case 0xd7: /* xlat */
5892 tcg_gen_mov_tl(s
->A0
, cpu_regs
[R_EBX
]);
5893 tcg_gen_ext8u_tl(s
->T0
, cpu_regs
[R_EAX
]);
5894 tcg_gen_add_tl(s
->A0
, s
->A0
, s
->T0
);
5895 gen_extu(s
->aflag
, s
->A0
);
5896 gen_add_A0_ds_seg(s
);
5897 gen_op_ld_v(s
, MO_8
, s
->T0
, s
->A0
);
5898 gen_op_mov_reg_v(s
, MO_8
, R_EAX
, s
->T0
);
5900 case 0xb0 ... 0xb7: /* mov R, Ib */
5901 val
= insn_get(env
, s
, MO_8
);
5902 tcg_gen_movi_tl(s
->T0
, val
);
5903 gen_op_mov_reg_v(s
, MO_8
, (b
& 7) | REX_B(s
), s
->T0
);
5905 case 0xb8 ... 0xbf: /* mov R, Iv */
5906 #ifdef TARGET_X86_64
5907 if (dflag
== MO_64
) {
5910 tmp
= x86_ldq_code(env
, s
);
5911 reg
= (b
& 7) | REX_B(s
);
5912 tcg_gen_movi_tl(s
->T0
, tmp
);
5913 gen_op_mov_reg_v(s
, MO_64
, reg
, s
->T0
);
5918 val
= insn_get(env
, s
, ot
);
5919 reg
= (b
& 7) | REX_B(s
);
5920 tcg_gen_movi_tl(s
->T0
, val
);
5921 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
5925 case 0x91 ... 0x97: /* xchg R, EAX */
5928 reg
= (b
& 7) | REX_B(s
);
5932 case 0x87: /* xchg Ev, Gv */
5933 ot
= mo_b_d(b
, dflag
);
5934 modrm
= x86_ldub_code(env
, s
);
5935 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5936 mod
= (modrm
>> 6) & 3;
5938 rm
= (modrm
& 7) | REX_B(s
);
5940 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
5941 gen_op_mov_v_reg(s
, ot
, s
->T1
, rm
);
5942 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
5943 gen_op_mov_reg_v(s
, ot
, reg
, s
->T1
);
5945 gen_lea_modrm(env
, s
, modrm
);
5946 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
5947 /* for xchg, lock is implicit */
5948 tcg_gen_atomic_xchg_tl(s
->T1
, s
->A0
, s
->T0
,
5949 s
->mem_index
, ot
| MO_LE
);
5950 gen_op_mov_reg_v(s
, ot
, reg
, s
->T1
);
5953 case 0xc4: /* les Gv */
5954 /* In CODE64 this is VEX3; see above. */
5957 case 0xc5: /* lds Gv */
5958 /* In CODE64 this is VEX2; see above. */
5961 case 0x1b2: /* lss Gv */
5964 case 0x1b4: /* lfs Gv */
5967 case 0x1b5: /* lgs Gv */
5970 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
5971 modrm
= x86_ldub_code(env
, s
);
5972 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
5973 mod
= (modrm
>> 6) & 3;
5976 gen_lea_modrm(env
, s
, modrm
);
5977 gen_op_ld_v(s
, ot
, s
->T1
, s
->A0
);
5978 gen_add_A0_im(s
, 1 << ot
);
5979 /* load the segment first to handle exceptions properly */
5980 gen_op_ld_v(s
, MO_16
, s
->T0
, s
->A0
);
5981 gen_movl_seg_T0(s
, op
);
5982 /* then put the data */
5983 gen_op_mov_reg_v(s
, ot
, reg
, s
->T1
);
5984 if (s
->base
.is_jmp
) {
5985 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
5990 /************************/
5998 ot
= mo_b_d(b
, dflag
);
5999 modrm
= x86_ldub_code(env
, s
);
6000 mod
= (modrm
>> 6) & 3;
6001 op
= (modrm
>> 3) & 7;
6007 gen_lea_modrm(env
, s
, modrm
);
6010 opreg
= (modrm
& 7) | REX_B(s
);
6015 gen_shift(s
, op
, ot
, opreg
, OR_ECX
);
6018 shift
= x86_ldub_code(env
, s
);
6020 gen_shifti(s
, op
, ot
, opreg
, shift
);
6035 case 0x1a4: /* shld imm */
6039 case 0x1a5: /* shld cl */
6043 case 0x1ac: /* shrd imm */
6047 case 0x1ad: /* shrd cl */
6052 modrm
= x86_ldub_code(env
, s
);
6053 mod
= (modrm
>> 6) & 3;
6054 rm
= (modrm
& 7) | REX_B(s
);
6055 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
6057 gen_lea_modrm(env
, s
, modrm
);
6062 gen_op_mov_v_reg(s
, ot
, s
->T1
, reg
);
6065 TCGv imm
= tcg_const_tl(x86_ldub_code(env
, s
));
6066 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, imm
);
6069 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, cpu_regs
[R_ECX
]);
6073 /************************/
6077 bool update_fip
= true;
6079 if (s
->flags
& (HF_EM_MASK
| HF_TS_MASK
)) {
6080 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
6081 /* XXX: what to do if illegal op ? */
6082 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
6085 modrm
= x86_ldub_code(env
, s
);
6086 mod
= (modrm
>> 6) & 3;
6088 op
= ((b
& 7) << 3) | ((modrm
>> 3) & 7);
6091 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
6092 TCGv ea
= gen_lea_modrm_1(s
, a
);
6093 TCGv last_addr
= tcg_temp_new();
6094 bool update_fdp
= true;
6096 tcg_gen_mov_tl(last_addr
, ea
);
6097 gen_lea_v_seg(s
, s
->aflag
, ea
, a
.def_seg
, s
->override
);
6100 case 0x00 ... 0x07: /* fxxxs */
6101 case 0x10 ... 0x17: /* fixxxl */
6102 case 0x20 ... 0x27: /* fxxxl */
6103 case 0x30 ... 0x37: /* fixxx */
6110 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
6111 s
->mem_index
, MO_LEUL
);
6112 gen_helper_flds_FT0(cpu_env
, s
->tmp2_i32
);
6115 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
6116 s
->mem_index
, MO_LEUL
);
6117 gen_helper_fildl_FT0(cpu_env
, s
->tmp2_i32
);
6120 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
,
6121 s
->mem_index
, MO_LEUQ
);
6122 gen_helper_fldl_FT0(cpu_env
, s
->tmp1_i64
);
6126 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
6127 s
->mem_index
, MO_LESW
);
6128 gen_helper_fildl_FT0(cpu_env
, s
->tmp2_i32
);
6132 gen_helper_fp_arith_ST0_FT0(op1
);
6134 /* fcomp needs pop */
6135 gen_helper_fpop(cpu_env
);
6139 case 0x08: /* flds */
6140 case 0x0a: /* fsts */
6141 case 0x0b: /* fstps */
6142 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
6143 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
6144 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
6149 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
6150 s
->mem_index
, MO_LEUL
);
6151 gen_helper_flds_ST0(cpu_env
, s
->tmp2_i32
);
6154 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
6155 s
->mem_index
, MO_LEUL
);
6156 gen_helper_fildl_ST0(cpu_env
, s
->tmp2_i32
);
6159 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
,
6160 s
->mem_index
, MO_LEUQ
);
6161 gen_helper_fldl_ST0(cpu_env
, s
->tmp1_i64
);
6165 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
6166 s
->mem_index
, MO_LESW
);
6167 gen_helper_fildl_ST0(cpu_env
, s
->tmp2_i32
);
6172 /* XXX: the corresponding CPUID bit must be tested ! */
6175 gen_helper_fisttl_ST0(s
->tmp2_i32
, cpu_env
);
6176 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
6177 s
->mem_index
, MO_LEUL
);
6180 gen_helper_fisttll_ST0(s
->tmp1_i64
, cpu_env
);
6181 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
,
6182 s
->mem_index
, MO_LEUQ
);
6186 gen_helper_fistt_ST0(s
->tmp2_i32
, cpu_env
);
6187 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
6188 s
->mem_index
, MO_LEUW
);
6191 gen_helper_fpop(cpu_env
);
6196 gen_helper_fsts_ST0(s
->tmp2_i32
, cpu_env
);
6197 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
6198 s
->mem_index
, MO_LEUL
);
6201 gen_helper_fistl_ST0(s
->tmp2_i32
, cpu_env
);
6202 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
6203 s
->mem_index
, MO_LEUL
);
6206 gen_helper_fstl_ST0(s
->tmp1_i64
, cpu_env
);
6207 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
,
6208 s
->mem_index
, MO_LEUQ
);
6212 gen_helper_fist_ST0(s
->tmp2_i32
, cpu_env
);
6213 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
6214 s
->mem_index
, MO_LEUW
);
6217 if ((op
& 7) == 3) {
6218 gen_helper_fpop(cpu_env
);
6223 case 0x0c: /* fldenv mem */
6224 gen_helper_fldenv(cpu_env
, s
->A0
,
6225 tcg_const_i32(dflag
- 1));
6226 update_fip
= update_fdp
= false;
6228 case 0x0d: /* fldcw mem */
6229 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
,
6230 s
->mem_index
, MO_LEUW
);
6231 gen_helper_fldcw(cpu_env
, s
->tmp2_i32
);
6232 update_fip
= update_fdp
= false;
6234 case 0x0e: /* fnstenv mem */
6235 gen_helper_fstenv(cpu_env
, s
->A0
,
6236 tcg_const_i32(dflag
- 1));
6237 update_fip
= update_fdp
= false;
6239 case 0x0f: /* fnstcw mem */
6240 gen_helper_fnstcw(s
->tmp2_i32
, cpu_env
);
6241 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
6242 s
->mem_index
, MO_LEUW
);
6243 update_fip
= update_fdp
= false;
6245 case 0x1d: /* fldt mem */
6246 gen_helper_fldt_ST0(cpu_env
, s
->A0
);
6248 case 0x1f: /* fstpt mem */
6249 gen_helper_fstt_ST0(cpu_env
, s
->A0
);
6250 gen_helper_fpop(cpu_env
);
6252 case 0x2c: /* frstor mem */
6253 gen_helper_frstor(cpu_env
, s
->A0
,
6254 tcg_const_i32(dflag
- 1));
6255 update_fip
= update_fdp
= false;
6257 case 0x2e: /* fnsave mem */
6258 gen_helper_fsave(cpu_env
, s
->A0
,
6259 tcg_const_i32(dflag
- 1));
6260 update_fip
= update_fdp
= false;
6262 case 0x2f: /* fnstsw mem */
6263 gen_helper_fnstsw(s
->tmp2_i32
, cpu_env
);
6264 tcg_gen_qemu_st_i32(s
->tmp2_i32
, s
->A0
,
6265 s
->mem_index
, MO_LEUW
);
6266 update_fip
= update_fdp
= false;
6268 case 0x3c: /* fbld */
6269 gen_helper_fbld_ST0(cpu_env
, s
->A0
);
6271 case 0x3e: /* fbstp */
6272 gen_helper_fbst_ST0(cpu_env
, s
->A0
);
6273 gen_helper_fpop(cpu_env
);
6275 case 0x3d: /* fildll */
6276 tcg_gen_qemu_ld_i64(s
->tmp1_i64
, s
->A0
,
6277 s
->mem_index
, MO_LEUQ
);
6278 gen_helper_fildll_ST0(cpu_env
, s
->tmp1_i64
);
6280 case 0x3f: /* fistpll */
6281 gen_helper_fistll_ST0(s
->tmp1_i64
, cpu_env
);
6282 tcg_gen_qemu_st_i64(s
->tmp1_i64
, s
->A0
,
6283 s
->mem_index
, MO_LEUQ
);
6284 gen_helper_fpop(cpu_env
);
6291 int last_seg
= s
->override
>= 0 ? s
->override
: a
.def_seg
;
6293 tcg_gen_ld_i32(s
->tmp2_i32
, cpu_env
,
6294 offsetof(CPUX86State
,
6295 segs
[last_seg
].selector
));
6296 tcg_gen_st16_i32(s
->tmp2_i32
, cpu_env
,
6297 offsetof(CPUX86State
, fpds
));
6298 tcg_gen_st_tl(last_addr
, cpu_env
,
6299 offsetof(CPUX86State
, fpdp
));
6301 tcg_temp_free(last_addr
);
6303 /* register float ops */
6307 case 0x08: /* fld sti */
6308 gen_helper_fpush(cpu_env
);
6309 gen_helper_fmov_ST0_STN(cpu_env
,
6310 tcg_const_i32((opreg
+ 1) & 7));
6312 case 0x09: /* fxchg sti */
6313 case 0x29: /* fxchg4 sti, undocumented op */
6314 case 0x39: /* fxchg7 sti, undocumented op */
6315 gen_helper_fxchg_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6317 case 0x0a: /* grp d9/2 */
6320 /* check exceptions (FreeBSD FPU probe) */
6321 gen_helper_fwait(cpu_env
);
6328 case 0x0c: /* grp d9/4 */
6331 gen_helper_fchs_ST0(cpu_env
);
6334 gen_helper_fabs_ST0(cpu_env
);
6337 gen_helper_fldz_FT0(cpu_env
);
6338 gen_helper_fcom_ST0_FT0(cpu_env
);
6341 gen_helper_fxam_ST0(cpu_env
);
6347 case 0x0d: /* grp d9/5 */
6351 gen_helper_fpush(cpu_env
);
6352 gen_helper_fld1_ST0(cpu_env
);
6355 gen_helper_fpush(cpu_env
);
6356 gen_helper_fldl2t_ST0(cpu_env
);
6359 gen_helper_fpush(cpu_env
);
6360 gen_helper_fldl2e_ST0(cpu_env
);
6363 gen_helper_fpush(cpu_env
);
6364 gen_helper_fldpi_ST0(cpu_env
);
6367 gen_helper_fpush(cpu_env
);
6368 gen_helper_fldlg2_ST0(cpu_env
);
6371 gen_helper_fpush(cpu_env
);
6372 gen_helper_fldln2_ST0(cpu_env
);
6375 gen_helper_fpush(cpu_env
);
6376 gen_helper_fldz_ST0(cpu_env
);
6383 case 0x0e: /* grp d9/6 */
6386 gen_helper_f2xm1(cpu_env
);
6389 gen_helper_fyl2x(cpu_env
);
6392 gen_helper_fptan(cpu_env
);
6394 case 3: /* fpatan */
6395 gen_helper_fpatan(cpu_env
);
6397 case 4: /* fxtract */
6398 gen_helper_fxtract(cpu_env
);
6400 case 5: /* fprem1 */
6401 gen_helper_fprem1(cpu_env
);
6403 case 6: /* fdecstp */
6404 gen_helper_fdecstp(cpu_env
);
6407 case 7: /* fincstp */
6408 gen_helper_fincstp(cpu_env
);
6412 case 0x0f: /* grp d9/7 */
6415 gen_helper_fprem(cpu_env
);
6417 case 1: /* fyl2xp1 */
6418 gen_helper_fyl2xp1(cpu_env
);
6421 gen_helper_fsqrt(cpu_env
);
6423 case 3: /* fsincos */
6424 gen_helper_fsincos(cpu_env
);
6426 case 5: /* fscale */
6427 gen_helper_fscale(cpu_env
);
6429 case 4: /* frndint */
6430 gen_helper_frndint(cpu_env
);
6433 gen_helper_fsin(cpu_env
);
6437 gen_helper_fcos(cpu_env
);
6441 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6442 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6443 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6449 gen_helper_fp_arith_STN_ST0(op1
, opreg
);
6451 gen_helper_fpop(cpu_env
);
6454 gen_helper_fmov_FT0_STN(cpu_env
,
6455 tcg_const_i32(opreg
));
6456 gen_helper_fp_arith_ST0_FT0(op1
);
6460 case 0x02: /* fcom */
6461 case 0x22: /* fcom2, undocumented op */
6462 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6463 gen_helper_fcom_ST0_FT0(cpu_env
);
6465 case 0x03: /* fcomp */
6466 case 0x23: /* fcomp3, undocumented op */
6467 case 0x32: /* fcomp5, undocumented op */
6468 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6469 gen_helper_fcom_ST0_FT0(cpu_env
);
6470 gen_helper_fpop(cpu_env
);
6472 case 0x15: /* da/5 */
6474 case 1: /* fucompp */
6475 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6476 gen_helper_fucom_ST0_FT0(cpu_env
);
6477 gen_helper_fpop(cpu_env
);
6478 gen_helper_fpop(cpu_env
);
6486 case 0: /* feni (287 only, just do nop here) */
6488 case 1: /* fdisi (287 only, just do nop here) */
6491 gen_helper_fclex(cpu_env
);
6494 case 3: /* fninit */
6495 gen_helper_fninit(cpu_env
);
6498 case 4: /* fsetpm (287 only, just do nop here) */
6504 case 0x1d: /* fucomi */
6505 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6508 gen_update_cc_op(s
);
6509 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6510 gen_helper_fucomi_ST0_FT0(cpu_env
);
6511 set_cc_op(s
, CC_OP_EFLAGS
);
6513 case 0x1e: /* fcomi */
6514 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6517 gen_update_cc_op(s
);
6518 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6519 gen_helper_fcomi_ST0_FT0(cpu_env
);
6520 set_cc_op(s
, CC_OP_EFLAGS
);
6522 case 0x28: /* ffree sti */
6523 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6525 case 0x2a: /* fst sti */
6526 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6528 case 0x2b: /* fstp sti */
6529 case 0x0b: /* fstp1 sti, undocumented op */
6530 case 0x3a: /* fstp8 sti, undocumented op */
6531 case 0x3b: /* fstp9 sti, undocumented op */
6532 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6533 gen_helper_fpop(cpu_env
);
6535 case 0x2c: /* fucom st(i) */
6536 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6537 gen_helper_fucom_ST0_FT0(cpu_env
);
6539 case 0x2d: /* fucomp st(i) */
6540 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6541 gen_helper_fucom_ST0_FT0(cpu_env
);
6542 gen_helper_fpop(cpu_env
);
6544 case 0x33: /* de/3 */
6546 case 1: /* fcompp */
6547 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6548 gen_helper_fcom_ST0_FT0(cpu_env
);
6549 gen_helper_fpop(cpu_env
);
6550 gen_helper_fpop(cpu_env
);
6556 case 0x38: /* ffreep sti, undocumented op */
6557 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6558 gen_helper_fpop(cpu_env
);
6560 case 0x3c: /* df/4 */
6563 gen_helper_fnstsw(s
->tmp2_i32
, cpu_env
);
6564 tcg_gen_extu_i32_tl(s
->T0
, s
->tmp2_i32
);
6565 gen_op_mov_reg_v(s
, MO_16
, R_EAX
, s
->T0
);
6571 case 0x3d: /* fucomip */
6572 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6575 gen_update_cc_op(s
);
6576 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6577 gen_helper_fucomi_ST0_FT0(cpu_env
);
6578 gen_helper_fpop(cpu_env
);
6579 set_cc_op(s
, CC_OP_EFLAGS
);
6581 case 0x3e: /* fcomip */
6582 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6585 gen_update_cc_op(s
);
6586 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6587 gen_helper_fcomi_ST0_FT0(cpu_env
);
6588 gen_helper_fpop(cpu_env
);
6589 set_cc_op(s
, CC_OP_EFLAGS
);
6591 case 0x10 ... 0x13: /* fcmovxx */
6596 static const uint8_t fcmov_cc
[8] = {
6603 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6606 op1
= fcmov_cc
[op
& 3] | (((op
>> 3) & 1) ^ 1);
6607 l1
= gen_new_label();
6608 gen_jcc1_noeob(s
, op1
, l1
);
6609 gen_helper_fmov_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6619 tcg_gen_ld_i32(s
->tmp2_i32
, cpu_env
,
6620 offsetof(CPUX86State
, segs
[R_CS
].selector
));
6621 tcg_gen_st16_i32(s
->tmp2_i32
, cpu_env
,
6622 offsetof(CPUX86State
, fpcs
));
6623 tcg_gen_st_tl(tcg_constant_tl(pc_start
- s
->cs_base
),
6624 cpu_env
, offsetof(CPUX86State
, fpip
));
6628 /************************/
6631 case 0xa4: /* movsS */
6633 ot
= mo_b_d(b
, dflag
);
6634 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6635 gen_repz_movs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6641 case 0xaa: /* stosS */
6643 ot
= mo_b_d(b
, dflag
);
6644 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6645 gen_repz_stos(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6650 case 0xac: /* lodsS */
6652 ot
= mo_b_d(b
, dflag
);
6653 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6654 gen_repz_lods(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6659 case 0xae: /* scasS */
6661 ot
= mo_b_d(b
, dflag
);
6662 if (prefixes
& PREFIX_REPNZ
) {
6663 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6664 } else if (prefixes
& PREFIX_REPZ
) {
6665 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6671 case 0xa6: /* cmpsS */
6673 ot
= mo_b_d(b
, dflag
);
6674 if (prefixes
& PREFIX_REPNZ
) {
6675 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6676 } else if (prefixes
& PREFIX_REPZ
) {
6677 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6682 case 0x6c: /* insS */
6684 ot
= mo_b_d32(b
, dflag
);
6685 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_EDX
]);
6686 tcg_gen_ext16u_i32(s
->tmp2_i32
, s
->tmp2_i32
);
6687 if (!gen_check_io(s
, ot
, s
->tmp2_i32
,
6688 SVM_IOIO_TYPE_MASK
| SVM_IOIO_STR_MASK
)) {
6691 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6694 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6695 gen_repz_ins(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6696 /* jump generated by gen_repz_ins */
6699 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6700 gen_jmp(s
, s
->pc
- s
->cs_base
);
6704 case 0x6e: /* outsS */
6706 ot
= mo_b_d32(b
, dflag
);
6707 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_EDX
]);
6708 tcg_gen_ext16u_i32(s
->tmp2_i32
, s
->tmp2_i32
);
6709 if (!gen_check_io(s
, ot
, s
->tmp2_i32
, SVM_IOIO_STR_MASK
)) {
6712 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6715 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6716 gen_repz_outs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6717 /* jump generated by gen_repz_outs */
6720 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6721 gen_jmp(s
, s
->pc
- s
->cs_base
);
6726 /************************/
6731 ot
= mo_b_d32(b
, dflag
);
6732 val
= x86_ldub_code(env
, s
);
6733 tcg_gen_movi_i32(s
->tmp2_i32
, val
);
6734 if (!gen_check_io(s
, ot
, s
->tmp2_i32
, SVM_IOIO_TYPE_MASK
)) {
6737 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6740 gen_helper_in_func(ot
, s
->T1
, s
->tmp2_i32
);
6741 gen_op_mov_reg_v(s
, ot
, R_EAX
, s
->T1
);
6742 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
6743 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6744 gen_jmp(s
, s
->pc
- s
->cs_base
);
6749 ot
= mo_b_d32(b
, dflag
);
6750 val
= x86_ldub_code(env
, s
);
6751 tcg_gen_movi_i32(s
->tmp2_i32
, val
);
6752 if (!gen_check_io(s
, ot
, s
->tmp2_i32
, 0)) {
6755 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6758 gen_op_mov_v_reg(s
, ot
, s
->T1
, R_EAX
);
6759 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, s
->T1
);
6760 gen_helper_out_func(ot
, s
->tmp2_i32
, s
->tmp3_i32
);
6761 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
6762 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6763 gen_jmp(s
, s
->pc
- s
->cs_base
);
6768 ot
= mo_b_d32(b
, dflag
);
6769 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_EDX
]);
6770 tcg_gen_ext16u_i32(s
->tmp2_i32
, s
->tmp2_i32
);
6771 if (!gen_check_io(s
, ot
, s
->tmp2_i32
, SVM_IOIO_TYPE_MASK
)) {
6774 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6777 gen_helper_in_func(ot
, s
->T1
, s
->tmp2_i32
);
6778 gen_op_mov_reg_v(s
, ot
, R_EAX
, s
->T1
);
6779 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
6780 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6781 gen_jmp(s
, s
->pc
- s
->cs_base
);
6786 ot
= mo_b_d32(b
, dflag
);
6787 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_EDX
]);
6788 tcg_gen_ext16u_i32(s
->tmp2_i32
, s
->tmp2_i32
);
6789 if (!gen_check_io(s
, ot
, s
->tmp2_i32
, 0)) {
6792 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6795 gen_op_mov_v_reg(s
, ot
, s
->T1
, R_EAX
);
6796 tcg_gen_trunc_tl_i32(s
->tmp3_i32
, s
->T1
);
6797 gen_helper_out_func(ot
, s
->tmp2_i32
, s
->tmp3_i32
);
6798 gen_bpt_io(s
, s
->tmp2_i32
, ot
);
6799 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
6800 gen_jmp(s
, s
->pc
- s
->cs_base
);
6804 /************************/
6806 case 0xc2: /* ret im */
6807 val
= x86_ldsw_code(env
, s
);
6809 gen_stack_update(s
, val
+ (1 << ot
));
6810 /* Note that gen_pop_T0 uses a zero-extending load. */
6811 gen_op_jmp_v(s
->T0
);
6815 case 0xc3: /* ret */
6817 gen_pop_update(s
, ot
);
6818 /* Note that gen_pop_T0 uses a zero-extending load. */
6819 gen_op_jmp_v(s
->T0
);
6823 case 0xca: /* lret im */
6824 val
= x86_ldsw_code(env
, s
);
6826 if (PE(s
) && !VM86(s
)) {
6827 gen_update_cc_op(s
);
6828 gen_jmp_im(s
, pc_start
- s
->cs_base
);
6829 gen_helper_lret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6830 tcg_const_i32(val
));
6834 gen_op_ld_v(s
, dflag
, s
->T0
, s
->A0
);
6835 /* NOTE: keeping EIP updated is not a problem in case of
6837 gen_op_jmp_v(s
->T0
);
6839 gen_add_A0_im(s
, 1 << dflag
);
6840 gen_op_ld_v(s
, dflag
, s
->T0
, s
->A0
);
6841 gen_op_movl_seg_T0_vm(s
, R_CS
);
6842 /* add stack offset */
6843 gen_stack_update(s
, val
+ (2 << dflag
));
6847 case 0xcb: /* lret */
6850 case 0xcf: /* iret */
6851 gen_svm_check_intercept(s
, SVM_EXIT_IRET
);
6852 if (!PE(s
) || VM86(s
)) {
6853 /* real mode or vm86 mode */
6854 if (!check_vm86_iopl(s
)) {
6857 gen_helper_iret_real(cpu_env
, tcg_const_i32(dflag
- 1));
6859 gen_helper_iret_protected(cpu_env
, tcg_const_i32(dflag
- 1),
6860 tcg_const_i32(s
->pc
- s
->cs_base
));
6862 set_cc_op(s
, CC_OP_EFLAGS
);
6865 case 0xe8: /* call im */
6867 if (dflag
!= MO_16
) {
6868 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6870 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6872 next_eip
= s
->pc
- s
->cs_base
;
6874 if (dflag
== MO_16
) {
6876 } else if (!CODE64(s
)) {
6879 tcg_gen_movi_tl(s
->T0
, next_eip
);
6880 gen_push_v(s
, s
->T0
);
6885 case 0x9a: /* lcall im */
6887 unsigned int selector
, offset
;
6892 offset
= insn_get(env
, s
, ot
);
6893 selector
= insn_get(env
, s
, MO_16
);
6895 tcg_gen_movi_tl(s
->T0
, selector
);
6896 tcg_gen_movi_tl(s
->T1
, offset
);
6899 case 0xe9: /* jmp im */
6900 if (dflag
!= MO_16
) {
6901 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6903 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6905 tval
+= s
->pc
- s
->cs_base
;
6906 if (dflag
== MO_16
) {
6908 } else if (!CODE64(s
)) {
6914 case 0xea: /* ljmp im */
6916 unsigned int selector
, offset
;
6921 offset
= insn_get(env
, s
, ot
);
6922 selector
= insn_get(env
, s
, MO_16
);
6924 tcg_gen_movi_tl(s
->T0
, selector
);
6925 tcg_gen_movi_tl(s
->T1
, offset
);
6928 case 0xeb: /* jmp Jb */
6929 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6930 tval
+= s
->pc
- s
->cs_base
;
6931 if (dflag
== MO_16
) {
6936 case 0x70 ... 0x7f: /* jcc Jb */
6937 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6939 case 0x180 ... 0x18f: /* jcc Jv */
6940 if (dflag
!= MO_16
) {
6941 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6943 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6946 next_eip
= s
->pc
- s
->cs_base
;
6948 if (dflag
== MO_16
) {
6952 gen_jcc(s
, b
, tval
, next_eip
);
6955 case 0x190 ... 0x19f: /* setcc Gv */
6956 modrm
= x86_ldub_code(env
, s
);
6957 gen_setcc1(s
, b
, s
->T0
);
6958 gen_ldst_modrm(env
, s
, modrm
, MO_8
, OR_TMP0
, 1);
6960 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6961 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6965 modrm
= x86_ldub_code(env
, s
);
6966 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
6967 gen_cmovcc1(env
, s
, ot
, b
, modrm
, reg
);
6970 /************************/
6972 case 0x9c: /* pushf */
6973 gen_svm_check_intercept(s
, SVM_EXIT_PUSHF
);
6974 if (check_vm86_iopl(s
)) {
6975 gen_update_cc_op(s
);
6976 gen_helper_read_eflags(s
->T0
, cpu_env
);
6977 gen_push_v(s
, s
->T0
);
6980 case 0x9d: /* popf */
6981 gen_svm_check_intercept(s
, SVM_EXIT_POPF
);
6982 if (check_vm86_iopl(s
)) {
6985 if (dflag
!= MO_16
) {
6986 gen_helper_write_eflags(cpu_env
, s
->T0
,
6987 tcg_const_i32((TF_MASK
| AC_MASK
|
6992 gen_helper_write_eflags(cpu_env
, s
->T0
,
6993 tcg_const_i32((TF_MASK
| AC_MASK
|
6995 IF_MASK
| IOPL_MASK
)
6999 if (CPL(s
) <= IOPL(s
)) {
7000 if (dflag
!= MO_16
) {
7001 gen_helper_write_eflags(cpu_env
, s
->T0
,
7002 tcg_const_i32((TF_MASK
|
7008 gen_helper_write_eflags(cpu_env
, s
->T0
,
7009 tcg_const_i32((TF_MASK
|
7017 if (dflag
!= MO_16
) {
7018 gen_helper_write_eflags(cpu_env
, s
->T0
,
7019 tcg_const_i32((TF_MASK
| AC_MASK
|
7020 ID_MASK
| NT_MASK
)));
7022 gen_helper_write_eflags(cpu_env
, s
->T0
,
7023 tcg_const_i32((TF_MASK
| AC_MASK
|
7029 gen_pop_update(s
, ot
);
7030 set_cc_op(s
, CC_OP_EFLAGS
);
7031 /* abort translation because TF/AC flag may change */
7032 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7036 case 0x9e: /* sahf */
7037 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
7039 gen_op_mov_v_reg(s
, MO_8
, s
->T0
, R_AH
);
7040 gen_compute_eflags(s
);
7041 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, CC_O
);
7042 tcg_gen_andi_tl(s
->T0
, s
->T0
, CC_S
| CC_Z
| CC_A
| CC_P
| CC_C
);
7043 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, s
->T0
);
7045 case 0x9f: /* lahf */
7046 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
7048 gen_compute_eflags(s
);
7049 /* Note: gen_compute_eflags() only gives the condition codes */
7050 tcg_gen_ori_tl(s
->T0
, cpu_cc_src
, 0x02);
7051 gen_op_mov_reg_v(s
, MO_8
, R_AH
, s
->T0
);
7053 case 0xf5: /* cmc */
7054 gen_compute_eflags(s
);
7055 tcg_gen_xori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
7057 case 0xf8: /* clc */
7058 gen_compute_eflags(s
);
7059 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_C
);
7061 case 0xf9: /* stc */
7062 gen_compute_eflags(s
);
7063 tcg_gen_ori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
7065 case 0xfc: /* cld */
7066 tcg_gen_movi_i32(s
->tmp2_i32
, 1);
7067 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
7069 case 0xfd: /* std */
7070 tcg_gen_movi_i32(s
->tmp2_i32
, -1);
7071 tcg_gen_st_i32(s
->tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
7074 /************************/
7075 /* bit operations */
7076 case 0x1ba: /* bt/bts/btr/btc Gv, im */
7078 modrm
= x86_ldub_code(env
, s
);
7079 op
= (modrm
>> 3) & 7;
7080 mod
= (modrm
>> 6) & 3;
7081 rm
= (modrm
& 7) | REX_B(s
);
7084 gen_lea_modrm(env
, s
, modrm
);
7085 if (!(s
->prefix
& PREFIX_LOCK
)) {
7086 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
7089 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
7092 val
= x86_ldub_code(env
, s
);
7093 tcg_gen_movi_tl(s
->T1
, val
);
7098 case 0x1a3: /* bt Gv, Ev */
7101 case 0x1ab: /* bts */
7104 case 0x1b3: /* btr */
7107 case 0x1bb: /* btc */
7111 modrm
= x86_ldub_code(env
, s
);
7112 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
7113 mod
= (modrm
>> 6) & 3;
7114 rm
= (modrm
& 7) | REX_B(s
);
7115 gen_op_mov_v_reg(s
, MO_32
, s
->T1
, reg
);
7117 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
7118 /* specific case: we need to add a displacement */
7119 gen_exts(ot
, s
->T1
);
7120 tcg_gen_sari_tl(s
->tmp0
, s
->T1
, 3 + ot
);
7121 tcg_gen_shli_tl(s
->tmp0
, s
->tmp0
, ot
);
7122 tcg_gen_add_tl(s
->A0
, gen_lea_modrm_1(s
, a
), s
->tmp0
);
7123 gen_lea_v_seg(s
, s
->aflag
, s
->A0
, a
.def_seg
, s
->override
);
7124 if (!(s
->prefix
& PREFIX_LOCK
)) {
7125 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
7128 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
7131 tcg_gen_andi_tl(s
->T1
, s
->T1
, (1 << (3 + ot
)) - 1);
7132 tcg_gen_movi_tl(s
->tmp0
, 1);
7133 tcg_gen_shl_tl(s
->tmp0
, s
->tmp0
, s
->T1
);
7134 if (s
->prefix
& PREFIX_LOCK
) {
7137 /* Needs no atomic ops; we surpressed the normal
7138 memory load for LOCK above so do it now. */
7139 gen_op_ld_v(s
, ot
, s
->T0
, s
->A0
);
7142 tcg_gen_atomic_fetch_or_tl(s
->T0
, s
->A0
, s
->tmp0
,
7143 s
->mem_index
, ot
| MO_LE
);
7146 tcg_gen_not_tl(s
->tmp0
, s
->tmp0
);
7147 tcg_gen_atomic_fetch_and_tl(s
->T0
, s
->A0
, s
->tmp0
,
7148 s
->mem_index
, ot
| MO_LE
);
7152 tcg_gen_atomic_fetch_xor_tl(s
->T0
, s
->A0
, s
->tmp0
,
7153 s
->mem_index
, ot
| MO_LE
);
7156 tcg_gen_shr_tl(s
->tmp4
, s
->T0
, s
->T1
);
7158 tcg_gen_shr_tl(s
->tmp4
, s
->T0
, s
->T1
);
7161 /* Data already loaded; nothing to do. */
7164 tcg_gen_or_tl(s
->T0
, s
->T0
, s
->tmp0
);
7167 tcg_gen_andc_tl(s
->T0
, s
->T0
, s
->tmp0
);
7171 tcg_gen_xor_tl(s
->T0
, s
->T0
, s
->tmp0
);
7176 gen_op_st_v(s
, ot
, s
->T0
, s
->A0
);
7178 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
7183 /* Delay all CC updates until after the store above. Note that
7184 C is the result of the test, Z is unchanged, and the others
7185 are all undefined. */
7187 case CC_OP_MULB
... CC_OP_MULQ
:
7188 case CC_OP_ADDB
... CC_OP_ADDQ
:
7189 case CC_OP_ADCB
... CC_OP_ADCQ
:
7190 case CC_OP_SUBB
... CC_OP_SUBQ
:
7191 case CC_OP_SBBB
... CC_OP_SBBQ
:
7192 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
7193 case CC_OP_INCB
... CC_OP_INCQ
:
7194 case CC_OP_DECB
... CC_OP_DECQ
:
7195 case CC_OP_SHLB
... CC_OP_SHLQ
:
7196 case CC_OP_SARB
... CC_OP_SARQ
:
7197 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
7198 /* Z was going to be computed from the non-zero status of CC_DST.
7199 We can get that same Z value (and the new C value) by leaving
7200 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
7202 tcg_gen_mov_tl(cpu_cc_src
, s
->tmp4
);
7203 set_cc_op(s
, ((s
->cc_op
- CC_OP_MULB
) & 3) + CC_OP_SARB
);
7206 /* Otherwise, generate EFLAGS and replace the C bit. */
7207 gen_compute_eflags(s
);
7208 tcg_gen_deposit_tl(cpu_cc_src
, cpu_cc_src
, s
->tmp4
,
7213 case 0x1bc: /* bsf / tzcnt */
7214 case 0x1bd: /* bsr / lzcnt */
7216 modrm
= x86_ldub_code(env
, s
);
7217 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
7218 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
7219 gen_extu(ot
, s
->T0
);
7221 /* Note that lzcnt and tzcnt are in different extensions. */
7222 if ((prefixes
& PREFIX_REPZ
)
7224 ? s
->cpuid_ext3_features
& CPUID_EXT3_ABM
7225 : s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)) {
7227 /* For lzcnt/tzcnt, C bit is defined related to the input. */
7228 tcg_gen_mov_tl(cpu_cc_src
, s
->T0
);
7230 /* For lzcnt, reduce the target_ulong result by the
7231 number of zeros that we expect to find at the top. */
7232 tcg_gen_clzi_tl(s
->T0
, s
->T0
, TARGET_LONG_BITS
);
7233 tcg_gen_subi_tl(s
->T0
, s
->T0
, TARGET_LONG_BITS
- size
);
7235 /* For tzcnt, a zero input must return the operand size. */
7236 tcg_gen_ctzi_tl(s
->T0
, s
->T0
, size
);
7238 /* For lzcnt/tzcnt, Z bit is defined related to the result. */
7239 gen_op_update1_cc(s
);
7240 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
7242 /* For bsr/bsf, only the Z bit is defined and it is related
7243 to the input and not the result. */
7244 tcg_gen_mov_tl(cpu_cc_dst
, s
->T0
);
7245 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
7247 /* ??? The manual says that the output is undefined when the
7248 input is zero, but real hardware leaves it unchanged, and
7249 real programs appear to depend on that. Accomplish this
7250 by passing the output as the value to return upon zero. */
7252 /* For bsr, return the bit index of the first 1 bit,
7253 not the count of leading zeros. */
7254 tcg_gen_xori_tl(s
->T1
, cpu_regs
[reg
], TARGET_LONG_BITS
- 1);
7255 tcg_gen_clz_tl(s
->T0
, s
->T0
, s
->T1
);
7256 tcg_gen_xori_tl(s
->T0
, s
->T0
, TARGET_LONG_BITS
- 1);
7258 tcg_gen_ctz_tl(s
->T0
, s
->T0
, cpu_regs
[reg
]);
7261 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
7263 /************************/
7265 case 0x27: /* daa */
7268 gen_update_cc_op(s
);
7269 gen_helper_daa(cpu_env
);
7270 set_cc_op(s
, CC_OP_EFLAGS
);
7272 case 0x2f: /* das */
7275 gen_update_cc_op(s
);
7276 gen_helper_das(cpu_env
);
7277 set_cc_op(s
, CC_OP_EFLAGS
);
7279 case 0x37: /* aaa */
7282 gen_update_cc_op(s
);
7283 gen_helper_aaa(cpu_env
);
7284 set_cc_op(s
, CC_OP_EFLAGS
);
7286 case 0x3f: /* aas */
7289 gen_update_cc_op(s
);
7290 gen_helper_aas(cpu_env
);
7291 set_cc_op(s
, CC_OP_EFLAGS
);
7293 case 0xd4: /* aam */
7296 val
= x86_ldub_code(env
, s
);
7298 gen_exception(s
, EXCP00_DIVZ
, pc_start
- s
->cs_base
);
7300 gen_helper_aam(cpu_env
, tcg_const_i32(val
));
7301 set_cc_op(s
, CC_OP_LOGICB
);
7304 case 0xd5: /* aad */
7307 val
= x86_ldub_code(env
, s
);
7308 gen_helper_aad(cpu_env
, tcg_const_i32(val
));
7309 set_cc_op(s
, CC_OP_LOGICB
);
7311 /************************/
7313 case 0x90: /* nop */
7314 /* XXX: correct lock test for all insn */
7315 if (prefixes
& PREFIX_LOCK
) {
7318 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
7320 goto do_xchg_reg_eax
;
7322 if (prefixes
& PREFIX_REPZ
) {
7323 gen_update_cc_op(s
);
7324 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7325 gen_helper_pause(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7326 s
->base
.is_jmp
= DISAS_NORETURN
;
7329 case 0x9b: /* fwait */
7330 if ((s
->flags
& (HF_MP_MASK
| HF_TS_MASK
)) ==
7331 (HF_MP_MASK
| HF_TS_MASK
)) {
7332 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7334 gen_helper_fwait(cpu_env
);
7337 case 0xcc: /* int3 */
7338 gen_interrupt(s
, EXCP03_INT3
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
7340 case 0xcd: /* int N */
7341 val
= x86_ldub_code(env
, s
);
7342 if (check_vm86_iopl(s
)) {
7343 gen_interrupt(s
, val
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
7346 case 0xce: /* into */
7349 gen_update_cc_op(s
);
7350 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7351 gen_helper_into(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7354 case 0xf1: /* icebp (undocumented, exits to external debugger) */
7355 gen_svm_check_intercept(s
, SVM_EXIT_ICEBP
);
7359 case 0xfa: /* cli */
7360 if (check_iopl(s
)) {
7361 gen_helper_cli(cpu_env
);
7364 case 0xfb: /* sti */
7365 if (check_iopl(s
)) {
7366 gen_helper_sti(cpu_env
);
7367 /* interruptions are enabled only the first insn after sti */
7368 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7369 gen_eob_inhibit_irq(s
, true);
7372 case 0x62: /* bound */
7376 modrm
= x86_ldub_code(env
, s
);
7377 reg
= (modrm
>> 3) & 7;
7378 mod
= (modrm
>> 6) & 3;
7381 gen_op_mov_v_reg(s
, ot
, s
->T0
, reg
);
7382 gen_lea_modrm(env
, s
, modrm
);
7383 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
7385 gen_helper_boundw(cpu_env
, s
->A0
, s
->tmp2_i32
);
7387 gen_helper_boundl(cpu_env
, s
->A0
, s
->tmp2_i32
);
7390 case 0x1c8 ... 0x1cf: /* bswap reg */
7391 reg
= (b
& 7) | REX_B(s
);
7392 #ifdef TARGET_X86_64
7393 if (dflag
== MO_64
) {
7394 tcg_gen_bswap64_i64(cpu_regs
[reg
], cpu_regs
[reg
]);
7398 tcg_gen_bswap32_tl(cpu_regs
[reg
], cpu_regs
[reg
], TCG_BSWAP_OZ
);
7400 case 0xd6: /* salc */
7403 gen_compute_eflags_c(s
, s
->T0
);
7404 tcg_gen_neg_tl(s
->T0
, s
->T0
);
7405 gen_op_mov_reg_v(s
, MO_8
, R_EAX
, s
->T0
);
7407 case 0xe0: /* loopnz */
7408 case 0xe1: /* loopz */
7409 case 0xe2: /* loop */
7410 case 0xe3: /* jecxz */
7412 TCGLabel
*l1
, *l2
, *l3
;
7414 tval
= (int8_t)insn_get(env
, s
, MO_8
);
7415 next_eip
= s
->pc
- s
->cs_base
;
7417 if (dflag
== MO_16
) {
7421 l1
= gen_new_label();
7422 l2
= gen_new_label();
7423 l3
= gen_new_label();
7424 gen_update_cc_op(s
);
7427 case 0: /* loopnz */
7429 gen_op_add_reg_im(s
, s
->aflag
, R_ECX
, -1);
7430 gen_op_jz_ecx(s
, s
->aflag
, l3
);
7431 gen_jcc1(s
, (JCC_Z
<< 1) | (b
^ 1), l1
);
7434 gen_op_add_reg_im(s
, s
->aflag
, R_ECX
, -1);
7435 gen_op_jnz_ecx(s
, s
->aflag
, l1
);
7439 gen_op_jz_ecx(s
, s
->aflag
, l1
);
7444 gen_jmp_im(s
, next_eip
);
7448 gen_jmp_im(s
, tval
);
7453 case 0x130: /* wrmsr */
7454 case 0x132: /* rdmsr */
7455 if (check_cpl0(s
)) {
7456 gen_update_cc_op(s
);
7457 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7459 gen_helper_rdmsr(cpu_env
);
7461 gen_helper_wrmsr(cpu_env
);
7462 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7467 case 0x131: /* rdtsc */
7468 gen_update_cc_op(s
);
7469 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7470 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7473 gen_helper_rdtsc(cpu_env
);
7474 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7475 gen_jmp(s
, s
->pc
- s
->cs_base
);
7478 case 0x133: /* rdpmc */
7479 gen_update_cc_op(s
);
7480 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7481 gen_helper_rdpmc(cpu_env
);
7482 s
->base
.is_jmp
= DISAS_NORETURN
;
7484 case 0x134: /* sysenter */
7485 /* For Intel SYSENTER is valid on 64-bit */
7486 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7489 gen_exception_gpf(s
);
7491 gen_helper_sysenter(cpu_env
);
7495 case 0x135: /* sysexit */
7496 /* For Intel SYSEXIT is valid on 64-bit */
7497 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7500 gen_exception_gpf(s
);
7502 gen_helper_sysexit(cpu_env
, tcg_const_i32(dflag
- 1));
7506 #ifdef TARGET_X86_64
7507 case 0x105: /* syscall */
7508 /* XXX: is it usable in real mode ? */
7509 gen_update_cc_op(s
);
7510 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7511 gen_helper_syscall(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7512 /* TF handling for the syscall insn is different. The TF bit is checked
7513 after the syscall insn completes. This allows #DB to not be
7514 generated after one has entered CPL0 if TF is set in FMASK. */
7515 gen_eob_worker(s
, false, true);
7517 case 0x107: /* sysret */
7519 gen_exception_gpf(s
);
7521 gen_helper_sysret(cpu_env
, tcg_const_i32(dflag
- 1));
7522 /* condition codes are modified only in long mode */
7524 set_cc_op(s
, CC_OP_EFLAGS
);
7526 /* TF handling for the sysret insn is different. The TF bit is
7527 checked after the sysret insn completes. This allows #DB to be
7528 generated "as if" the syscall insn in userspace has just
7530 gen_eob_worker(s
, false, true);
7534 case 0x1a2: /* cpuid */
7535 gen_update_cc_op(s
);
7536 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7537 gen_helper_cpuid(cpu_env
);
7539 case 0xf4: /* hlt */
7540 if (check_cpl0(s
)) {
7541 gen_update_cc_op(s
);
7542 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7543 gen_helper_hlt(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7544 s
->base
.is_jmp
= DISAS_NORETURN
;
7548 modrm
= x86_ldub_code(env
, s
);
7549 mod
= (modrm
>> 6) & 3;
7550 op
= (modrm
>> 3) & 7;
7553 if (!PE(s
) || VM86(s
))
7555 if (s
->flags
& HF_UMIP_MASK
&& !check_cpl0(s
)) {
7558 gen_svm_check_intercept(s
, SVM_EXIT_LDTR_READ
);
7559 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
7560 offsetof(CPUX86State
, ldt
.selector
));
7561 ot
= mod
== 3 ? dflag
: MO_16
;
7562 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7565 if (!PE(s
) || VM86(s
))
7567 if (check_cpl0(s
)) {
7568 gen_svm_check_intercept(s
, SVM_EXIT_LDTR_WRITE
);
7569 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7570 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
7571 gen_helper_lldt(cpu_env
, s
->tmp2_i32
);
7575 if (!PE(s
) || VM86(s
))
7577 if (s
->flags
& HF_UMIP_MASK
&& !check_cpl0(s
)) {
7580 gen_svm_check_intercept(s
, SVM_EXIT_TR_READ
);
7581 tcg_gen_ld32u_tl(s
->T0
, cpu_env
,
7582 offsetof(CPUX86State
, tr
.selector
));
7583 ot
= mod
== 3 ? dflag
: MO_16
;
7584 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7587 if (!PE(s
) || VM86(s
))
7589 if (check_cpl0(s
)) {
7590 gen_svm_check_intercept(s
, SVM_EXIT_TR_WRITE
);
7591 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7592 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, s
->T0
);
7593 gen_helper_ltr(cpu_env
, s
->tmp2_i32
);
7598 if (!PE(s
) || VM86(s
))
7600 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7601 gen_update_cc_op(s
);
7603 gen_helper_verr(cpu_env
, s
->T0
);
7605 gen_helper_verw(cpu_env
, s
->T0
);
7607 set_cc_op(s
, CC_OP_EFLAGS
);
7615 modrm
= x86_ldub_code(env
, s
);
7617 CASE_MODRM_MEM_OP(0): /* sgdt */
7618 if (s
->flags
& HF_UMIP_MASK
&& !check_cpl0(s
)) {
7621 gen_svm_check_intercept(s
, SVM_EXIT_GDTR_READ
);
7622 gen_lea_modrm(env
, s
, modrm
);
7623 tcg_gen_ld32u_tl(s
->T0
,
7624 cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7625 gen_op_st_v(s
, MO_16
, s
->T0
, s
->A0
);
7626 gen_add_A0_im(s
, 2);
7627 tcg_gen_ld_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7628 if (dflag
== MO_16
) {
7629 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xffffff);
7631 gen_op_st_v(s
, CODE64(s
) + MO_32
, s
->T0
, s
->A0
);
7634 case 0xc8: /* monitor */
7635 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) || CPL(s
) != 0) {
7638 gen_update_cc_op(s
);
7639 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7640 tcg_gen_mov_tl(s
->A0
, cpu_regs
[R_EAX
]);
7641 gen_extu(s
->aflag
, s
->A0
);
7642 gen_add_A0_ds_seg(s
);
7643 gen_helper_monitor(cpu_env
, s
->A0
);
7646 case 0xc9: /* mwait */
7647 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) || CPL(s
) != 0) {
7650 gen_update_cc_op(s
);
7651 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7652 gen_helper_mwait(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7653 s
->base
.is_jmp
= DISAS_NORETURN
;
7656 case 0xca: /* clac */
7657 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
)
7661 gen_helper_clac(cpu_env
);
7662 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7666 case 0xcb: /* stac */
7667 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
)
7671 gen_helper_stac(cpu_env
);
7672 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7676 CASE_MODRM_MEM_OP(1): /* sidt */
7677 if (s
->flags
& HF_UMIP_MASK
&& !check_cpl0(s
)) {
7680 gen_svm_check_intercept(s
, SVM_EXIT_IDTR_READ
);
7681 gen_lea_modrm(env
, s
, modrm
);
7682 tcg_gen_ld32u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7683 gen_op_st_v(s
, MO_16
, s
->T0
, s
->A0
);
7684 gen_add_A0_im(s
, 2);
7685 tcg_gen_ld_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, idt
.base
));
7686 if (dflag
== MO_16
) {
7687 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xffffff);
7689 gen_op_st_v(s
, CODE64(s
) + MO_32
, s
->T0
, s
->A0
);
7692 case 0xd0: /* xgetbv */
7693 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
7694 || (s
->prefix
& (PREFIX_LOCK
| PREFIX_DATA
7695 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
7698 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_ECX
]);
7699 gen_helper_xgetbv(s
->tmp1_i64
, cpu_env
, s
->tmp2_i32
);
7700 tcg_gen_extr_i64_tl(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
], s
->tmp1_i64
);
7703 case 0xd1: /* xsetbv */
7704 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
7705 || (s
->prefix
& (PREFIX_LOCK
| PREFIX_DATA
7706 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
7709 if (!check_cpl0(s
)) {
7712 tcg_gen_concat_tl_i64(s
->tmp1_i64
, cpu_regs
[R_EAX
],
7714 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_ECX
]);
7715 gen_helper_xsetbv(cpu_env
, s
->tmp2_i32
, s
->tmp1_i64
);
7716 /* End TB because translation flags may change. */
7717 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7721 case 0xd8: /* VMRUN */
7722 if (!SVME(s
) || !PE(s
)) {
7725 if (!check_cpl0(s
)) {
7728 gen_update_cc_op(s
);
7729 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7730 gen_helper_vmrun(cpu_env
, tcg_const_i32(s
->aflag
- 1),
7731 tcg_const_i32(s
->pc
- pc_start
));
7732 tcg_gen_exit_tb(NULL
, 0);
7733 s
->base
.is_jmp
= DISAS_NORETURN
;
7736 case 0xd9: /* VMMCALL */
7740 gen_update_cc_op(s
);
7741 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7742 gen_helper_vmmcall(cpu_env
);
7745 case 0xda: /* VMLOAD */
7746 if (!SVME(s
) || !PE(s
)) {
7749 if (!check_cpl0(s
)) {
7752 gen_update_cc_op(s
);
7753 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7754 gen_helper_vmload(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7757 case 0xdb: /* VMSAVE */
7758 if (!SVME(s
) || !PE(s
)) {
7761 if (!check_cpl0(s
)) {
7764 gen_update_cc_op(s
);
7765 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7766 gen_helper_vmsave(cpu_env
, tcg_const_i32(s
->aflag
- 1));
7769 case 0xdc: /* STGI */
7770 if ((!SVME(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
))
7774 if (!check_cpl0(s
)) {
7777 gen_update_cc_op(s
);
7778 gen_helper_stgi(cpu_env
);
7779 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7783 case 0xdd: /* CLGI */
7784 if (!SVME(s
) || !PE(s
)) {
7787 if (!check_cpl0(s
)) {
7790 gen_update_cc_op(s
);
7791 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7792 gen_helper_clgi(cpu_env
);
7795 case 0xde: /* SKINIT */
7796 if ((!SVME(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
))
7800 gen_svm_check_intercept(s
, SVM_EXIT_SKINIT
);
7801 /* If not intercepted, not implemented -- raise #UD. */
7804 case 0xdf: /* INVLPGA */
7805 if (!SVME(s
) || !PE(s
)) {
7808 if (!check_cpl0(s
)) {
7811 gen_svm_check_intercept(s
, SVM_EXIT_INVLPGA
);
7812 if (s
->aflag
== MO_64
) {
7813 tcg_gen_mov_tl(s
->A0
, cpu_regs
[R_EAX
]);
7815 tcg_gen_ext32u_tl(s
->A0
, cpu_regs
[R_EAX
]);
7817 gen_helper_flush_page(cpu_env
, s
->A0
);
7818 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7822 CASE_MODRM_MEM_OP(2): /* lgdt */
7823 if (!check_cpl0(s
)) {
7826 gen_svm_check_intercept(s
, SVM_EXIT_GDTR_WRITE
);
7827 gen_lea_modrm(env
, s
, modrm
);
7828 gen_op_ld_v(s
, MO_16
, s
->T1
, s
->A0
);
7829 gen_add_A0_im(s
, 2);
7830 gen_op_ld_v(s
, CODE64(s
) + MO_32
, s
->T0
, s
->A0
);
7831 if (dflag
== MO_16
) {
7832 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xffffff);
7834 tcg_gen_st_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7835 tcg_gen_st32_tl(s
->T1
, cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7838 CASE_MODRM_MEM_OP(3): /* lidt */
7839 if (!check_cpl0(s
)) {
7842 gen_svm_check_intercept(s
, SVM_EXIT_IDTR_WRITE
);
7843 gen_lea_modrm(env
, s
, modrm
);
7844 gen_op_ld_v(s
, MO_16
, s
->T1
, s
->A0
);
7845 gen_add_A0_im(s
, 2);
7846 gen_op_ld_v(s
, CODE64(s
) + MO_32
, s
->T0
, s
->A0
);
7847 if (dflag
== MO_16
) {
7848 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xffffff);
7850 tcg_gen_st_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, idt
.base
));
7851 tcg_gen_st32_tl(s
->T1
, cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7854 CASE_MODRM_OP(4): /* smsw */
7855 if (s
->flags
& HF_UMIP_MASK
&& !check_cpl0(s
)) {
7858 gen_svm_check_intercept(s
, SVM_EXIT_READ_CR0
);
7859 tcg_gen_ld_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, cr
[0]));
7861 * In 32-bit mode, the higher 16 bits of the destination
7862 * register are undefined. In practice CR0[31:0] is stored
7863 * just like in 64-bit mode.
7865 mod
= (modrm
>> 6) & 3;
7866 ot
= (mod
!= 3 ? MO_16
: s
->dflag
);
7867 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7869 case 0xee: /* rdpkru */
7870 if (prefixes
& PREFIX_LOCK
) {
7873 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_ECX
]);
7874 gen_helper_rdpkru(s
->tmp1_i64
, cpu_env
, s
->tmp2_i32
);
7875 tcg_gen_extr_i64_tl(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
], s
->tmp1_i64
);
7877 case 0xef: /* wrpkru */
7878 if (prefixes
& PREFIX_LOCK
) {
7881 tcg_gen_concat_tl_i64(s
->tmp1_i64
, cpu_regs
[R_EAX
],
7883 tcg_gen_trunc_tl_i32(s
->tmp2_i32
, cpu_regs
[R_ECX
]);
7884 gen_helper_wrpkru(cpu_env
, s
->tmp2_i32
, s
->tmp1_i64
);
7887 CASE_MODRM_OP(6): /* lmsw */
7888 if (!check_cpl0(s
)) {
7891 gen_svm_check_intercept(s
, SVM_EXIT_WRITE_CR0
);
7892 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7894 * Only the 4 lower bits of CR0 are modified.
7895 * PE cannot be set to zero if already set to one.
7897 tcg_gen_ld_tl(s
->T1
, cpu_env
, offsetof(CPUX86State
, cr
[0]));
7898 tcg_gen_andi_tl(s
->T0
, s
->T0
, 0xf);
7899 tcg_gen_andi_tl(s
->T1
, s
->T1
, ~0xe);
7900 tcg_gen_or_tl(s
->T0
, s
->T0
, s
->T1
);
7901 gen_helper_write_crN(cpu_env
, tcg_constant_i32(0), s
->T0
);
7902 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7906 CASE_MODRM_MEM_OP(7): /* invlpg */
7907 if (!check_cpl0(s
)) {
7910 gen_svm_check_intercept(s
, SVM_EXIT_INVLPG
);
7911 gen_lea_modrm(env
, s
, modrm
);
7912 gen_helper_flush_page(cpu_env
, s
->A0
);
7913 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
7917 case 0xf8: /* swapgs */
7918 #ifdef TARGET_X86_64
7920 if (check_cpl0(s
)) {
7921 tcg_gen_mov_tl(s
->T0
, cpu_seg_base
[R_GS
]);
7922 tcg_gen_ld_tl(cpu_seg_base
[R_GS
], cpu_env
,
7923 offsetof(CPUX86State
, kernelgsbase
));
7924 tcg_gen_st_tl(s
->T0
, cpu_env
,
7925 offsetof(CPUX86State
, kernelgsbase
));
7932 case 0xf9: /* rdtscp */
7933 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_RDTSCP
)) {
7936 gen_update_cc_op(s
);
7937 gen_jmp_im(s
, pc_start
- s
->cs_base
);
7938 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7941 gen_helper_rdtscp(cpu_env
);
7942 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
7943 gen_jmp(s
, s
->pc
- s
->cs_base
);
7952 case 0x108: /* invd */
7953 case 0x109: /* wbinvd */
7954 if (check_cpl0(s
)) {
7955 gen_svm_check_intercept(s
, (b
& 2) ? SVM_EXIT_INVD
: SVM_EXIT_WBINVD
);
7959 case 0x63: /* arpl or movslS (x86_64) */
7960 #ifdef TARGET_X86_64
7963 /* d_ot is the size of destination */
7966 modrm
= x86_ldub_code(env
, s
);
7967 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
7968 mod
= (modrm
>> 6) & 3;
7969 rm
= (modrm
& 7) | REX_B(s
);
7972 gen_op_mov_v_reg(s
, MO_32
, s
->T0
, rm
);
7974 if (d_ot
== MO_64
) {
7975 tcg_gen_ext32s_tl(s
->T0
, s
->T0
);
7977 gen_op_mov_reg_v(s
, d_ot
, reg
, s
->T0
);
7979 gen_lea_modrm(env
, s
, modrm
);
7980 gen_op_ld_v(s
, MO_32
| MO_SIGN
, s
->T0
, s
->A0
);
7981 gen_op_mov_reg_v(s
, d_ot
, reg
, s
->T0
);
7987 TCGv t0
, t1
, t2
, a0
;
7989 if (!PE(s
) || VM86(s
))
7991 t0
= tcg_temp_local_new();
7992 t1
= tcg_temp_local_new();
7993 t2
= tcg_temp_local_new();
7995 modrm
= x86_ldub_code(env
, s
);
7996 reg
= (modrm
>> 3) & 7;
7997 mod
= (modrm
>> 6) & 3;
8000 gen_lea_modrm(env
, s
, modrm
);
8001 gen_op_ld_v(s
, ot
, t0
, s
->A0
);
8002 a0
= tcg_temp_local_new();
8003 tcg_gen_mov_tl(a0
, s
->A0
);
8005 gen_op_mov_v_reg(s
, ot
, t0
, rm
);
8008 gen_op_mov_v_reg(s
, ot
, t1
, reg
);
8009 tcg_gen_andi_tl(s
->tmp0
, t0
, 3);
8010 tcg_gen_andi_tl(t1
, t1
, 3);
8011 tcg_gen_movi_tl(t2
, 0);
8012 label1
= gen_new_label();
8013 tcg_gen_brcond_tl(TCG_COND_GE
, s
->tmp0
, t1
, label1
);
8014 tcg_gen_andi_tl(t0
, t0
, ~3);
8015 tcg_gen_or_tl(t0
, t0
, t1
);
8016 tcg_gen_movi_tl(t2
, CC_Z
);
8017 gen_set_label(label1
);
8019 gen_op_st_v(s
, ot
, t0
, a0
);
8022 gen_op_mov_reg_v(s
, ot
, rm
, t0
);
8024 gen_compute_eflags(s
);
8025 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_Z
);
8026 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, t2
);
8032 case 0x102: /* lar */
8033 case 0x103: /* lsl */
8037 if (!PE(s
) || VM86(s
))
8039 ot
= dflag
!= MO_16
? MO_32
: MO_16
;
8040 modrm
= x86_ldub_code(env
, s
);
8041 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
8042 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
8043 t0
= tcg_temp_local_new();
8044 gen_update_cc_op(s
);
8046 gen_helper_lar(t0
, cpu_env
, s
->T0
);
8048 gen_helper_lsl(t0
, cpu_env
, s
->T0
);
8050 tcg_gen_andi_tl(s
->tmp0
, cpu_cc_src
, CC_Z
);
8051 label1
= gen_new_label();
8052 tcg_gen_brcondi_tl(TCG_COND_EQ
, s
->tmp0
, 0, label1
);
8053 gen_op_mov_reg_v(s
, ot
, reg
, t0
);
8054 gen_set_label(label1
);
8055 set_cc_op(s
, CC_OP_EFLAGS
);
8060 modrm
= x86_ldub_code(env
, s
);
8061 mod
= (modrm
>> 6) & 3;
8062 op
= (modrm
>> 3) & 7;
8064 case 0: /* prefetchnta */
8065 case 1: /* prefetchnt0 */
8066 case 2: /* prefetchnt0 */
8067 case 3: /* prefetchnt0 */
8070 gen_nop_modrm(env
, s
, modrm
);
8071 /* nothing more to do */
8073 default: /* nop (multi byte) */
8074 gen_nop_modrm(env
, s
, modrm
);
8079 modrm
= x86_ldub_code(env
, s
);
8080 if (s
->flags
& HF_MPX_EN_MASK
) {
8081 mod
= (modrm
>> 6) & 3;
8082 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
8083 if (prefixes
& PREFIX_REPZ
) {
8086 || (prefixes
& PREFIX_LOCK
)
8087 || s
->aflag
== MO_16
) {
8090 gen_bndck(env
, s
, modrm
, TCG_COND_LTU
, cpu_bndl
[reg
]);
8091 } else if (prefixes
& PREFIX_REPNZ
) {
8094 || (prefixes
& PREFIX_LOCK
)
8095 || s
->aflag
== MO_16
) {
8098 TCGv_i64 notu
= tcg_temp_new_i64();
8099 tcg_gen_not_i64(notu
, cpu_bndu
[reg
]);
8100 gen_bndck(env
, s
, modrm
, TCG_COND_GTU
, notu
);
8101 tcg_temp_free_i64(notu
);
8102 } else if (prefixes
& PREFIX_DATA
) {
8103 /* bndmov -- from reg/mem */
8104 if (reg
>= 4 || s
->aflag
== MO_16
) {
8108 int reg2
= (modrm
& 7) | REX_B(s
);
8109 if (reg2
>= 4 || (prefixes
& PREFIX_LOCK
)) {
8112 if (s
->flags
& HF_MPX_IU_MASK
) {
8113 tcg_gen_mov_i64(cpu_bndl
[reg
], cpu_bndl
[reg2
]);
8114 tcg_gen_mov_i64(cpu_bndu
[reg
], cpu_bndu
[reg2
]);
8117 gen_lea_modrm(env
, s
, modrm
);
8119 tcg_gen_qemu_ld_i64(cpu_bndl
[reg
], s
->A0
,
8120 s
->mem_index
, MO_LEUQ
);
8121 tcg_gen_addi_tl(s
->A0
, s
->A0
, 8);
8122 tcg_gen_qemu_ld_i64(cpu_bndu
[reg
], s
->A0
,
8123 s
->mem_index
, MO_LEUQ
);
8125 tcg_gen_qemu_ld_i64(cpu_bndl
[reg
], s
->A0
,
8126 s
->mem_index
, MO_LEUL
);
8127 tcg_gen_addi_tl(s
->A0
, s
->A0
, 4);
8128 tcg_gen_qemu_ld_i64(cpu_bndu
[reg
], s
->A0
,
8129 s
->mem_index
, MO_LEUL
);
8131 /* bnd registers are now in-use */
8132 gen_set_hflag(s
, HF_MPX_IU_MASK
);
8134 } else if (mod
!= 3) {
8136 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
8138 || (prefixes
& PREFIX_LOCK
)
8139 || s
->aflag
== MO_16
8144 tcg_gen_addi_tl(s
->A0
, cpu_regs
[a
.base
], a
.disp
);
8146 tcg_gen_movi_tl(s
->A0
, 0);
8148 gen_lea_v_seg(s
, s
->aflag
, s
->A0
, a
.def_seg
, s
->override
);
8150 tcg_gen_mov_tl(s
->T0
, cpu_regs
[a
.index
]);
8152 tcg_gen_movi_tl(s
->T0
, 0);
8155 gen_helper_bndldx64(cpu_bndl
[reg
], cpu_env
, s
->A0
, s
->T0
);
8156 tcg_gen_ld_i64(cpu_bndu
[reg
], cpu_env
,
8157 offsetof(CPUX86State
, mmx_t0
.MMX_Q(0)));
8159 gen_helper_bndldx32(cpu_bndu
[reg
], cpu_env
, s
->A0
, s
->T0
);
8160 tcg_gen_ext32u_i64(cpu_bndl
[reg
], cpu_bndu
[reg
]);
8161 tcg_gen_shri_i64(cpu_bndu
[reg
], cpu_bndu
[reg
], 32);
8163 gen_set_hflag(s
, HF_MPX_IU_MASK
);
8166 gen_nop_modrm(env
, s
, modrm
);
8169 modrm
= x86_ldub_code(env
, s
);
8170 if (s
->flags
& HF_MPX_EN_MASK
) {
8171 mod
= (modrm
>> 6) & 3;
8172 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
8173 if (mod
!= 3 && (prefixes
& PREFIX_REPZ
)) {
8176 || (prefixes
& PREFIX_LOCK
)
8177 || s
->aflag
== MO_16
) {
8180 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
8182 tcg_gen_extu_tl_i64(cpu_bndl
[reg
], cpu_regs
[a
.base
]);
8184 tcg_gen_ext32u_i64(cpu_bndl
[reg
], cpu_bndl
[reg
]);
8186 } else if (a
.base
== -1) {
8187 /* no base register has lower bound of 0 */
8188 tcg_gen_movi_i64(cpu_bndl
[reg
], 0);
8190 /* rip-relative generates #ud */
8193 tcg_gen_not_tl(s
->A0
, gen_lea_modrm_1(s
, a
));
8195 tcg_gen_ext32u_tl(s
->A0
, s
->A0
);
8197 tcg_gen_extu_tl_i64(cpu_bndu
[reg
], s
->A0
);
8198 /* bnd registers are now in-use */
8199 gen_set_hflag(s
, HF_MPX_IU_MASK
);
8201 } else if (prefixes
& PREFIX_REPNZ
) {
8204 || (prefixes
& PREFIX_LOCK
)
8205 || s
->aflag
== MO_16
) {
8208 gen_bndck(env
, s
, modrm
, TCG_COND_GTU
, cpu_bndu
[reg
]);
8209 } else if (prefixes
& PREFIX_DATA
) {
8210 /* bndmov -- to reg/mem */
8211 if (reg
>= 4 || s
->aflag
== MO_16
) {
8215 int reg2
= (modrm
& 7) | REX_B(s
);
8216 if (reg2
>= 4 || (prefixes
& PREFIX_LOCK
)) {
8219 if (s
->flags
& HF_MPX_IU_MASK
) {
8220 tcg_gen_mov_i64(cpu_bndl
[reg2
], cpu_bndl
[reg
]);
8221 tcg_gen_mov_i64(cpu_bndu
[reg2
], cpu_bndu
[reg
]);
8224 gen_lea_modrm(env
, s
, modrm
);
8226 tcg_gen_qemu_st_i64(cpu_bndl
[reg
], s
->A0
,
8227 s
->mem_index
, MO_LEUQ
);
8228 tcg_gen_addi_tl(s
->A0
, s
->A0
, 8);
8229 tcg_gen_qemu_st_i64(cpu_bndu
[reg
], s
->A0
,
8230 s
->mem_index
, MO_LEUQ
);
8232 tcg_gen_qemu_st_i64(cpu_bndl
[reg
], s
->A0
,
8233 s
->mem_index
, MO_LEUL
);
8234 tcg_gen_addi_tl(s
->A0
, s
->A0
, 4);
8235 tcg_gen_qemu_st_i64(cpu_bndu
[reg
], s
->A0
,
8236 s
->mem_index
, MO_LEUL
);
8239 } else if (mod
!= 3) {
8241 AddressParts a
= gen_lea_modrm_0(env
, s
, modrm
);
8243 || (prefixes
& PREFIX_LOCK
)
8244 || s
->aflag
== MO_16
8249 tcg_gen_addi_tl(s
->A0
, cpu_regs
[a
.base
], a
.disp
);
8251 tcg_gen_movi_tl(s
->A0
, 0);
8253 gen_lea_v_seg(s
, s
->aflag
, s
->A0
, a
.def_seg
, s
->override
);
8255 tcg_gen_mov_tl(s
->T0
, cpu_regs
[a
.index
]);
8257 tcg_gen_movi_tl(s
->T0
, 0);
8260 gen_helper_bndstx64(cpu_env
, s
->A0
, s
->T0
,
8261 cpu_bndl
[reg
], cpu_bndu
[reg
]);
8263 gen_helper_bndstx32(cpu_env
, s
->A0
, s
->T0
,
8264 cpu_bndl
[reg
], cpu_bndu
[reg
]);
8268 gen_nop_modrm(env
, s
, modrm
);
8270 case 0x119: case 0x11c ... 0x11f: /* nop (multi byte) */
8271 modrm
= x86_ldub_code(env
, s
);
8272 gen_nop_modrm(env
, s
, modrm
);
8275 case 0x120: /* mov reg, crN */
8276 case 0x122: /* mov crN, reg */
8277 if (!check_cpl0(s
)) {
8280 modrm
= x86_ldub_code(env
, s
);
8282 * Ignore the mod bits (assume (modrm&0xc0)==0xc0).
8283 * AMD documentation (24594.pdf) and testing of Intel 386 and 486
8284 * processors all show that the mod bits are assumed to be 1's,
8285 * regardless of actual values.
8287 rm
= (modrm
& 7) | REX_B(s
);
8288 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
8291 if ((prefixes
& PREFIX_LOCK
) &&
8292 (s
->cpuid_ext3_features
& CPUID_EXT3_CR8LEG
)) {
8304 ot
= (CODE64(s
) ? MO_64
: MO_32
);
8306 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
8310 gen_svm_check_intercept(s
, SVM_EXIT_WRITE_CR0
+ reg
);
8311 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
8312 gen_helper_write_crN(cpu_env
, tcg_constant_i32(reg
), s
->T0
);
8313 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8316 gen_svm_check_intercept(s
, SVM_EXIT_READ_CR0
+ reg
);
8317 gen_helper_read_crN(s
->T0
, cpu_env
, tcg_constant_i32(reg
));
8318 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
8319 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
8320 gen_jmp(s
, s
->pc
- s
->cs_base
);
8325 case 0x121: /* mov reg, drN */
8326 case 0x123: /* mov drN, reg */
8327 if (check_cpl0(s
)) {
8328 modrm
= x86_ldub_code(env
, s
);
8329 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
8330 * AMD documentation (24594.pdf) and testing of
8331 * intel 386 and 486 processors all show that the mod bits
8332 * are assumed to be 1's, regardless of actual values.
8334 rm
= (modrm
& 7) | REX_B(s
);
8335 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
8344 gen_svm_check_intercept(s
, SVM_EXIT_WRITE_DR0
+ reg
);
8345 gen_op_mov_v_reg(s
, ot
, s
->T0
, rm
);
8346 tcg_gen_movi_i32(s
->tmp2_i32
, reg
);
8347 gen_helper_set_dr(cpu_env
, s
->tmp2_i32
, s
->T0
);
8348 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8351 gen_svm_check_intercept(s
, SVM_EXIT_READ_DR0
+ reg
);
8352 tcg_gen_movi_i32(s
->tmp2_i32
, reg
);
8353 gen_helper_get_dr(s
->T0
, cpu_env
, s
->tmp2_i32
);
8354 gen_op_mov_reg_v(s
, ot
, rm
, s
->T0
);
8358 case 0x106: /* clts */
8359 if (check_cpl0(s
)) {
8360 gen_svm_check_intercept(s
, SVM_EXIT_WRITE_CR0
);
8361 gen_helper_clts(cpu_env
);
8362 /* abort block because static cpu state changed */
8363 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8367 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
8368 case 0x1c3: /* MOVNTI reg, mem */
8369 if (!(s
->cpuid_features
& CPUID_SSE2
))
8371 ot
= mo_64_32(dflag
);
8372 modrm
= x86_ldub_code(env
, s
);
8373 mod
= (modrm
>> 6) & 3;
8376 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
8377 /* generate a generic store */
8378 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
8381 modrm
= x86_ldub_code(env
, s
);
8383 CASE_MODRM_MEM_OP(0): /* fxsave */
8384 if (!(s
->cpuid_features
& CPUID_FXSR
)
8385 || (prefixes
& PREFIX_LOCK
)) {
8388 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
8389 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8392 gen_lea_modrm(env
, s
, modrm
);
8393 gen_helper_fxsave(cpu_env
, s
->A0
);
8396 CASE_MODRM_MEM_OP(1): /* fxrstor */
8397 if (!(s
->cpuid_features
& CPUID_FXSR
)
8398 || (prefixes
& PREFIX_LOCK
)) {
8401 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
8402 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8405 gen_lea_modrm(env
, s
, modrm
);
8406 gen_helper_fxrstor(cpu_env
, s
->A0
);
8409 CASE_MODRM_MEM_OP(2): /* ldmxcsr */
8410 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
)) {
8413 if (s
->flags
& HF_TS_MASK
) {
8414 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8417 gen_lea_modrm(env
, s
, modrm
);
8418 tcg_gen_qemu_ld_i32(s
->tmp2_i32
, s
->A0
, s
->mem_index
, MO_LEUL
);
8419 gen_helper_ldmxcsr(cpu_env
, s
->tmp2_i32
);
8422 CASE_MODRM_MEM_OP(3): /* stmxcsr */
8423 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
)) {
8426 if (s
->flags
& HF_TS_MASK
) {
8427 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8430 gen_helper_update_mxcsr(cpu_env
);
8431 gen_lea_modrm(env
, s
, modrm
);
8432 tcg_gen_ld32u_tl(s
->T0
, cpu_env
, offsetof(CPUX86State
, mxcsr
));
8433 gen_op_st_v(s
, MO_32
, s
->T0
, s
->A0
);
8436 CASE_MODRM_MEM_OP(4): /* xsave */
8437 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8438 || (prefixes
& (PREFIX_LOCK
| PREFIX_DATA
8439 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
8442 gen_lea_modrm(env
, s
, modrm
);
8443 tcg_gen_concat_tl_i64(s
->tmp1_i64
, cpu_regs
[R_EAX
],
8445 gen_helper_xsave(cpu_env
, s
->A0
, s
->tmp1_i64
);
8448 CASE_MODRM_MEM_OP(5): /* xrstor */
8449 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8450 || (prefixes
& (PREFIX_LOCK
| PREFIX_DATA
8451 | PREFIX_REPZ
| PREFIX_REPNZ
))) {
8454 gen_lea_modrm(env
, s
, modrm
);
8455 tcg_gen_concat_tl_i64(s
->tmp1_i64
, cpu_regs
[R_EAX
],
8457 gen_helper_xrstor(cpu_env
, s
->A0
, s
->tmp1_i64
);
8458 /* XRSTOR is how MPX is enabled, which changes how
8459 we translate. Thus we need to end the TB. */
8460 gen_update_cc_op(s
);
8461 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8465 CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */
8466 if (prefixes
& PREFIX_LOCK
) {
8469 if (prefixes
& PREFIX_DATA
) {
8471 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLWB
)) {
8474 gen_nop_modrm(env
, s
, modrm
);
8477 if ((s
->cpuid_ext_features
& CPUID_EXT_XSAVE
) == 0
8478 || (s
->cpuid_xsave_features
& CPUID_XSAVE_XSAVEOPT
) == 0
8479 || (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
))) {
8482 gen_lea_modrm(env
, s
, modrm
);
8483 tcg_gen_concat_tl_i64(s
->tmp1_i64
, cpu_regs
[R_EAX
],
8485 gen_helper_xsaveopt(cpu_env
, s
->A0
, s
->tmp1_i64
);
8489 CASE_MODRM_MEM_OP(7): /* clflush / clflushopt */
8490 if (prefixes
& PREFIX_LOCK
) {
8493 if (prefixes
& PREFIX_DATA
) {
8495 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_CLFLUSHOPT
)) {
8500 if ((s
->prefix
& (PREFIX_REPZ
| PREFIX_REPNZ
))
8501 || !(s
->cpuid_features
& CPUID_CLFLUSH
)) {
8505 gen_nop_modrm(env
, s
, modrm
);
8508 case 0xc0 ... 0xc7: /* rdfsbase (f3 0f ae /0) */
8509 case 0xc8 ... 0xcf: /* rdgsbase (f3 0f ae /1) */
8510 case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */
8511 case 0xd8 ... 0xdf: /* wrgsbase (f3 0f ae /3) */
8513 && (prefixes
& PREFIX_REPZ
)
8514 && !(prefixes
& PREFIX_LOCK
)
8515 && (s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_FSGSBASE
)) {
8516 TCGv base
, treg
, src
, dst
;
8518 /* Preserve hflags bits by testing CR4 at runtime. */
8519 tcg_gen_movi_i32(s
->tmp2_i32
, CR4_FSGSBASE_MASK
);
8520 gen_helper_cr4_testbit(cpu_env
, s
->tmp2_i32
);
8522 base
= cpu_seg_base
[modrm
& 8 ? R_GS
: R_FS
];
8523 treg
= cpu_regs
[(modrm
& 7) | REX_B(s
)];
8527 dst
= base
, src
= treg
;
8530 dst
= treg
, src
= base
;
8533 if (s
->dflag
== MO_32
) {
8534 tcg_gen_ext32u_tl(dst
, src
);
8536 tcg_gen_mov_tl(dst
, src
);
8542 case 0xf8: /* sfence / pcommit */
8543 if (prefixes
& PREFIX_DATA
) {
8545 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_PCOMMIT
)
8546 || (prefixes
& PREFIX_LOCK
)) {
8552 case 0xf9 ... 0xff: /* sfence */
8553 if (!(s
->cpuid_features
& CPUID_SSE
)
8554 || (prefixes
& PREFIX_LOCK
)) {
8557 tcg_gen_mb(TCG_MO_ST_ST
| TCG_BAR_SC
);
8559 case 0xe8 ... 0xef: /* lfence */
8560 if (!(s
->cpuid_features
& CPUID_SSE
)
8561 || (prefixes
& PREFIX_LOCK
)) {
8564 tcg_gen_mb(TCG_MO_LD_LD
| TCG_BAR_SC
);
8566 case 0xf0 ... 0xf7: /* mfence */
8567 if (!(s
->cpuid_features
& CPUID_SSE2
)
8568 || (prefixes
& PREFIX_LOCK
)) {
8571 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8579 case 0x10d: /* 3DNow! prefetch(w) */
8580 modrm
= x86_ldub_code(env
, s
);
8581 mod
= (modrm
>> 6) & 3;
8584 gen_nop_modrm(env
, s
, modrm
);
8586 case 0x1aa: /* rsm */
8587 gen_svm_check_intercept(s
, SVM_EXIT_RSM
);
8588 if (!(s
->flags
& HF_SMM_MASK
))
8590 #ifdef CONFIG_USER_ONLY
8591 /* we should not be in SMM mode */
8592 g_assert_not_reached();
8594 gen_update_cc_op(s
);
8595 gen_jmp_im(s
, s
->pc
- s
->cs_base
);
8596 gen_helper_rsm(cpu_env
);
8597 #endif /* CONFIG_USER_ONLY */
8600 case 0x1b8: /* SSE4.2 popcnt */
8601 if ((prefixes
& (PREFIX_REPZ
| PREFIX_LOCK
| PREFIX_REPNZ
)) !=
8604 if (!(s
->cpuid_ext_features
& CPUID_EXT_POPCNT
))
8607 modrm
= x86_ldub_code(env
, s
);
8608 reg
= ((modrm
>> 3) & 7) | REX_R(s
);
8610 if (s
->prefix
& PREFIX_DATA
) {
8613 ot
= mo_64_32(dflag
);
8616 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
8617 gen_extu(ot
, s
->T0
);
8618 tcg_gen_mov_tl(cpu_cc_src
, s
->T0
);
8619 tcg_gen_ctpop_tl(s
->T0
, s
->T0
);
8620 gen_op_mov_reg_v(s
, ot
, reg
, s
->T0
);
8622 set_cc_op(s
, CC_OP_POPCNT
);
8624 case 0x10e ... 0x10f:
8625 /* 3DNow! instructions, ignore prefixes */
8626 s
->prefix
&= ~(PREFIX_REPZ
| PREFIX_REPNZ
| PREFIX_DATA
);
8628 case 0x110 ... 0x117:
8629 case 0x128 ... 0x12f:
8630 case 0x138 ... 0x13a:
8631 case 0x150 ... 0x179:
8632 case 0x17c ... 0x17f:
8634 case 0x1c4 ... 0x1c6:
8635 case 0x1d0 ... 0x1fe:
8636 gen_sse(env
, s
, b
, pc_start
);
8643 gen_illegal_opcode(s
);
8646 gen_unknown_opcode(env
, s
);
8650 void tcg_x86_init(void)
8652 static const char reg_names
[CPU_NB_REGS
][4] = {
8653 #ifdef TARGET_X86_64
8681 static const char seg_base_names
[6][8] = {
8689 static const char bnd_regl_names
[4][8] = {
8690 "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb"
8692 static const char bnd_regu_names
[4][8] = {
8693 "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub"
8697 cpu_cc_op
= tcg_global_mem_new_i32(cpu_env
,
8698 offsetof(CPUX86State
, cc_op
), "cc_op");
8699 cpu_cc_dst
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_dst
),
8701 cpu_cc_src
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_src
),
8703 cpu_cc_src2
= tcg_global_mem_new(cpu_env
, offsetof(CPUX86State
, cc_src2
),
8706 for (i
= 0; i
< CPU_NB_REGS
; ++i
) {
8707 cpu_regs
[i
] = tcg_global_mem_new(cpu_env
,
8708 offsetof(CPUX86State
, regs
[i
]),
8712 for (i
= 0; i
< 6; ++i
) {
8714 = tcg_global_mem_new(cpu_env
,
8715 offsetof(CPUX86State
, segs
[i
].base
),
8719 for (i
= 0; i
< 4; ++i
) {
8721 = tcg_global_mem_new_i64(cpu_env
,
8722 offsetof(CPUX86State
, bnd_regs
[i
].lb
),
8725 = tcg_global_mem_new_i64(cpu_env
,
8726 offsetof(CPUX86State
, bnd_regs
[i
].ub
),
8731 static void i386_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cpu
)
8733 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8734 CPUX86State
*env
= cpu
->env_ptr
;
8735 uint32_t flags
= dc
->base
.tb
->flags
;
8736 uint32_t cflags
= tb_cflags(dc
->base
.tb
);
8737 int cpl
= (flags
>> HF_CPL_SHIFT
) & 3;
8738 int iopl
= (flags
>> IOPL_SHIFT
) & 3;
8740 dc
->cs_base
= dc
->base
.tb
->cs_base
;
8742 #ifndef CONFIG_USER_ONLY
8747 /* We make some simplifying assumptions; validate they're correct. */
8748 g_assert(PE(dc
) == ((flags
& HF_PE_MASK
) != 0));
8749 g_assert(CPL(dc
) == cpl
);
8750 g_assert(IOPL(dc
) == iopl
);
8751 g_assert(VM86(dc
) == ((flags
& HF_VM_MASK
) != 0));
8752 g_assert(CODE32(dc
) == ((flags
& HF_CS32_MASK
) != 0));
8753 g_assert(CODE64(dc
) == ((flags
& HF_CS64_MASK
) != 0));
8754 g_assert(SS32(dc
) == ((flags
& HF_SS32_MASK
) != 0));
8755 g_assert(LMA(dc
) == ((flags
& HF_LMA_MASK
) != 0));
8756 g_assert(ADDSEG(dc
) == ((flags
& HF_ADDSEG_MASK
) != 0));
8757 g_assert(SVME(dc
) == ((flags
& HF_SVME_MASK
) != 0));
8758 g_assert(GUEST(dc
) == ((flags
& HF_GUEST_MASK
) != 0));
8760 dc
->cc_op
= CC_OP_DYNAMIC
;
8761 dc
->cc_op_dirty
= false;
8762 dc
->popl_esp_hack
= 0;
8763 /* select memory access functions */
8765 #ifdef CONFIG_SOFTMMU
8766 dc
->mem_index
= cpu_mmu_index(env
, false);
8768 dc
->cpuid_features
= env
->features
[FEAT_1_EDX
];
8769 dc
->cpuid_ext_features
= env
->features
[FEAT_1_ECX
];
8770 dc
->cpuid_ext2_features
= env
->features
[FEAT_8000_0001_EDX
];
8771 dc
->cpuid_ext3_features
= env
->features
[FEAT_8000_0001_ECX
];
8772 dc
->cpuid_7_0_ebx_features
= env
->features
[FEAT_7_0_EBX
];
8773 dc
->cpuid_xsave_features
= env
->features
[FEAT_XSAVE
];
8774 dc
->jmp_opt
= !((cflags
& CF_NO_GOTO_TB
) ||
8775 (flags
& (HF_TF_MASK
| HF_INHIBIT_IRQ_MASK
)));
8777 * If jmp_opt, we want to handle each string instruction individually.
8778 * For icount also disable repz optimization so that each iteration
8779 * is accounted separately.
8781 dc
->repz_opt
= !dc
->jmp_opt
&& !(cflags
& CF_USE_ICOUNT
);
8783 dc
->T0
= tcg_temp_new();
8784 dc
->T1
= tcg_temp_new();
8785 dc
->A0
= tcg_temp_new();
8787 dc
->tmp0
= tcg_temp_new();
8788 dc
->tmp1_i64
= tcg_temp_new_i64();
8789 dc
->tmp2_i32
= tcg_temp_new_i32();
8790 dc
->tmp3_i32
= tcg_temp_new_i32();
8791 dc
->tmp4
= tcg_temp_new();
8792 dc
->ptr0
= tcg_temp_new_ptr();
8793 dc
->ptr1
= tcg_temp_new_ptr();
8794 dc
->cc_srcT
= tcg_temp_local_new();
8797 static void i386_tr_tb_start(DisasContextBase
*db
, CPUState
*cpu
)
8801 static void i386_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
8803 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8805 dc
->prev_insn_end
= tcg_last_op();
8806 tcg_gen_insn_start(dc
->base
.pc_next
, dc
->cc_op
);
8809 static void i386_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
8811 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8812 target_ulong pc_next
;
8814 #ifdef TARGET_VSYSCALL_PAGE
8816 * Detect entry into the vsyscall page and invoke the syscall.
8818 if ((dc
->base
.pc_next
& TARGET_PAGE_MASK
) == TARGET_VSYSCALL_PAGE
) {
8819 gen_exception(dc
, EXCP_VSYSCALL
, dc
->base
.pc_next
);
8820 dc
->base
.pc_next
= dc
->pc
+ 1;
8825 pc_next
= disas_insn(dc
, cpu
);
8826 dc
->base
.pc_next
= pc_next
;
8828 if (dc
->base
.is_jmp
== DISAS_NEXT
) {
8829 if (dc
->flags
& (HF_TF_MASK
| HF_INHIBIT_IRQ_MASK
)) {
8831 * If single step mode, we generate only one instruction and
8832 * generate an exception.
8833 * If irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
8834 * the flag and abort the translation to give the irqs a
8837 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
8838 } else if (!is_same_page(&dc
->base
, pc_next
)) {
8839 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
8844 static void i386_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cpu
)
8846 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8848 if (dc
->base
.is_jmp
== DISAS_TOO_MANY
) {
8849 gen_jmp_im(dc
, dc
->base
.pc_next
- dc
->cs_base
);
8854 static void i386_tr_disas_log(const DisasContextBase
*dcbase
,
8855 CPUState
*cpu
, FILE *logfile
)
8857 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
8859 fprintf(logfile
, "IN: %s\n", lookup_symbol(dc
->base
.pc_first
));
8860 target_disas(logfile
, cpu
, dc
->base
.pc_first
, dc
->base
.tb
->size
);
8863 static const TranslatorOps i386_tr_ops
= {
8864 .init_disas_context
= i386_tr_init_disas_context
,
8865 .tb_start
= i386_tr_tb_start
,
8866 .insn_start
= i386_tr_insn_start
,
8867 .translate_insn
= i386_tr_translate_insn
,
8868 .tb_stop
= i386_tr_tb_stop
,
8869 .disas_log
= i386_tr_disas_log
,
8872 /* generate intermediate code for basic block 'tb'. */
8873 void gen_intermediate_code(CPUState
*cpu
, TranslationBlock
*tb
, int max_insns
,
8874 target_ulong pc
, void *host_pc
)
8878 translator_loop(cpu
, tb
, max_insns
, pc
, host_pc
, &i386_tr_ops
, &dc
.base
);
8881 void restore_state_to_opc(CPUX86State
*env
, TranslationBlock
*tb
,
8884 int cc_op
= data
[1];
8885 env
->eip
= data
[0] - tb
->cs_base
;
8886 if (cc_op
!= CC_OP_DYNAMIC
) {