4 * Copyright (c) 2003 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
26 #include "qemu/host-utils.h"
28 #include "disas/disas.h"
35 #define PREFIX_REPZ 0x01
36 #define PREFIX_REPNZ 0x02
37 #define PREFIX_LOCK 0x04
38 #define PREFIX_DATA 0x08
39 #define PREFIX_ADR 0x10
40 #define PREFIX_VEX 0x20
43 #define CODE64(s) ((s)->code64)
44 #define REX_X(s) ((s)->rex_x)
45 #define REX_B(s) ((s)->rex_b)
60 //#define MACRO_TEST 1
62 /* global register indexes */
63 static TCGv_ptr cpu_env
;
65 static TCGv cpu_cc_dst
, cpu_cc_src
, cpu_cc_src2
, cpu_cc_srcT
;
66 static TCGv_i32 cpu_cc_op
;
67 static TCGv cpu_regs
[CPU_NB_REGS
];
70 /* local register indexes (only used inside old micro ops) */
71 static TCGv cpu_tmp0
, cpu_tmp4
;
72 static TCGv_ptr cpu_ptr0
, cpu_ptr1
;
73 static TCGv_i32 cpu_tmp2_i32
, cpu_tmp3_i32
;
74 static TCGv_i64 cpu_tmp1_i64
;
76 static uint8_t gen_opc_cc_op
[OPC_BUF_SIZE
];
78 #include "exec/gen-icount.h"
81 static int x86_64_hregs
;
84 typedef struct DisasContext
{
85 /* current insn context */
86 int override
; /* -1 if no override */
89 target_ulong pc
; /* pc = eip + cs_base */
90 int is_jmp
; /* 1 = means jump (stop translation), 2 means CPU
91 static state change (stop translation) */
92 /* current block context */
93 target_ulong cs_base
; /* base of CS segment */
94 int pe
; /* protected mode */
95 int code32
; /* 32 bit code segment */
97 int lma
; /* long mode active */
98 int code64
; /* 64 bit code segment */
101 int vex_l
; /* vex vector length */
102 int vex_v
; /* vex vvvv register, without 1's compliment. */
103 int ss32
; /* 32 bit stack segment */
104 CCOp cc_op
; /* current CC operation */
106 int addseg
; /* non zero if either DS/ES/SS have a non zero base */
107 int f_st
; /* currently unused */
108 int vm86
; /* vm86 mode */
111 int tf
; /* TF cpu flag */
112 int singlestep_enabled
; /* "hardware" single step enabled */
113 int jmp_opt
; /* use direct block chaining for direct jumps */
114 int mem_index
; /* select memory access functions */
115 uint64_t flags
; /* all execution flags */
116 struct TranslationBlock
*tb
;
117 int popl_esp_hack
; /* for correct popl with esp base handling */
118 int rip_offset
; /* only used in x86_64, but left for simplicity */
120 int cpuid_ext_features
;
121 int cpuid_ext2_features
;
122 int cpuid_ext3_features
;
123 int cpuid_7_0_ebx_features
;
126 static void gen_eob(DisasContext
*s
);
127 static void gen_jmp(DisasContext
*s
, target_ulong eip
);
128 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
);
129 static void gen_op(DisasContext
*s1
, int op
, int ot
, int d
);
131 /* i386 arith/logic operations */
151 OP_SHL1
, /* undocumented */
167 /* I386 int registers */
168 OR_EAX
, /* MUST be even numbered */
177 OR_TMP0
= 16, /* temporary operand register */
179 OR_A0
, /* temporary register used when doing address evaluation */
189 /* Bit set if the global variable is live after setting CC_OP to X. */
190 static const uint8_t cc_op_live
[CC_OP_NB
] = {
191 [CC_OP_DYNAMIC
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
192 [CC_OP_EFLAGS
] = USES_CC_SRC
,
193 [CC_OP_MULB
... CC_OP_MULQ
] = USES_CC_DST
| USES_CC_SRC
,
194 [CC_OP_ADDB
... CC_OP_ADDQ
] = USES_CC_DST
| USES_CC_SRC
,
195 [CC_OP_ADCB
... CC_OP_ADCQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
196 [CC_OP_SUBB
... CC_OP_SUBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRCT
,
197 [CC_OP_SBBB
... CC_OP_SBBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
198 [CC_OP_LOGICB
... CC_OP_LOGICQ
] = USES_CC_DST
,
199 [CC_OP_INCB
... CC_OP_INCQ
] = USES_CC_DST
| USES_CC_SRC
,
200 [CC_OP_DECB
... CC_OP_DECQ
] = USES_CC_DST
| USES_CC_SRC
,
201 [CC_OP_SHLB
... CC_OP_SHLQ
] = USES_CC_DST
| USES_CC_SRC
,
202 [CC_OP_SARB
... CC_OP_SARQ
] = USES_CC_DST
| USES_CC_SRC
,
203 [CC_OP_BMILGB
... CC_OP_BMILGQ
] = USES_CC_DST
| USES_CC_SRC
,
204 [CC_OP_ADCX
] = USES_CC_DST
| USES_CC_SRC
,
205 [CC_OP_ADOX
] = USES_CC_SRC
| USES_CC_SRC2
,
206 [CC_OP_ADCOX
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
210 static void set_cc_op(DisasContext
*s
, CCOp op
)
214 if (s
->cc_op
== op
) {
218 /* Discard CC computation that will no longer be used. */
219 dead
= cc_op_live
[s
->cc_op
] & ~cc_op_live
[op
];
220 if (dead
& USES_CC_DST
) {
221 tcg_gen_discard_tl(cpu_cc_dst
);
223 if (dead
& USES_CC_SRC
) {
224 tcg_gen_discard_tl(cpu_cc_src
);
226 if (dead
& USES_CC_SRC2
) {
227 tcg_gen_discard_tl(cpu_cc_src2
);
229 if (dead
& USES_CC_SRCT
) {
230 tcg_gen_discard_tl(cpu_cc_srcT
);
233 if (op
== CC_OP_DYNAMIC
) {
234 /* The DYNAMIC setting is translator only, and should never be
235 stored. Thus we always consider it clean. */
236 s
->cc_op_dirty
= false;
238 /* Discard any computed CC_OP value (see shifts). */
239 if (s
->cc_op
== CC_OP_DYNAMIC
) {
240 tcg_gen_discard_i32(cpu_cc_op
);
242 s
->cc_op_dirty
= true;
247 static void gen_update_cc_op(DisasContext
*s
)
249 if (s
->cc_op_dirty
) {
250 tcg_gen_movi_i32(cpu_cc_op
, s
->cc_op
);
251 s
->cc_op_dirty
= false;
255 static inline void gen_op_movl_T0_0(void)
257 tcg_gen_movi_tl(cpu_T
[0], 0);
260 static inline void gen_op_movl_T0_im(int32_t val
)
262 tcg_gen_movi_tl(cpu_T
[0], val
);
265 static inline void gen_op_movl_T0_imu(uint32_t val
)
267 tcg_gen_movi_tl(cpu_T
[0], val
);
270 static inline void gen_op_movl_T1_im(int32_t val
)
272 tcg_gen_movi_tl(cpu_T
[1], val
);
275 static inline void gen_op_movl_T1_imu(uint32_t val
)
277 tcg_gen_movi_tl(cpu_T
[1], val
);
280 static inline void gen_op_movl_A0_im(uint32_t val
)
282 tcg_gen_movi_tl(cpu_A0
, val
);
286 static inline void gen_op_movq_A0_im(int64_t val
)
288 tcg_gen_movi_tl(cpu_A0
, val
);
292 static inline void gen_movtl_T0_im(target_ulong val
)
294 tcg_gen_movi_tl(cpu_T
[0], val
);
297 static inline void gen_movtl_T1_im(target_ulong val
)
299 tcg_gen_movi_tl(cpu_T
[1], val
);
302 static inline void gen_op_andl_T0_ffff(void)
304 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffff);
307 static inline void gen_op_andl_T0_im(uint32_t val
)
309 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], val
);
312 static inline void gen_op_movl_T0_T1(void)
314 tcg_gen_mov_tl(cpu_T
[0], cpu_T
[1]);
317 static inline void gen_op_andl_A0_ffff(void)
319 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffff);
324 #define NB_OP_SIZES 4
326 #else /* !TARGET_X86_64 */
328 #define NB_OP_SIZES 3
330 #endif /* !TARGET_X86_64 */
332 #if defined(HOST_WORDS_BIGENDIAN)
333 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
334 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
335 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
336 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
337 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
339 #define REG_B_OFFSET 0
340 #define REG_H_OFFSET 1
341 #define REG_W_OFFSET 0
342 #define REG_L_OFFSET 0
343 #define REG_LH_OFFSET 4
346 /* In instruction encodings for byte register accesses the
347 * register number usually indicates "low 8 bits of register N";
348 * however there are some special cases where N 4..7 indicates
349 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
350 * true for this special case, false otherwise.
352 static inline bool byte_reg_is_xH(int reg
)
358 if (reg
>= 8 || x86_64_hregs
) {
365 static inline void gen_op_mov_reg_v(int ot
, int reg
, TCGv t0
)
369 if (!byte_reg_is_xH(reg
)) {
370 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 8);
372 tcg_gen_deposit_tl(cpu_regs
[reg
- 4], cpu_regs
[reg
- 4], t0
, 8, 8);
376 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 16);
378 default: /* XXX this shouldn't be reached; abort? */
380 /* For x86_64, this sets the higher half of register to zero.
381 For i386, this is equivalent to a mov. */
382 tcg_gen_ext32u_tl(cpu_regs
[reg
], t0
);
386 tcg_gen_mov_tl(cpu_regs
[reg
], t0
);
392 static inline void gen_op_mov_reg_T0(int ot
, int reg
)
394 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
397 static inline void gen_op_mov_reg_T1(int ot
, int reg
)
399 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
402 static inline void gen_op_mov_reg_A0(int size
, int reg
)
406 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], cpu_A0
, 0, 16);
408 default: /* XXX this shouldn't be reached; abort? */
410 /* For x86_64, this sets the higher half of register to zero.
411 For i386, this is equivalent to a mov. */
412 tcg_gen_ext32u_tl(cpu_regs
[reg
], cpu_A0
);
416 tcg_gen_mov_tl(cpu_regs
[reg
], cpu_A0
);
422 static inline void gen_op_mov_v_reg(int ot
, TCGv t0
, int reg
)
424 if (ot
== MO_8
&& byte_reg_is_xH(reg
)) {
425 tcg_gen_shri_tl(t0
, cpu_regs
[reg
- 4], 8);
426 tcg_gen_ext8u_tl(t0
, t0
);
428 tcg_gen_mov_tl(t0
, cpu_regs
[reg
]);
432 static inline void gen_op_mov_TN_reg(int ot
, int t_index
, int reg
)
434 gen_op_mov_v_reg(ot
, cpu_T
[t_index
], reg
);
437 static inline void gen_op_movl_A0_reg(int reg
)
439 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[reg
]);
442 static inline void gen_op_addl_A0_im(int32_t val
)
444 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, val
);
446 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffffffff);
451 static inline void gen_op_addq_A0_im(int64_t val
)
453 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, val
);
457 static void gen_add_A0_im(DisasContext
*s
, int val
)
461 gen_op_addq_A0_im(val
);
464 gen_op_addl_A0_im(val
);
467 static inline void gen_op_addl_T0_T1(void)
469 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
472 static inline void gen_op_jmp_T0(void)
474 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, eip
));
477 static inline void gen_op_add_reg_im(int size
, int reg
, int32_t val
)
481 tcg_gen_addi_tl(cpu_tmp0
, cpu_regs
[reg
], val
);
482 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], cpu_tmp0
, 0, 16);
485 tcg_gen_addi_tl(cpu_tmp0
, cpu_regs
[reg
], val
);
486 /* For x86_64, this sets the higher half of register to zero.
487 For i386, this is equivalent to a nop. */
488 tcg_gen_ext32u_tl(cpu_tmp0
, cpu_tmp0
);
489 tcg_gen_mov_tl(cpu_regs
[reg
], cpu_tmp0
);
493 tcg_gen_addi_tl(cpu_regs
[reg
], cpu_regs
[reg
], val
);
499 static inline void gen_op_add_reg_T0(int size
, int reg
)
503 tcg_gen_add_tl(cpu_tmp0
, cpu_regs
[reg
], cpu_T
[0]);
504 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], cpu_tmp0
, 0, 16);
507 tcg_gen_add_tl(cpu_tmp0
, cpu_regs
[reg
], cpu_T
[0]);
508 /* For x86_64, this sets the higher half of register to zero.
509 For i386, this is equivalent to a nop. */
510 tcg_gen_ext32u_tl(cpu_tmp0
, cpu_tmp0
);
511 tcg_gen_mov_tl(cpu_regs
[reg
], cpu_tmp0
);
515 tcg_gen_add_tl(cpu_regs
[reg
], cpu_regs
[reg
], cpu_T
[0]);
521 static inline void gen_op_addl_A0_reg_sN(int shift
, int reg
)
523 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[reg
]);
525 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, shift
);
526 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
527 /* For x86_64, this sets the higher half of register to zero.
528 For i386, this is equivalent to a nop. */
529 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
532 static inline void gen_op_movl_A0_seg(int reg
)
534 tcg_gen_ld32u_tl(cpu_A0
, cpu_env
, offsetof(CPUX86State
, segs
[reg
].base
) + REG_L_OFFSET
);
537 static inline void gen_op_addl_A0_seg(DisasContext
*s
, int reg
)
539 tcg_gen_ld_tl(cpu_tmp0
, cpu_env
, offsetof(CPUX86State
, segs
[reg
].base
));
542 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffffffff);
543 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
545 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
546 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffffffff);
549 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
554 static inline void gen_op_movq_A0_seg(int reg
)
556 tcg_gen_ld_tl(cpu_A0
, cpu_env
, offsetof(CPUX86State
, segs
[reg
].base
));
559 static inline void gen_op_addq_A0_seg(int reg
)
561 tcg_gen_ld_tl(cpu_tmp0
, cpu_env
, offsetof(CPUX86State
, segs
[reg
].base
));
562 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
565 static inline void gen_op_movq_A0_reg(int reg
)
567 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[reg
]);
570 static inline void gen_op_addq_A0_reg_sN(int shift
, int reg
)
572 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[reg
]);
574 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, shift
);
575 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
579 static inline void gen_op_lds_T0_A0(DisasContext
*s
, int idx
)
581 tcg_gen_qemu_ld_tl(cpu_T
[0], cpu_A0
, s
->mem_index
, idx
| MO_LE
| MO_SIGN
);
584 static inline void gen_op_ld_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
586 tcg_gen_qemu_ld_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
589 static inline void gen_op_st_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
591 tcg_gen_qemu_st_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
594 static inline void gen_op_st_T0_A0(DisasContext
*s
, int idx
)
596 gen_op_st_v(s
, idx
, cpu_T
[0], cpu_A0
);
599 static inline void gen_op_st_T1_A0(DisasContext
*s
, int idx
)
601 gen_op_st_v(s
, idx
, cpu_T
[1], cpu_A0
);
604 static inline void gen_jmp_im(target_ulong pc
)
606 tcg_gen_movi_tl(cpu_tmp0
, pc
);
607 tcg_gen_st_tl(cpu_tmp0
, cpu_env
, offsetof(CPUX86State
, eip
));
610 static inline void gen_string_movl_A0_ESI(DisasContext
*s
)
614 override
= s
->override
;
618 gen_op_movq_A0_seg(override
);
619 gen_op_addq_A0_reg_sN(0, R_ESI
);
621 gen_op_movq_A0_reg(R_ESI
);
627 if (s
->addseg
&& override
< 0)
630 gen_op_movl_A0_seg(override
);
631 gen_op_addl_A0_reg_sN(0, R_ESI
);
633 gen_op_movl_A0_reg(R_ESI
);
636 /* 16 address, always override */
639 gen_op_movl_A0_reg(R_ESI
);
640 gen_op_andl_A0_ffff();
641 gen_op_addl_A0_seg(s
, override
);
645 static inline void gen_string_movl_A0_EDI(DisasContext
*s
)
649 gen_op_movq_A0_reg(R_EDI
);
654 gen_op_movl_A0_seg(R_ES
);
655 gen_op_addl_A0_reg_sN(0, R_EDI
);
657 gen_op_movl_A0_reg(R_EDI
);
660 gen_op_movl_A0_reg(R_EDI
);
661 gen_op_andl_A0_ffff();
662 gen_op_addl_A0_seg(s
, R_ES
);
666 static inline void gen_op_movl_T0_Dshift(int ot
)
668 tcg_gen_ld32s_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, df
));
669 tcg_gen_shli_tl(cpu_T
[0], cpu_T
[0], ot
);
672 static TCGv
gen_ext_tl(TCGv dst
, TCGv src
, int size
, bool sign
)
677 tcg_gen_ext8s_tl(dst
, src
);
679 tcg_gen_ext8u_tl(dst
, src
);
684 tcg_gen_ext16s_tl(dst
, src
);
686 tcg_gen_ext16u_tl(dst
, src
);
692 tcg_gen_ext32s_tl(dst
, src
);
694 tcg_gen_ext32u_tl(dst
, src
);
703 static void gen_extu(int ot
, TCGv reg
)
705 gen_ext_tl(reg
, reg
, ot
, false);
708 static void gen_exts(int ot
, TCGv reg
)
710 gen_ext_tl(reg
, reg
, ot
, true);
713 static inline void gen_op_jnz_ecx(int size
, int label1
)
715 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[R_ECX
]);
716 gen_extu(size
+ 1, cpu_tmp0
);
717 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_tmp0
, 0, label1
);
720 static inline void gen_op_jz_ecx(int size
, int label1
)
722 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[R_ECX
]);
723 gen_extu(size
+ 1, cpu_tmp0
);
724 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
727 static void gen_helper_in_func(int ot
, TCGv v
, TCGv_i32 n
)
731 gen_helper_inb(v
, n
);
734 gen_helper_inw(v
, n
);
737 gen_helper_inl(v
, n
);
742 static void gen_helper_out_func(int ot
, TCGv_i32 v
, TCGv_i32 n
)
746 gen_helper_outb(v
, n
);
749 gen_helper_outw(v
, n
);
752 gen_helper_outl(v
, n
);
757 static void gen_check_io(DisasContext
*s
, int ot
, target_ulong cur_eip
,
761 target_ulong next_eip
;
764 if (s
->pe
&& (s
->cpl
> s
->iopl
|| s
->vm86
)) {
768 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
771 gen_helper_check_iob(cpu_env
, cpu_tmp2_i32
);
774 gen_helper_check_iow(cpu_env
, cpu_tmp2_i32
);
777 gen_helper_check_iol(cpu_env
, cpu_tmp2_i32
);
781 if(s
->flags
& HF_SVMI_MASK
) {
786 svm_flags
|= (1 << (4 + ot
));
787 next_eip
= s
->pc
- s
->cs_base
;
788 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
789 gen_helper_svm_check_io(cpu_env
, cpu_tmp2_i32
,
790 tcg_const_i32(svm_flags
),
791 tcg_const_i32(next_eip
- cur_eip
));
795 static inline void gen_movs(DisasContext
*s
, int ot
)
797 gen_string_movl_A0_ESI(s
);
798 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
799 gen_string_movl_A0_EDI(s
);
800 gen_op_st_T0_A0(s
, ot
);
801 gen_op_movl_T0_Dshift(ot
);
802 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
803 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
806 static void gen_op_update1_cc(void)
808 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
811 static void gen_op_update2_cc(void)
813 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
814 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
817 static void gen_op_update3_cc(TCGv reg
)
819 tcg_gen_mov_tl(cpu_cc_src2
, reg
);
820 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
821 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
824 static inline void gen_op_testl_T0_T1_cc(void)
826 tcg_gen_and_tl(cpu_cc_dst
, cpu_T
[0], cpu_T
[1]);
829 static void gen_op_update_neg_cc(void)
831 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
832 tcg_gen_neg_tl(cpu_cc_src
, cpu_T
[0]);
833 tcg_gen_movi_tl(cpu_cc_srcT
, 0);
836 /* compute all eflags to cc_src */
837 static void gen_compute_eflags(DisasContext
*s
)
839 TCGv zero
, dst
, src1
, src2
;
842 if (s
->cc_op
== CC_OP_EFLAGS
) {
845 if (s
->cc_op
== CC_OP_CLR
) {
846 tcg_gen_movi_tl(cpu_cc_src
, CC_Z
);
847 set_cc_op(s
, CC_OP_EFLAGS
);
856 /* Take care to not read values that are not live. */
857 live
= cc_op_live
[s
->cc_op
] & ~USES_CC_SRCT
;
858 dead
= live
^ (USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
);
860 zero
= tcg_const_tl(0);
861 if (dead
& USES_CC_DST
) {
864 if (dead
& USES_CC_SRC
) {
867 if (dead
& USES_CC_SRC2
) {
873 gen_helper_cc_compute_all(cpu_cc_src
, dst
, src1
, src2
, cpu_cc_op
);
874 set_cc_op(s
, CC_OP_EFLAGS
);
881 typedef struct CCPrepare
{
891 /* compute eflags.C to reg */
892 static CCPrepare
gen_prepare_eflags_c(DisasContext
*s
, TCGv reg
)
898 case CC_OP_SUBB
... CC_OP_SUBQ
:
899 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
900 size
= s
->cc_op
- CC_OP_SUBB
;
901 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
902 /* If no temporary was used, be careful not to alias t1 and t0. */
903 t0
= TCGV_EQUAL(t1
, cpu_cc_src
) ? cpu_tmp0
: reg
;
904 tcg_gen_mov_tl(t0
, cpu_cc_srcT
);
908 case CC_OP_ADDB
... CC_OP_ADDQ
:
909 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
910 size
= s
->cc_op
- CC_OP_ADDB
;
911 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
912 t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
914 return (CCPrepare
) { .cond
= TCG_COND_LTU
, .reg
= t0
,
915 .reg2
= t1
, .mask
= -1, .use_reg2
= true };
917 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
919 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
921 case CC_OP_INCB
... CC_OP_INCQ
:
922 case CC_OP_DECB
... CC_OP_DECQ
:
923 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
924 .mask
= -1, .no_setcond
= true };
926 case CC_OP_SHLB
... CC_OP_SHLQ
:
927 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
928 size
= s
->cc_op
- CC_OP_SHLB
;
929 shift
= (8 << size
) - 1;
930 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
931 .mask
= (target_ulong
)1 << shift
};
933 case CC_OP_MULB
... CC_OP_MULQ
:
934 return (CCPrepare
) { .cond
= TCG_COND_NE
,
935 .reg
= cpu_cc_src
, .mask
= -1 };
937 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
938 size
= s
->cc_op
- CC_OP_BMILGB
;
939 t0
= gen_ext_tl(reg
, cpu_cc_src
, size
, false);
940 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
944 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_dst
,
945 .mask
= -1, .no_setcond
= true };
948 case CC_OP_SARB
... CC_OP_SARQ
:
950 return (CCPrepare
) { .cond
= TCG_COND_NE
,
951 .reg
= cpu_cc_src
, .mask
= CC_C
};
954 /* The need to compute only C from CC_OP_DYNAMIC is important
955 in efficiently implementing e.g. INC at the start of a TB. */
957 gen_helper_cc_compute_c(reg
, cpu_cc_dst
, cpu_cc_src
,
958 cpu_cc_src2
, cpu_cc_op
);
959 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
960 .mask
= -1, .no_setcond
= true };
964 /* compute eflags.P to reg */
965 static CCPrepare
gen_prepare_eflags_p(DisasContext
*s
, TCGv reg
)
967 gen_compute_eflags(s
);
968 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
972 /* compute eflags.S to reg */
973 static CCPrepare
gen_prepare_eflags_s(DisasContext
*s
, TCGv reg
)
977 gen_compute_eflags(s
);
983 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
986 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
989 int size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
990 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, true);
991 return (CCPrepare
) { .cond
= TCG_COND_LT
, .reg
= t0
, .mask
= -1 };
996 /* compute eflags.O to reg */
997 static CCPrepare
gen_prepare_eflags_o(DisasContext
*s
, TCGv reg
)
1002 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src2
,
1003 .mask
= -1, .no_setcond
= true };
1005 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
1007 gen_compute_eflags(s
);
1008 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
1013 /* compute eflags.Z to reg */
1014 static CCPrepare
gen_prepare_eflags_z(DisasContext
*s
, TCGv reg
)
1018 gen_compute_eflags(s
);
1024 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
1027 return (CCPrepare
) { .cond
= TCG_COND_ALWAYS
, .mask
= -1 };
1030 int size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
1031 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
1032 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
1037 /* perform a conditional store into register 'reg' according to jump opcode
1038 value 'b'. In the fast case, T0 is guaranted not to be used. */
1039 static CCPrepare
gen_prepare_cc(DisasContext
*s
, int b
, TCGv reg
)
1041 int inv
, jcc_op
, size
, cond
;
1046 jcc_op
= (b
>> 1) & 7;
1049 case CC_OP_SUBB
... CC_OP_SUBQ
:
1050 /* We optimize relational operators for the cmp/jcc case. */
1051 size
= s
->cc_op
- CC_OP_SUBB
;
1054 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
1055 gen_extu(size
, cpu_tmp4
);
1056 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
1057 cc
= (CCPrepare
) { .cond
= TCG_COND_LEU
, .reg
= cpu_tmp4
,
1058 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
1067 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
1068 gen_exts(size
, cpu_tmp4
);
1069 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, true);
1070 cc
= (CCPrepare
) { .cond
= cond
, .reg
= cpu_tmp4
,
1071 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
1081 /* This actually generates good code for JC, JZ and JS. */
1084 cc
= gen_prepare_eflags_o(s
, reg
);
1087 cc
= gen_prepare_eflags_c(s
, reg
);
1090 cc
= gen_prepare_eflags_z(s
, reg
);
1093 gen_compute_eflags(s
);
1094 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
1095 .mask
= CC_Z
| CC_C
};
1098 cc
= gen_prepare_eflags_s(s
, reg
);
1101 cc
= gen_prepare_eflags_p(s
, reg
);
1104 gen_compute_eflags(s
);
1105 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
1108 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
1109 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
1110 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
1115 gen_compute_eflags(s
);
1116 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
1119 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
1120 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
1121 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
1122 .mask
= CC_S
| CC_Z
};
1129 cc
.cond
= tcg_invert_cond(cc
.cond
);
1134 static void gen_setcc1(DisasContext
*s
, int b
, TCGv reg
)
1136 CCPrepare cc
= gen_prepare_cc(s
, b
, reg
);
1138 if (cc
.no_setcond
) {
1139 if (cc
.cond
== TCG_COND_EQ
) {
1140 tcg_gen_xori_tl(reg
, cc
.reg
, 1);
1142 tcg_gen_mov_tl(reg
, cc
.reg
);
1147 if (cc
.cond
== TCG_COND_NE
&& !cc
.use_reg2
&& cc
.imm
== 0 &&
1148 cc
.mask
!= 0 && (cc
.mask
& (cc
.mask
- 1)) == 0) {
1149 tcg_gen_shri_tl(reg
, cc
.reg
, ctztl(cc
.mask
));
1150 tcg_gen_andi_tl(reg
, reg
, 1);
1153 if (cc
.mask
!= -1) {
1154 tcg_gen_andi_tl(reg
, cc
.reg
, cc
.mask
);
1158 tcg_gen_setcond_tl(cc
.cond
, reg
, cc
.reg
, cc
.reg2
);
1160 tcg_gen_setcondi_tl(cc
.cond
, reg
, cc
.reg
, cc
.imm
);
1164 static inline void gen_compute_eflags_c(DisasContext
*s
, TCGv reg
)
1166 gen_setcc1(s
, JCC_B
<< 1, reg
);
1169 /* generate a conditional jump to label 'l1' according to jump opcode
1170 value 'b'. In the fast case, T0 is guaranted not to be used. */
1171 static inline void gen_jcc1_noeob(DisasContext
*s
, int b
, int l1
)
1173 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T
[0]);
1175 if (cc
.mask
!= -1) {
1176 tcg_gen_andi_tl(cpu_T
[0], cc
.reg
, cc
.mask
);
1180 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1182 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1186 /* Generate a conditional jump to label 'l1' according to jump opcode
1187 value 'b'. In the fast case, T0 is guaranted not to be used.
1188 A translation block must end soon. */
1189 static inline void gen_jcc1(DisasContext
*s
, int b
, int l1
)
1191 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T
[0]);
1193 gen_update_cc_op(s
);
1194 if (cc
.mask
!= -1) {
1195 tcg_gen_andi_tl(cpu_T
[0], cc
.reg
, cc
.mask
);
1198 set_cc_op(s
, CC_OP_DYNAMIC
);
1200 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1202 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1206 /* XXX: does not work with gdbstub "ice" single step - not a
1208 static int gen_jz_ecx_string(DisasContext
*s
, target_ulong next_eip
)
1212 l1
= gen_new_label();
1213 l2
= gen_new_label();
1214 gen_op_jnz_ecx(s
->aflag
, l1
);
1216 gen_jmp_tb(s
, next_eip
, 1);
1221 static inline void gen_stos(DisasContext
*s
, int ot
)
1223 gen_op_mov_TN_reg(MO_32
, 0, R_EAX
);
1224 gen_string_movl_A0_EDI(s
);
1225 gen_op_st_T0_A0(s
, ot
);
1226 gen_op_movl_T0_Dshift(ot
);
1227 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1230 static inline void gen_lods(DisasContext
*s
, int ot
)
1232 gen_string_movl_A0_ESI(s
);
1233 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1234 gen_op_mov_reg_T0(ot
, R_EAX
);
1235 gen_op_movl_T0_Dshift(ot
);
1236 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1239 static inline void gen_scas(DisasContext
*s
, int ot
)
1241 gen_string_movl_A0_EDI(s
);
1242 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
1243 gen_op(s
, OP_CMPL
, ot
, R_EAX
);
1244 gen_op_movl_T0_Dshift(ot
);
1245 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1248 static inline void gen_cmps(DisasContext
*s
, int ot
)
1250 gen_string_movl_A0_EDI(s
);
1251 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
1252 gen_string_movl_A0_ESI(s
);
1253 gen_op(s
, OP_CMPL
, ot
, OR_TMP0
);
1254 gen_op_movl_T0_Dshift(ot
);
1255 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1256 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1259 static inline void gen_ins(DisasContext
*s
, int ot
)
1263 gen_string_movl_A0_EDI(s
);
1264 /* Note: we must do this dummy write first to be restartable in
1265 case of page fault. */
1267 gen_op_st_T0_A0(s
, ot
);
1268 gen_op_mov_TN_reg(MO_16
, 1, R_EDX
);
1269 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[1]);
1270 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1271 gen_helper_in_func(ot
, cpu_T
[0], cpu_tmp2_i32
);
1272 gen_op_st_T0_A0(s
, ot
);
1273 gen_op_movl_T0_Dshift(ot
);
1274 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1279 static inline void gen_outs(DisasContext
*s
, int ot
)
1283 gen_string_movl_A0_ESI(s
);
1284 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1286 gen_op_mov_TN_reg(MO_16
, 1, R_EDX
);
1287 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[1]);
1288 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1289 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[0]);
1290 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1292 gen_op_movl_T0_Dshift(ot
);
1293 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1298 /* same method as Valgrind : we generate jumps to current or next
1300 #define GEN_REPZ(op) \
1301 static inline void gen_repz_ ## op(DisasContext *s, int ot, \
1302 target_ulong cur_eip, target_ulong next_eip) \
1305 gen_update_cc_op(s); \
1306 l2 = gen_jz_ecx_string(s, next_eip); \
1307 gen_ ## op(s, ot); \
1308 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1309 /* a loop would cause two single step exceptions if ECX = 1 \
1310 before rep string_insn */ \
1312 gen_op_jz_ecx(s->aflag, l2); \
1313 gen_jmp(s, cur_eip); \
1316 #define GEN_REPZ2(op) \
1317 static inline void gen_repz_ ## op(DisasContext *s, int ot, \
1318 target_ulong cur_eip, \
1319 target_ulong next_eip, \
1323 gen_update_cc_op(s); \
1324 l2 = gen_jz_ecx_string(s, next_eip); \
1325 gen_ ## op(s, ot); \
1326 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1327 gen_update_cc_op(s); \
1328 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
1330 gen_op_jz_ecx(s->aflag, l2); \
1331 gen_jmp(s, cur_eip); \
1342 static void gen_helper_fp_arith_ST0_FT0(int op
)
1346 gen_helper_fadd_ST0_FT0(cpu_env
);
1349 gen_helper_fmul_ST0_FT0(cpu_env
);
1352 gen_helper_fcom_ST0_FT0(cpu_env
);
1355 gen_helper_fcom_ST0_FT0(cpu_env
);
1358 gen_helper_fsub_ST0_FT0(cpu_env
);
1361 gen_helper_fsubr_ST0_FT0(cpu_env
);
1364 gen_helper_fdiv_ST0_FT0(cpu_env
);
1367 gen_helper_fdivr_ST0_FT0(cpu_env
);
1372 /* NOTE the exception in "r" op ordering */
1373 static void gen_helper_fp_arith_STN_ST0(int op
, int opreg
)
1375 TCGv_i32 tmp
= tcg_const_i32(opreg
);
1378 gen_helper_fadd_STN_ST0(cpu_env
, tmp
);
1381 gen_helper_fmul_STN_ST0(cpu_env
, tmp
);
1384 gen_helper_fsubr_STN_ST0(cpu_env
, tmp
);
1387 gen_helper_fsub_STN_ST0(cpu_env
, tmp
);
1390 gen_helper_fdivr_STN_ST0(cpu_env
, tmp
);
1393 gen_helper_fdiv_STN_ST0(cpu_env
, tmp
);
1398 /* if d == OR_TMP0, it means memory operand (address in A0) */
1399 static void gen_op(DisasContext
*s1
, int op
, int ot
, int d
)
1402 gen_op_mov_TN_reg(ot
, 0, d
);
1404 gen_op_ld_v(s1
, ot
, cpu_T
[0], cpu_A0
);
1408 gen_compute_eflags_c(s1
, cpu_tmp4
);
1409 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1410 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_tmp4
);
1412 gen_op_mov_reg_T0(ot
, d
);
1414 gen_op_st_T0_A0(s1
, ot
);
1415 gen_op_update3_cc(cpu_tmp4
);
1416 set_cc_op(s1
, CC_OP_ADCB
+ ot
);
1419 gen_compute_eflags_c(s1
, cpu_tmp4
);
1420 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1421 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_tmp4
);
1423 gen_op_mov_reg_T0(ot
, d
);
1425 gen_op_st_T0_A0(s1
, ot
);
1426 gen_op_update3_cc(cpu_tmp4
);
1427 set_cc_op(s1
, CC_OP_SBBB
+ ot
);
1430 gen_op_addl_T0_T1();
1432 gen_op_mov_reg_T0(ot
, d
);
1434 gen_op_st_T0_A0(s1
, ot
);
1435 gen_op_update2_cc();
1436 set_cc_op(s1
, CC_OP_ADDB
+ ot
);
1439 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T
[0]);
1440 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1442 gen_op_mov_reg_T0(ot
, d
);
1444 gen_op_st_T0_A0(s1
, ot
);
1445 gen_op_update2_cc();
1446 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1450 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1452 gen_op_mov_reg_T0(ot
, d
);
1454 gen_op_st_T0_A0(s1
, ot
);
1455 gen_op_update1_cc();
1456 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1459 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1461 gen_op_mov_reg_T0(ot
, d
);
1463 gen_op_st_T0_A0(s1
, ot
);
1464 gen_op_update1_cc();
1465 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1468 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1470 gen_op_mov_reg_T0(ot
, d
);
1472 gen_op_st_T0_A0(s1
, ot
);
1473 gen_op_update1_cc();
1474 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1477 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
1478 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T
[0]);
1479 tcg_gen_sub_tl(cpu_cc_dst
, cpu_T
[0], cpu_T
[1]);
1480 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1485 /* if d == OR_TMP0, it means memory operand (address in A0) */
1486 static void gen_inc(DisasContext
*s1
, int ot
, int d
, int c
)
1489 gen_op_mov_TN_reg(ot
, 0, d
);
1491 gen_op_ld_v(s1
, ot
, cpu_T
[0], cpu_A0
);
1493 gen_compute_eflags_c(s1
, cpu_cc_src
);
1495 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], 1);
1496 set_cc_op(s1
, CC_OP_INCB
+ ot
);
1498 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], -1);
1499 set_cc_op(s1
, CC_OP_DECB
+ ot
);
1502 gen_op_mov_reg_T0(ot
, d
);
1504 gen_op_st_T0_A0(s1
, ot
);
1505 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
1508 static void gen_shift_flags(DisasContext
*s
, int ot
, TCGv result
, TCGv shm1
,
1509 TCGv count
, bool is_right
)
1511 TCGv_i32 z32
, s32
, oldop
;
1514 /* Store the results into the CC variables. If we know that the
1515 variable must be dead, store unconditionally. Otherwise we'll
1516 need to not disrupt the current contents. */
1517 z_tl
= tcg_const_tl(0);
1518 if (cc_op_live
[s
->cc_op
] & USES_CC_DST
) {
1519 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_dst
, count
, z_tl
,
1520 result
, cpu_cc_dst
);
1522 tcg_gen_mov_tl(cpu_cc_dst
, result
);
1524 if (cc_op_live
[s
->cc_op
] & USES_CC_SRC
) {
1525 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_src
, count
, z_tl
,
1528 tcg_gen_mov_tl(cpu_cc_src
, shm1
);
1530 tcg_temp_free(z_tl
);
1532 /* Get the two potential CC_OP values into temporaries. */
1533 tcg_gen_movi_i32(cpu_tmp2_i32
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1534 if (s
->cc_op
== CC_OP_DYNAMIC
) {
1537 tcg_gen_movi_i32(cpu_tmp3_i32
, s
->cc_op
);
1538 oldop
= cpu_tmp3_i32
;
1541 /* Conditionally store the CC_OP value. */
1542 z32
= tcg_const_i32(0);
1543 s32
= tcg_temp_new_i32();
1544 tcg_gen_trunc_tl_i32(s32
, count
);
1545 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, s32
, z32
, cpu_tmp2_i32
, oldop
);
1546 tcg_temp_free_i32(z32
);
1547 tcg_temp_free_i32(s32
);
1549 /* The CC_OP value is no longer predictable. */
1550 set_cc_op(s
, CC_OP_DYNAMIC
);
1553 static void gen_shift_rm_T1(DisasContext
*s
, int ot
, int op1
,
1554 int is_right
, int is_arith
)
1556 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1559 if (op1
== OR_TMP0
) {
1560 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1562 gen_op_mov_TN_reg(ot
, 0, op1
);
1565 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], mask
);
1566 tcg_gen_subi_tl(cpu_tmp0
, cpu_T
[1], 1);
1570 gen_exts(ot
, cpu_T
[0]);
1571 tcg_gen_sar_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1572 tcg_gen_sar_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1574 gen_extu(ot
, cpu_T
[0]);
1575 tcg_gen_shr_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1576 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1579 tcg_gen_shl_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1580 tcg_gen_shl_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1584 if (op1
== OR_TMP0
) {
1585 gen_op_st_T0_A0(s
, ot
);
1587 gen_op_mov_reg_T0(ot
, op1
);
1590 gen_shift_flags(s
, ot
, cpu_T
[0], cpu_tmp0
, cpu_T
[1], is_right
);
1593 static void gen_shift_rm_im(DisasContext
*s
, int ot
, int op1
, int op2
,
1594 int is_right
, int is_arith
)
1596 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1600 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1602 gen_op_mov_TN_reg(ot
, 0, op1
);
1608 gen_exts(ot
, cpu_T
[0]);
1609 tcg_gen_sari_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1610 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], op2
);
1612 gen_extu(ot
, cpu_T
[0]);
1613 tcg_gen_shri_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1614 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], op2
);
1617 tcg_gen_shli_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1618 tcg_gen_shli_tl(cpu_T
[0], cpu_T
[0], op2
);
1624 gen_op_st_T0_A0(s
, ot
);
1626 gen_op_mov_reg_T0(ot
, op1
);
1628 /* update eflags if non zero shift */
1630 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
1631 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
1632 set_cc_op(s
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1636 static inline void tcg_gen_lshift(TCGv ret
, TCGv arg1
, target_long arg2
)
1639 tcg_gen_shli_tl(ret
, arg1
, arg2
);
1641 tcg_gen_shri_tl(ret
, arg1
, -arg2
);
1644 static void gen_rot_rm_T1(DisasContext
*s
, int ot
, int op1
, int is_right
)
1646 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1650 if (op1
== OR_TMP0
) {
1651 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1653 gen_op_mov_TN_reg(ot
, 0, op1
);
1656 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], mask
);
1660 /* Replicate the 8-bit input so that a 32-bit rotate works. */
1661 tcg_gen_ext8u_tl(cpu_T
[0], cpu_T
[0]);
1662 tcg_gen_muli_tl(cpu_T
[0], cpu_T
[0], 0x01010101);
1665 /* Replicate the 16-bit input so that a 32-bit rotate works. */
1666 tcg_gen_deposit_tl(cpu_T
[0], cpu_T
[0], cpu_T
[0], 16, 16);
1669 #ifdef TARGET_X86_64
1671 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
1672 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
1674 tcg_gen_rotr_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1676 tcg_gen_rotl_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1678 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
1683 tcg_gen_rotr_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1685 tcg_gen_rotl_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1691 if (op1
== OR_TMP0
) {
1692 gen_op_st_T0_A0(s
, ot
);
1694 gen_op_mov_reg_T0(ot
, op1
);
1697 /* We'll need the flags computed into CC_SRC. */
1698 gen_compute_eflags(s
);
1700 /* The value that was "rotated out" is now present at the other end
1701 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1702 since we've computed the flags into CC_SRC, these variables are
1705 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T
[0], mask
- 1);
1706 tcg_gen_shri_tl(cpu_cc_dst
, cpu_T
[0], mask
);
1707 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1709 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T
[0], mask
);
1710 tcg_gen_andi_tl(cpu_cc_dst
, cpu_T
[0], 1);
1712 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1713 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1715 /* Now conditionally store the new CC_OP value. If the shift count
1716 is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1717 Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1718 exactly as we computed above. */
1719 t0
= tcg_const_i32(0);
1720 t1
= tcg_temp_new_i32();
1721 tcg_gen_trunc_tl_i32(t1
, cpu_T
[1]);
1722 tcg_gen_movi_i32(cpu_tmp2_i32
, CC_OP_ADCOX
);
1723 tcg_gen_movi_i32(cpu_tmp3_i32
, CC_OP_EFLAGS
);
1724 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, t1
, t0
,
1725 cpu_tmp2_i32
, cpu_tmp3_i32
);
1726 tcg_temp_free_i32(t0
);
1727 tcg_temp_free_i32(t1
);
1729 /* The CC_OP value is no longer predictable. */
1730 set_cc_op(s
, CC_OP_DYNAMIC
);
1733 static void gen_rot_rm_im(DisasContext
*s
, int ot
, int op1
, int op2
,
1736 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1740 if (op1
== OR_TMP0
) {
1741 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1743 gen_op_mov_TN_reg(ot
, 0, op1
);
1749 #ifdef TARGET_X86_64
1751 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
1753 tcg_gen_rotri_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, op2
);
1755 tcg_gen_rotli_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, op2
);
1757 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
1762 tcg_gen_rotri_tl(cpu_T
[0], cpu_T
[0], op2
);
1764 tcg_gen_rotli_tl(cpu_T
[0], cpu_T
[0], op2
);
1775 shift
= mask
+ 1 - shift
;
1777 gen_extu(ot
, cpu_T
[0]);
1778 tcg_gen_shli_tl(cpu_tmp0
, cpu_T
[0], shift
);
1779 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], mask
+ 1 - shift
);
1780 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
1786 if (op1
== OR_TMP0
) {
1787 gen_op_st_T0_A0(s
, ot
);
1789 gen_op_mov_reg_T0(ot
, op1
);
1793 /* Compute the flags into CC_SRC. */
1794 gen_compute_eflags(s
);
1796 /* The value that was "rotated out" is now present at the other end
1797 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1798 since we've computed the flags into CC_SRC, these variables are
1801 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T
[0], mask
- 1);
1802 tcg_gen_shri_tl(cpu_cc_dst
, cpu_T
[0], mask
);
1803 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1805 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T
[0], mask
);
1806 tcg_gen_andi_tl(cpu_cc_dst
, cpu_T
[0], 1);
1808 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1809 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1810 set_cc_op(s
, CC_OP_ADCOX
);
1814 /* XXX: add faster immediate = 1 case */
1815 static void gen_rotc_rm_T1(DisasContext
*s
, int ot
, int op1
,
1818 gen_compute_eflags(s
);
1819 assert(s
->cc_op
== CC_OP_EFLAGS
);
1823 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1825 gen_op_mov_TN_reg(ot
, 0, op1
);
1830 gen_helper_rcrb(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1833 gen_helper_rcrw(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1836 gen_helper_rcrl(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1838 #ifdef TARGET_X86_64
1840 gen_helper_rcrq(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1847 gen_helper_rclb(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1850 gen_helper_rclw(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1853 gen_helper_rcll(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1855 #ifdef TARGET_X86_64
1857 gen_helper_rclq(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1864 gen_op_st_T0_A0(s
, ot
);
1866 gen_op_mov_reg_T0(ot
, op1
);
1869 /* XXX: add faster immediate case */
1870 static void gen_shiftd_rm_T1(DisasContext
*s
, int ot
, int op1
,
1871 bool is_right
, TCGv count_in
)
1873 target_ulong mask
= (ot
== MO_64
? 63 : 31);
1877 if (op1
== OR_TMP0
) {
1878 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1880 gen_op_mov_TN_reg(ot
, 0, op1
);
1883 count
= tcg_temp_new();
1884 tcg_gen_andi_tl(count
, count_in
, mask
);
1888 /* Note: we implement the Intel behaviour for shift count > 16.
1889 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A
1890 portion by constructing it as a 32-bit value. */
1892 tcg_gen_deposit_tl(cpu_tmp0
, cpu_T
[0], cpu_T
[1], 16, 16);
1893 tcg_gen_mov_tl(cpu_T
[1], cpu_T
[0]);
1894 tcg_gen_mov_tl(cpu_T
[0], cpu_tmp0
);
1896 tcg_gen_deposit_tl(cpu_T
[1], cpu_T
[0], cpu_T
[1], 16, 16);
1899 #ifdef TARGET_X86_64
1901 /* Concatenate the two 32-bit values and use a 64-bit shift. */
1902 tcg_gen_subi_tl(cpu_tmp0
, count
, 1);
1904 tcg_gen_concat_tl_i64(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1905 tcg_gen_shr_i64(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1906 tcg_gen_shr_i64(cpu_T
[0], cpu_T
[0], count
);
1908 tcg_gen_concat_tl_i64(cpu_T
[0], cpu_T
[1], cpu_T
[0]);
1909 tcg_gen_shl_i64(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1910 tcg_gen_shl_i64(cpu_T
[0], cpu_T
[0], count
);
1911 tcg_gen_shri_i64(cpu_tmp0
, cpu_tmp0
, 32);
1912 tcg_gen_shri_i64(cpu_T
[0], cpu_T
[0], 32);
1917 tcg_gen_subi_tl(cpu_tmp0
, count
, 1);
1919 tcg_gen_shr_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1921 tcg_gen_subfi_tl(cpu_tmp4
, mask
+ 1, count
);
1922 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], count
);
1923 tcg_gen_shl_tl(cpu_T
[1], cpu_T
[1], cpu_tmp4
);
1925 tcg_gen_shl_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1927 /* Only needed if count > 16, for Intel behaviour. */
1928 tcg_gen_subfi_tl(cpu_tmp4
, 33, count
);
1929 tcg_gen_shr_tl(cpu_tmp4
, cpu_T
[1], cpu_tmp4
);
1930 tcg_gen_or_tl(cpu_tmp0
, cpu_tmp0
, cpu_tmp4
);
1933 tcg_gen_subfi_tl(cpu_tmp4
, mask
+ 1, count
);
1934 tcg_gen_shl_tl(cpu_T
[0], cpu_T
[0], count
);
1935 tcg_gen_shr_tl(cpu_T
[1], cpu_T
[1], cpu_tmp4
);
1937 tcg_gen_movi_tl(cpu_tmp4
, 0);
1938 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_T
[1], count
, cpu_tmp4
,
1939 cpu_tmp4
, cpu_T
[1]);
1940 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1945 if (op1
== OR_TMP0
) {
1946 gen_op_st_T0_A0(s
, ot
);
1948 gen_op_mov_reg_T0(ot
, op1
);
1951 gen_shift_flags(s
, ot
, cpu_T
[0], cpu_tmp0
, count
, is_right
);
1952 tcg_temp_free(count
);
1955 static void gen_shift(DisasContext
*s1
, int op
, int ot
, int d
, int s
)
1958 gen_op_mov_TN_reg(ot
, 1, s
);
1961 gen_rot_rm_T1(s1
, ot
, d
, 0);
1964 gen_rot_rm_T1(s1
, ot
, d
, 1);
1968 gen_shift_rm_T1(s1
, ot
, d
, 0, 0);
1971 gen_shift_rm_T1(s1
, ot
, d
, 1, 0);
1974 gen_shift_rm_T1(s1
, ot
, d
, 1, 1);
1977 gen_rotc_rm_T1(s1
, ot
, d
, 0);
1980 gen_rotc_rm_T1(s1
, ot
, d
, 1);
1985 static void gen_shifti(DisasContext
*s1
, int op
, int ot
, int d
, int c
)
1989 gen_rot_rm_im(s1
, ot
, d
, c
, 0);
1992 gen_rot_rm_im(s1
, ot
, d
, c
, 1);
1996 gen_shift_rm_im(s1
, ot
, d
, c
, 0, 0);
1999 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 0);
2002 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 1);
2005 /* currently not optimized */
2006 gen_op_movl_T1_im(c
);
2007 gen_shift(s1
, op
, ot
, d
, OR_TMP1
);
2012 static void gen_lea_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2013 int *reg_ptr
, int *offset_ptr
)
2021 int mod
, rm
, code
, override
, must_add_seg
;
2024 override
= s
->override
;
2025 must_add_seg
= s
->addseg
;
2028 mod
= (modrm
>> 6) & 3;
2039 code
= cpu_ldub_code(env
, s
->pc
++);
2040 scale
= (code
>> 6) & 3;
2041 index
= ((code
>> 3) & 7) | REX_X(s
);
2043 index
= -1; /* no index */
2051 if ((base
& 7) == 5) {
2053 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
2055 if (CODE64(s
) && !havesib
) {
2056 disp
+= s
->pc
+ s
->rip_offset
;
2063 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
2067 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
2072 /* For correct popl handling with esp. */
2073 if (base
== R_ESP
&& s
->popl_esp_hack
) {
2074 disp
+= s
->popl_esp_hack
;
2077 /* Compute the address, with a minimum number of TCG ops. */
2081 sum
= cpu_regs
[index
];
2083 tcg_gen_shli_tl(cpu_A0
, cpu_regs
[index
], scale
);
2087 tcg_gen_add_tl(cpu_A0
, sum
, cpu_regs
[base
]);
2090 } else if (base
>= 0) {
2091 sum
= cpu_regs
[base
];
2093 if (TCGV_IS_UNUSED(sum
)) {
2094 tcg_gen_movi_tl(cpu_A0
, disp
);
2096 tcg_gen_addi_tl(cpu_A0
, sum
, disp
);
2101 if (base
== R_EBP
|| base
== R_ESP
) {
2108 tcg_gen_ld_tl(cpu_tmp0
, cpu_env
,
2109 offsetof(CPUX86State
, segs
[override
].base
));
2111 if (s
->aflag
!= 2) {
2112 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
2114 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
2118 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
2121 if (s
->aflag
!= 2) {
2122 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
2128 disp
= cpu_lduw_code(env
, s
->pc
);
2130 gen_op_movl_A0_im(disp
);
2131 rm
= 0; /* avoid SS override */
2138 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
2142 disp
= cpu_lduw_code(env
, s
->pc
);
2148 gen_op_movl_A0_reg(R_EBX
);
2149 gen_op_addl_A0_reg_sN(0, R_ESI
);
2152 gen_op_movl_A0_reg(R_EBX
);
2153 gen_op_addl_A0_reg_sN(0, R_EDI
);
2156 gen_op_movl_A0_reg(R_EBP
);
2157 gen_op_addl_A0_reg_sN(0, R_ESI
);
2160 gen_op_movl_A0_reg(R_EBP
);
2161 gen_op_addl_A0_reg_sN(0, R_EDI
);
2164 gen_op_movl_A0_reg(R_ESI
);
2167 gen_op_movl_A0_reg(R_EDI
);
2170 gen_op_movl_A0_reg(R_EBP
);
2174 gen_op_movl_A0_reg(R_EBX
);
2178 gen_op_addl_A0_im(disp
);
2179 gen_op_andl_A0_ffff();
2183 if (rm
== 2 || rm
== 3 || rm
== 6)
2188 gen_op_addl_A0_seg(s
, override
);
2199 static void gen_nop_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2201 int mod
, rm
, base
, code
;
2203 mod
= (modrm
>> 6) & 3;
2213 code
= cpu_ldub_code(env
, s
->pc
++);
2249 /* used for LEA and MOV AX, mem */
2250 static void gen_add_A0_ds_seg(DisasContext
*s
)
2252 int override
, must_add_seg
;
2253 must_add_seg
= s
->addseg
;
2255 if (s
->override
>= 0) {
2256 override
= s
->override
;
2260 #ifdef TARGET_X86_64
2262 gen_op_addq_A0_seg(override
);
2266 gen_op_addl_A0_seg(s
, override
);
2271 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2273 static void gen_ldst_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2274 int ot
, int reg
, int is_store
)
2276 int mod
, rm
, opreg
, disp
;
2278 mod
= (modrm
>> 6) & 3;
2279 rm
= (modrm
& 7) | REX_B(s
);
2283 gen_op_mov_TN_reg(ot
, 0, reg
);
2284 gen_op_mov_reg_T0(ot
, rm
);
2286 gen_op_mov_TN_reg(ot
, 0, rm
);
2288 gen_op_mov_reg_T0(ot
, reg
);
2291 gen_lea_modrm(env
, s
, modrm
, &opreg
, &disp
);
2294 gen_op_mov_TN_reg(ot
, 0, reg
);
2295 gen_op_st_T0_A0(s
, ot
);
2297 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
2299 gen_op_mov_reg_T0(ot
, reg
);
2304 static inline uint32_t insn_get(CPUX86State
*env
, DisasContext
*s
, int ot
)
2310 ret
= cpu_ldub_code(env
, s
->pc
);
2314 ret
= cpu_lduw_code(env
, s
->pc
);
2319 ret
= cpu_ldl_code(env
, s
->pc
);
2326 static inline int insn_const_size(unsigned int ot
)
2335 static inline void gen_goto_tb(DisasContext
*s
, int tb_num
, target_ulong eip
)
2337 TranslationBlock
*tb
;
2340 pc
= s
->cs_base
+ eip
;
2342 /* NOTE: we handle the case where the TB spans two pages here */
2343 if ((pc
& TARGET_PAGE_MASK
) == (tb
->pc
& TARGET_PAGE_MASK
) ||
2344 (pc
& TARGET_PAGE_MASK
) == ((s
->pc
- 1) & TARGET_PAGE_MASK
)) {
2345 /* jump to same page: we can use a direct jump */
2346 tcg_gen_goto_tb(tb_num
);
2348 tcg_gen_exit_tb((uintptr_t)tb
+ tb_num
);
2350 /* jump to another page: currently not optimized */
2356 static inline void gen_jcc(DisasContext
*s
, int b
,
2357 target_ulong val
, target_ulong next_eip
)
2362 l1
= gen_new_label();
2365 gen_goto_tb(s
, 0, next_eip
);
2368 gen_goto_tb(s
, 1, val
);
2369 s
->is_jmp
= DISAS_TB_JUMP
;
2371 l1
= gen_new_label();
2372 l2
= gen_new_label();
2375 gen_jmp_im(next_eip
);
2385 static void gen_cmovcc1(CPUX86State
*env
, DisasContext
*s
, int ot
, int b
,
2390 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
2392 cc
= gen_prepare_cc(s
, b
, cpu_T
[1]);
2393 if (cc
.mask
!= -1) {
2394 TCGv t0
= tcg_temp_new();
2395 tcg_gen_andi_tl(t0
, cc
.reg
, cc
.mask
);
2399 cc
.reg2
= tcg_const_tl(cc
.imm
);
2402 tcg_gen_movcond_tl(cc
.cond
, cpu_T
[0], cc
.reg
, cc
.reg2
,
2403 cpu_T
[0], cpu_regs
[reg
]);
2404 gen_op_mov_reg_T0(ot
, reg
);
2406 if (cc
.mask
!= -1) {
2407 tcg_temp_free(cc
.reg
);
2410 tcg_temp_free(cc
.reg2
);
2414 static inline void gen_op_movl_T0_seg(int seg_reg
)
2416 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
,
2417 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2420 static inline void gen_op_movl_seg_T0_vm(int seg_reg
)
2422 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffff);
2423 tcg_gen_st32_tl(cpu_T
[0], cpu_env
,
2424 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2425 tcg_gen_shli_tl(cpu_T
[0], cpu_T
[0], 4);
2426 tcg_gen_st_tl(cpu_T
[0], cpu_env
,
2427 offsetof(CPUX86State
,segs
[seg_reg
].base
));
2430 /* move T0 to seg_reg and compute if the CPU state may change. Never
2431 call this function with seg_reg == R_CS */
2432 static void gen_movl_seg_T0(DisasContext
*s
, int seg_reg
, target_ulong cur_eip
)
2434 if (s
->pe
&& !s
->vm86
) {
2435 /* XXX: optimize by finding processor state dynamically */
2436 gen_update_cc_op(s
);
2437 gen_jmp_im(cur_eip
);
2438 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
2439 gen_helper_load_seg(cpu_env
, tcg_const_i32(seg_reg
), cpu_tmp2_i32
);
2440 /* abort translation because the addseg value may change or
2441 because ss32 may change. For R_SS, translation must always
2442 stop as a special handling must be done to disable hardware
2443 interrupts for the next instruction */
2444 if (seg_reg
== R_SS
|| (s
->code32
&& seg_reg
< R_FS
))
2445 s
->is_jmp
= DISAS_TB_JUMP
;
2447 gen_op_movl_seg_T0_vm(seg_reg
);
2448 if (seg_reg
== R_SS
)
2449 s
->is_jmp
= DISAS_TB_JUMP
;
2453 static inline int svm_is_rep(int prefixes
)
2455 return ((prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) ? 8 : 0);
2459 gen_svm_check_intercept_param(DisasContext
*s
, target_ulong pc_start
,
2460 uint32_t type
, uint64_t param
)
2462 /* no SVM activated; fast case */
2463 if (likely(!(s
->flags
& HF_SVMI_MASK
)))
2465 gen_update_cc_op(s
);
2466 gen_jmp_im(pc_start
- s
->cs_base
);
2467 gen_helper_svm_check_intercept_param(cpu_env
, tcg_const_i32(type
),
2468 tcg_const_i64(param
));
2472 gen_svm_check_intercept(DisasContext
*s
, target_ulong pc_start
, uint64_t type
)
2474 gen_svm_check_intercept_param(s
, pc_start
, type
, 0);
2477 static inline void gen_stack_update(DisasContext
*s
, int addend
)
2479 #ifdef TARGET_X86_64
2481 gen_op_add_reg_im(2, R_ESP
, addend
);
2485 gen_op_add_reg_im(1, R_ESP
, addend
);
2487 gen_op_add_reg_im(0, R_ESP
, addend
);
2491 /* generate a push. It depends on ss32, addseg and dflag */
2492 static void gen_push_T0(DisasContext
*s
)
2494 #ifdef TARGET_X86_64
2496 gen_op_movq_A0_reg(R_ESP
);
2498 gen_op_addq_A0_im(-8);
2499 gen_op_st_T0_A0(s
, MO_64
);
2501 gen_op_addq_A0_im(-2);
2502 gen_op_st_T0_A0(s
, MO_16
);
2504 gen_op_mov_reg_A0(2, R_ESP
);
2508 gen_op_movl_A0_reg(R_ESP
);
2510 gen_op_addl_A0_im(-2);
2512 gen_op_addl_A0_im(-4);
2515 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2516 gen_op_addl_A0_seg(s
, R_SS
);
2519 gen_op_andl_A0_ffff();
2520 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2521 gen_op_addl_A0_seg(s
, R_SS
);
2523 gen_op_st_T0_A0(s
, s
->dflag
+ 1);
2524 if (s
->ss32
&& !s
->addseg
)
2525 gen_op_mov_reg_A0(1, R_ESP
);
2527 gen_op_mov_reg_T1(s
->ss32
+ 1, R_ESP
);
2531 /* generate a push. It depends on ss32, addseg and dflag */
2532 /* slower version for T1, only used for call Ev */
2533 static void gen_push_T1(DisasContext
*s
)
2535 #ifdef TARGET_X86_64
2537 gen_op_movq_A0_reg(R_ESP
);
2539 gen_op_addq_A0_im(-8);
2540 gen_op_st_T1_A0(s
, MO_64
);
2542 gen_op_addq_A0_im(-2);
2543 gen_op_st_T0_A0(s
, MO_16
);
2545 gen_op_mov_reg_A0(2, R_ESP
);
2549 gen_op_movl_A0_reg(R_ESP
);
2551 gen_op_addl_A0_im(-2);
2553 gen_op_addl_A0_im(-4);
2556 gen_op_addl_A0_seg(s
, R_SS
);
2559 gen_op_andl_A0_ffff();
2560 gen_op_addl_A0_seg(s
, R_SS
);
2562 gen_op_st_T1_A0(s
, s
->dflag
+ 1);
2564 if (s
->ss32
&& !s
->addseg
)
2565 gen_op_mov_reg_A0(1, R_ESP
);
2567 gen_stack_update(s
, (-2) << s
->dflag
);
2571 /* two step pop is necessary for precise exceptions */
2572 static void gen_pop_T0(DisasContext
*s
)
2574 #ifdef TARGET_X86_64
2576 gen_op_movq_A0_reg(R_ESP
);
2577 gen_op_ld_v(s
, s
->dflag
? MO_64
: MO_16
, cpu_T
[0], cpu_A0
);
2581 gen_op_movl_A0_reg(R_ESP
);
2584 gen_op_addl_A0_seg(s
, R_SS
);
2586 gen_op_andl_A0_ffff();
2587 gen_op_addl_A0_seg(s
, R_SS
);
2589 gen_op_ld_v(s
, s
->dflag
+ 1, cpu_T
[0], cpu_A0
);
2593 static void gen_pop_update(DisasContext
*s
)
2595 #ifdef TARGET_X86_64
2596 if (CODE64(s
) && s
->dflag
) {
2597 gen_stack_update(s
, 8);
2601 gen_stack_update(s
, 2 << s
->dflag
);
2605 static void gen_stack_A0(DisasContext
*s
)
2607 gen_op_movl_A0_reg(R_ESP
);
2609 gen_op_andl_A0_ffff();
2610 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2612 gen_op_addl_A0_seg(s
, R_SS
);
2615 /* NOTE: wrap around in 16 bit not fully handled */
2616 static void gen_pusha(DisasContext
*s
)
2619 gen_op_movl_A0_reg(R_ESP
);
2620 gen_op_addl_A0_im(-16 << s
->dflag
);
2622 gen_op_andl_A0_ffff();
2623 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2625 gen_op_addl_A0_seg(s
, R_SS
);
2626 for(i
= 0;i
< 8; i
++) {
2627 gen_op_mov_TN_reg(MO_32
, 0, 7 - i
);
2628 gen_op_st_T0_A0(s
, MO_16
+ s
->dflag
);
2629 gen_op_addl_A0_im(2 << s
->dflag
);
2631 gen_op_mov_reg_T1(MO_16
+ s
->ss32
, R_ESP
);
2634 /* NOTE: wrap around in 16 bit not fully handled */
2635 static void gen_popa(DisasContext
*s
)
2638 gen_op_movl_A0_reg(R_ESP
);
2640 gen_op_andl_A0_ffff();
2641 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2642 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], 16 << s
->dflag
);
2644 gen_op_addl_A0_seg(s
, R_SS
);
2645 for(i
= 0;i
< 8; i
++) {
2646 /* ESP is not reloaded */
2648 gen_op_ld_v(s
, MO_16
+ s
->dflag
, cpu_T
[0], cpu_A0
);
2649 gen_op_mov_reg_T0(MO_16
+ s
->dflag
, 7 - i
);
2651 gen_op_addl_A0_im(2 << s
->dflag
);
2653 gen_op_mov_reg_T1(MO_16
+ s
->ss32
, R_ESP
);
2656 static void gen_enter(DisasContext
*s
, int esp_addend
, int level
)
2661 #ifdef TARGET_X86_64
2663 ot
= s
->dflag
? MO_64
: MO_16
;
2666 gen_op_movl_A0_reg(R_ESP
);
2667 gen_op_addq_A0_im(-opsize
);
2668 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2671 gen_op_mov_TN_reg(MO_32
, 0, R_EBP
);
2672 gen_op_st_T0_A0(s
, ot
);
2674 /* XXX: must save state */
2675 gen_helper_enter64_level(cpu_env
, tcg_const_i32(level
),
2676 tcg_const_i32((ot
== MO_64
)),
2679 gen_op_mov_reg_T1(ot
, R_EBP
);
2680 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], -esp_addend
+ (-opsize
* level
));
2681 gen_op_mov_reg_T1(MO_64
, R_ESP
);
2685 ot
= s
->dflag
+ MO_16
;
2686 opsize
= 2 << s
->dflag
;
2688 gen_op_movl_A0_reg(R_ESP
);
2689 gen_op_addl_A0_im(-opsize
);
2691 gen_op_andl_A0_ffff();
2692 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2694 gen_op_addl_A0_seg(s
, R_SS
);
2696 gen_op_mov_TN_reg(MO_32
, 0, R_EBP
);
2697 gen_op_st_T0_A0(s
, ot
);
2699 /* XXX: must save state */
2700 gen_helper_enter_level(cpu_env
, tcg_const_i32(level
),
2701 tcg_const_i32(s
->dflag
),
2704 gen_op_mov_reg_T1(ot
, R_EBP
);
2705 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], -esp_addend
+ (-opsize
* level
));
2706 gen_op_mov_reg_T1(MO_16
+ s
->ss32
, R_ESP
);
2710 static void gen_exception(DisasContext
*s
, int trapno
, target_ulong cur_eip
)
2712 gen_update_cc_op(s
);
2713 gen_jmp_im(cur_eip
);
2714 gen_helper_raise_exception(cpu_env
, tcg_const_i32(trapno
));
2715 s
->is_jmp
= DISAS_TB_JUMP
;
2718 /* an interrupt is different from an exception because of the
2720 static void gen_interrupt(DisasContext
*s
, int intno
,
2721 target_ulong cur_eip
, target_ulong next_eip
)
2723 gen_update_cc_op(s
);
2724 gen_jmp_im(cur_eip
);
2725 gen_helper_raise_interrupt(cpu_env
, tcg_const_i32(intno
),
2726 tcg_const_i32(next_eip
- cur_eip
));
2727 s
->is_jmp
= DISAS_TB_JUMP
;
2730 static void gen_debug(DisasContext
*s
, target_ulong cur_eip
)
2732 gen_update_cc_op(s
);
2733 gen_jmp_im(cur_eip
);
2734 gen_helper_debug(cpu_env
);
2735 s
->is_jmp
= DISAS_TB_JUMP
;
2738 /* generate a generic end of block. Trace exception is also generated
2740 static void gen_eob(DisasContext
*s
)
2742 gen_update_cc_op(s
);
2743 if (s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
) {
2744 gen_helper_reset_inhibit_irq(cpu_env
);
2746 if (s
->tb
->flags
& HF_RF_MASK
) {
2747 gen_helper_reset_rf(cpu_env
);
2749 if (s
->singlestep_enabled
) {
2750 gen_helper_debug(cpu_env
);
2752 gen_helper_single_step(cpu_env
);
2756 s
->is_jmp
= DISAS_TB_JUMP
;
2759 /* generate a jump to eip. No segment change must happen before as a
2760 direct call to the next block may occur */
2761 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
)
2763 gen_update_cc_op(s
);
2764 set_cc_op(s
, CC_OP_DYNAMIC
);
2766 gen_goto_tb(s
, tb_num
, eip
);
2767 s
->is_jmp
= DISAS_TB_JUMP
;
2774 static void gen_jmp(DisasContext
*s
, target_ulong eip
)
2776 gen_jmp_tb(s
, eip
, 0);
2779 static inline void gen_ldq_env_A0(DisasContext
*s
, int offset
)
2781 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
2782 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2785 static inline void gen_stq_env_A0(DisasContext
*s
, int offset
)
2787 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2788 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
2791 static inline void gen_ldo_env_A0(DisasContext
*s
, int offset
)
2793 int mem_index
= s
->mem_index
;
2794 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, mem_index
, MO_LEQ
);
2795 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(0)));
2796 tcg_gen_addi_tl(cpu_tmp0
, cpu_A0
, 8);
2797 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
, MO_LEQ
);
2798 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(1)));
2801 static inline void gen_sto_env_A0(DisasContext
*s
, int offset
)
2803 int mem_index
= s
->mem_index
;
2804 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(0)));
2805 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, mem_index
, MO_LEQ
);
2806 tcg_gen_addi_tl(cpu_tmp0
, cpu_A0
, 8);
2807 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(1)));
2808 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
, MO_LEQ
);
2811 static inline void gen_op_movo(int d_offset
, int s_offset
)
2813 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
);
2814 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2815 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
+ 8);
2816 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
+ 8);
2819 static inline void gen_op_movq(int d_offset
, int s_offset
)
2821 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
);
2822 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2825 static inline void gen_op_movl(int d_offset
, int s_offset
)
2827 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
, s_offset
);
2828 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, d_offset
);
2831 static inline void gen_op_movq_env_0(int d_offset
)
2833 tcg_gen_movi_i64(cpu_tmp1_i64
, 0);
2834 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2837 typedef void (*SSEFunc_i_ep
)(TCGv_i32 val
, TCGv_ptr env
, TCGv_ptr reg
);
2838 typedef void (*SSEFunc_l_ep
)(TCGv_i64 val
, TCGv_ptr env
, TCGv_ptr reg
);
2839 typedef void (*SSEFunc_0_epi
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i32 val
);
2840 typedef void (*SSEFunc_0_epl
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i64 val
);
2841 typedef void (*SSEFunc_0_epp
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
);
2842 typedef void (*SSEFunc_0_eppi
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2844 typedef void (*SSEFunc_0_ppi
)(TCGv_ptr reg_a
, TCGv_ptr reg_b
, TCGv_i32 val
);
2845 typedef void (*SSEFunc_0_eppt
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2848 #define SSE_SPECIAL ((void *)1)
2849 #define SSE_DUMMY ((void *)2)
2851 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2852 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2853 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2855 static const SSEFunc_0_epp sse_op_table1
[256][4] = {
2856 /* 3DNow! extensions */
2857 [0x0e] = { SSE_DUMMY
}, /* femms */
2858 [0x0f] = { SSE_DUMMY
}, /* pf... */
2859 /* pure SSE operations */
2860 [0x10] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2861 [0x11] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2862 [0x12] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd, movsldup, movddup */
2863 [0x13] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd */
2864 [0x14] = { gen_helper_punpckldq_xmm
, gen_helper_punpcklqdq_xmm
},
2865 [0x15] = { gen_helper_punpckhdq_xmm
, gen_helper_punpckhqdq_xmm
},
2866 [0x16] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd, movshdup */
2867 [0x17] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd */
2869 [0x28] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2870 [0x29] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2871 [0x2a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2872 [0x2b] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movntps, movntpd, movntss, movntsd */
2873 [0x2c] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2874 [0x2d] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2875 [0x2e] = { gen_helper_ucomiss
, gen_helper_ucomisd
},
2876 [0x2f] = { gen_helper_comiss
, gen_helper_comisd
},
2877 [0x50] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movmskps, movmskpd */
2878 [0x51] = SSE_FOP(sqrt
),
2879 [0x52] = { gen_helper_rsqrtps
, NULL
, gen_helper_rsqrtss
, NULL
},
2880 [0x53] = { gen_helper_rcpps
, NULL
, gen_helper_rcpss
, NULL
},
2881 [0x54] = { gen_helper_pand_xmm
, gen_helper_pand_xmm
}, /* andps, andpd */
2882 [0x55] = { gen_helper_pandn_xmm
, gen_helper_pandn_xmm
}, /* andnps, andnpd */
2883 [0x56] = { gen_helper_por_xmm
, gen_helper_por_xmm
}, /* orps, orpd */
2884 [0x57] = { gen_helper_pxor_xmm
, gen_helper_pxor_xmm
}, /* xorps, xorpd */
2885 [0x58] = SSE_FOP(add
),
2886 [0x59] = SSE_FOP(mul
),
2887 [0x5a] = { gen_helper_cvtps2pd
, gen_helper_cvtpd2ps
,
2888 gen_helper_cvtss2sd
, gen_helper_cvtsd2ss
},
2889 [0x5b] = { gen_helper_cvtdq2ps
, gen_helper_cvtps2dq
, gen_helper_cvttps2dq
},
2890 [0x5c] = SSE_FOP(sub
),
2891 [0x5d] = SSE_FOP(min
),
2892 [0x5e] = SSE_FOP(div
),
2893 [0x5f] = SSE_FOP(max
),
2895 [0xc2] = SSE_FOP(cmpeq
),
2896 [0xc6] = { (SSEFunc_0_epp
)gen_helper_shufps
,
2897 (SSEFunc_0_epp
)gen_helper_shufpd
}, /* XXX: casts */
2899 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */
2900 [0x38] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2901 [0x3a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2903 /* MMX ops and their SSE extensions */
2904 [0x60] = MMX_OP2(punpcklbw
),
2905 [0x61] = MMX_OP2(punpcklwd
),
2906 [0x62] = MMX_OP2(punpckldq
),
2907 [0x63] = MMX_OP2(packsswb
),
2908 [0x64] = MMX_OP2(pcmpgtb
),
2909 [0x65] = MMX_OP2(pcmpgtw
),
2910 [0x66] = MMX_OP2(pcmpgtl
),
2911 [0x67] = MMX_OP2(packuswb
),
2912 [0x68] = MMX_OP2(punpckhbw
),
2913 [0x69] = MMX_OP2(punpckhwd
),
2914 [0x6a] = MMX_OP2(punpckhdq
),
2915 [0x6b] = MMX_OP2(packssdw
),
2916 [0x6c] = { NULL
, gen_helper_punpcklqdq_xmm
},
2917 [0x6d] = { NULL
, gen_helper_punpckhqdq_xmm
},
2918 [0x6e] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movd mm, ea */
2919 [0x6f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, , movqdu */
2920 [0x70] = { (SSEFunc_0_epp
)gen_helper_pshufw_mmx
,
2921 (SSEFunc_0_epp
)gen_helper_pshufd_xmm
,
2922 (SSEFunc_0_epp
)gen_helper_pshufhw_xmm
,
2923 (SSEFunc_0_epp
)gen_helper_pshuflw_xmm
}, /* XXX: casts */
2924 [0x71] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftw */
2925 [0x72] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftd */
2926 [0x73] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftq */
2927 [0x74] = MMX_OP2(pcmpeqb
),
2928 [0x75] = MMX_OP2(pcmpeqw
),
2929 [0x76] = MMX_OP2(pcmpeql
),
2930 [0x77] = { SSE_DUMMY
}, /* emms */
2931 [0x78] = { NULL
, SSE_SPECIAL
, NULL
, SSE_SPECIAL
}, /* extrq_i, insertq_i */
2932 [0x79] = { NULL
, gen_helper_extrq_r
, NULL
, gen_helper_insertq_r
},
2933 [0x7c] = { NULL
, gen_helper_haddpd
, NULL
, gen_helper_haddps
},
2934 [0x7d] = { NULL
, gen_helper_hsubpd
, NULL
, gen_helper_hsubps
},
2935 [0x7e] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movd, movd, , movq */
2936 [0x7f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, movdqu */
2937 [0xc4] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pinsrw */
2938 [0xc5] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pextrw */
2939 [0xd0] = { NULL
, gen_helper_addsubpd
, NULL
, gen_helper_addsubps
},
2940 [0xd1] = MMX_OP2(psrlw
),
2941 [0xd2] = MMX_OP2(psrld
),
2942 [0xd3] = MMX_OP2(psrlq
),
2943 [0xd4] = MMX_OP2(paddq
),
2944 [0xd5] = MMX_OP2(pmullw
),
2945 [0xd6] = { NULL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2946 [0xd7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pmovmskb */
2947 [0xd8] = MMX_OP2(psubusb
),
2948 [0xd9] = MMX_OP2(psubusw
),
2949 [0xda] = MMX_OP2(pminub
),
2950 [0xdb] = MMX_OP2(pand
),
2951 [0xdc] = MMX_OP2(paddusb
),
2952 [0xdd] = MMX_OP2(paddusw
),
2953 [0xde] = MMX_OP2(pmaxub
),
2954 [0xdf] = MMX_OP2(pandn
),
2955 [0xe0] = MMX_OP2(pavgb
),
2956 [0xe1] = MMX_OP2(psraw
),
2957 [0xe2] = MMX_OP2(psrad
),
2958 [0xe3] = MMX_OP2(pavgw
),
2959 [0xe4] = MMX_OP2(pmulhuw
),
2960 [0xe5] = MMX_OP2(pmulhw
),
2961 [0xe6] = { NULL
, gen_helper_cvttpd2dq
, gen_helper_cvtdq2pd
, gen_helper_cvtpd2dq
},
2962 [0xe7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movntq, movntq */
2963 [0xe8] = MMX_OP2(psubsb
),
2964 [0xe9] = MMX_OP2(psubsw
),
2965 [0xea] = MMX_OP2(pminsw
),
2966 [0xeb] = MMX_OP2(por
),
2967 [0xec] = MMX_OP2(paddsb
),
2968 [0xed] = MMX_OP2(paddsw
),
2969 [0xee] = MMX_OP2(pmaxsw
),
2970 [0xef] = MMX_OP2(pxor
),
2971 [0xf0] = { NULL
, NULL
, NULL
, SSE_SPECIAL
}, /* lddqu */
2972 [0xf1] = MMX_OP2(psllw
),
2973 [0xf2] = MMX_OP2(pslld
),
2974 [0xf3] = MMX_OP2(psllq
),
2975 [0xf4] = MMX_OP2(pmuludq
),
2976 [0xf5] = MMX_OP2(pmaddwd
),
2977 [0xf6] = MMX_OP2(psadbw
),
2978 [0xf7] = { (SSEFunc_0_epp
)gen_helper_maskmov_mmx
,
2979 (SSEFunc_0_epp
)gen_helper_maskmov_xmm
}, /* XXX: casts */
2980 [0xf8] = MMX_OP2(psubb
),
2981 [0xf9] = MMX_OP2(psubw
),
2982 [0xfa] = MMX_OP2(psubl
),
2983 [0xfb] = MMX_OP2(psubq
),
2984 [0xfc] = MMX_OP2(paddb
),
2985 [0xfd] = MMX_OP2(paddw
),
2986 [0xfe] = MMX_OP2(paddl
),
2989 static const SSEFunc_0_epp sse_op_table2
[3 * 8][2] = {
2990 [0 + 2] = MMX_OP2(psrlw
),
2991 [0 + 4] = MMX_OP2(psraw
),
2992 [0 + 6] = MMX_OP2(psllw
),
2993 [8 + 2] = MMX_OP2(psrld
),
2994 [8 + 4] = MMX_OP2(psrad
),
2995 [8 + 6] = MMX_OP2(pslld
),
2996 [16 + 2] = MMX_OP2(psrlq
),
2997 [16 + 3] = { NULL
, gen_helper_psrldq_xmm
},
2998 [16 + 6] = MMX_OP2(psllq
),
2999 [16 + 7] = { NULL
, gen_helper_pslldq_xmm
},
3002 static const SSEFunc_0_epi sse_op_table3ai
[] = {
3003 gen_helper_cvtsi2ss
,
3007 #ifdef TARGET_X86_64
3008 static const SSEFunc_0_epl sse_op_table3aq
[] = {
3009 gen_helper_cvtsq2ss
,
3014 static const SSEFunc_i_ep sse_op_table3bi
[] = {
3015 gen_helper_cvttss2si
,
3016 gen_helper_cvtss2si
,
3017 gen_helper_cvttsd2si
,
3021 #ifdef TARGET_X86_64
3022 static const SSEFunc_l_ep sse_op_table3bq
[] = {
3023 gen_helper_cvttss2sq
,
3024 gen_helper_cvtss2sq
,
3025 gen_helper_cvttsd2sq
,
3030 static const SSEFunc_0_epp sse_op_table4
[8][4] = {
3041 static const SSEFunc_0_epp sse_op_table5
[256] = {
3042 [0x0c] = gen_helper_pi2fw
,
3043 [0x0d] = gen_helper_pi2fd
,
3044 [0x1c] = gen_helper_pf2iw
,
3045 [0x1d] = gen_helper_pf2id
,
3046 [0x8a] = gen_helper_pfnacc
,
3047 [0x8e] = gen_helper_pfpnacc
,
3048 [0x90] = gen_helper_pfcmpge
,
3049 [0x94] = gen_helper_pfmin
,
3050 [0x96] = gen_helper_pfrcp
,
3051 [0x97] = gen_helper_pfrsqrt
,
3052 [0x9a] = gen_helper_pfsub
,
3053 [0x9e] = gen_helper_pfadd
,
3054 [0xa0] = gen_helper_pfcmpgt
,
3055 [0xa4] = gen_helper_pfmax
,
3056 [0xa6] = gen_helper_movq
, /* pfrcpit1; no need to actually increase precision */
3057 [0xa7] = gen_helper_movq
, /* pfrsqit1 */
3058 [0xaa] = gen_helper_pfsubr
,
3059 [0xae] = gen_helper_pfacc
,
3060 [0xb0] = gen_helper_pfcmpeq
,
3061 [0xb4] = gen_helper_pfmul
,
3062 [0xb6] = gen_helper_movq
, /* pfrcpit2 */
3063 [0xb7] = gen_helper_pmulhrw_mmx
,
3064 [0xbb] = gen_helper_pswapd
,
3065 [0xbf] = gen_helper_pavgb_mmx
/* pavgusb */
3068 struct SSEOpHelper_epp
{
3069 SSEFunc_0_epp op
[2];
3073 struct SSEOpHelper_eppi
{
3074 SSEFunc_0_eppi op
[2];
3078 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
3079 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
3080 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
3081 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
3082 #define PCLMULQDQ_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, \
3083 CPUID_EXT_PCLMULQDQ }
3084 #define AESNI_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_AES }
3086 static const struct SSEOpHelper_epp sse_op_table6
[256] = {
3087 [0x00] = SSSE3_OP(pshufb
),
3088 [0x01] = SSSE3_OP(phaddw
),
3089 [0x02] = SSSE3_OP(phaddd
),
3090 [0x03] = SSSE3_OP(phaddsw
),
3091 [0x04] = SSSE3_OP(pmaddubsw
),
3092 [0x05] = SSSE3_OP(phsubw
),
3093 [0x06] = SSSE3_OP(phsubd
),
3094 [0x07] = SSSE3_OP(phsubsw
),
3095 [0x08] = SSSE3_OP(psignb
),
3096 [0x09] = SSSE3_OP(psignw
),
3097 [0x0a] = SSSE3_OP(psignd
),
3098 [0x0b] = SSSE3_OP(pmulhrsw
),
3099 [0x10] = SSE41_OP(pblendvb
),
3100 [0x14] = SSE41_OP(blendvps
),
3101 [0x15] = SSE41_OP(blendvpd
),
3102 [0x17] = SSE41_OP(ptest
),
3103 [0x1c] = SSSE3_OP(pabsb
),
3104 [0x1d] = SSSE3_OP(pabsw
),
3105 [0x1e] = SSSE3_OP(pabsd
),
3106 [0x20] = SSE41_OP(pmovsxbw
),
3107 [0x21] = SSE41_OP(pmovsxbd
),
3108 [0x22] = SSE41_OP(pmovsxbq
),
3109 [0x23] = SSE41_OP(pmovsxwd
),
3110 [0x24] = SSE41_OP(pmovsxwq
),
3111 [0x25] = SSE41_OP(pmovsxdq
),
3112 [0x28] = SSE41_OP(pmuldq
),
3113 [0x29] = SSE41_OP(pcmpeqq
),
3114 [0x2a] = SSE41_SPECIAL
, /* movntqda */
3115 [0x2b] = SSE41_OP(packusdw
),
3116 [0x30] = SSE41_OP(pmovzxbw
),
3117 [0x31] = SSE41_OP(pmovzxbd
),
3118 [0x32] = SSE41_OP(pmovzxbq
),
3119 [0x33] = SSE41_OP(pmovzxwd
),
3120 [0x34] = SSE41_OP(pmovzxwq
),
3121 [0x35] = SSE41_OP(pmovzxdq
),
3122 [0x37] = SSE42_OP(pcmpgtq
),
3123 [0x38] = SSE41_OP(pminsb
),
3124 [0x39] = SSE41_OP(pminsd
),
3125 [0x3a] = SSE41_OP(pminuw
),
3126 [0x3b] = SSE41_OP(pminud
),
3127 [0x3c] = SSE41_OP(pmaxsb
),
3128 [0x3d] = SSE41_OP(pmaxsd
),
3129 [0x3e] = SSE41_OP(pmaxuw
),
3130 [0x3f] = SSE41_OP(pmaxud
),
3131 [0x40] = SSE41_OP(pmulld
),
3132 [0x41] = SSE41_OP(phminposuw
),
3133 [0xdb] = AESNI_OP(aesimc
),
3134 [0xdc] = AESNI_OP(aesenc
),
3135 [0xdd] = AESNI_OP(aesenclast
),
3136 [0xde] = AESNI_OP(aesdec
),
3137 [0xdf] = AESNI_OP(aesdeclast
),
3140 static const struct SSEOpHelper_eppi sse_op_table7
[256] = {
3141 [0x08] = SSE41_OP(roundps
),
3142 [0x09] = SSE41_OP(roundpd
),
3143 [0x0a] = SSE41_OP(roundss
),
3144 [0x0b] = SSE41_OP(roundsd
),
3145 [0x0c] = SSE41_OP(blendps
),
3146 [0x0d] = SSE41_OP(blendpd
),
3147 [0x0e] = SSE41_OP(pblendw
),
3148 [0x0f] = SSSE3_OP(palignr
),
3149 [0x14] = SSE41_SPECIAL
, /* pextrb */
3150 [0x15] = SSE41_SPECIAL
, /* pextrw */
3151 [0x16] = SSE41_SPECIAL
, /* pextrd/pextrq */
3152 [0x17] = SSE41_SPECIAL
, /* extractps */
3153 [0x20] = SSE41_SPECIAL
, /* pinsrb */
3154 [0x21] = SSE41_SPECIAL
, /* insertps */
3155 [0x22] = SSE41_SPECIAL
, /* pinsrd/pinsrq */
3156 [0x40] = SSE41_OP(dpps
),
3157 [0x41] = SSE41_OP(dppd
),
3158 [0x42] = SSE41_OP(mpsadbw
),
3159 [0x44] = PCLMULQDQ_OP(pclmulqdq
),
3160 [0x60] = SSE42_OP(pcmpestrm
),
3161 [0x61] = SSE42_OP(pcmpestri
),
3162 [0x62] = SSE42_OP(pcmpistrm
),
3163 [0x63] = SSE42_OP(pcmpistri
),
3164 [0xdf] = AESNI_OP(aeskeygenassist
),
3167 static void gen_sse(CPUX86State
*env
, DisasContext
*s
, int b
,
3168 target_ulong pc_start
, int rex_r
)
3170 int b1
, op1_offset
, op2_offset
, is_xmm
, val
, ot
;
3171 int modrm
, mod
, rm
, reg
, reg_addr
, offset_addr
;
3172 SSEFunc_0_epp sse_fn_epp
;
3173 SSEFunc_0_eppi sse_fn_eppi
;
3174 SSEFunc_0_ppi sse_fn_ppi
;
3175 SSEFunc_0_eppt sse_fn_eppt
;
3178 if (s
->prefix
& PREFIX_DATA
)
3180 else if (s
->prefix
& PREFIX_REPZ
)
3182 else if (s
->prefix
& PREFIX_REPNZ
)
3186 sse_fn_epp
= sse_op_table1
[b
][b1
];
3190 if ((b
<= 0x5f && b
>= 0x10) || b
== 0xc6 || b
== 0xc2) {
3200 /* simple MMX/SSE operation */
3201 if (s
->flags
& HF_TS_MASK
) {
3202 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
3205 if (s
->flags
& HF_EM_MASK
) {
3207 gen_exception(s
, EXCP06_ILLOP
, pc_start
- s
->cs_base
);
3210 if (is_xmm
&& !(s
->flags
& HF_OSFXSR_MASK
))
3211 if ((b
!= 0x38 && b
!= 0x3a) || (s
->prefix
& PREFIX_DATA
))
3214 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
))
3217 gen_helper_emms(cpu_env
);
3222 gen_helper_emms(cpu_env
);
3225 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3226 the static cpu state) */
3228 gen_helper_enter_mmx(cpu_env
);
3231 modrm
= cpu_ldub_code(env
, s
->pc
++);
3232 reg
= ((modrm
>> 3) & 7);
3235 mod
= (modrm
>> 6) & 3;
3236 if (sse_fn_epp
== SSE_SPECIAL
) {
3239 case 0x0e7: /* movntq */
3242 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3243 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3245 case 0x1e7: /* movntdq */
3246 case 0x02b: /* movntps */
3247 case 0x12b: /* movntps */
3250 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3251 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3253 case 0x3f0: /* lddqu */
3256 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3257 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3259 case 0x22b: /* movntss */
3260 case 0x32b: /* movntsd */
3263 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3265 gen_stq_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3267 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
3268 xmm_regs
[reg
].XMM_L(0)));
3269 gen_op_st_T0_A0(s
, MO_32
);
3272 case 0x6e: /* movd mm, ea */
3273 #ifdef TARGET_X86_64
3274 if (s
->dflag
== 2) {
3275 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3276 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3280 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3281 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3282 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3283 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3284 gen_helper_movl_mm_T0_mmx(cpu_ptr0
, cpu_tmp2_i32
);
3287 case 0x16e: /* movd xmm, ea */
3288 #ifdef TARGET_X86_64
3289 if (s
->dflag
== 2) {
3290 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3291 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3292 offsetof(CPUX86State
,xmm_regs
[reg
]));
3293 gen_helper_movq_mm_T0_xmm(cpu_ptr0
, cpu_T
[0]);
3297 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3298 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3299 offsetof(CPUX86State
,xmm_regs
[reg
]));
3300 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3301 gen_helper_movl_mm_T0_xmm(cpu_ptr0
, cpu_tmp2_i32
);
3304 case 0x6f: /* movq mm, ea */
3306 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3307 gen_ldq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3310 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
3311 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3312 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
3313 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3316 case 0x010: /* movups */
3317 case 0x110: /* movupd */
3318 case 0x028: /* movaps */
3319 case 0x128: /* movapd */
3320 case 0x16f: /* movdqa xmm, ea */
3321 case 0x26f: /* movdqu xmm, ea */
3323 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3324 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3326 rm
= (modrm
& 7) | REX_B(s
);
3327 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[reg
]),
3328 offsetof(CPUX86State
,xmm_regs
[rm
]));
3331 case 0x210: /* movss xmm, ea */
3333 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3334 gen_op_ld_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
3335 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3337 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(1)));
3338 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)));
3339 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)));
3341 rm
= (modrm
& 7) | REX_B(s
);
3342 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)),
3343 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(0)));
3346 case 0x310: /* movsd xmm, ea */
3348 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3349 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3350 xmm_regs
[reg
].XMM_Q(0)));
3352 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)));
3353 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)));
3355 rm
= (modrm
& 7) | REX_B(s
);
3356 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3357 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3360 case 0x012: /* movlps */
3361 case 0x112: /* movlpd */
3363 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3364 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3365 xmm_regs
[reg
].XMM_Q(0)));
3368 rm
= (modrm
& 7) | REX_B(s
);
3369 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3370 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(1)));
3373 case 0x212: /* movsldup */
3375 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3376 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3378 rm
= (modrm
& 7) | REX_B(s
);
3379 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)),
3380 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(0)));
3381 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)),
3382 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(2)));
3384 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(1)),
3385 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3386 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)),
3387 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)));
3389 case 0x312: /* movddup */
3391 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3392 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3393 xmm_regs
[reg
].XMM_Q(0)));
3395 rm
= (modrm
& 7) | REX_B(s
);
3396 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3397 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3399 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)),
3400 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3402 case 0x016: /* movhps */
3403 case 0x116: /* movhpd */
3405 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3406 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3407 xmm_regs
[reg
].XMM_Q(1)));
3410 rm
= (modrm
& 7) | REX_B(s
);
3411 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)),
3412 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3415 case 0x216: /* movshdup */
3417 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3418 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3420 rm
= (modrm
& 7) | REX_B(s
);
3421 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(1)),
3422 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(1)));
3423 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)),
3424 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(3)));
3426 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)),
3427 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(1)));
3428 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)),
3429 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)));
3434 int bit_index
, field_length
;
3436 if (b1
== 1 && reg
!= 0)
3438 field_length
= cpu_ldub_code(env
, s
->pc
++) & 0x3F;
3439 bit_index
= cpu_ldub_code(env
, s
->pc
++) & 0x3F;
3440 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3441 offsetof(CPUX86State
,xmm_regs
[reg
]));
3443 gen_helper_extrq_i(cpu_env
, cpu_ptr0
,
3444 tcg_const_i32(bit_index
),
3445 tcg_const_i32(field_length
));
3447 gen_helper_insertq_i(cpu_env
, cpu_ptr0
,
3448 tcg_const_i32(bit_index
),
3449 tcg_const_i32(field_length
));
3452 case 0x7e: /* movd ea, mm */
3453 #ifdef TARGET_X86_64
3454 if (s
->dflag
== 2) {
3455 tcg_gen_ld_i64(cpu_T
[0], cpu_env
,
3456 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3457 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3461 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
,
3462 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_L(0)));
3463 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3466 case 0x17e: /* movd ea, xmm */
3467 #ifdef TARGET_X86_64
3468 if (s
->dflag
== 2) {
3469 tcg_gen_ld_i64(cpu_T
[0], cpu_env
,
3470 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3471 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3475 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
,
3476 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3477 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3480 case 0x27e: /* movq xmm, ea */
3482 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3483 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3484 xmm_regs
[reg
].XMM_Q(0)));
3486 rm
= (modrm
& 7) | REX_B(s
);
3487 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3488 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3490 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)));
3492 case 0x7f: /* movq ea, mm */
3494 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3495 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3498 gen_op_movq(offsetof(CPUX86State
,fpregs
[rm
].mmx
),
3499 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3502 case 0x011: /* movups */
3503 case 0x111: /* movupd */
3504 case 0x029: /* movaps */
3505 case 0x129: /* movapd */
3506 case 0x17f: /* movdqa ea, xmm */
3507 case 0x27f: /* movdqu ea, xmm */
3509 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3510 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3512 rm
= (modrm
& 7) | REX_B(s
);
3513 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[rm
]),
3514 offsetof(CPUX86State
,xmm_regs
[reg
]));
3517 case 0x211: /* movss ea, xmm */
3519 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3520 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3521 gen_op_st_T0_A0(s
, MO_32
);
3523 rm
= (modrm
& 7) | REX_B(s
);
3524 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(0)),
3525 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3528 case 0x311: /* movsd ea, xmm */
3530 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3531 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3532 xmm_regs
[reg
].XMM_Q(0)));
3534 rm
= (modrm
& 7) | REX_B(s
);
3535 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)),
3536 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3539 case 0x013: /* movlps */
3540 case 0x113: /* movlpd */
3542 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3543 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3544 xmm_regs
[reg
].XMM_Q(0)));
3549 case 0x017: /* movhps */
3550 case 0x117: /* movhpd */
3552 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3553 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3554 xmm_regs
[reg
].XMM_Q(1)));
3559 case 0x71: /* shift mm, im */
3562 case 0x171: /* shift xmm, im */
3568 val
= cpu_ldub_code(env
, s
->pc
++);
3570 gen_op_movl_T0_im(val
);
3571 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.XMM_L(0)));
3573 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.XMM_L(1)));
3574 op1_offset
= offsetof(CPUX86State
,xmm_t0
);
3576 gen_op_movl_T0_im(val
);
3577 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,mmx_t0
.MMX_L(0)));
3579 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,mmx_t0
.MMX_L(1)));
3580 op1_offset
= offsetof(CPUX86State
,mmx_t0
);
3582 sse_fn_epp
= sse_op_table2
[((b
- 1) & 3) * 8 +
3583 (((modrm
>> 3)) & 7)][b1
];
3588 rm
= (modrm
& 7) | REX_B(s
);
3589 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3592 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3594 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3595 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op1_offset
);
3596 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3598 case 0x050: /* movmskps */
3599 rm
= (modrm
& 7) | REX_B(s
);
3600 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3601 offsetof(CPUX86State
,xmm_regs
[rm
]));
3602 gen_helper_movmskps(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3603 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
3604 gen_op_mov_reg_T0(MO_32
, reg
);
3606 case 0x150: /* movmskpd */
3607 rm
= (modrm
& 7) | REX_B(s
);
3608 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3609 offsetof(CPUX86State
,xmm_regs
[rm
]));
3610 gen_helper_movmskpd(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3611 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
3612 gen_op_mov_reg_T0(MO_32
, reg
);
3614 case 0x02a: /* cvtpi2ps */
3615 case 0x12a: /* cvtpi2pd */
3616 gen_helper_enter_mmx(cpu_env
);
3618 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3619 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3620 gen_ldq_env_A0(s
, op2_offset
);
3623 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3625 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3626 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3627 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3630 gen_helper_cvtpi2ps(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3634 gen_helper_cvtpi2pd(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3638 case 0x22a: /* cvtsi2ss */
3639 case 0x32a: /* cvtsi2sd */
3640 ot
= (s
->dflag
== 2) ? MO_64
: MO_32
;
3641 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3642 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3643 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3645 SSEFunc_0_epi sse_fn_epi
= sse_op_table3ai
[(b
>> 8) & 1];
3646 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3647 sse_fn_epi(cpu_env
, cpu_ptr0
, cpu_tmp2_i32
);
3649 #ifdef TARGET_X86_64
3650 SSEFunc_0_epl sse_fn_epl
= sse_op_table3aq
[(b
>> 8) & 1];
3651 sse_fn_epl(cpu_env
, cpu_ptr0
, cpu_T
[0]);
3657 case 0x02c: /* cvttps2pi */
3658 case 0x12c: /* cvttpd2pi */
3659 case 0x02d: /* cvtps2pi */
3660 case 0x12d: /* cvtpd2pi */
3661 gen_helper_enter_mmx(cpu_env
);
3663 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3664 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3665 gen_ldo_env_A0(s
, op2_offset
);
3667 rm
= (modrm
& 7) | REX_B(s
);
3668 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3670 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
);
3671 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3672 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3675 gen_helper_cvttps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3678 gen_helper_cvttpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3681 gen_helper_cvtps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3684 gen_helper_cvtpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3688 case 0x22c: /* cvttss2si */
3689 case 0x32c: /* cvttsd2si */
3690 case 0x22d: /* cvtss2si */
3691 case 0x32d: /* cvtsd2si */
3692 ot
= (s
->dflag
== 2) ? MO_64
: MO_32
;
3694 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3696 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.XMM_Q(0)));
3698 gen_op_ld_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
3699 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.XMM_L(0)));
3701 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3703 rm
= (modrm
& 7) | REX_B(s
);
3704 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3706 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3708 SSEFunc_i_ep sse_fn_i_ep
=
3709 sse_op_table3bi
[((b
>> 7) & 2) | (b
& 1)];
3710 sse_fn_i_ep(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3711 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
3713 #ifdef TARGET_X86_64
3714 SSEFunc_l_ep sse_fn_l_ep
=
3715 sse_op_table3bq
[((b
>> 7) & 2) | (b
& 1)];
3716 sse_fn_l_ep(cpu_T
[0], cpu_env
, cpu_ptr0
);
3721 gen_op_mov_reg_T0(ot
, reg
);
3723 case 0xc4: /* pinsrw */
3726 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
3727 val
= cpu_ldub_code(env
, s
->pc
++);
3730 tcg_gen_st16_tl(cpu_T
[0], cpu_env
,
3731 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_W(val
)));
3734 tcg_gen_st16_tl(cpu_T
[0], cpu_env
,
3735 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_W(val
)));
3738 case 0xc5: /* pextrw */
3742 ot
= (s
->dflag
== 2) ? MO_64
: MO_32
;
3743 val
= cpu_ldub_code(env
, s
->pc
++);
3746 rm
= (modrm
& 7) | REX_B(s
);
3747 tcg_gen_ld16u_tl(cpu_T
[0], cpu_env
,
3748 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_W(val
)));
3752 tcg_gen_ld16u_tl(cpu_T
[0], cpu_env
,
3753 offsetof(CPUX86State
,fpregs
[rm
].mmx
.MMX_W(val
)));
3755 reg
= ((modrm
>> 3) & 7) | rex_r
;
3756 gen_op_mov_reg_T0(ot
, reg
);
3758 case 0x1d6: /* movq ea, xmm */
3760 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3761 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3762 xmm_regs
[reg
].XMM_Q(0)));
3764 rm
= (modrm
& 7) | REX_B(s
);
3765 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)),
3766 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3767 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(1)));
3770 case 0x2d6: /* movq2dq */
3771 gen_helper_enter_mmx(cpu_env
);
3773 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3774 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3775 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)));
3777 case 0x3d6: /* movdq2q */
3778 gen_helper_enter_mmx(cpu_env
);
3779 rm
= (modrm
& 7) | REX_B(s
);
3780 gen_op_movq(offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
),
3781 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3783 case 0xd7: /* pmovmskb */
3788 rm
= (modrm
& 7) | REX_B(s
);
3789 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[rm
]));
3790 gen_helper_pmovmskb_xmm(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3793 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3794 gen_helper_pmovmskb_mmx(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3796 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
3797 reg
= ((modrm
>> 3) & 7) | rex_r
;
3798 gen_op_mov_reg_T0(MO_32
, reg
);
3804 if ((b
& 0xf0) == 0xf0) {
3807 modrm
= cpu_ldub_code(env
, s
->pc
++);
3809 reg
= ((modrm
>> 3) & 7) | rex_r
;
3810 mod
= (modrm
>> 6) & 3;
3815 sse_fn_epp
= sse_op_table6
[b
].op
[b1
];
3819 if (!(s
->cpuid_ext_features
& sse_op_table6
[b
].ext_mask
))
3823 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3825 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
3827 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3828 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3830 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3831 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3832 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3833 gen_ldq_env_A0(s
, op2_offset
+
3834 offsetof(XMMReg
, XMM_Q(0)));
3836 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3837 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3838 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
3839 s
->mem_index
, MO_LEUL
);
3840 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, op2_offset
+
3841 offsetof(XMMReg
, XMM_L(0)));
3843 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3844 tcg_gen_qemu_ld_tl(cpu_tmp0
, cpu_A0
,
3845 s
->mem_index
, MO_LEUW
);
3846 tcg_gen_st16_tl(cpu_tmp0
, cpu_env
, op2_offset
+
3847 offsetof(XMMReg
, XMM_W(0)));
3849 case 0x2a: /* movntqda */
3850 gen_ldo_env_A0(s
, op1_offset
);
3853 gen_ldo_env_A0(s
, op2_offset
);
3857 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
3859 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3861 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3862 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3863 gen_ldq_env_A0(s
, op2_offset
);
3866 if (sse_fn_epp
== SSE_SPECIAL
) {
3870 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3871 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3872 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3875 set_cc_op(s
, CC_OP_EFLAGS
);
3882 /* Various integer extensions at 0f 38 f[0-f]. */
3883 b
= modrm
| (b1
<< 8);
3884 modrm
= cpu_ldub_code(env
, s
->pc
++);
3885 reg
= ((modrm
>> 3) & 7) | rex_r
;
3888 case 0x3f0: /* crc32 Gd,Eb */
3889 case 0x3f1: /* crc32 Gd,Ey */
3891 if (!(s
->cpuid_ext_features
& CPUID_EXT_SSE42
)) {
3894 if ((b
& 0xff) == 0xf0) {
3896 } else if (s
->dflag
!= 2) {
3897 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3902 gen_op_mov_TN_reg(MO_32
, 0, reg
);
3903 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3904 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3905 gen_helper_crc32(cpu_T
[0], cpu_tmp2_i32
,
3906 cpu_T
[0], tcg_const_i32(8 << ot
));
3908 ot
= (s
->dflag
== 2) ? MO_64
: MO_32
;
3909 gen_op_mov_reg_T0(ot
, reg
);
3912 case 0x1f0: /* crc32 or movbe */
3914 /* For these insns, the f3 prefix is supposed to have priority
3915 over the 66 prefix, but that's not what we implement above
3917 if (s
->prefix
& PREFIX_REPNZ
) {
3921 case 0x0f0: /* movbe Gy,My */
3922 case 0x0f1: /* movbe My,Gy */
3923 if (!(s
->cpuid_ext_features
& CPUID_EXT_MOVBE
)) {
3926 if (s
->dflag
!= 2) {
3927 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3932 /* Load the data incoming to the bswap. Note that the TCG
3933 implementation of bswap requires the input be zero
3934 extended. In the case of the loads, we simply know that
3935 gen_op_ld_v via gen_ldst_modrm does that already. */
3937 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3941 tcg_gen_ext16u_tl(cpu_T
[0], cpu_regs
[reg
]);
3944 tcg_gen_ext32u_tl(cpu_T
[0], cpu_regs
[reg
]);
3947 tcg_gen_mov_tl(cpu_T
[0], cpu_regs
[reg
]);
3954 tcg_gen_bswap16_tl(cpu_T
[0], cpu_T
[0]);
3957 tcg_gen_bswap32_tl(cpu_T
[0], cpu_T
[0]);
3959 #ifdef TARGET_X86_64
3961 tcg_gen_bswap64_tl(cpu_T
[0], cpu_T
[0]);
3967 gen_op_mov_reg_T0(ot
, reg
);
3969 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
3973 case 0x0f2: /* andn Gy, By, Ey */
3974 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3975 || !(s
->prefix
& PREFIX_VEX
)
3979 ot
= s
->dflag
== 2 ? MO_64
: MO_32
;
3980 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3981 tcg_gen_andc_tl(cpu_T
[0], cpu_regs
[s
->vex_v
], cpu_T
[0]);
3982 gen_op_mov_reg_T0(ot
, reg
);
3983 gen_op_update1_cc();
3984 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3987 case 0x0f7: /* bextr Gy, Ey, By */
3988 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3989 || !(s
->prefix
& PREFIX_VEX
)
3993 ot
= s
->dflag
== 2 ? MO_64
: MO_32
;
3997 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3998 /* Extract START, and shift the operand.
3999 Shifts larger than operand size get zeros. */
4000 tcg_gen_ext8u_tl(cpu_A0
, cpu_regs
[s
->vex_v
]);
4001 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], cpu_A0
);
4003 bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
4004 zero
= tcg_const_tl(0);
4005 tcg_gen_movcond_tl(TCG_COND_LEU
, cpu_T
[0], cpu_A0
, bound
,
4007 tcg_temp_free(zero
);
4009 /* Extract the LEN into a mask. Lengths larger than
4010 operand size get all ones. */
4011 tcg_gen_shri_tl(cpu_A0
, cpu_regs
[s
->vex_v
], 8);
4012 tcg_gen_ext8u_tl(cpu_A0
, cpu_A0
);
4013 tcg_gen_movcond_tl(TCG_COND_LEU
, cpu_A0
, cpu_A0
, bound
,
4015 tcg_temp_free(bound
);
4016 tcg_gen_movi_tl(cpu_T
[1], 1);
4017 tcg_gen_shl_tl(cpu_T
[1], cpu_T
[1], cpu_A0
);
4018 tcg_gen_subi_tl(cpu_T
[1], cpu_T
[1], 1);
4019 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4021 gen_op_mov_reg_T0(ot
, reg
);
4022 gen_op_update1_cc();
4023 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4027 case 0x0f5: /* bzhi Gy, Ey, By */
4028 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4029 || !(s
->prefix
& PREFIX_VEX
)
4033 ot
= s
->dflag
== 2 ? MO_64
: MO_32
;
4034 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4035 tcg_gen_ext8u_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
4037 TCGv bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
4038 /* Note that since we're using BMILG (in order to get O
4039 cleared) we need to store the inverse into C. */
4040 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_cc_src
,
4042 tcg_gen_movcond_tl(TCG_COND_GT
, cpu_T
[1], cpu_T
[1],
4043 bound
, bound
, cpu_T
[1]);
4044 tcg_temp_free(bound
);
4046 tcg_gen_movi_tl(cpu_A0
, -1);
4047 tcg_gen_shl_tl(cpu_A0
, cpu_A0
, cpu_T
[1]);
4048 tcg_gen_andc_tl(cpu_T
[0], cpu_T
[0], cpu_A0
);
4049 gen_op_mov_reg_T0(ot
, reg
);
4050 gen_op_update1_cc();
4051 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4054 case 0x3f6: /* mulx By, Gy, rdx, Ey */
4055 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4056 || !(s
->prefix
& PREFIX_VEX
)
4060 ot
= s
->dflag
== 2 ? MO_64
: MO_32
;
4061 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4064 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4065 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EDX
]);
4066 tcg_gen_mulu2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4067 cpu_tmp2_i32
, cpu_tmp3_i32
);
4068 tcg_gen_extu_i32_tl(cpu_regs
[s
->vex_v
], cpu_tmp2_i32
);
4069 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp3_i32
);
4071 #ifdef TARGET_X86_64
4073 tcg_gen_mulu2_i64(cpu_regs
[s
->vex_v
], cpu_regs
[reg
],
4074 cpu_T
[0], cpu_regs
[R_EDX
]);
4080 case 0x3f5: /* pdep Gy, By, Ey */
4081 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4082 || !(s
->prefix
& PREFIX_VEX
)
4086 ot
= s
->dflag
== 2 ? MO_64
: MO_32
;
4087 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4088 /* Note that by zero-extending the mask operand, we
4089 automatically handle zero-extending the result. */
4090 if (s
->dflag
== 2) {
4091 tcg_gen_mov_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
4093 tcg_gen_ext32u_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
4095 gen_helper_pdep(cpu_regs
[reg
], cpu_T
[0], cpu_T
[1]);
4098 case 0x2f5: /* pext Gy, By, Ey */
4099 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4100 || !(s
->prefix
& PREFIX_VEX
)
4104 ot
= s
->dflag
== 2 ? MO_64
: MO_32
;
4105 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4106 /* Note that by zero-extending the mask operand, we
4107 automatically handle zero-extending the result. */
4108 if (s
->dflag
== 2) {
4109 tcg_gen_mov_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
4111 tcg_gen_ext32u_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
4113 gen_helper_pext(cpu_regs
[reg
], cpu_T
[0], cpu_T
[1]);
4116 case 0x1f6: /* adcx Gy, Ey */
4117 case 0x2f6: /* adox Gy, Ey */
4118 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_ADX
)) {
4121 TCGv carry_in
, carry_out
, zero
;
4124 ot
= (s
->dflag
== 2 ? MO_64
: MO_32
);
4125 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4127 /* Re-use the carry-out from a previous round. */
4128 TCGV_UNUSED(carry_in
);
4129 carry_out
= (b
== 0x1f6 ? cpu_cc_dst
: cpu_cc_src2
);
4133 carry_in
= cpu_cc_dst
;
4134 end_op
= CC_OP_ADCX
;
4136 end_op
= CC_OP_ADCOX
;
4141 end_op
= CC_OP_ADCOX
;
4143 carry_in
= cpu_cc_src2
;
4144 end_op
= CC_OP_ADOX
;
4148 end_op
= CC_OP_ADCOX
;
4149 carry_in
= carry_out
;
4152 end_op
= (b
== 0x1f6 ? CC_OP_ADCX
: CC_OP_ADOX
);
4155 /* If we can't reuse carry-out, get it out of EFLAGS. */
4156 if (TCGV_IS_UNUSED(carry_in
)) {
4157 if (s
->cc_op
!= CC_OP_ADCX
&& s
->cc_op
!= CC_OP_ADOX
) {
4158 gen_compute_eflags(s
);
4160 carry_in
= cpu_tmp0
;
4161 tcg_gen_shri_tl(carry_in
, cpu_cc_src
,
4162 ctz32(b
== 0x1f6 ? CC_C
: CC_O
));
4163 tcg_gen_andi_tl(carry_in
, carry_in
, 1);
4167 #ifdef TARGET_X86_64
4169 /* If we know TL is 64-bit, and we want a 32-bit
4170 result, just do everything in 64-bit arithmetic. */
4171 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_regs
[reg
]);
4172 tcg_gen_ext32u_i64(cpu_T
[0], cpu_T
[0]);
4173 tcg_gen_add_i64(cpu_T
[0], cpu_T
[0], cpu_regs
[reg
]);
4174 tcg_gen_add_i64(cpu_T
[0], cpu_T
[0], carry_in
);
4175 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_T
[0]);
4176 tcg_gen_shri_i64(carry_out
, cpu_T
[0], 32);
4180 /* Otherwise compute the carry-out in two steps. */
4181 zero
= tcg_const_tl(0);
4182 tcg_gen_add2_tl(cpu_T
[0], carry_out
,
4185 tcg_gen_add2_tl(cpu_regs
[reg
], carry_out
,
4186 cpu_regs
[reg
], carry_out
,
4188 tcg_temp_free(zero
);
4191 set_cc_op(s
, end_op
);
4195 case 0x1f7: /* shlx Gy, Ey, By */
4196 case 0x2f7: /* sarx Gy, Ey, By */
4197 case 0x3f7: /* shrx Gy, Ey, By */
4198 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4199 || !(s
->prefix
& PREFIX_VEX
)
4203 ot
= (s
->dflag
== 2 ? MO_64
: MO_32
);
4204 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4206 tcg_gen_andi_tl(cpu_T
[1], cpu_regs
[s
->vex_v
], 63);
4208 tcg_gen_andi_tl(cpu_T
[1], cpu_regs
[s
->vex_v
], 31);
4211 tcg_gen_shl_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4212 } else if (b
== 0x2f7) {
4214 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
4216 tcg_gen_sar_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4219 tcg_gen_ext32u_tl(cpu_T
[0], cpu_T
[0]);
4221 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4223 gen_op_mov_reg_T0(ot
, reg
);
4229 case 0x3f3: /* Group 17 */
4230 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
4231 || !(s
->prefix
& PREFIX_VEX
)
4235 ot
= s
->dflag
== 2 ? MO_64
: MO_32
;
4236 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4239 case 1: /* blsr By,Ey */
4240 tcg_gen_neg_tl(cpu_T
[1], cpu_T
[0]);
4241 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4242 gen_op_mov_reg_T0(ot
, s
->vex_v
);
4243 gen_op_update2_cc();
4244 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4247 case 2: /* blsmsk By,Ey */
4248 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
4249 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], 1);
4250 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_cc_src
);
4251 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4252 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4255 case 3: /* blsi By, Ey */
4256 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
4257 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], 1);
4258 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_cc_src
);
4259 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4260 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4276 modrm
= cpu_ldub_code(env
, s
->pc
++);
4278 reg
= ((modrm
>> 3) & 7) | rex_r
;
4279 mod
= (modrm
>> 6) & 3;
4284 sse_fn_eppi
= sse_op_table7
[b
].op
[b1
];
4288 if (!(s
->cpuid_ext_features
& sse_op_table7
[b
].ext_mask
))
4291 if (sse_fn_eppi
== SSE_SPECIAL
) {
4292 ot
= (s
->dflag
== 2) ? MO_64
: MO_32
;
4293 rm
= (modrm
& 7) | REX_B(s
);
4295 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4296 reg
= ((modrm
>> 3) & 7) | rex_r
;
4297 val
= cpu_ldub_code(env
, s
->pc
++);
4299 case 0x14: /* pextrb */
4300 tcg_gen_ld8u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4301 xmm_regs
[reg
].XMM_B(val
& 15)));
4303 gen_op_mov_reg_T0(ot
, rm
);
4305 tcg_gen_qemu_st_tl(cpu_T
[0], cpu_A0
,
4306 s
->mem_index
, MO_UB
);
4309 case 0x15: /* pextrw */
4310 tcg_gen_ld16u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4311 xmm_regs
[reg
].XMM_W(val
& 7)));
4313 gen_op_mov_reg_T0(ot
, rm
);
4315 tcg_gen_qemu_st_tl(cpu_T
[0], cpu_A0
,
4316 s
->mem_index
, MO_LEUW
);
4320 if (ot
== MO_32
) { /* pextrd */
4321 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4322 offsetof(CPUX86State
,
4323 xmm_regs
[reg
].XMM_L(val
& 3)));
4324 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
4326 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4328 tcg_gen_qemu_st_tl(cpu_T
[0], cpu_A0
,
4329 s
->mem_index
, MO_LEUL
);
4331 } else { /* pextrq */
4332 #ifdef TARGET_X86_64
4333 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
4334 offsetof(CPUX86State
,
4335 xmm_regs
[reg
].XMM_Q(val
& 1)));
4337 gen_op_mov_reg_v(ot
, rm
, cpu_tmp1_i64
);
4339 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
4340 s
->mem_index
, MO_LEQ
);
4347 case 0x17: /* extractps */
4348 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4349 xmm_regs
[reg
].XMM_L(val
& 3)));
4351 gen_op_mov_reg_T0(ot
, rm
);
4353 tcg_gen_qemu_st_tl(cpu_T
[0], cpu_A0
,
4354 s
->mem_index
, MO_LEUL
);
4357 case 0x20: /* pinsrb */
4359 gen_op_mov_TN_reg(MO_32
, 0, rm
);
4361 tcg_gen_qemu_ld_tl(cpu_T
[0], cpu_A0
,
4362 s
->mem_index
, MO_UB
);
4364 tcg_gen_st8_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4365 xmm_regs
[reg
].XMM_B(val
& 15)));
4367 case 0x21: /* insertps */
4369 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4370 offsetof(CPUX86State
,xmm_regs
[rm
]
4371 .XMM_L((val
>> 6) & 3)));
4373 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
4374 s
->mem_index
, MO_LEUL
);
4376 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4377 offsetof(CPUX86State
,xmm_regs
[reg
]
4378 .XMM_L((val
>> 4) & 3)));
4380 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4381 cpu_env
, offsetof(CPUX86State
,
4382 xmm_regs
[reg
].XMM_L(0)));
4384 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4385 cpu_env
, offsetof(CPUX86State
,
4386 xmm_regs
[reg
].XMM_L(1)));
4388 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4389 cpu_env
, offsetof(CPUX86State
,
4390 xmm_regs
[reg
].XMM_L(2)));
4392 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4393 cpu_env
, offsetof(CPUX86State
,
4394 xmm_regs
[reg
].XMM_L(3)));
4397 if (ot
== MO_32
) { /* pinsrd */
4399 gen_op_mov_v_reg(ot
, cpu_tmp0
, rm
);
4401 tcg_gen_qemu_ld_tl(cpu_tmp0
, cpu_A0
,
4402 s
->mem_index
, MO_LEUL
);
4404 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_tmp0
);
4405 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4406 offsetof(CPUX86State
,
4407 xmm_regs
[reg
].XMM_L(val
& 3)));
4408 } else { /* pinsrq */
4409 #ifdef TARGET_X86_64
4411 gen_op_mov_v_reg(ot
, cpu_tmp1_i64
, rm
);
4413 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
4414 s
->mem_index
, MO_LEQ
);
4416 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
4417 offsetof(CPUX86State
,
4418 xmm_regs
[reg
].XMM_Q(val
& 1)));
4429 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4431 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
4433 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4434 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4435 gen_ldo_env_A0(s
, op2_offset
);
4438 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4440 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4442 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4443 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4444 gen_ldq_env_A0(s
, op2_offset
);
4447 val
= cpu_ldub_code(env
, s
->pc
++);
4449 if ((b
& 0xfc) == 0x60) { /* pcmpXstrX */
4450 set_cc_op(s
, CC_OP_EFLAGS
);
4453 /* The helper must use entire 64-bit gp registers */
4457 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4458 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4459 sse_fn_eppi(cpu_env
, cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4463 /* Various integer extensions at 0f 3a f[0-f]. */
4464 b
= modrm
| (b1
<< 8);
4465 modrm
= cpu_ldub_code(env
, s
->pc
++);
4466 reg
= ((modrm
>> 3) & 7) | rex_r
;
4469 case 0x3f0: /* rorx Gy,Ey, Ib */
4470 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4471 || !(s
->prefix
& PREFIX_VEX
)
4475 ot
= s
->dflag
== 2 ? MO_64
: MO_32
;
4476 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4477 b
= cpu_ldub_code(env
, s
->pc
++);
4479 tcg_gen_rotri_tl(cpu_T
[0], cpu_T
[0], b
& 63);
4481 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4482 tcg_gen_rotri_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, b
& 31);
4483 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
4485 gen_op_mov_reg_T0(ot
, reg
);
4497 /* generic MMX or SSE operation */
4499 case 0x70: /* pshufx insn */
4500 case 0xc6: /* pshufx insn */
4501 case 0xc2: /* compare insns */
4508 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4510 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4511 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4512 if (b1
>= 2 && ((b
>= 0x50 && b
<= 0x5f && b
!= 0x5b) ||
4514 /* specific case for SSE single instructions */
4517 gen_op_ld_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
4518 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.XMM_L(0)));
4521 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
4525 gen_ldo_env_A0(s
, op2_offset
);
4528 rm
= (modrm
& 7) | REX_B(s
);
4529 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
4532 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4534 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4535 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4536 gen_ldq_env_A0(s
, op2_offset
);
4539 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4543 case 0x0f: /* 3DNow! data insns */
4544 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
))
4546 val
= cpu_ldub_code(env
, s
->pc
++);
4547 sse_fn_epp
= sse_op_table5
[val
];
4551 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4552 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4553 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4555 case 0x70: /* pshufx insn */
4556 case 0xc6: /* pshufx insn */
4557 val
= cpu_ldub_code(env
, s
->pc
++);
4558 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4559 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4560 /* XXX: introduce a new table? */
4561 sse_fn_ppi
= (SSEFunc_0_ppi
)sse_fn_epp
;
4562 sse_fn_ppi(cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4566 val
= cpu_ldub_code(env
, s
->pc
++);
4569 sse_fn_epp
= sse_op_table4
[val
][b1
];
4571 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4572 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4573 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4576 /* maskmov : we must prepare A0 */
4579 #ifdef TARGET_X86_64
4580 if (s
->aflag
== 2) {
4581 gen_op_movq_A0_reg(R_EDI
);
4585 gen_op_movl_A0_reg(R_EDI
);
4587 gen_op_andl_A0_ffff();
4589 gen_add_A0_ds_seg(s
);
4591 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4592 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4593 /* XXX: introduce a new table? */
4594 sse_fn_eppt
= (SSEFunc_0_eppt
)sse_fn_epp
;
4595 sse_fn_eppt(cpu_env
, cpu_ptr0
, cpu_ptr1
, cpu_A0
);
4598 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4599 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4600 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4603 if (b
== 0x2e || b
== 0x2f) {
4604 set_cc_op(s
, CC_OP_EFLAGS
);
4609 /* convert one instruction. s->is_jmp is set if the translation must
4610 be stopped. Return the next pc value */
4611 static target_ulong
disas_insn(CPUX86State
*env
, DisasContext
*s
,
4612 target_ulong pc_start
)
4614 int b
, prefixes
, aflag
, dflag
;
4616 int modrm
, reg
, rm
, mod
, reg_addr
, op
, opreg
, offset_addr
, val
;
4617 target_ulong next_eip
, tval
;
4620 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
4621 tcg_gen_debug_insn_start(pc_start
);
4628 #ifdef TARGET_X86_64
4633 s
->rip_offset
= 0; /* for relative ip address */
4637 b
= cpu_ldub_code(env
, s
->pc
);
4639 /* Collect prefixes. */
4642 prefixes
|= PREFIX_REPZ
;
4645 prefixes
|= PREFIX_REPNZ
;
4648 prefixes
|= PREFIX_LOCK
;
4669 prefixes
|= PREFIX_DATA
;
4672 prefixes
|= PREFIX_ADR
;
4674 #ifdef TARGET_X86_64
4678 rex_w
= (b
>> 3) & 1;
4679 rex_r
= (b
& 0x4) << 1;
4680 s
->rex_x
= (b
& 0x2) << 2;
4681 REX_B(s
) = (b
& 0x1) << 3;
4682 x86_64_hregs
= 1; /* select uniform byte register addressing */
4687 case 0xc5: /* 2-byte VEX */
4688 case 0xc4: /* 3-byte VEX */
4689 /* VEX prefixes cannot be used except in 32-bit mode.
4690 Otherwise the instruction is LES or LDS. */
4691 if (s
->code32
&& !s
->vm86
) {
4692 static const int pp_prefix
[4] = {
4693 0, PREFIX_DATA
, PREFIX_REPZ
, PREFIX_REPNZ
4695 int vex3
, vex2
= cpu_ldub_code(env
, s
->pc
);
4697 if (!CODE64(s
) && (vex2
& 0xc0) != 0xc0) {
4698 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4699 otherwise the instruction is LES or LDS. */
4704 /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
4705 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
4706 | PREFIX_LOCK
| PREFIX_DATA
)) {
4709 #ifdef TARGET_X86_64
4714 rex_r
= (~vex2
>> 4) & 8;
4717 b
= cpu_ldub_code(env
, s
->pc
++);
4719 #ifdef TARGET_X86_64
4720 s
->rex_x
= (~vex2
>> 3) & 8;
4721 s
->rex_b
= (~vex2
>> 2) & 8;
4723 vex3
= cpu_ldub_code(env
, s
->pc
++);
4724 rex_w
= (vex3
>> 7) & 1;
4725 switch (vex2
& 0x1f) {
4726 case 0x01: /* Implied 0f leading opcode bytes. */
4727 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4729 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4732 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4735 default: /* Reserved for future use. */
4739 s
->vex_v
= (~vex3
>> 3) & 0xf;
4740 s
->vex_l
= (vex3
>> 2) & 1;
4741 prefixes
|= pp_prefix
[vex3
& 3] | PREFIX_VEX
;
4746 /* Post-process prefixes. */
4748 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit
4749 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4750 over 0x66 if both are present. */
4751 dflag
= (rex_w
> 0 ? 2 : prefixes
& PREFIX_DATA
? 0 : 1);
4752 /* In 64-bit mode, 0x67 selects 32-bit addressing. */
4753 aflag
= (prefixes
& PREFIX_ADR
? 1 : 2);
4755 /* In 16/32-bit mode, 0x66 selects the opposite data size. */
4757 if (prefixes
& PREFIX_DATA
) {
4760 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */
4762 if (prefixes
& PREFIX_ADR
) {
4767 s
->prefix
= prefixes
;
4771 /* lock generation */
4772 if (prefixes
& PREFIX_LOCK
)
4775 /* now check op code */
4779 /**************************/
4780 /* extended op code */
4781 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4784 /**************************/
4805 case 0: /* OP Ev, Gv */
4806 modrm
= cpu_ldub_code(env
, s
->pc
++);
4807 reg
= ((modrm
>> 3) & 7) | rex_r
;
4808 mod
= (modrm
>> 6) & 3;
4809 rm
= (modrm
& 7) | REX_B(s
);
4811 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4813 } else if (op
== OP_XORL
&& rm
== reg
) {
4815 /* xor reg, reg optimisation */
4816 set_cc_op(s
, CC_OP_CLR
);
4818 gen_op_mov_reg_T0(ot
, reg
);
4823 gen_op_mov_TN_reg(ot
, 1, reg
);
4824 gen_op(s
, op
, ot
, opreg
);
4826 case 1: /* OP Gv, Ev */
4827 modrm
= cpu_ldub_code(env
, s
->pc
++);
4828 mod
= (modrm
>> 6) & 3;
4829 reg
= ((modrm
>> 3) & 7) | rex_r
;
4830 rm
= (modrm
& 7) | REX_B(s
);
4832 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4833 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
4834 } else if (op
== OP_XORL
&& rm
== reg
) {
4837 gen_op_mov_TN_reg(ot
, 1, rm
);
4839 gen_op(s
, op
, ot
, reg
);
4841 case 2: /* OP A, Iv */
4842 val
= insn_get(env
, s
, ot
);
4843 gen_op_movl_T1_im(val
);
4844 gen_op(s
, op
, ot
, OR_EAX
);
4853 case 0x80: /* GRP1 */
4864 modrm
= cpu_ldub_code(env
, s
->pc
++);
4865 mod
= (modrm
>> 6) & 3;
4866 rm
= (modrm
& 7) | REX_B(s
);
4867 op
= (modrm
>> 3) & 7;
4873 s
->rip_offset
= insn_const_size(ot
);
4874 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4885 val
= insn_get(env
, s
, ot
);
4888 val
= (int8_t)insn_get(env
, s
, MO_8
);
4891 gen_op_movl_T1_im(val
);
4892 gen_op(s
, op
, ot
, opreg
);
4896 /**************************/
4897 /* inc, dec, and other misc arith */
4898 case 0x40 ... 0x47: /* inc Gv */
4899 ot
= dflag
? MO_32
: MO_16
;
4900 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), 1);
4902 case 0x48 ... 0x4f: /* dec Gv */
4903 ot
= dflag
? MO_32
: MO_16
;
4904 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), -1);
4906 case 0xf6: /* GRP3 */
4913 modrm
= cpu_ldub_code(env
, s
->pc
++);
4914 mod
= (modrm
>> 6) & 3;
4915 rm
= (modrm
& 7) | REX_B(s
);
4916 op
= (modrm
>> 3) & 7;
4919 s
->rip_offset
= insn_const_size(ot
);
4920 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4921 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
4923 gen_op_mov_TN_reg(ot
, 0, rm
);
4928 val
= insn_get(env
, s
, ot
);
4929 gen_op_movl_T1_im(val
);
4930 gen_op_testl_T0_T1_cc();
4931 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4934 tcg_gen_not_tl(cpu_T
[0], cpu_T
[0]);
4936 gen_op_st_T0_A0(s
, ot
);
4938 gen_op_mov_reg_T0(ot
, rm
);
4942 tcg_gen_neg_tl(cpu_T
[0], cpu_T
[0]);
4944 gen_op_st_T0_A0(s
, ot
);
4946 gen_op_mov_reg_T0(ot
, rm
);
4948 gen_op_update_neg_cc();
4949 set_cc_op(s
, CC_OP_SUBB
+ ot
);
4954 gen_op_mov_TN_reg(MO_8
, 1, R_EAX
);
4955 tcg_gen_ext8u_tl(cpu_T
[0], cpu_T
[0]);
4956 tcg_gen_ext8u_tl(cpu_T
[1], cpu_T
[1]);
4957 /* XXX: use 32 bit mul which could be faster */
4958 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4959 gen_op_mov_reg_T0(MO_16
, R_EAX
);
4960 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4961 tcg_gen_andi_tl(cpu_cc_src
, cpu_T
[0], 0xff00);
4962 set_cc_op(s
, CC_OP_MULB
);
4965 gen_op_mov_TN_reg(MO_16
, 1, R_EAX
);
4966 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
4967 tcg_gen_ext16u_tl(cpu_T
[1], cpu_T
[1]);
4968 /* XXX: use 32 bit mul which could be faster */
4969 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4970 gen_op_mov_reg_T0(MO_16
, R_EAX
);
4971 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4972 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], 16);
4973 gen_op_mov_reg_T0(MO_16
, R_EDX
);
4974 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
4975 set_cc_op(s
, CC_OP_MULW
);
4979 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4980 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
4981 tcg_gen_mulu2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4982 cpu_tmp2_i32
, cpu_tmp3_i32
);
4983 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
4984 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
4985 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4986 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4987 set_cc_op(s
, CC_OP_MULL
);
4989 #ifdef TARGET_X86_64
4991 tcg_gen_mulu2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4992 cpu_T
[0], cpu_regs
[R_EAX
]);
4993 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4994 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4995 set_cc_op(s
, CC_OP_MULQ
);
5003 gen_op_mov_TN_reg(MO_8
, 1, R_EAX
);
5004 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
5005 tcg_gen_ext8s_tl(cpu_T
[1], cpu_T
[1]);
5006 /* XXX: use 32 bit mul which could be faster */
5007 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5008 gen_op_mov_reg_T0(MO_16
, R_EAX
);
5009 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5010 tcg_gen_ext8s_tl(cpu_tmp0
, cpu_T
[0]);
5011 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
5012 set_cc_op(s
, CC_OP_MULB
);
5015 gen_op_mov_TN_reg(MO_16
, 1, R_EAX
);
5016 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5017 tcg_gen_ext16s_tl(cpu_T
[1], cpu_T
[1]);
5018 /* XXX: use 32 bit mul which could be faster */
5019 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5020 gen_op_mov_reg_T0(MO_16
, R_EAX
);
5021 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5022 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T
[0]);
5023 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
5024 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], 16);
5025 gen_op_mov_reg_T0(MO_16
, R_EDX
);
5026 set_cc_op(s
, CC_OP_MULW
);
5030 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5031 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
5032 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
5033 cpu_tmp2_i32
, cpu_tmp3_i32
);
5034 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
5035 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
5036 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
5037 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
5038 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
5039 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
5040 set_cc_op(s
, CC_OP_MULL
);
5042 #ifdef TARGET_X86_64
5044 tcg_gen_muls2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
5045 cpu_T
[0], cpu_regs
[R_EAX
]);
5046 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
5047 tcg_gen_sari_tl(cpu_cc_src
, cpu_regs
[R_EAX
], 63);
5048 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_regs
[R_EDX
]);
5049 set_cc_op(s
, CC_OP_MULQ
);
5057 gen_jmp_im(pc_start
- s
->cs_base
);
5058 gen_helper_divb_AL(cpu_env
, cpu_T
[0]);
5061 gen_jmp_im(pc_start
- s
->cs_base
);
5062 gen_helper_divw_AX(cpu_env
, cpu_T
[0]);
5066 gen_jmp_im(pc_start
- s
->cs_base
);
5067 gen_helper_divl_EAX(cpu_env
, cpu_T
[0]);
5069 #ifdef TARGET_X86_64
5071 gen_jmp_im(pc_start
- s
->cs_base
);
5072 gen_helper_divq_EAX(cpu_env
, cpu_T
[0]);
5080 gen_jmp_im(pc_start
- s
->cs_base
);
5081 gen_helper_idivb_AL(cpu_env
, cpu_T
[0]);
5084 gen_jmp_im(pc_start
- s
->cs_base
);
5085 gen_helper_idivw_AX(cpu_env
, cpu_T
[0]);
5089 gen_jmp_im(pc_start
- s
->cs_base
);
5090 gen_helper_idivl_EAX(cpu_env
, cpu_T
[0]);
5092 #ifdef TARGET_X86_64
5094 gen_jmp_im(pc_start
- s
->cs_base
);
5095 gen_helper_idivq_EAX(cpu_env
, cpu_T
[0]);
5105 case 0xfe: /* GRP4 */
5106 case 0xff: /* GRP5 */
5112 modrm
= cpu_ldub_code(env
, s
->pc
++);
5113 mod
= (modrm
>> 6) & 3;
5114 rm
= (modrm
& 7) | REX_B(s
);
5115 op
= (modrm
>> 3) & 7;
5116 if (op
>= 2 && b
== 0xfe) {
5120 if (op
== 2 || op
== 4) {
5121 /* operand size for jumps is 64 bit */
5123 } else if (op
== 3 || op
== 5) {
5124 ot
= dflag
? MO_32
+ (rex_w
== 1) : MO_16
;
5125 } else if (op
== 6) {
5126 /* default push size is 64 bit */
5127 ot
= dflag
? MO_64
: MO_16
;
5131 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5132 if (op
>= 2 && op
!= 3 && op
!= 5)
5133 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
5135 gen_op_mov_TN_reg(ot
, 0, rm
);
5139 case 0: /* inc Ev */
5144 gen_inc(s
, ot
, opreg
, 1);
5146 case 1: /* dec Ev */
5151 gen_inc(s
, ot
, opreg
, -1);
5153 case 2: /* call Ev */
5154 /* XXX: optimize if memory (no 'and' is necessary) */
5156 gen_op_andl_T0_ffff();
5157 next_eip
= s
->pc
- s
->cs_base
;
5158 gen_movtl_T1_im(next_eip
);
5163 case 3: /* lcall Ev */
5164 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
5165 gen_add_A0_im(s
, 1 << (ot
- MO_16
+ 1));
5166 gen_op_ld_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
5168 if (s
->pe
&& !s
->vm86
) {
5169 gen_update_cc_op(s
);
5170 gen_jmp_im(pc_start
- s
->cs_base
);
5171 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5172 gen_helper_lcall_protected(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
5173 tcg_const_i32(dflag
),
5174 tcg_const_i32(s
->pc
- pc_start
));
5176 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5177 gen_helper_lcall_real(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
5178 tcg_const_i32(dflag
),
5179 tcg_const_i32(s
->pc
- s
->cs_base
));
5183 case 4: /* jmp Ev */
5185 gen_op_andl_T0_ffff();
5189 case 5: /* ljmp Ev */
5190 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
5191 gen_add_A0_im(s
, 1 << (ot
- MO_16
+ 1));
5192 gen_op_ld_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
5194 if (s
->pe
&& !s
->vm86
) {
5195 gen_update_cc_op(s
);
5196 gen_jmp_im(pc_start
- s
->cs_base
);
5197 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5198 gen_helper_ljmp_protected(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
5199 tcg_const_i32(s
->pc
- pc_start
));
5201 gen_op_movl_seg_T0_vm(R_CS
);
5202 gen_op_movl_T0_T1();
5207 case 6: /* push Ev */
5215 case 0x84: /* test Ev, Gv */
5222 modrm
= cpu_ldub_code(env
, s
->pc
++);
5223 reg
= ((modrm
>> 3) & 7) | rex_r
;
5225 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5226 gen_op_mov_TN_reg(ot
, 1, reg
);
5227 gen_op_testl_T0_T1_cc();
5228 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5231 case 0xa8: /* test eAX, Iv */
5237 val
= insn_get(env
, s
, ot
);
5239 gen_op_mov_TN_reg(ot
, 0, OR_EAX
);
5240 gen_op_movl_T1_im(val
);
5241 gen_op_testl_T0_T1_cc();
5242 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5245 case 0x98: /* CWDE/CBW */
5246 #ifdef TARGET_X86_64
5248 gen_op_mov_TN_reg(MO_32
, 0, R_EAX
);
5249 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
5250 gen_op_mov_reg_T0(MO_64
, R_EAX
);
5254 gen_op_mov_TN_reg(MO_16
, 0, R_EAX
);
5255 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5256 gen_op_mov_reg_T0(MO_32
, R_EAX
);
5258 gen_op_mov_TN_reg(MO_8
, 0, R_EAX
);
5259 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
5260 gen_op_mov_reg_T0(MO_16
, R_EAX
);
5263 case 0x99: /* CDQ/CWD */
5264 #ifdef TARGET_X86_64
5266 gen_op_mov_TN_reg(MO_64
, 0, R_EAX
);
5267 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 63);
5268 gen_op_mov_reg_T0(MO_64
, R_EDX
);
5272 gen_op_mov_TN_reg(MO_32
, 0, R_EAX
);
5273 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
5274 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 31);
5275 gen_op_mov_reg_T0(MO_32
, R_EDX
);
5277 gen_op_mov_TN_reg(MO_16
, 0, R_EAX
);
5278 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5279 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 15);
5280 gen_op_mov_reg_T0(MO_16
, R_EDX
);
5283 case 0x1af: /* imul Gv, Ev */
5284 case 0x69: /* imul Gv, Ev, I */
5287 modrm
= cpu_ldub_code(env
, s
->pc
++);
5288 reg
= ((modrm
>> 3) & 7) | rex_r
;
5290 s
->rip_offset
= insn_const_size(ot
);
5293 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5295 val
= insn_get(env
, s
, ot
);
5296 gen_op_movl_T1_im(val
);
5297 } else if (b
== 0x6b) {
5298 val
= (int8_t)insn_get(env
, s
, MO_8
);
5299 gen_op_movl_T1_im(val
);
5301 gen_op_mov_TN_reg(ot
, 1, reg
);
5304 #ifdef TARGET_X86_64
5306 tcg_gen_muls2_i64(cpu_regs
[reg
], cpu_T
[1], cpu_T
[0], cpu_T
[1]);
5307 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5308 tcg_gen_sari_tl(cpu_cc_src
, cpu_cc_dst
, 63);
5309 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_T
[1]);
5313 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5314 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
5315 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
5316 cpu_tmp2_i32
, cpu_tmp3_i32
);
5317 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
5318 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
5319 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5320 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
5321 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
5324 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5325 tcg_gen_ext16s_tl(cpu_T
[1], cpu_T
[1]);
5326 /* XXX: use 32 bit mul which could be faster */
5327 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5328 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5329 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T
[0]);
5330 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
5331 gen_op_mov_reg_T0(ot
, reg
);
5334 set_cc_op(s
, CC_OP_MULB
+ ot
);
5337 case 0x1c1: /* xadd Ev, Gv */
5342 modrm
= cpu_ldub_code(env
, s
->pc
++);
5343 reg
= ((modrm
>> 3) & 7) | rex_r
;
5344 mod
= (modrm
>> 6) & 3;
5346 rm
= (modrm
& 7) | REX_B(s
);
5347 gen_op_mov_TN_reg(ot
, 0, reg
);
5348 gen_op_mov_TN_reg(ot
, 1, rm
);
5349 gen_op_addl_T0_T1();
5350 gen_op_mov_reg_T1(ot
, reg
);
5351 gen_op_mov_reg_T0(ot
, rm
);
5353 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5354 gen_op_mov_TN_reg(ot
, 0, reg
);
5355 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
5356 gen_op_addl_T0_T1();
5357 gen_op_st_T0_A0(s
, ot
);
5358 gen_op_mov_reg_T1(ot
, reg
);
5360 gen_op_update2_cc();
5361 set_cc_op(s
, CC_OP_ADDB
+ ot
);
5364 case 0x1b1: /* cmpxchg Ev, Gv */
5367 TCGv t0
, t1
, t2
, a0
;
5373 modrm
= cpu_ldub_code(env
, s
->pc
++);
5374 reg
= ((modrm
>> 3) & 7) | rex_r
;
5375 mod
= (modrm
>> 6) & 3;
5376 t0
= tcg_temp_local_new();
5377 t1
= tcg_temp_local_new();
5378 t2
= tcg_temp_local_new();
5379 a0
= tcg_temp_local_new();
5380 gen_op_mov_v_reg(ot
, t1
, reg
);
5382 rm
= (modrm
& 7) | REX_B(s
);
5383 gen_op_mov_v_reg(ot
, t0
, rm
);
5385 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5386 tcg_gen_mov_tl(a0
, cpu_A0
);
5387 gen_op_ld_v(s
, ot
, t0
, a0
);
5388 rm
= 0; /* avoid warning */
5390 label1
= gen_new_label();
5391 tcg_gen_mov_tl(t2
, cpu_regs
[R_EAX
]);
5394 tcg_gen_brcond_tl(TCG_COND_EQ
, t2
, t0
, label1
);
5395 label2
= gen_new_label();
5397 gen_op_mov_reg_v(ot
, R_EAX
, t0
);
5399 gen_set_label(label1
);
5400 gen_op_mov_reg_v(ot
, rm
, t1
);
5402 /* perform no-op store cycle like physical cpu; must be
5403 before changing accumulator to ensure idempotency if
5404 the store faults and the instruction is restarted */
5405 gen_op_st_v(s
, ot
, t0
, a0
);
5406 gen_op_mov_reg_v(ot
, R_EAX
, t0
);
5408 gen_set_label(label1
);
5409 gen_op_st_v(s
, ot
, t1
, a0
);
5411 gen_set_label(label2
);
5412 tcg_gen_mov_tl(cpu_cc_src
, t0
);
5413 tcg_gen_mov_tl(cpu_cc_srcT
, t2
);
5414 tcg_gen_sub_tl(cpu_cc_dst
, t2
, t0
);
5415 set_cc_op(s
, CC_OP_SUBB
+ ot
);
5422 case 0x1c7: /* cmpxchg8b */
5423 modrm
= cpu_ldub_code(env
, s
->pc
++);
5424 mod
= (modrm
>> 6) & 3;
5425 if ((mod
== 3) || ((modrm
& 0x38) != 0x8))
5427 #ifdef TARGET_X86_64
5429 if (!(s
->cpuid_ext_features
& CPUID_EXT_CX16
))
5431 gen_jmp_im(pc_start
- s
->cs_base
);
5432 gen_update_cc_op(s
);
5433 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5434 gen_helper_cmpxchg16b(cpu_env
, cpu_A0
);
5438 if (!(s
->cpuid_features
& CPUID_CX8
))
5440 gen_jmp_im(pc_start
- s
->cs_base
);
5441 gen_update_cc_op(s
);
5442 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5443 gen_helper_cmpxchg8b(cpu_env
, cpu_A0
);
5445 set_cc_op(s
, CC_OP_EFLAGS
);
5448 /**************************/
5450 case 0x50 ... 0x57: /* push */
5451 gen_op_mov_TN_reg(MO_32
, 0, (b
& 7) | REX_B(s
));
5454 case 0x58 ... 0x5f: /* pop */
5456 ot
= dflag
? MO_64
: MO_16
;
5461 /* NOTE: order is important for pop %sp */
5463 gen_op_mov_reg_T0(ot
, (b
& 7) | REX_B(s
));
5465 case 0x60: /* pusha */
5470 case 0x61: /* popa */
5475 case 0x68: /* push Iv */
5478 ot
= dflag
? MO_64
: MO_16
;
5483 val
= insn_get(env
, s
, ot
);
5485 val
= (int8_t)insn_get(env
, s
, MO_8
);
5486 gen_op_movl_T0_im(val
);
5489 case 0x8f: /* pop Ev */
5491 ot
= dflag
? MO_64
: MO_16
;
5495 modrm
= cpu_ldub_code(env
, s
->pc
++);
5496 mod
= (modrm
>> 6) & 3;
5499 /* NOTE: order is important for pop %sp */
5501 rm
= (modrm
& 7) | REX_B(s
);
5502 gen_op_mov_reg_T0(ot
, rm
);
5504 /* NOTE: order is important too for MMU exceptions */
5505 s
->popl_esp_hack
= 1 << ot
;
5506 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5507 s
->popl_esp_hack
= 0;
5511 case 0xc8: /* enter */
5514 val
= cpu_lduw_code(env
, s
->pc
);
5516 level
= cpu_ldub_code(env
, s
->pc
++);
5517 gen_enter(s
, val
, level
);
5520 case 0xc9: /* leave */
5521 /* XXX: exception not precise (ESP is updated before potential exception) */
5523 gen_op_mov_TN_reg(MO_64
, 0, R_EBP
);
5524 gen_op_mov_reg_T0(MO_64
, R_ESP
);
5525 } else if (s
->ss32
) {
5526 gen_op_mov_TN_reg(MO_32
, 0, R_EBP
);
5527 gen_op_mov_reg_T0(MO_32
, R_ESP
);
5529 gen_op_mov_TN_reg(MO_16
, 0, R_EBP
);
5530 gen_op_mov_reg_T0(MO_16
, R_ESP
);
5534 ot
= dflag
? MO_64
: MO_16
;
5538 gen_op_mov_reg_T0(ot
, R_EBP
);
5541 case 0x06: /* push es */
5542 case 0x0e: /* push cs */
5543 case 0x16: /* push ss */
5544 case 0x1e: /* push ds */
5547 gen_op_movl_T0_seg(b
>> 3);
5550 case 0x1a0: /* push fs */
5551 case 0x1a8: /* push gs */
5552 gen_op_movl_T0_seg((b
>> 3) & 7);
5555 case 0x07: /* pop es */
5556 case 0x17: /* pop ss */
5557 case 0x1f: /* pop ds */
5562 gen_movl_seg_T0(s
, reg
, pc_start
- s
->cs_base
);
5565 /* if reg == SS, inhibit interrupts/trace. */
5566 /* If several instructions disable interrupts, only the
5568 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
5569 gen_helper_set_inhibit_irq(cpu_env
);
5573 gen_jmp_im(s
->pc
- s
->cs_base
);
5577 case 0x1a1: /* pop fs */
5578 case 0x1a9: /* pop gs */
5580 gen_movl_seg_T0(s
, (b
>> 3) & 7, pc_start
- s
->cs_base
);
5583 gen_jmp_im(s
->pc
- s
->cs_base
);
5588 /**************************/
5591 case 0x89: /* mov Gv, Ev */
5596 modrm
= cpu_ldub_code(env
, s
->pc
++);
5597 reg
= ((modrm
>> 3) & 7) | rex_r
;
5599 /* generate a generic store */
5600 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
5603 case 0xc7: /* mov Ev, Iv */
5608 modrm
= cpu_ldub_code(env
, s
->pc
++);
5609 mod
= (modrm
>> 6) & 3;
5611 s
->rip_offset
= insn_const_size(ot
);
5612 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5614 val
= insn_get(env
, s
, ot
);
5615 gen_op_movl_T0_im(val
);
5617 gen_op_st_T0_A0(s
, ot
);
5619 gen_op_mov_reg_T0(ot
, (modrm
& 7) | REX_B(s
));
5622 case 0x8b: /* mov Ev, Gv */
5627 modrm
= cpu_ldub_code(env
, s
->pc
++);
5628 reg
= ((modrm
>> 3) & 7) | rex_r
;
5630 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5631 gen_op_mov_reg_T0(ot
, reg
);
5633 case 0x8e: /* mov seg, Gv */
5634 modrm
= cpu_ldub_code(env
, s
->pc
++);
5635 reg
= (modrm
>> 3) & 7;
5636 if (reg
>= 6 || reg
== R_CS
)
5638 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
5639 gen_movl_seg_T0(s
, reg
, pc_start
- s
->cs_base
);
5641 /* if reg == SS, inhibit interrupts/trace */
5642 /* If several instructions disable interrupts, only the
5644 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
5645 gen_helper_set_inhibit_irq(cpu_env
);
5649 gen_jmp_im(s
->pc
- s
->cs_base
);
5653 case 0x8c: /* mov Gv, seg */
5654 modrm
= cpu_ldub_code(env
, s
->pc
++);
5655 reg
= (modrm
>> 3) & 7;
5656 mod
= (modrm
>> 6) & 3;
5659 gen_op_movl_T0_seg(reg
);
5664 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5667 case 0x1b6: /* movzbS Gv, Eb */
5668 case 0x1b7: /* movzwS Gv, Eb */
5669 case 0x1be: /* movsbS Gv, Eb */
5670 case 0x1bf: /* movswS Gv, Eb */
5673 /* d_ot is the size of destination */
5674 d_ot
= dflag
+ MO_16
;
5675 /* ot is the size of source */
5676 ot
= (b
& 1) + MO_8
;
5677 modrm
= cpu_ldub_code(env
, s
->pc
++);
5678 reg
= ((modrm
>> 3) & 7) | rex_r
;
5679 mod
= (modrm
>> 6) & 3;
5680 rm
= (modrm
& 7) | REX_B(s
);
5683 gen_op_mov_TN_reg(ot
, 0, rm
);
5684 switch(ot
| (b
& 8)) {
5686 tcg_gen_ext8u_tl(cpu_T
[0], cpu_T
[0]);
5689 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
5692 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
5696 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5699 gen_op_mov_reg_T0(d_ot
, reg
);
5701 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5703 gen_op_lds_T0_A0(s
, ot
);
5705 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
5707 gen_op_mov_reg_T0(d_ot
, reg
);
5712 case 0x8d: /* lea */
5714 modrm
= cpu_ldub_code(env
, s
->pc
++);
5715 mod
= (modrm
>> 6) & 3;
5718 reg
= ((modrm
>> 3) & 7) | rex_r
;
5719 /* we must ensure that no segment is added */
5723 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5725 gen_op_mov_reg_A0(ot
- MO_16
, reg
);
5728 case 0xa0: /* mov EAX, Ov */
5730 case 0xa2: /* mov Ov, EAX */
5733 target_ulong offset_addr
;
5739 #ifdef TARGET_X86_64
5740 if (s
->aflag
== 2) {
5741 offset_addr
= cpu_ldq_code(env
, s
->pc
);
5743 gen_op_movq_A0_im(offset_addr
);
5748 offset_addr
= insn_get(env
, s
, MO_32
);
5750 offset_addr
= insn_get(env
, s
, MO_16
);
5752 gen_op_movl_A0_im(offset_addr
);
5754 gen_add_A0_ds_seg(s
);
5756 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
5757 gen_op_mov_reg_T0(ot
, R_EAX
);
5759 gen_op_mov_TN_reg(ot
, 0, R_EAX
);
5760 gen_op_st_T0_A0(s
, ot
);
5764 case 0xd7: /* xlat */
5765 #ifdef TARGET_X86_64
5766 if (s
->aflag
== 2) {
5767 gen_op_movq_A0_reg(R_EBX
);
5768 gen_op_mov_TN_reg(MO_64
, 0, R_EAX
);
5769 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xff);
5770 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_T
[0]);
5774 gen_op_movl_A0_reg(R_EBX
);
5775 gen_op_mov_TN_reg(MO_32
, 0, R_EAX
);
5776 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xff);
5777 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_T
[0]);
5779 gen_op_andl_A0_ffff();
5781 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffffffff);
5783 gen_add_A0_ds_seg(s
);
5784 gen_op_ld_v(s
, MO_8
, cpu_T
[0], cpu_A0
);
5785 gen_op_mov_reg_T0(MO_8
, R_EAX
);
5787 case 0xb0 ... 0xb7: /* mov R, Ib */
5788 val
= insn_get(env
, s
, MO_8
);
5789 gen_op_movl_T0_im(val
);
5790 gen_op_mov_reg_T0(MO_8
, (b
& 7) | REX_B(s
));
5792 case 0xb8 ... 0xbf: /* mov R, Iv */
5793 #ifdef TARGET_X86_64
5797 tmp
= cpu_ldq_code(env
, s
->pc
);
5799 reg
= (b
& 7) | REX_B(s
);
5800 gen_movtl_T0_im(tmp
);
5801 gen_op_mov_reg_T0(MO_64
, reg
);
5805 ot
= dflag
? MO_32
: MO_16
;
5806 val
= insn_get(env
, s
, ot
);
5807 reg
= (b
& 7) | REX_B(s
);
5808 gen_op_movl_T0_im(val
);
5809 gen_op_mov_reg_T0(ot
, reg
);
5813 case 0x91 ... 0x97: /* xchg R, EAX */
5816 reg
= (b
& 7) | REX_B(s
);
5820 case 0x87: /* xchg Ev, Gv */
5825 modrm
= cpu_ldub_code(env
, s
->pc
++);
5826 reg
= ((modrm
>> 3) & 7) | rex_r
;
5827 mod
= (modrm
>> 6) & 3;
5829 rm
= (modrm
& 7) | REX_B(s
);
5831 gen_op_mov_TN_reg(ot
, 0, reg
);
5832 gen_op_mov_TN_reg(ot
, 1, rm
);
5833 gen_op_mov_reg_T0(ot
, rm
);
5834 gen_op_mov_reg_T1(ot
, reg
);
5836 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5837 gen_op_mov_TN_reg(ot
, 0, reg
);
5838 /* for xchg, lock is implicit */
5839 if (!(prefixes
& PREFIX_LOCK
))
5841 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
5842 gen_op_st_T0_A0(s
, ot
);
5843 if (!(prefixes
& PREFIX_LOCK
))
5844 gen_helper_unlock();
5845 gen_op_mov_reg_T1(ot
, reg
);
5848 case 0xc4: /* les Gv */
5849 /* In CODE64 this is VEX3; see above. */
5852 case 0xc5: /* lds Gv */
5853 /* In CODE64 this is VEX2; see above. */
5856 case 0x1b2: /* lss Gv */
5859 case 0x1b4: /* lfs Gv */
5862 case 0x1b5: /* lgs Gv */
5865 ot
= dflag
? MO_32
: MO_16
;
5866 modrm
= cpu_ldub_code(env
, s
->pc
++);
5867 reg
= ((modrm
>> 3) & 7) | rex_r
;
5868 mod
= (modrm
>> 6) & 3;
5871 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5872 gen_op_ld_v(s
, ot
, cpu_T
[1], cpu_A0
);
5873 gen_add_A0_im(s
, 1 << (ot
- MO_16
+ 1));
5874 /* load the segment first to handle exceptions properly */
5875 gen_op_ld_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
5876 gen_movl_seg_T0(s
, op
, pc_start
- s
->cs_base
);
5877 /* then put the data */
5878 gen_op_mov_reg_T1(ot
, reg
);
5880 gen_jmp_im(s
->pc
- s
->cs_base
);
5885 /************************/
5898 modrm
= cpu_ldub_code(env
, s
->pc
++);
5899 mod
= (modrm
>> 6) & 3;
5900 op
= (modrm
>> 3) & 7;
5906 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5909 opreg
= (modrm
& 7) | REX_B(s
);
5914 gen_shift(s
, op
, ot
, opreg
, OR_ECX
);
5917 shift
= cpu_ldub_code(env
, s
->pc
++);
5919 gen_shifti(s
, op
, ot
, opreg
, shift
);
5934 case 0x1a4: /* shld imm */
5938 case 0x1a5: /* shld cl */
5942 case 0x1ac: /* shrd imm */
5946 case 0x1ad: /* shrd cl */
5951 modrm
= cpu_ldub_code(env
, s
->pc
++);
5952 mod
= (modrm
>> 6) & 3;
5953 rm
= (modrm
& 7) | REX_B(s
);
5954 reg
= ((modrm
>> 3) & 7) | rex_r
;
5956 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5961 gen_op_mov_TN_reg(ot
, 1, reg
);
5964 TCGv imm
= tcg_const_tl(cpu_ldub_code(env
, s
->pc
++));
5965 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, imm
);
5968 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, cpu_regs
[R_ECX
]);
5972 /************************/
5975 if (s
->flags
& (HF_EM_MASK
| HF_TS_MASK
)) {
5976 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5977 /* XXX: what to do if illegal op ? */
5978 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
5981 modrm
= cpu_ldub_code(env
, s
->pc
++);
5982 mod
= (modrm
>> 6) & 3;
5984 op
= ((b
& 7) << 3) | ((modrm
>> 3) & 7);
5987 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5989 case 0x00 ... 0x07: /* fxxxs */
5990 case 0x10 ... 0x17: /* fixxxl */
5991 case 0x20 ... 0x27: /* fxxxl */
5992 case 0x30 ... 0x37: /* fixxx */
5999 gen_op_ld_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
6000 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6001 gen_helper_flds_FT0(cpu_env
, cpu_tmp2_i32
);
6004 gen_op_ld_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
6005 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6006 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
6009 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
6010 s
->mem_index
, MO_LEQ
);
6011 gen_helper_fldl_FT0(cpu_env
, cpu_tmp1_i64
);
6015 gen_op_lds_T0_A0(s
, MO_16
);
6016 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6017 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
6021 gen_helper_fp_arith_ST0_FT0(op1
);
6023 /* fcomp needs pop */
6024 gen_helper_fpop(cpu_env
);
6028 case 0x08: /* flds */
6029 case 0x0a: /* fsts */
6030 case 0x0b: /* fstps */
6031 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
6032 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
6033 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
6038 gen_op_ld_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
6039 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6040 gen_helper_flds_ST0(cpu_env
, cpu_tmp2_i32
);
6043 gen_op_ld_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
6044 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6045 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
6048 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
6049 s
->mem_index
, MO_LEQ
);
6050 gen_helper_fldl_ST0(cpu_env
, cpu_tmp1_i64
);
6054 gen_op_lds_T0_A0(s
, MO_16
);
6055 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6056 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
6061 /* XXX: the corresponding CPUID bit must be tested ! */
6064 gen_helper_fisttl_ST0(cpu_tmp2_i32
, cpu_env
);
6065 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6066 gen_op_st_T0_A0(s
, MO_32
);
6069 gen_helper_fisttll_ST0(cpu_tmp1_i64
, cpu_env
);
6070 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
6071 s
->mem_index
, MO_LEQ
);
6075 gen_helper_fistt_ST0(cpu_tmp2_i32
, cpu_env
);
6076 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6077 gen_op_st_T0_A0(s
, MO_16
);
6080 gen_helper_fpop(cpu_env
);
6085 gen_helper_fsts_ST0(cpu_tmp2_i32
, cpu_env
);
6086 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6087 gen_op_st_T0_A0(s
, MO_32
);
6090 gen_helper_fistl_ST0(cpu_tmp2_i32
, cpu_env
);
6091 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6092 gen_op_st_T0_A0(s
, MO_32
);
6095 gen_helper_fstl_ST0(cpu_tmp1_i64
, cpu_env
);
6096 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
6097 s
->mem_index
, MO_LEQ
);
6101 gen_helper_fist_ST0(cpu_tmp2_i32
, cpu_env
);
6102 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6103 gen_op_st_T0_A0(s
, MO_16
);
6107 gen_helper_fpop(cpu_env
);
6111 case 0x0c: /* fldenv mem */
6112 gen_update_cc_op(s
);
6113 gen_jmp_im(pc_start
- s
->cs_base
);
6114 gen_helper_fldenv(cpu_env
, cpu_A0
, tcg_const_i32(s
->dflag
));
6116 case 0x0d: /* fldcw mem */
6117 gen_op_ld_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
6118 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6119 gen_helper_fldcw(cpu_env
, cpu_tmp2_i32
);
6121 case 0x0e: /* fnstenv mem */
6122 gen_update_cc_op(s
);
6123 gen_jmp_im(pc_start
- s
->cs_base
);
6124 gen_helper_fstenv(cpu_env
, cpu_A0
, tcg_const_i32(s
->dflag
));
6126 case 0x0f: /* fnstcw mem */
6127 gen_helper_fnstcw(cpu_tmp2_i32
, cpu_env
);
6128 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6129 gen_op_st_T0_A0(s
, MO_16
);
6131 case 0x1d: /* fldt mem */
6132 gen_update_cc_op(s
);
6133 gen_jmp_im(pc_start
- s
->cs_base
);
6134 gen_helper_fldt_ST0(cpu_env
, cpu_A0
);
6136 case 0x1f: /* fstpt mem */
6137 gen_update_cc_op(s
);
6138 gen_jmp_im(pc_start
- s
->cs_base
);
6139 gen_helper_fstt_ST0(cpu_env
, cpu_A0
);
6140 gen_helper_fpop(cpu_env
);
6142 case 0x2c: /* frstor mem */
6143 gen_update_cc_op(s
);
6144 gen_jmp_im(pc_start
- s
->cs_base
);
6145 gen_helper_frstor(cpu_env
, cpu_A0
, tcg_const_i32(s
->dflag
));
6147 case 0x2e: /* fnsave mem */
6148 gen_update_cc_op(s
);
6149 gen_jmp_im(pc_start
- s
->cs_base
);
6150 gen_helper_fsave(cpu_env
, cpu_A0
, tcg_const_i32(s
->dflag
));
6152 case 0x2f: /* fnstsw mem */
6153 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
6154 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6155 gen_op_st_T0_A0(s
, MO_16
);
6157 case 0x3c: /* fbld */
6158 gen_update_cc_op(s
);
6159 gen_jmp_im(pc_start
- s
->cs_base
);
6160 gen_helper_fbld_ST0(cpu_env
, cpu_A0
);
6162 case 0x3e: /* fbstp */
6163 gen_update_cc_op(s
);
6164 gen_jmp_im(pc_start
- s
->cs_base
);
6165 gen_helper_fbst_ST0(cpu_env
, cpu_A0
);
6166 gen_helper_fpop(cpu_env
);
6168 case 0x3d: /* fildll */
6169 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
6170 gen_helper_fildll_ST0(cpu_env
, cpu_tmp1_i64
);
6172 case 0x3f: /* fistpll */
6173 gen_helper_fistll_ST0(cpu_tmp1_i64
, cpu_env
);
6174 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
6175 gen_helper_fpop(cpu_env
);
6181 /* register float ops */
6185 case 0x08: /* fld sti */
6186 gen_helper_fpush(cpu_env
);
6187 gen_helper_fmov_ST0_STN(cpu_env
,
6188 tcg_const_i32((opreg
+ 1) & 7));
6190 case 0x09: /* fxchg sti */
6191 case 0x29: /* fxchg4 sti, undocumented op */
6192 case 0x39: /* fxchg7 sti, undocumented op */
6193 gen_helper_fxchg_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6195 case 0x0a: /* grp d9/2 */
6198 /* check exceptions (FreeBSD FPU probe) */
6199 gen_update_cc_op(s
);
6200 gen_jmp_im(pc_start
- s
->cs_base
);
6201 gen_helper_fwait(cpu_env
);
6207 case 0x0c: /* grp d9/4 */
6210 gen_helper_fchs_ST0(cpu_env
);
6213 gen_helper_fabs_ST0(cpu_env
);
6216 gen_helper_fldz_FT0(cpu_env
);
6217 gen_helper_fcom_ST0_FT0(cpu_env
);
6220 gen_helper_fxam_ST0(cpu_env
);
6226 case 0x0d: /* grp d9/5 */
6230 gen_helper_fpush(cpu_env
);
6231 gen_helper_fld1_ST0(cpu_env
);
6234 gen_helper_fpush(cpu_env
);
6235 gen_helper_fldl2t_ST0(cpu_env
);
6238 gen_helper_fpush(cpu_env
);
6239 gen_helper_fldl2e_ST0(cpu_env
);
6242 gen_helper_fpush(cpu_env
);
6243 gen_helper_fldpi_ST0(cpu_env
);
6246 gen_helper_fpush(cpu_env
);
6247 gen_helper_fldlg2_ST0(cpu_env
);
6250 gen_helper_fpush(cpu_env
);
6251 gen_helper_fldln2_ST0(cpu_env
);
6254 gen_helper_fpush(cpu_env
);
6255 gen_helper_fldz_ST0(cpu_env
);
6262 case 0x0e: /* grp d9/6 */
6265 gen_helper_f2xm1(cpu_env
);
6268 gen_helper_fyl2x(cpu_env
);
6271 gen_helper_fptan(cpu_env
);
6273 case 3: /* fpatan */
6274 gen_helper_fpatan(cpu_env
);
6276 case 4: /* fxtract */
6277 gen_helper_fxtract(cpu_env
);
6279 case 5: /* fprem1 */
6280 gen_helper_fprem1(cpu_env
);
6282 case 6: /* fdecstp */
6283 gen_helper_fdecstp(cpu_env
);
6286 case 7: /* fincstp */
6287 gen_helper_fincstp(cpu_env
);
6291 case 0x0f: /* grp d9/7 */
6294 gen_helper_fprem(cpu_env
);
6296 case 1: /* fyl2xp1 */
6297 gen_helper_fyl2xp1(cpu_env
);
6300 gen_helper_fsqrt(cpu_env
);
6302 case 3: /* fsincos */
6303 gen_helper_fsincos(cpu_env
);
6305 case 5: /* fscale */
6306 gen_helper_fscale(cpu_env
);
6308 case 4: /* frndint */
6309 gen_helper_frndint(cpu_env
);
6312 gen_helper_fsin(cpu_env
);
6316 gen_helper_fcos(cpu_env
);
6320 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6321 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6322 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6328 gen_helper_fp_arith_STN_ST0(op1
, opreg
);
6330 gen_helper_fpop(cpu_env
);
6332 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6333 gen_helper_fp_arith_ST0_FT0(op1
);
6337 case 0x02: /* fcom */
6338 case 0x22: /* fcom2, undocumented op */
6339 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6340 gen_helper_fcom_ST0_FT0(cpu_env
);
6342 case 0x03: /* fcomp */
6343 case 0x23: /* fcomp3, undocumented op */
6344 case 0x32: /* fcomp5, undocumented op */
6345 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6346 gen_helper_fcom_ST0_FT0(cpu_env
);
6347 gen_helper_fpop(cpu_env
);
6349 case 0x15: /* da/5 */
6351 case 1: /* fucompp */
6352 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6353 gen_helper_fucom_ST0_FT0(cpu_env
);
6354 gen_helper_fpop(cpu_env
);
6355 gen_helper_fpop(cpu_env
);
6363 case 0: /* feni (287 only, just do nop here) */
6365 case 1: /* fdisi (287 only, just do nop here) */
6368 gen_helper_fclex(cpu_env
);
6370 case 3: /* fninit */
6371 gen_helper_fninit(cpu_env
);
6373 case 4: /* fsetpm (287 only, just do nop here) */
6379 case 0x1d: /* fucomi */
6380 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6383 gen_update_cc_op(s
);
6384 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6385 gen_helper_fucomi_ST0_FT0(cpu_env
);
6386 set_cc_op(s
, CC_OP_EFLAGS
);
6388 case 0x1e: /* fcomi */
6389 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6392 gen_update_cc_op(s
);
6393 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6394 gen_helper_fcomi_ST0_FT0(cpu_env
);
6395 set_cc_op(s
, CC_OP_EFLAGS
);
6397 case 0x28: /* ffree sti */
6398 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6400 case 0x2a: /* fst sti */
6401 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6403 case 0x2b: /* fstp sti */
6404 case 0x0b: /* fstp1 sti, undocumented op */
6405 case 0x3a: /* fstp8 sti, undocumented op */
6406 case 0x3b: /* fstp9 sti, undocumented op */
6407 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6408 gen_helper_fpop(cpu_env
);
6410 case 0x2c: /* fucom st(i) */
6411 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6412 gen_helper_fucom_ST0_FT0(cpu_env
);
6414 case 0x2d: /* fucomp st(i) */
6415 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6416 gen_helper_fucom_ST0_FT0(cpu_env
);
6417 gen_helper_fpop(cpu_env
);
6419 case 0x33: /* de/3 */
6421 case 1: /* fcompp */
6422 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6423 gen_helper_fcom_ST0_FT0(cpu_env
);
6424 gen_helper_fpop(cpu_env
);
6425 gen_helper_fpop(cpu_env
);
6431 case 0x38: /* ffreep sti, undocumented op */
6432 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6433 gen_helper_fpop(cpu_env
);
6435 case 0x3c: /* df/4 */
6438 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
6439 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6440 gen_op_mov_reg_T0(MO_16
, R_EAX
);
6446 case 0x3d: /* fucomip */
6447 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6450 gen_update_cc_op(s
);
6451 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6452 gen_helper_fucomi_ST0_FT0(cpu_env
);
6453 gen_helper_fpop(cpu_env
);
6454 set_cc_op(s
, CC_OP_EFLAGS
);
6456 case 0x3e: /* fcomip */
6457 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6460 gen_update_cc_op(s
);
6461 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6462 gen_helper_fcomi_ST0_FT0(cpu_env
);
6463 gen_helper_fpop(cpu_env
);
6464 set_cc_op(s
, CC_OP_EFLAGS
);
6466 case 0x10 ... 0x13: /* fcmovxx */
6470 static const uint8_t fcmov_cc
[8] = {
6477 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6480 op1
= fcmov_cc
[op
& 3] | (((op
>> 3) & 1) ^ 1);
6481 l1
= gen_new_label();
6482 gen_jcc1_noeob(s
, op1
, l1
);
6483 gen_helper_fmov_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6492 /************************/
6495 case 0xa4: /* movsS */
6502 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6503 gen_repz_movs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6509 case 0xaa: /* stosS */
6516 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6517 gen_repz_stos(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6522 case 0xac: /* lodsS */
6528 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6529 gen_repz_lods(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6534 case 0xae: /* scasS */
6540 if (prefixes
& PREFIX_REPNZ
) {
6541 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6542 } else if (prefixes
& PREFIX_REPZ
) {
6543 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6549 case 0xa6: /* cmpsS */
6555 if (prefixes
& PREFIX_REPNZ
) {
6556 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6557 } else if (prefixes
& PREFIX_REPZ
) {
6558 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6563 case 0x6c: /* insS */
6568 ot
= dflag
? MO_32
: MO_16
;
6569 gen_op_mov_TN_reg(MO_16
, 0, R_EDX
);
6570 gen_op_andl_T0_ffff();
6571 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6572 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
) | 4);
6573 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6574 gen_repz_ins(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6578 gen_jmp(s
, s
->pc
- s
->cs_base
);
6582 case 0x6e: /* outsS */
6587 ot
= dflag
? MO_32
: MO_16
;
6588 gen_op_mov_TN_reg(MO_16
, 0, R_EDX
);
6589 gen_op_andl_T0_ffff();
6590 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6591 svm_is_rep(prefixes
) | 4);
6592 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6593 gen_repz_outs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6597 gen_jmp(s
, s
->pc
- s
->cs_base
);
6602 /************************/
6610 ot
= dflag
? MO_32
: MO_16
;
6611 val
= cpu_ldub_code(env
, s
->pc
++);
6612 gen_op_movl_T0_im(val
);
6613 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6614 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6617 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6618 gen_helper_in_func(ot
, cpu_T
[1], cpu_tmp2_i32
);
6619 gen_op_mov_reg_T1(ot
, R_EAX
);
6622 gen_jmp(s
, s
->pc
- s
->cs_base
);
6630 ot
= dflag
? MO_32
: MO_16
;
6631 val
= cpu_ldub_code(env
, s
->pc
++);
6632 gen_op_movl_T0_im(val
);
6633 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6634 svm_is_rep(prefixes
));
6635 gen_op_mov_TN_reg(ot
, 1, R_EAX
);
6639 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6640 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
6641 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6644 gen_jmp(s
, s
->pc
- s
->cs_base
);
6652 ot
= dflag
? MO_32
: MO_16
;
6653 gen_op_mov_TN_reg(MO_16
, 0, R_EDX
);
6654 gen_op_andl_T0_ffff();
6655 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6656 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6659 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6660 gen_helper_in_func(ot
, cpu_T
[1], cpu_tmp2_i32
);
6661 gen_op_mov_reg_T1(ot
, R_EAX
);
6664 gen_jmp(s
, s
->pc
- s
->cs_base
);
6672 ot
= dflag
? MO_32
: MO_16
;
6673 gen_op_mov_TN_reg(MO_16
, 0, R_EDX
);
6674 gen_op_andl_T0_ffff();
6675 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6676 svm_is_rep(prefixes
));
6677 gen_op_mov_TN_reg(ot
, 1, R_EAX
);
6681 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6682 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
6683 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6686 gen_jmp(s
, s
->pc
- s
->cs_base
);
6690 /************************/
6692 case 0xc2: /* ret im */
6693 val
= cpu_ldsw_code(env
, s
->pc
);
6696 if (CODE64(s
) && s
->dflag
)
6698 gen_stack_update(s
, val
+ (2 << s
->dflag
));
6700 gen_op_andl_T0_ffff();
6704 case 0xc3: /* ret */
6708 gen_op_andl_T0_ffff();
6712 case 0xca: /* lret im */
6713 val
= cpu_ldsw_code(env
, s
->pc
);
6716 if (s
->pe
&& !s
->vm86
) {
6717 gen_update_cc_op(s
);
6718 gen_jmp_im(pc_start
- s
->cs_base
);
6719 gen_helper_lret_protected(cpu_env
, tcg_const_i32(s
->dflag
),
6720 tcg_const_i32(val
));
6724 gen_op_ld_v(s
, 1 + s
->dflag
, cpu_T
[0], cpu_A0
);
6726 gen_op_andl_T0_ffff();
6727 /* NOTE: keeping EIP updated is not a problem in case of
6731 gen_op_addl_A0_im(2 << s
->dflag
);
6732 gen_op_ld_v(s
, 1 + s
->dflag
, cpu_T
[0], cpu_A0
);
6733 gen_op_movl_seg_T0_vm(R_CS
);
6734 /* add stack offset */
6735 gen_stack_update(s
, val
+ (4 << s
->dflag
));
6739 case 0xcb: /* lret */
6742 case 0xcf: /* iret */
6743 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IRET
);
6746 gen_helper_iret_real(cpu_env
, tcg_const_i32(s
->dflag
));
6747 set_cc_op(s
, CC_OP_EFLAGS
);
6748 } else if (s
->vm86
) {
6750 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6752 gen_helper_iret_real(cpu_env
, tcg_const_i32(s
->dflag
));
6753 set_cc_op(s
, CC_OP_EFLAGS
);
6756 gen_update_cc_op(s
);
6757 gen_jmp_im(pc_start
- s
->cs_base
);
6758 gen_helper_iret_protected(cpu_env
, tcg_const_i32(s
->dflag
),
6759 tcg_const_i32(s
->pc
- s
->cs_base
));
6760 set_cc_op(s
, CC_OP_EFLAGS
);
6764 case 0xe8: /* call im */
6767 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6769 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6770 next_eip
= s
->pc
- s
->cs_base
;
6776 gen_movtl_T0_im(next_eip
);
6781 case 0x9a: /* lcall im */
6783 unsigned int selector
, offset
;
6787 ot
= dflag
? MO_32
: MO_16
;
6788 offset
= insn_get(env
, s
, ot
);
6789 selector
= insn_get(env
, s
, MO_16
);
6791 gen_op_movl_T0_im(selector
);
6792 gen_op_movl_T1_imu(offset
);
6795 case 0xe9: /* jmp im */
6797 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6799 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6800 tval
+= s
->pc
- s
->cs_base
;
6807 case 0xea: /* ljmp im */
6809 unsigned int selector
, offset
;
6813 ot
= dflag
? MO_32
: MO_16
;
6814 offset
= insn_get(env
, s
, ot
);
6815 selector
= insn_get(env
, s
, MO_16
);
6817 gen_op_movl_T0_im(selector
);
6818 gen_op_movl_T1_imu(offset
);
6821 case 0xeb: /* jmp Jb */
6822 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6823 tval
+= s
->pc
- s
->cs_base
;
6828 case 0x70 ... 0x7f: /* jcc Jb */
6829 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6831 case 0x180 ... 0x18f: /* jcc Jv */
6833 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6835 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6838 next_eip
= s
->pc
- s
->cs_base
;
6842 gen_jcc(s
, b
, tval
, next_eip
);
6845 case 0x190 ... 0x19f: /* setcc Gv */
6846 modrm
= cpu_ldub_code(env
, s
->pc
++);
6847 gen_setcc1(s
, b
, cpu_T
[0]);
6848 gen_ldst_modrm(env
, s
, modrm
, MO_8
, OR_TMP0
, 1);
6850 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6851 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6855 modrm
= cpu_ldub_code(env
, s
->pc
++);
6856 reg
= ((modrm
>> 3) & 7) | rex_r
;
6857 gen_cmovcc1(env
, s
, ot
, b
, modrm
, reg
);
6860 /************************/
6862 case 0x9c: /* pushf */
6863 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_PUSHF
);
6864 if (s
->vm86
&& s
->iopl
!= 3) {
6865 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6867 gen_update_cc_op(s
);
6868 gen_helper_read_eflags(cpu_T
[0], cpu_env
);
6872 case 0x9d: /* popf */
6873 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_POPF
);
6874 if (s
->vm86
&& s
->iopl
!= 3) {
6875 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6880 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6881 tcg_const_i32((TF_MASK
| AC_MASK
|
6886 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6887 tcg_const_i32((TF_MASK
| AC_MASK
|
6889 IF_MASK
| IOPL_MASK
)
6893 if (s
->cpl
<= s
->iopl
) {
6895 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6896 tcg_const_i32((TF_MASK
|
6902 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6903 tcg_const_i32((TF_MASK
|
6912 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6913 tcg_const_i32((TF_MASK
| AC_MASK
|
6914 ID_MASK
| NT_MASK
)));
6916 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6917 tcg_const_i32((TF_MASK
| AC_MASK
|
6924 set_cc_op(s
, CC_OP_EFLAGS
);
6925 /* abort translation because TF/AC flag may change */
6926 gen_jmp_im(s
->pc
- s
->cs_base
);
6930 case 0x9e: /* sahf */
6931 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6933 gen_op_mov_TN_reg(MO_8
, 0, R_AH
);
6934 gen_compute_eflags(s
);
6935 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, CC_O
);
6936 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], CC_S
| CC_Z
| CC_A
| CC_P
| CC_C
);
6937 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, cpu_T
[0]);
6939 case 0x9f: /* lahf */
6940 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6942 gen_compute_eflags(s
);
6943 /* Note: gen_compute_eflags() only gives the condition codes */
6944 tcg_gen_ori_tl(cpu_T
[0], cpu_cc_src
, 0x02);
6945 gen_op_mov_reg_T0(MO_8
, R_AH
);
6947 case 0xf5: /* cmc */
6948 gen_compute_eflags(s
);
6949 tcg_gen_xori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6951 case 0xf8: /* clc */
6952 gen_compute_eflags(s
);
6953 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_C
);
6955 case 0xf9: /* stc */
6956 gen_compute_eflags(s
);
6957 tcg_gen_ori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6959 case 0xfc: /* cld */
6960 tcg_gen_movi_i32(cpu_tmp2_i32
, 1);
6961 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6963 case 0xfd: /* std */
6964 tcg_gen_movi_i32(cpu_tmp2_i32
, -1);
6965 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6968 /************************/
6969 /* bit operations */
6970 case 0x1ba: /* bt/bts/btr/btc Gv, im */
6972 modrm
= cpu_ldub_code(env
, s
->pc
++);
6973 op
= (modrm
>> 3) & 7;
6974 mod
= (modrm
>> 6) & 3;
6975 rm
= (modrm
& 7) | REX_B(s
);
6978 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
6979 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
6981 gen_op_mov_TN_reg(ot
, 0, rm
);
6984 val
= cpu_ldub_code(env
, s
->pc
++);
6985 gen_op_movl_T1_im(val
);
6990 case 0x1a3: /* bt Gv, Ev */
6993 case 0x1ab: /* bts */
6996 case 0x1b3: /* btr */
6999 case 0x1bb: /* btc */
7003 modrm
= cpu_ldub_code(env
, s
->pc
++);
7004 reg
= ((modrm
>> 3) & 7) | rex_r
;
7005 mod
= (modrm
>> 6) & 3;
7006 rm
= (modrm
& 7) | REX_B(s
);
7007 gen_op_mov_TN_reg(MO_32
, 1, reg
);
7009 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7010 /* specific case: we need to add a displacement */
7011 gen_exts(ot
, cpu_T
[1]);
7012 tcg_gen_sari_tl(cpu_tmp0
, cpu_T
[1], 3 + ot
);
7013 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, ot
);
7014 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
7015 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
7017 gen_op_mov_TN_reg(ot
, 0, rm
);
7020 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], (1 << (3 + ot
)) - 1);
7023 tcg_gen_shr_tl(cpu_cc_src
, cpu_T
[0], cpu_T
[1]);
7024 tcg_gen_movi_tl(cpu_cc_dst
, 0);
7027 tcg_gen_shr_tl(cpu_tmp4
, cpu_T
[0], cpu_T
[1]);
7028 tcg_gen_movi_tl(cpu_tmp0
, 1);
7029 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
7030 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
7033 tcg_gen_shr_tl(cpu_tmp4
, cpu_T
[0], cpu_T
[1]);
7034 tcg_gen_movi_tl(cpu_tmp0
, 1);
7035 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
7036 tcg_gen_not_tl(cpu_tmp0
, cpu_tmp0
);
7037 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
7041 tcg_gen_shr_tl(cpu_tmp4
, cpu_T
[0], cpu_T
[1]);
7042 tcg_gen_movi_tl(cpu_tmp0
, 1);
7043 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
7044 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
7047 set_cc_op(s
, CC_OP_SARB
+ ot
);
7050 gen_op_st_T0_A0(s
, ot
);
7052 gen_op_mov_reg_T0(ot
, rm
);
7053 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
7054 tcg_gen_movi_tl(cpu_cc_dst
, 0);
7057 case 0x1bc: /* bsf / tzcnt */
7058 case 0x1bd: /* bsr / lzcnt */
7060 modrm
= cpu_ldub_code(env
, s
->pc
++);
7061 reg
= ((modrm
>> 3) & 7) | rex_r
;
7062 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
7063 gen_extu(ot
, cpu_T
[0]);
7065 /* Note that lzcnt and tzcnt are in different extensions. */
7066 if ((prefixes
& PREFIX_REPZ
)
7068 ? s
->cpuid_ext3_features
& CPUID_EXT3_ABM
7069 : s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)) {
7071 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
7073 /* For lzcnt, reduce the target_ulong result by the
7074 number of zeros that we expect to find at the top. */
7075 gen_helper_clz(cpu_T
[0], cpu_T
[0]);
7076 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], TARGET_LONG_BITS
- size
);
7078 /* For tzcnt, a zero input must return the operand size:
7079 force all bits outside the operand size to 1. */
7080 target_ulong mask
= (target_ulong
)-2 << (size
- 1);
7081 tcg_gen_ori_tl(cpu_T
[0], cpu_T
[0], mask
);
7082 gen_helper_ctz(cpu_T
[0], cpu_T
[0]);
7084 /* For lzcnt/tzcnt, C and Z bits are defined and are
7085 related to the result. */
7086 gen_op_update1_cc();
7087 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
7089 /* For bsr/bsf, only the Z bit is defined and it is related
7090 to the input and not the result. */
7091 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
7092 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
7094 /* For bsr, return the bit index of the first 1 bit,
7095 not the count of leading zeros. */
7096 gen_helper_clz(cpu_T
[0], cpu_T
[0]);
7097 tcg_gen_xori_tl(cpu_T
[0], cpu_T
[0], TARGET_LONG_BITS
- 1);
7099 gen_helper_ctz(cpu_T
[0], cpu_T
[0]);
7101 /* ??? The manual says that the output is undefined when the
7102 input is zero, but real hardware leaves it unchanged, and
7103 real programs appear to depend on that. */
7104 tcg_gen_movi_tl(cpu_tmp0
, 0);
7105 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_T
[0], cpu_cc_dst
, cpu_tmp0
,
7106 cpu_regs
[reg
], cpu_T
[0]);
7108 gen_op_mov_reg_T0(ot
, reg
);
7110 /************************/
7112 case 0x27: /* daa */
7115 gen_update_cc_op(s
);
7116 gen_helper_daa(cpu_env
);
7117 set_cc_op(s
, CC_OP_EFLAGS
);
7119 case 0x2f: /* das */
7122 gen_update_cc_op(s
);
7123 gen_helper_das(cpu_env
);
7124 set_cc_op(s
, CC_OP_EFLAGS
);
7126 case 0x37: /* aaa */
7129 gen_update_cc_op(s
);
7130 gen_helper_aaa(cpu_env
);
7131 set_cc_op(s
, CC_OP_EFLAGS
);
7133 case 0x3f: /* aas */
7136 gen_update_cc_op(s
);
7137 gen_helper_aas(cpu_env
);
7138 set_cc_op(s
, CC_OP_EFLAGS
);
7140 case 0xd4: /* aam */
7143 val
= cpu_ldub_code(env
, s
->pc
++);
7145 gen_exception(s
, EXCP00_DIVZ
, pc_start
- s
->cs_base
);
7147 gen_helper_aam(cpu_env
, tcg_const_i32(val
));
7148 set_cc_op(s
, CC_OP_LOGICB
);
7151 case 0xd5: /* aad */
7154 val
= cpu_ldub_code(env
, s
->pc
++);
7155 gen_helper_aad(cpu_env
, tcg_const_i32(val
));
7156 set_cc_op(s
, CC_OP_LOGICB
);
7158 /************************/
7160 case 0x90: /* nop */
7161 /* XXX: correct lock test for all insn */
7162 if (prefixes
& PREFIX_LOCK
) {
7165 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
7167 goto do_xchg_reg_eax
;
7169 if (prefixes
& PREFIX_REPZ
) {
7170 gen_update_cc_op(s
);
7171 gen_jmp_im(pc_start
- s
->cs_base
);
7172 gen_helper_pause(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7173 s
->is_jmp
= DISAS_TB_JUMP
;
7176 case 0x9b: /* fwait */
7177 if ((s
->flags
& (HF_MP_MASK
| HF_TS_MASK
)) ==
7178 (HF_MP_MASK
| HF_TS_MASK
)) {
7179 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7181 gen_update_cc_op(s
);
7182 gen_jmp_im(pc_start
- s
->cs_base
);
7183 gen_helper_fwait(cpu_env
);
7186 case 0xcc: /* int3 */
7187 gen_interrupt(s
, EXCP03_INT3
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
7189 case 0xcd: /* int N */
7190 val
= cpu_ldub_code(env
, s
->pc
++);
7191 if (s
->vm86
&& s
->iopl
!= 3) {
7192 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7194 gen_interrupt(s
, val
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
7197 case 0xce: /* into */
7200 gen_update_cc_op(s
);
7201 gen_jmp_im(pc_start
- s
->cs_base
);
7202 gen_helper_into(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7205 case 0xf1: /* icebp (undocumented, exits to external debugger) */
7206 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_ICEBP
);
7208 gen_debug(s
, pc_start
- s
->cs_base
);
7212 qemu_set_log(CPU_LOG_INT
| CPU_LOG_TB_IN_ASM
);
7216 case 0xfa: /* cli */
7218 if (s
->cpl
<= s
->iopl
) {
7219 gen_helper_cli(cpu_env
);
7221 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7225 gen_helper_cli(cpu_env
);
7227 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7231 case 0xfb: /* sti */
7233 if (s
->cpl
<= s
->iopl
) {
7235 gen_helper_sti(cpu_env
);
7236 /* interruptions are enabled only the first insn after sti */
7237 /* If several instructions disable interrupts, only the
7239 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
7240 gen_helper_set_inhibit_irq(cpu_env
);
7241 /* give a chance to handle pending irqs */
7242 gen_jmp_im(s
->pc
- s
->cs_base
);
7245 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7251 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7255 case 0x62: /* bound */
7258 ot
= dflag
? MO_32
: MO_16
;
7259 modrm
= cpu_ldub_code(env
, s
->pc
++);
7260 reg
= (modrm
>> 3) & 7;
7261 mod
= (modrm
>> 6) & 3;
7264 gen_op_mov_TN_reg(ot
, 0, reg
);
7265 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7266 gen_jmp_im(pc_start
- s
->cs_base
);
7267 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
7269 gen_helper_boundw(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
7271 gen_helper_boundl(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
7274 case 0x1c8 ... 0x1cf: /* bswap reg */
7275 reg
= (b
& 7) | REX_B(s
);
7276 #ifdef TARGET_X86_64
7278 gen_op_mov_TN_reg(MO_64
, 0, reg
);
7279 tcg_gen_bswap64_i64(cpu_T
[0], cpu_T
[0]);
7280 gen_op_mov_reg_T0(MO_64
, reg
);
7284 gen_op_mov_TN_reg(MO_32
, 0, reg
);
7285 tcg_gen_ext32u_tl(cpu_T
[0], cpu_T
[0]);
7286 tcg_gen_bswap32_tl(cpu_T
[0], cpu_T
[0]);
7287 gen_op_mov_reg_T0(MO_32
, reg
);
7290 case 0xd6: /* salc */
7293 gen_compute_eflags_c(s
, cpu_T
[0]);
7294 tcg_gen_neg_tl(cpu_T
[0], cpu_T
[0]);
7295 gen_op_mov_reg_T0(MO_8
, R_EAX
);
7297 case 0xe0: /* loopnz */
7298 case 0xe1: /* loopz */
7299 case 0xe2: /* loop */
7300 case 0xe3: /* jecxz */
7304 tval
= (int8_t)insn_get(env
, s
, MO_8
);
7305 next_eip
= s
->pc
- s
->cs_base
;
7310 l1
= gen_new_label();
7311 l2
= gen_new_label();
7312 l3
= gen_new_label();
7315 case 0: /* loopnz */
7317 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
7318 gen_op_jz_ecx(s
->aflag
, l3
);
7319 gen_jcc1(s
, (JCC_Z
<< 1) | (b
^ 1), l1
);
7322 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
7323 gen_op_jnz_ecx(s
->aflag
, l1
);
7327 gen_op_jz_ecx(s
->aflag
, l1
);
7332 gen_jmp_im(next_eip
);
7341 case 0x130: /* wrmsr */
7342 case 0x132: /* rdmsr */
7344 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7346 gen_update_cc_op(s
);
7347 gen_jmp_im(pc_start
- s
->cs_base
);
7349 gen_helper_rdmsr(cpu_env
);
7351 gen_helper_wrmsr(cpu_env
);
7355 case 0x131: /* rdtsc */
7356 gen_update_cc_op(s
);
7357 gen_jmp_im(pc_start
- s
->cs_base
);
7360 gen_helper_rdtsc(cpu_env
);
7363 gen_jmp(s
, s
->pc
- s
->cs_base
);
7366 case 0x133: /* rdpmc */
7367 gen_update_cc_op(s
);
7368 gen_jmp_im(pc_start
- s
->cs_base
);
7369 gen_helper_rdpmc(cpu_env
);
7371 case 0x134: /* sysenter */
7372 /* For Intel SYSENTER is valid on 64-bit */
7373 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7376 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7378 gen_update_cc_op(s
);
7379 gen_jmp_im(pc_start
- s
->cs_base
);
7380 gen_helper_sysenter(cpu_env
);
7384 case 0x135: /* sysexit */
7385 /* For Intel SYSEXIT is valid on 64-bit */
7386 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7389 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7391 gen_update_cc_op(s
);
7392 gen_jmp_im(pc_start
- s
->cs_base
);
7393 gen_helper_sysexit(cpu_env
, tcg_const_i32(dflag
));
7397 #ifdef TARGET_X86_64
7398 case 0x105: /* syscall */
7399 /* XXX: is it usable in real mode ? */
7400 gen_update_cc_op(s
);
7401 gen_jmp_im(pc_start
- s
->cs_base
);
7402 gen_helper_syscall(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7405 case 0x107: /* sysret */
7407 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7409 gen_update_cc_op(s
);
7410 gen_jmp_im(pc_start
- s
->cs_base
);
7411 gen_helper_sysret(cpu_env
, tcg_const_i32(s
->dflag
));
7412 /* condition codes are modified only in long mode */
7414 set_cc_op(s
, CC_OP_EFLAGS
);
7420 case 0x1a2: /* cpuid */
7421 gen_update_cc_op(s
);
7422 gen_jmp_im(pc_start
- s
->cs_base
);
7423 gen_helper_cpuid(cpu_env
);
7425 case 0xf4: /* hlt */
7427 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7429 gen_update_cc_op(s
);
7430 gen_jmp_im(pc_start
- s
->cs_base
);
7431 gen_helper_hlt(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7432 s
->is_jmp
= DISAS_TB_JUMP
;
7436 modrm
= cpu_ldub_code(env
, s
->pc
++);
7437 mod
= (modrm
>> 6) & 3;
7438 op
= (modrm
>> 3) & 7;
7441 if (!s
->pe
|| s
->vm86
)
7443 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_READ
);
7444 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,ldt
.selector
));
7448 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7451 if (!s
->pe
|| s
->vm86
)
7454 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7456 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_WRITE
);
7457 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7458 gen_jmp_im(pc_start
- s
->cs_base
);
7459 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
7460 gen_helper_lldt(cpu_env
, cpu_tmp2_i32
);
7464 if (!s
->pe
|| s
->vm86
)
7466 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_READ
);
7467 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,tr
.selector
));
7471 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7474 if (!s
->pe
|| s
->vm86
)
7477 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7479 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_WRITE
);
7480 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7481 gen_jmp_im(pc_start
- s
->cs_base
);
7482 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
7483 gen_helper_ltr(cpu_env
, cpu_tmp2_i32
);
7488 if (!s
->pe
|| s
->vm86
)
7490 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7491 gen_update_cc_op(s
);
7493 gen_helper_verr(cpu_env
, cpu_T
[0]);
7495 gen_helper_verw(cpu_env
, cpu_T
[0]);
7497 set_cc_op(s
, CC_OP_EFLAGS
);
7504 modrm
= cpu_ldub_code(env
, s
->pc
++);
7505 mod
= (modrm
>> 6) & 3;
7506 op
= (modrm
>> 3) & 7;
7512 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_READ
);
7513 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7514 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7515 gen_op_st_T0_A0(s
, MO_16
);
7516 gen_add_A0_im(s
, 2);
7517 tcg_gen_ld_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7519 gen_op_andl_T0_im(0xffffff);
7520 gen_op_st_T0_A0(s
, CODE64(s
) + MO_32
);
7525 case 0: /* monitor */
7526 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) ||
7529 gen_update_cc_op(s
);
7530 gen_jmp_im(pc_start
- s
->cs_base
);
7531 #ifdef TARGET_X86_64
7532 if (s
->aflag
== 2) {
7533 gen_op_movq_A0_reg(R_EAX
);
7537 gen_op_movl_A0_reg(R_EAX
);
7539 gen_op_andl_A0_ffff();
7541 gen_add_A0_ds_seg(s
);
7542 gen_helper_monitor(cpu_env
, cpu_A0
);
7545 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) ||
7548 gen_update_cc_op(s
);
7549 gen_jmp_im(pc_start
- s
->cs_base
);
7550 gen_helper_mwait(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7554 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
) ||
7558 gen_helper_clac(cpu_env
);
7559 gen_jmp_im(s
->pc
- s
->cs_base
);
7563 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
) ||
7567 gen_helper_stac(cpu_env
);
7568 gen_jmp_im(s
->pc
- s
->cs_base
);
7575 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_READ
);
7576 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7577 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7578 gen_op_st_T0_A0(s
, MO_16
);
7579 gen_add_A0_im(s
, 2);
7580 tcg_gen_ld_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, idt
.base
));
7582 gen_op_andl_T0_im(0xffffff);
7583 gen_op_st_T0_A0(s
, CODE64(s
) + MO_32
);
7589 gen_update_cc_op(s
);
7590 gen_jmp_im(pc_start
- s
->cs_base
);
7593 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7596 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7599 gen_helper_vmrun(cpu_env
, tcg_const_i32(s
->aflag
),
7600 tcg_const_i32(s
->pc
- pc_start
));
7602 s
->is_jmp
= DISAS_TB_JUMP
;
7605 case 1: /* VMMCALL */
7606 if (!(s
->flags
& HF_SVME_MASK
))
7608 gen_helper_vmmcall(cpu_env
);
7610 case 2: /* VMLOAD */
7611 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7614 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7617 gen_helper_vmload(cpu_env
, tcg_const_i32(s
->aflag
));
7620 case 3: /* VMSAVE */
7621 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7624 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7627 gen_helper_vmsave(cpu_env
, tcg_const_i32(s
->aflag
));
7631 if ((!(s
->flags
& HF_SVME_MASK
) &&
7632 !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
)) ||
7636 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7639 gen_helper_stgi(cpu_env
);
7643 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7646 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7649 gen_helper_clgi(cpu_env
);
7652 case 6: /* SKINIT */
7653 if ((!(s
->flags
& HF_SVME_MASK
) &&
7654 !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
)) ||
7657 gen_helper_skinit(cpu_env
);
7659 case 7: /* INVLPGA */
7660 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7663 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7666 gen_helper_invlpga(cpu_env
, tcg_const_i32(s
->aflag
));
7672 } else if (s
->cpl
!= 0) {
7673 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7675 gen_svm_check_intercept(s
, pc_start
,
7676 op
==2 ? SVM_EXIT_GDTR_WRITE
: SVM_EXIT_IDTR_WRITE
);
7677 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7678 gen_op_ld_v(s
, MO_16
, cpu_T
[1], cpu_A0
);
7679 gen_add_A0_im(s
, 2);
7680 gen_op_ld_v(s
, CODE64(s
) + MO_32
, cpu_T
[0], cpu_A0
);
7682 gen_op_andl_T0_im(0xffffff);
7684 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,gdt
.base
));
7685 tcg_gen_st32_tl(cpu_T
[1], cpu_env
, offsetof(CPUX86State
,gdt
.limit
));
7687 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,idt
.base
));
7688 tcg_gen_st32_tl(cpu_T
[1], cpu_env
, offsetof(CPUX86State
,idt
.limit
));
7693 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_CR0
);
7694 #if defined TARGET_X86_64 && defined HOST_WORDS_BIGENDIAN
7695 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,cr
[0]) + 4);
7697 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,cr
[0]));
7699 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 1);
7703 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7705 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7706 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7707 gen_helper_lmsw(cpu_env
, cpu_T
[0]);
7708 gen_jmp_im(s
->pc
- s
->cs_base
);
7713 if (mod
!= 3) { /* invlpg */
7715 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7717 gen_update_cc_op(s
);
7718 gen_jmp_im(pc_start
- s
->cs_base
);
7719 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7720 gen_helper_invlpg(cpu_env
, cpu_A0
);
7721 gen_jmp_im(s
->pc
- s
->cs_base
);
7726 case 0: /* swapgs */
7727 #ifdef TARGET_X86_64
7730 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7732 tcg_gen_ld_tl(cpu_T
[0], cpu_env
,
7733 offsetof(CPUX86State
,segs
[R_GS
].base
));
7734 tcg_gen_ld_tl(cpu_T
[1], cpu_env
,
7735 offsetof(CPUX86State
,kernelgsbase
));
7736 tcg_gen_st_tl(cpu_T
[1], cpu_env
,
7737 offsetof(CPUX86State
,segs
[R_GS
].base
));
7738 tcg_gen_st_tl(cpu_T
[0], cpu_env
,
7739 offsetof(CPUX86State
,kernelgsbase
));
7747 case 1: /* rdtscp */
7748 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_RDTSCP
))
7750 gen_update_cc_op(s
);
7751 gen_jmp_im(pc_start
- s
->cs_base
);
7754 gen_helper_rdtscp(cpu_env
);
7757 gen_jmp(s
, s
->pc
- s
->cs_base
);
7769 case 0x108: /* invd */
7770 case 0x109: /* wbinvd */
7772 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7774 gen_svm_check_intercept(s
, pc_start
, (b
& 2) ? SVM_EXIT_INVD
: SVM_EXIT_WBINVD
);
7778 case 0x63: /* arpl or movslS (x86_64) */
7779 #ifdef TARGET_X86_64
7782 /* d_ot is the size of destination */
7783 d_ot
= dflag
+ MO_16
;
7785 modrm
= cpu_ldub_code(env
, s
->pc
++);
7786 reg
= ((modrm
>> 3) & 7) | rex_r
;
7787 mod
= (modrm
>> 6) & 3;
7788 rm
= (modrm
& 7) | REX_B(s
);
7791 gen_op_mov_TN_reg(MO_32
, 0, rm
);
7793 if (d_ot
== MO_64
) {
7794 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
7796 gen_op_mov_reg_T0(d_ot
, reg
);
7798 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7799 if (d_ot
== MO_64
) {
7800 gen_op_lds_T0_A0(s
, MO_32
);
7802 gen_op_ld_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
7804 gen_op_mov_reg_T0(d_ot
, reg
);
7810 TCGv t0
, t1
, t2
, a0
;
7812 if (!s
->pe
|| s
->vm86
)
7814 t0
= tcg_temp_local_new();
7815 t1
= tcg_temp_local_new();
7816 t2
= tcg_temp_local_new();
7818 modrm
= cpu_ldub_code(env
, s
->pc
++);
7819 reg
= (modrm
>> 3) & 7;
7820 mod
= (modrm
>> 6) & 3;
7823 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7824 gen_op_ld_v(s
, ot
, t0
, cpu_A0
);
7825 a0
= tcg_temp_local_new();
7826 tcg_gen_mov_tl(a0
, cpu_A0
);
7828 gen_op_mov_v_reg(ot
, t0
, rm
);
7831 gen_op_mov_v_reg(ot
, t1
, reg
);
7832 tcg_gen_andi_tl(cpu_tmp0
, t0
, 3);
7833 tcg_gen_andi_tl(t1
, t1
, 3);
7834 tcg_gen_movi_tl(t2
, 0);
7835 label1
= gen_new_label();
7836 tcg_gen_brcond_tl(TCG_COND_GE
, cpu_tmp0
, t1
, label1
);
7837 tcg_gen_andi_tl(t0
, t0
, ~3);
7838 tcg_gen_or_tl(t0
, t0
, t1
);
7839 tcg_gen_movi_tl(t2
, CC_Z
);
7840 gen_set_label(label1
);
7842 gen_op_st_v(s
, ot
, t0
, a0
);
7845 gen_op_mov_reg_v(ot
, rm
, t0
);
7847 gen_compute_eflags(s
);
7848 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_Z
);
7849 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, t2
);
7855 case 0x102: /* lar */
7856 case 0x103: /* lsl */
7860 if (!s
->pe
|| s
->vm86
)
7862 ot
= dflag
? MO_32
: MO_16
;
7863 modrm
= cpu_ldub_code(env
, s
->pc
++);
7864 reg
= ((modrm
>> 3) & 7) | rex_r
;
7865 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7866 t0
= tcg_temp_local_new();
7867 gen_update_cc_op(s
);
7869 gen_helper_lar(t0
, cpu_env
, cpu_T
[0]);
7871 gen_helper_lsl(t0
, cpu_env
, cpu_T
[0]);
7873 tcg_gen_andi_tl(cpu_tmp0
, cpu_cc_src
, CC_Z
);
7874 label1
= gen_new_label();
7875 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
7876 gen_op_mov_reg_v(ot
, reg
, t0
);
7877 gen_set_label(label1
);
7878 set_cc_op(s
, CC_OP_EFLAGS
);
7883 modrm
= cpu_ldub_code(env
, s
->pc
++);
7884 mod
= (modrm
>> 6) & 3;
7885 op
= (modrm
>> 3) & 7;
7887 case 0: /* prefetchnta */
7888 case 1: /* prefetchnt0 */
7889 case 2: /* prefetchnt0 */
7890 case 3: /* prefetchnt0 */
7893 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7894 /* nothing more to do */
7896 default: /* nop (multi byte) */
7897 gen_nop_modrm(env
, s
, modrm
);
7901 case 0x119 ... 0x11f: /* nop (multi byte) */
7902 modrm
= cpu_ldub_code(env
, s
->pc
++);
7903 gen_nop_modrm(env
, s
, modrm
);
7905 case 0x120: /* mov reg, crN */
7906 case 0x122: /* mov crN, reg */
7908 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7910 modrm
= cpu_ldub_code(env
, s
->pc
++);
7911 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7912 * AMD documentation (24594.pdf) and testing of
7913 * intel 386 and 486 processors all show that the mod bits
7914 * are assumed to be 1's, regardless of actual values.
7916 rm
= (modrm
& 7) | REX_B(s
);
7917 reg
= ((modrm
>> 3) & 7) | rex_r
;
7922 if ((prefixes
& PREFIX_LOCK
) && (reg
== 0) &&
7923 (s
->cpuid_ext3_features
& CPUID_EXT3_CR8LEG
)) {
7932 gen_update_cc_op(s
);
7933 gen_jmp_im(pc_start
- s
->cs_base
);
7935 gen_op_mov_TN_reg(ot
, 0, rm
);
7936 gen_helper_write_crN(cpu_env
, tcg_const_i32(reg
),
7938 gen_jmp_im(s
->pc
- s
->cs_base
);
7941 gen_helper_read_crN(cpu_T
[0], cpu_env
, tcg_const_i32(reg
));
7942 gen_op_mov_reg_T0(ot
, rm
);
7950 case 0x121: /* mov reg, drN */
7951 case 0x123: /* mov drN, reg */
7953 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7955 modrm
= cpu_ldub_code(env
, s
->pc
++);
7956 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7957 * AMD documentation (24594.pdf) and testing of
7958 * intel 386 and 486 processors all show that the mod bits
7959 * are assumed to be 1's, regardless of actual values.
7961 rm
= (modrm
& 7) | REX_B(s
);
7962 reg
= ((modrm
>> 3) & 7) | rex_r
;
7967 /* XXX: do it dynamically with CR4.DE bit */
7968 if (reg
== 4 || reg
== 5 || reg
>= 8)
7971 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_DR0
+ reg
);
7972 gen_op_mov_TN_reg(ot
, 0, rm
);
7973 gen_helper_movl_drN_T0(cpu_env
, tcg_const_i32(reg
), cpu_T
[0]);
7974 gen_jmp_im(s
->pc
- s
->cs_base
);
7977 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_DR0
+ reg
);
7978 tcg_gen_ld_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,dr
[reg
]));
7979 gen_op_mov_reg_T0(ot
, rm
);
7983 case 0x106: /* clts */
7985 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7987 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7988 gen_helper_clts(cpu_env
);
7989 /* abort block because static cpu state changed */
7990 gen_jmp_im(s
->pc
- s
->cs_base
);
7994 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
7995 case 0x1c3: /* MOVNTI reg, mem */
7996 if (!(s
->cpuid_features
& CPUID_SSE2
))
7998 ot
= s
->dflag
== 2 ? MO_64
: MO_32
;
7999 modrm
= cpu_ldub_code(env
, s
->pc
++);
8000 mod
= (modrm
>> 6) & 3;
8003 reg
= ((modrm
>> 3) & 7) | rex_r
;
8004 /* generate a generic store */
8005 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
8008 modrm
= cpu_ldub_code(env
, s
->pc
++);
8009 mod
= (modrm
>> 6) & 3;
8010 op
= (modrm
>> 3) & 7;
8012 case 0: /* fxsave */
8013 if (mod
== 3 || !(s
->cpuid_features
& CPUID_FXSR
) ||
8014 (s
->prefix
& PREFIX_LOCK
))
8016 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
8017 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8020 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
8021 gen_update_cc_op(s
);
8022 gen_jmp_im(pc_start
- s
->cs_base
);
8023 gen_helper_fxsave(cpu_env
, cpu_A0
, tcg_const_i32((s
->dflag
== 2)));
8025 case 1: /* fxrstor */
8026 if (mod
== 3 || !(s
->cpuid_features
& CPUID_FXSR
) ||
8027 (s
->prefix
& PREFIX_LOCK
))
8029 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
8030 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8033 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
8034 gen_update_cc_op(s
);
8035 gen_jmp_im(pc_start
- s
->cs_base
);
8036 gen_helper_fxrstor(cpu_env
, cpu_A0
,
8037 tcg_const_i32((s
->dflag
== 2)));
8039 case 2: /* ldmxcsr */
8040 case 3: /* stmxcsr */
8041 if (s
->flags
& HF_TS_MASK
) {
8042 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8045 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
) ||
8048 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
8050 gen_op_ld_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
8051 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
8052 gen_helper_ldmxcsr(cpu_env
, cpu_tmp2_i32
);
8054 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, mxcsr
));
8055 gen_op_st_T0_A0(s
, MO_32
);
8058 case 5: /* lfence */
8059 case 6: /* mfence */
8060 if ((modrm
& 0xc7) != 0xc0 || !(s
->cpuid_features
& CPUID_SSE2
))
8063 case 7: /* sfence / clflush */
8064 if ((modrm
& 0xc7) == 0xc0) {
8066 /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX */
8067 if (!(s
->cpuid_features
& CPUID_SSE
))
8071 if (!(s
->cpuid_features
& CPUID_CLFLUSH
))
8073 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
8080 case 0x10d: /* 3DNow! prefetch(w) */
8081 modrm
= cpu_ldub_code(env
, s
->pc
++);
8082 mod
= (modrm
>> 6) & 3;
8085 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
8086 /* ignore for now */
8088 case 0x1aa: /* rsm */
8089 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_RSM
);
8090 if (!(s
->flags
& HF_SMM_MASK
))
8092 gen_update_cc_op(s
);
8093 gen_jmp_im(s
->pc
- s
->cs_base
);
8094 gen_helper_rsm(cpu_env
);
8097 case 0x1b8: /* SSE4.2 popcnt */
8098 if ((prefixes
& (PREFIX_REPZ
| PREFIX_LOCK
| PREFIX_REPNZ
)) !=
8101 if (!(s
->cpuid_ext_features
& CPUID_EXT_POPCNT
))
8104 modrm
= cpu_ldub_code(env
, s
->pc
++);
8105 reg
= ((modrm
>> 3) & 7) | rex_r
;
8107 if (s
->prefix
& PREFIX_DATA
)
8109 else if (s
->dflag
!= 2)
8114 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
8115 gen_helper_popcnt(cpu_T
[0], cpu_env
, cpu_T
[0], tcg_const_i32(ot
));
8116 gen_op_mov_reg_T0(ot
, reg
);
8118 set_cc_op(s
, CC_OP_EFLAGS
);
8120 case 0x10e ... 0x10f:
8121 /* 3DNow! instructions, ignore prefixes */
8122 s
->prefix
&= ~(PREFIX_REPZ
| PREFIX_REPNZ
| PREFIX_DATA
);
8123 case 0x110 ... 0x117:
8124 case 0x128 ... 0x12f:
8125 case 0x138 ... 0x13a:
8126 case 0x150 ... 0x179:
8127 case 0x17c ... 0x17f:
8129 case 0x1c4 ... 0x1c6:
8130 case 0x1d0 ... 0x1fe:
8131 gen_sse(env
, s
, b
, pc_start
, rex_r
);
8136 /* lock generation */
8137 if (s
->prefix
& PREFIX_LOCK
)
8138 gen_helper_unlock();
8141 if (s
->prefix
& PREFIX_LOCK
)
8142 gen_helper_unlock();
8143 /* XXX: ensure that no lock was generated */
8144 gen_exception(s
, EXCP06_ILLOP
, pc_start
- s
->cs_base
);
8148 void optimize_flags_init(void)
8150 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
8151 cpu_cc_op
= tcg_global_mem_new_i32(TCG_AREG0
,
8152 offsetof(CPUX86State
, cc_op
), "cc_op");
8153 cpu_cc_dst
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_dst
),
8155 cpu_cc_src
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_src
),
8157 cpu_cc_src2
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_src2
),
8160 #ifdef TARGET_X86_64
8161 cpu_regs
[R_EAX
] = tcg_global_mem_new_i64(TCG_AREG0
,
8162 offsetof(CPUX86State
, regs
[R_EAX
]), "rax");
8163 cpu_regs
[R_ECX
] = tcg_global_mem_new_i64(TCG_AREG0
,
8164 offsetof(CPUX86State
, regs
[R_ECX
]), "rcx");
8165 cpu_regs
[R_EDX
] = tcg_global_mem_new_i64(TCG_AREG0
,
8166 offsetof(CPUX86State
, regs
[R_EDX
]), "rdx");
8167 cpu_regs
[R_EBX
] = tcg_global_mem_new_i64(TCG_AREG0
,
8168 offsetof(CPUX86State
, regs
[R_EBX
]), "rbx");
8169 cpu_regs
[R_ESP
] = tcg_global_mem_new_i64(TCG_AREG0
,
8170 offsetof(CPUX86State
, regs
[R_ESP
]), "rsp");
8171 cpu_regs
[R_EBP
] = tcg_global_mem_new_i64(TCG_AREG0
,
8172 offsetof(CPUX86State
, regs
[R_EBP
]), "rbp");
8173 cpu_regs
[R_ESI
] = tcg_global_mem_new_i64(TCG_AREG0
,
8174 offsetof(CPUX86State
, regs
[R_ESI
]), "rsi");
8175 cpu_regs
[R_EDI
] = tcg_global_mem_new_i64(TCG_AREG0
,
8176 offsetof(CPUX86State
, regs
[R_EDI
]), "rdi");
8177 cpu_regs
[8] = tcg_global_mem_new_i64(TCG_AREG0
,
8178 offsetof(CPUX86State
, regs
[8]), "r8");
8179 cpu_regs
[9] = tcg_global_mem_new_i64(TCG_AREG0
,
8180 offsetof(CPUX86State
, regs
[9]), "r9");
8181 cpu_regs
[10] = tcg_global_mem_new_i64(TCG_AREG0
,
8182 offsetof(CPUX86State
, regs
[10]), "r10");
8183 cpu_regs
[11] = tcg_global_mem_new_i64(TCG_AREG0
,
8184 offsetof(CPUX86State
, regs
[11]), "r11");
8185 cpu_regs
[12] = tcg_global_mem_new_i64(TCG_AREG0
,
8186 offsetof(CPUX86State
, regs
[12]), "r12");
8187 cpu_regs
[13] = tcg_global_mem_new_i64(TCG_AREG0
,
8188 offsetof(CPUX86State
, regs
[13]), "r13");
8189 cpu_regs
[14] = tcg_global_mem_new_i64(TCG_AREG0
,
8190 offsetof(CPUX86State
, regs
[14]), "r14");
8191 cpu_regs
[15] = tcg_global_mem_new_i64(TCG_AREG0
,
8192 offsetof(CPUX86State
, regs
[15]), "r15");
8194 cpu_regs
[R_EAX
] = tcg_global_mem_new_i32(TCG_AREG0
,
8195 offsetof(CPUX86State
, regs
[R_EAX
]), "eax");
8196 cpu_regs
[R_ECX
] = tcg_global_mem_new_i32(TCG_AREG0
,
8197 offsetof(CPUX86State
, regs
[R_ECX
]), "ecx");
8198 cpu_regs
[R_EDX
] = tcg_global_mem_new_i32(TCG_AREG0
,
8199 offsetof(CPUX86State
, regs
[R_EDX
]), "edx");
8200 cpu_regs
[R_EBX
] = tcg_global_mem_new_i32(TCG_AREG0
,
8201 offsetof(CPUX86State
, regs
[R_EBX
]), "ebx");
8202 cpu_regs
[R_ESP
] = tcg_global_mem_new_i32(TCG_AREG0
,
8203 offsetof(CPUX86State
, regs
[R_ESP
]), "esp");
8204 cpu_regs
[R_EBP
] = tcg_global_mem_new_i32(TCG_AREG0
,
8205 offsetof(CPUX86State
, regs
[R_EBP
]), "ebp");
8206 cpu_regs
[R_ESI
] = tcg_global_mem_new_i32(TCG_AREG0
,
8207 offsetof(CPUX86State
, regs
[R_ESI
]), "esi");
8208 cpu_regs
[R_EDI
] = tcg_global_mem_new_i32(TCG_AREG0
,
8209 offsetof(CPUX86State
, regs
[R_EDI
]), "edi");
8213 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
8214 basic block 'tb'. If search_pc is TRUE, also generate PC
8215 information for each intermediate instruction. */
8216 static inline void gen_intermediate_code_internal(X86CPU
*cpu
,
8217 TranslationBlock
*tb
,
8220 CPUState
*cs
= CPU(cpu
);
8221 CPUX86State
*env
= &cpu
->env
;
8222 DisasContext dc1
, *dc
= &dc1
;
8223 target_ulong pc_ptr
;
8224 uint16_t *gen_opc_end
;
8228 target_ulong pc_start
;
8229 target_ulong cs_base
;
8233 /* generate intermediate code */
8235 cs_base
= tb
->cs_base
;
8238 dc
->pe
= (flags
>> HF_PE_SHIFT
) & 1;
8239 dc
->code32
= (flags
>> HF_CS32_SHIFT
) & 1;
8240 dc
->ss32
= (flags
>> HF_SS32_SHIFT
) & 1;
8241 dc
->addseg
= (flags
>> HF_ADDSEG_SHIFT
) & 1;
8243 dc
->vm86
= (flags
>> VM_SHIFT
) & 1;
8244 dc
->cpl
= (flags
>> HF_CPL_SHIFT
) & 3;
8245 dc
->iopl
= (flags
>> IOPL_SHIFT
) & 3;
8246 dc
->tf
= (flags
>> TF_SHIFT
) & 1;
8247 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
8248 dc
->cc_op
= CC_OP_DYNAMIC
;
8249 dc
->cc_op_dirty
= false;
8250 dc
->cs_base
= cs_base
;
8252 dc
->popl_esp_hack
= 0;
8253 /* select memory access functions */
8255 if (flags
& HF_SOFTMMU_MASK
) {
8256 dc
->mem_index
= cpu_mmu_index(env
);
8258 dc
->cpuid_features
= env
->features
[FEAT_1_EDX
];
8259 dc
->cpuid_ext_features
= env
->features
[FEAT_1_ECX
];
8260 dc
->cpuid_ext2_features
= env
->features
[FEAT_8000_0001_EDX
];
8261 dc
->cpuid_ext3_features
= env
->features
[FEAT_8000_0001_ECX
];
8262 dc
->cpuid_7_0_ebx_features
= env
->features
[FEAT_7_0_EBX
];
8263 #ifdef TARGET_X86_64
8264 dc
->lma
= (flags
>> HF_LMA_SHIFT
) & 1;
8265 dc
->code64
= (flags
>> HF_CS64_SHIFT
) & 1;
8268 dc
->jmp_opt
= !(dc
->tf
|| cs
->singlestep_enabled
||
8269 (flags
& HF_INHIBIT_IRQ_MASK
)
8270 #ifndef CONFIG_SOFTMMU
8271 || (flags
& HF_SOFTMMU_MASK
)
8275 /* check addseg logic */
8276 if (!dc
->addseg
&& (dc
->vm86
|| !dc
->pe
|| !dc
->code32
))
8277 printf("ERROR addseg\n");
8280 cpu_T
[0] = tcg_temp_new();
8281 cpu_T
[1] = tcg_temp_new();
8282 cpu_A0
= tcg_temp_new();
8284 cpu_tmp0
= tcg_temp_new();
8285 cpu_tmp1_i64
= tcg_temp_new_i64();
8286 cpu_tmp2_i32
= tcg_temp_new_i32();
8287 cpu_tmp3_i32
= tcg_temp_new_i32();
8288 cpu_tmp4
= tcg_temp_new();
8289 cpu_ptr0
= tcg_temp_new_ptr();
8290 cpu_ptr1
= tcg_temp_new_ptr();
8291 cpu_cc_srcT
= tcg_temp_local_new();
8293 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
8295 dc
->is_jmp
= DISAS_NEXT
;
8299 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
8301 max_insns
= CF_COUNT_MASK
;
8305 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
8306 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
8307 if (bp
->pc
== pc_ptr
&&
8308 !((bp
->flags
& BP_CPU
) && (tb
->flags
& HF_RF_MASK
))) {
8309 gen_debug(dc
, pc_ptr
- dc
->cs_base
);
8315 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
8319 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
8321 tcg_ctx
.gen_opc_pc
[lj
] = pc_ptr
;
8322 gen_opc_cc_op
[lj
] = dc
->cc_op
;
8323 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
8324 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
8326 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
8329 pc_ptr
= disas_insn(env
, dc
, pc_ptr
);
8331 /* stop translation if indicated */
8334 /* if single step mode, we generate only one instruction and
8335 generate an exception */
8336 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
8337 the flag and abort the translation to give the irqs a
8338 change to be happen */
8339 if (dc
->tf
|| dc
->singlestep_enabled
||
8340 (flags
& HF_INHIBIT_IRQ_MASK
)) {
8341 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8345 /* if too long translation, stop generation too */
8346 if (tcg_ctx
.gen_opc_ptr
>= gen_opc_end
||
8347 (pc_ptr
- pc_start
) >= (TARGET_PAGE_SIZE
- 32) ||
8348 num_insns
>= max_insns
) {
8349 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8354 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8359 if (tb
->cflags
& CF_LAST_IO
)
8361 gen_tb_end(tb
, num_insns
);
8362 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
8363 /* we don't forget to fill the last values */
8365 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
8368 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
8372 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
8374 qemu_log("----------------\n");
8375 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
8376 #ifdef TARGET_X86_64
8381 disas_flags
= !dc
->code32
;
8382 log_target_disas(env
, pc_start
, pc_ptr
- pc_start
, disas_flags
);
8388 tb
->size
= pc_ptr
- pc_start
;
8389 tb
->icount
= num_insns
;
8393 void gen_intermediate_code(CPUX86State
*env
, TranslationBlock
*tb
)
8395 gen_intermediate_code_internal(x86_env_get_cpu(env
), tb
, false);
8398 void gen_intermediate_code_pc(CPUX86State
*env
, TranslationBlock
*tb
)
8400 gen_intermediate_code_internal(x86_env_get_cpu(env
), tb
, true);
8403 void restore_state_to_opc(CPUX86State
*env
, TranslationBlock
*tb
, int pc_pos
)
8407 if (qemu_loglevel_mask(CPU_LOG_TB_OP
)) {
8409 qemu_log("RESTORE:\n");
8410 for(i
= 0;i
<= pc_pos
; i
++) {
8411 if (tcg_ctx
.gen_opc_instr_start
[i
]) {
8412 qemu_log("0x%04x: " TARGET_FMT_lx
"\n", i
,
8413 tcg_ctx
.gen_opc_pc
[i
]);
8416 qemu_log("pc_pos=0x%x eip=" TARGET_FMT_lx
" cs_base=%x\n",
8417 pc_pos
, tcg_ctx
.gen_opc_pc
[pc_pos
] - tb
->cs_base
,
8418 (uint32_t)tb
->cs_base
);
8421 env
->eip
= tcg_ctx
.gen_opc_pc
[pc_pos
] - tb
->cs_base
;
8422 cc_op
= gen_opc_cc_op
[pc_pos
];
8423 if (cc_op
!= CC_OP_DYNAMIC
)