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_ld_T1_A0(DisasContext
*s
, int idx
)
591 gen_op_ld_v(s
, idx
, cpu_T
[1], cpu_A0
);
594 static inline void gen_op_st_v(DisasContext
*s
, int idx
, TCGv t0
, TCGv a0
)
596 tcg_gen_qemu_st_tl(t0
, a0
, s
->mem_index
, idx
| MO_LE
);
599 static inline void gen_op_st_T0_A0(DisasContext
*s
, int idx
)
601 gen_op_st_v(s
, idx
, cpu_T
[0], cpu_A0
);
604 static inline void gen_op_st_T1_A0(DisasContext
*s
, int idx
)
606 gen_op_st_v(s
, idx
, cpu_T
[1], cpu_A0
);
609 static inline void gen_jmp_im(target_ulong pc
)
611 tcg_gen_movi_tl(cpu_tmp0
, pc
);
612 tcg_gen_st_tl(cpu_tmp0
, cpu_env
, offsetof(CPUX86State
, eip
));
615 static inline void gen_string_movl_A0_ESI(DisasContext
*s
)
619 override
= s
->override
;
623 gen_op_movq_A0_seg(override
);
624 gen_op_addq_A0_reg_sN(0, R_ESI
);
626 gen_op_movq_A0_reg(R_ESI
);
632 if (s
->addseg
&& override
< 0)
635 gen_op_movl_A0_seg(override
);
636 gen_op_addl_A0_reg_sN(0, R_ESI
);
638 gen_op_movl_A0_reg(R_ESI
);
641 /* 16 address, always override */
644 gen_op_movl_A0_reg(R_ESI
);
645 gen_op_andl_A0_ffff();
646 gen_op_addl_A0_seg(s
, override
);
650 static inline void gen_string_movl_A0_EDI(DisasContext
*s
)
654 gen_op_movq_A0_reg(R_EDI
);
659 gen_op_movl_A0_seg(R_ES
);
660 gen_op_addl_A0_reg_sN(0, R_EDI
);
662 gen_op_movl_A0_reg(R_EDI
);
665 gen_op_movl_A0_reg(R_EDI
);
666 gen_op_andl_A0_ffff();
667 gen_op_addl_A0_seg(s
, R_ES
);
671 static inline void gen_op_movl_T0_Dshift(int ot
)
673 tcg_gen_ld32s_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, df
));
674 tcg_gen_shli_tl(cpu_T
[0], cpu_T
[0], ot
);
677 static TCGv
gen_ext_tl(TCGv dst
, TCGv src
, int size
, bool sign
)
682 tcg_gen_ext8s_tl(dst
, src
);
684 tcg_gen_ext8u_tl(dst
, src
);
689 tcg_gen_ext16s_tl(dst
, src
);
691 tcg_gen_ext16u_tl(dst
, src
);
697 tcg_gen_ext32s_tl(dst
, src
);
699 tcg_gen_ext32u_tl(dst
, src
);
708 static void gen_extu(int ot
, TCGv reg
)
710 gen_ext_tl(reg
, reg
, ot
, false);
713 static void gen_exts(int ot
, TCGv reg
)
715 gen_ext_tl(reg
, reg
, ot
, true);
718 static inline void gen_op_jnz_ecx(int size
, int label1
)
720 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[R_ECX
]);
721 gen_extu(size
+ 1, cpu_tmp0
);
722 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_tmp0
, 0, label1
);
725 static inline void gen_op_jz_ecx(int size
, int label1
)
727 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[R_ECX
]);
728 gen_extu(size
+ 1, cpu_tmp0
);
729 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
732 static void gen_helper_in_func(int ot
, TCGv v
, TCGv_i32 n
)
736 gen_helper_inb(v
, n
);
739 gen_helper_inw(v
, n
);
742 gen_helper_inl(v
, n
);
747 static void gen_helper_out_func(int ot
, TCGv_i32 v
, TCGv_i32 n
)
751 gen_helper_outb(v
, n
);
754 gen_helper_outw(v
, n
);
757 gen_helper_outl(v
, n
);
762 static void gen_check_io(DisasContext
*s
, int ot
, target_ulong cur_eip
,
766 target_ulong next_eip
;
769 if (s
->pe
&& (s
->cpl
> s
->iopl
|| s
->vm86
)) {
773 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
776 gen_helper_check_iob(cpu_env
, cpu_tmp2_i32
);
779 gen_helper_check_iow(cpu_env
, cpu_tmp2_i32
);
782 gen_helper_check_iol(cpu_env
, cpu_tmp2_i32
);
786 if(s
->flags
& HF_SVMI_MASK
) {
791 svm_flags
|= (1 << (4 + ot
));
792 next_eip
= s
->pc
- s
->cs_base
;
793 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
794 gen_helper_svm_check_io(cpu_env
, cpu_tmp2_i32
,
795 tcg_const_i32(svm_flags
),
796 tcg_const_i32(next_eip
- cur_eip
));
800 static inline void gen_movs(DisasContext
*s
, int ot
)
802 gen_string_movl_A0_ESI(s
);
803 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
804 gen_string_movl_A0_EDI(s
);
805 gen_op_st_T0_A0(s
, ot
);
806 gen_op_movl_T0_Dshift(ot
);
807 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
808 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
811 static void gen_op_update1_cc(void)
813 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
816 static void gen_op_update2_cc(void)
818 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
819 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
822 static void gen_op_update3_cc(TCGv reg
)
824 tcg_gen_mov_tl(cpu_cc_src2
, reg
);
825 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
826 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
829 static inline void gen_op_testl_T0_T1_cc(void)
831 tcg_gen_and_tl(cpu_cc_dst
, cpu_T
[0], cpu_T
[1]);
834 static void gen_op_update_neg_cc(void)
836 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
837 tcg_gen_neg_tl(cpu_cc_src
, cpu_T
[0]);
838 tcg_gen_movi_tl(cpu_cc_srcT
, 0);
841 /* compute all eflags to cc_src */
842 static void gen_compute_eflags(DisasContext
*s
)
844 TCGv zero
, dst
, src1
, src2
;
847 if (s
->cc_op
== CC_OP_EFLAGS
) {
850 if (s
->cc_op
== CC_OP_CLR
) {
851 tcg_gen_movi_tl(cpu_cc_src
, CC_Z
);
852 set_cc_op(s
, CC_OP_EFLAGS
);
861 /* Take care to not read values that are not live. */
862 live
= cc_op_live
[s
->cc_op
] & ~USES_CC_SRCT
;
863 dead
= live
^ (USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
);
865 zero
= tcg_const_tl(0);
866 if (dead
& USES_CC_DST
) {
869 if (dead
& USES_CC_SRC
) {
872 if (dead
& USES_CC_SRC2
) {
878 gen_helper_cc_compute_all(cpu_cc_src
, dst
, src1
, src2
, cpu_cc_op
);
879 set_cc_op(s
, CC_OP_EFLAGS
);
886 typedef struct CCPrepare
{
896 /* compute eflags.C to reg */
897 static CCPrepare
gen_prepare_eflags_c(DisasContext
*s
, TCGv reg
)
903 case CC_OP_SUBB
... CC_OP_SUBQ
:
904 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
905 size
= s
->cc_op
- CC_OP_SUBB
;
906 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
907 /* If no temporary was used, be careful not to alias t1 and t0. */
908 t0
= TCGV_EQUAL(t1
, cpu_cc_src
) ? cpu_tmp0
: reg
;
909 tcg_gen_mov_tl(t0
, cpu_cc_srcT
);
913 case CC_OP_ADDB
... CC_OP_ADDQ
:
914 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
915 size
= s
->cc_op
- CC_OP_ADDB
;
916 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
917 t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
919 return (CCPrepare
) { .cond
= TCG_COND_LTU
, .reg
= t0
,
920 .reg2
= t1
, .mask
= -1, .use_reg2
= true };
922 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
924 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
926 case CC_OP_INCB
... CC_OP_INCQ
:
927 case CC_OP_DECB
... CC_OP_DECQ
:
928 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
929 .mask
= -1, .no_setcond
= true };
931 case CC_OP_SHLB
... CC_OP_SHLQ
:
932 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
933 size
= s
->cc_op
- CC_OP_SHLB
;
934 shift
= (8 << size
) - 1;
935 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
936 .mask
= (target_ulong
)1 << shift
};
938 case CC_OP_MULB
... CC_OP_MULQ
:
939 return (CCPrepare
) { .cond
= TCG_COND_NE
,
940 .reg
= cpu_cc_src
, .mask
= -1 };
942 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
943 size
= s
->cc_op
- CC_OP_BMILGB
;
944 t0
= gen_ext_tl(reg
, cpu_cc_src
, size
, false);
945 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
949 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_dst
,
950 .mask
= -1, .no_setcond
= true };
953 case CC_OP_SARB
... CC_OP_SARQ
:
955 return (CCPrepare
) { .cond
= TCG_COND_NE
,
956 .reg
= cpu_cc_src
, .mask
= CC_C
};
959 /* The need to compute only C from CC_OP_DYNAMIC is important
960 in efficiently implementing e.g. INC at the start of a TB. */
962 gen_helper_cc_compute_c(reg
, cpu_cc_dst
, cpu_cc_src
,
963 cpu_cc_src2
, cpu_cc_op
);
964 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
965 .mask
= -1, .no_setcond
= true };
969 /* compute eflags.P to reg */
970 static CCPrepare
gen_prepare_eflags_p(DisasContext
*s
, TCGv reg
)
972 gen_compute_eflags(s
);
973 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
977 /* compute eflags.S to reg */
978 static CCPrepare
gen_prepare_eflags_s(DisasContext
*s
, TCGv reg
)
982 gen_compute_eflags(s
);
988 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
991 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
994 int size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
995 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, true);
996 return (CCPrepare
) { .cond
= TCG_COND_LT
, .reg
= t0
, .mask
= -1 };
1001 /* compute eflags.O to reg */
1002 static CCPrepare
gen_prepare_eflags_o(DisasContext
*s
, TCGv reg
)
1007 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src2
,
1008 .mask
= -1, .no_setcond
= true };
1010 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
1012 gen_compute_eflags(s
);
1013 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
1018 /* compute eflags.Z to reg */
1019 static CCPrepare
gen_prepare_eflags_z(DisasContext
*s
, TCGv reg
)
1023 gen_compute_eflags(s
);
1029 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
1032 return (CCPrepare
) { .cond
= TCG_COND_ALWAYS
, .mask
= -1 };
1035 int size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
1036 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
1037 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
1042 /* perform a conditional store into register 'reg' according to jump opcode
1043 value 'b'. In the fast case, T0 is guaranted not to be used. */
1044 static CCPrepare
gen_prepare_cc(DisasContext
*s
, int b
, TCGv reg
)
1046 int inv
, jcc_op
, size
, cond
;
1051 jcc_op
= (b
>> 1) & 7;
1054 case CC_OP_SUBB
... CC_OP_SUBQ
:
1055 /* We optimize relational operators for the cmp/jcc case. */
1056 size
= s
->cc_op
- CC_OP_SUBB
;
1059 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
1060 gen_extu(size
, cpu_tmp4
);
1061 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
1062 cc
= (CCPrepare
) { .cond
= TCG_COND_LEU
, .reg
= cpu_tmp4
,
1063 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
1072 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
1073 gen_exts(size
, cpu_tmp4
);
1074 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, true);
1075 cc
= (CCPrepare
) { .cond
= cond
, .reg
= cpu_tmp4
,
1076 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
1086 /* This actually generates good code for JC, JZ and JS. */
1089 cc
= gen_prepare_eflags_o(s
, reg
);
1092 cc
= gen_prepare_eflags_c(s
, reg
);
1095 cc
= gen_prepare_eflags_z(s
, reg
);
1098 gen_compute_eflags(s
);
1099 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
1100 .mask
= CC_Z
| CC_C
};
1103 cc
= gen_prepare_eflags_s(s
, reg
);
1106 cc
= gen_prepare_eflags_p(s
, reg
);
1109 gen_compute_eflags(s
);
1110 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
1113 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
1114 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
1115 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
1120 gen_compute_eflags(s
);
1121 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
1124 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
1125 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
1126 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
1127 .mask
= CC_S
| CC_Z
};
1134 cc
.cond
= tcg_invert_cond(cc
.cond
);
1139 static void gen_setcc1(DisasContext
*s
, int b
, TCGv reg
)
1141 CCPrepare cc
= gen_prepare_cc(s
, b
, reg
);
1143 if (cc
.no_setcond
) {
1144 if (cc
.cond
== TCG_COND_EQ
) {
1145 tcg_gen_xori_tl(reg
, cc
.reg
, 1);
1147 tcg_gen_mov_tl(reg
, cc
.reg
);
1152 if (cc
.cond
== TCG_COND_NE
&& !cc
.use_reg2
&& cc
.imm
== 0 &&
1153 cc
.mask
!= 0 && (cc
.mask
& (cc
.mask
- 1)) == 0) {
1154 tcg_gen_shri_tl(reg
, cc
.reg
, ctztl(cc
.mask
));
1155 tcg_gen_andi_tl(reg
, reg
, 1);
1158 if (cc
.mask
!= -1) {
1159 tcg_gen_andi_tl(reg
, cc
.reg
, cc
.mask
);
1163 tcg_gen_setcond_tl(cc
.cond
, reg
, cc
.reg
, cc
.reg2
);
1165 tcg_gen_setcondi_tl(cc
.cond
, reg
, cc
.reg
, cc
.imm
);
1169 static inline void gen_compute_eflags_c(DisasContext
*s
, TCGv reg
)
1171 gen_setcc1(s
, JCC_B
<< 1, reg
);
1174 /* generate a conditional jump to label 'l1' according to jump opcode
1175 value 'b'. In the fast case, T0 is guaranted not to be used. */
1176 static inline void gen_jcc1_noeob(DisasContext
*s
, int b
, int l1
)
1178 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T
[0]);
1180 if (cc
.mask
!= -1) {
1181 tcg_gen_andi_tl(cpu_T
[0], cc
.reg
, cc
.mask
);
1185 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1187 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1191 /* Generate a conditional jump to label 'l1' according to jump opcode
1192 value 'b'. In the fast case, T0 is guaranted not to be used.
1193 A translation block must end soon. */
1194 static inline void gen_jcc1(DisasContext
*s
, int b
, int l1
)
1196 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T
[0]);
1198 gen_update_cc_op(s
);
1199 if (cc
.mask
!= -1) {
1200 tcg_gen_andi_tl(cpu_T
[0], cc
.reg
, cc
.mask
);
1203 set_cc_op(s
, CC_OP_DYNAMIC
);
1205 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1207 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1211 /* XXX: does not work with gdbstub "ice" single step - not a
1213 static int gen_jz_ecx_string(DisasContext
*s
, target_ulong next_eip
)
1217 l1
= gen_new_label();
1218 l2
= gen_new_label();
1219 gen_op_jnz_ecx(s
->aflag
, l1
);
1221 gen_jmp_tb(s
, next_eip
, 1);
1226 static inline void gen_stos(DisasContext
*s
, int ot
)
1228 gen_op_mov_TN_reg(MO_32
, 0, R_EAX
);
1229 gen_string_movl_A0_EDI(s
);
1230 gen_op_st_T0_A0(s
, ot
);
1231 gen_op_movl_T0_Dshift(ot
);
1232 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1235 static inline void gen_lods(DisasContext
*s
, int ot
)
1237 gen_string_movl_A0_ESI(s
);
1238 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1239 gen_op_mov_reg_T0(ot
, R_EAX
);
1240 gen_op_movl_T0_Dshift(ot
);
1241 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1244 static inline void gen_scas(DisasContext
*s
, int ot
)
1246 gen_string_movl_A0_EDI(s
);
1247 gen_op_ld_T1_A0(s
, ot
);
1248 gen_op(s
, OP_CMPL
, ot
, R_EAX
);
1249 gen_op_movl_T0_Dshift(ot
);
1250 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1253 static inline void gen_cmps(DisasContext
*s
, int ot
)
1255 gen_string_movl_A0_EDI(s
);
1256 gen_op_ld_T1_A0(s
, ot
);
1257 gen_string_movl_A0_ESI(s
);
1258 gen_op(s
, OP_CMPL
, ot
, OR_TMP0
);
1259 gen_op_movl_T0_Dshift(ot
);
1260 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1261 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1264 static inline void gen_ins(DisasContext
*s
, int ot
)
1268 gen_string_movl_A0_EDI(s
);
1269 /* Note: we must do this dummy write first to be restartable in
1270 case of page fault. */
1272 gen_op_st_T0_A0(s
, ot
);
1273 gen_op_mov_TN_reg(MO_16
, 1, R_EDX
);
1274 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[1]);
1275 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1276 gen_helper_in_func(ot
, cpu_T
[0], cpu_tmp2_i32
);
1277 gen_op_st_T0_A0(s
, ot
);
1278 gen_op_movl_T0_Dshift(ot
);
1279 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1284 static inline void gen_outs(DisasContext
*s
, int ot
)
1288 gen_string_movl_A0_ESI(s
);
1289 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1291 gen_op_mov_TN_reg(MO_16
, 1, R_EDX
);
1292 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[1]);
1293 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1294 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[0]);
1295 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1297 gen_op_movl_T0_Dshift(ot
);
1298 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1303 /* same method as Valgrind : we generate jumps to current or next
1305 #define GEN_REPZ(op) \
1306 static inline void gen_repz_ ## op(DisasContext *s, int ot, \
1307 target_ulong cur_eip, target_ulong next_eip) \
1310 gen_update_cc_op(s); \
1311 l2 = gen_jz_ecx_string(s, next_eip); \
1312 gen_ ## op(s, ot); \
1313 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1314 /* a loop would cause two single step exceptions if ECX = 1 \
1315 before rep string_insn */ \
1317 gen_op_jz_ecx(s->aflag, l2); \
1318 gen_jmp(s, cur_eip); \
1321 #define GEN_REPZ2(op) \
1322 static inline void gen_repz_ ## op(DisasContext *s, int ot, \
1323 target_ulong cur_eip, \
1324 target_ulong next_eip, \
1328 gen_update_cc_op(s); \
1329 l2 = gen_jz_ecx_string(s, next_eip); \
1330 gen_ ## op(s, ot); \
1331 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1332 gen_update_cc_op(s); \
1333 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
1335 gen_op_jz_ecx(s->aflag, l2); \
1336 gen_jmp(s, cur_eip); \
1347 static void gen_helper_fp_arith_ST0_FT0(int op
)
1351 gen_helper_fadd_ST0_FT0(cpu_env
);
1354 gen_helper_fmul_ST0_FT0(cpu_env
);
1357 gen_helper_fcom_ST0_FT0(cpu_env
);
1360 gen_helper_fcom_ST0_FT0(cpu_env
);
1363 gen_helper_fsub_ST0_FT0(cpu_env
);
1366 gen_helper_fsubr_ST0_FT0(cpu_env
);
1369 gen_helper_fdiv_ST0_FT0(cpu_env
);
1372 gen_helper_fdivr_ST0_FT0(cpu_env
);
1377 /* NOTE the exception in "r" op ordering */
1378 static void gen_helper_fp_arith_STN_ST0(int op
, int opreg
)
1380 TCGv_i32 tmp
= tcg_const_i32(opreg
);
1383 gen_helper_fadd_STN_ST0(cpu_env
, tmp
);
1386 gen_helper_fmul_STN_ST0(cpu_env
, tmp
);
1389 gen_helper_fsubr_STN_ST0(cpu_env
, tmp
);
1392 gen_helper_fsub_STN_ST0(cpu_env
, tmp
);
1395 gen_helper_fdivr_STN_ST0(cpu_env
, tmp
);
1398 gen_helper_fdiv_STN_ST0(cpu_env
, tmp
);
1403 /* if d == OR_TMP0, it means memory operand (address in A0) */
1404 static void gen_op(DisasContext
*s1
, int op
, int ot
, int d
)
1407 gen_op_mov_TN_reg(ot
, 0, d
);
1409 gen_op_ld_v(s1
, ot
, cpu_T
[0], cpu_A0
);
1413 gen_compute_eflags_c(s1
, cpu_tmp4
);
1414 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1415 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_tmp4
);
1417 gen_op_mov_reg_T0(ot
, d
);
1419 gen_op_st_T0_A0(s1
, ot
);
1420 gen_op_update3_cc(cpu_tmp4
);
1421 set_cc_op(s1
, CC_OP_ADCB
+ ot
);
1424 gen_compute_eflags_c(s1
, cpu_tmp4
);
1425 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1426 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_tmp4
);
1428 gen_op_mov_reg_T0(ot
, d
);
1430 gen_op_st_T0_A0(s1
, ot
);
1431 gen_op_update3_cc(cpu_tmp4
);
1432 set_cc_op(s1
, CC_OP_SBBB
+ ot
);
1435 gen_op_addl_T0_T1();
1437 gen_op_mov_reg_T0(ot
, d
);
1439 gen_op_st_T0_A0(s1
, ot
);
1440 gen_op_update2_cc();
1441 set_cc_op(s1
, CC_OP_ADDB
+ ot
);
1444 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T
[0]);
1445 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1447 gen_op_mov_reg_T0(ot
, d
);
1449 gen_op_st_T0_A0(s1
, ot
);
1450 gen_op_update2_cc();
1451 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1455 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1457 gen_op_mov_reg_T0(ot
, d
);
1459 gen_op_st_T0_A0(s1
, ot
);
1460 gen_op_update1_cc();
1461 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1464 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1466 gen_op_mov_reg_T0(ot
, d
);
1468 gen_op_st_T0_A0(s1
, ot
);
1469 gen_op_update1_cc();
1470 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1473 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1475 gen_op_mov_reg_T0(ot
, d
);
1477 gen_op_st_T0_A0(s1
, ot
);
1478 gen_op_update1_cc();
1479 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1482 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
1483 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T
[0]);
1484 tcg_gen_sub_tl(cpu_cc_dst
, cpu_T
[0], cpu_T
[1]);
1485 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1490 /* if d == OR_TMP0, it means memory operand (address in A0) */
1491 static void gen_inc(DisasContext
*s1
, int ot
, int d
, int c
)
1494 gen_op_mov_TN_reg(ot
, 0, d
);
1496 gen_op_ld_v(s1
, ot
, cpu_T
[0], cpu_A0
);
1498 gen_compute_eflags_c(s1
, cpu_cc_src
);
1500 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], 1);
1501 set_cc_op(s1
, CC_OP_INCB
+ ot
);
1503 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], -1);
1504 set_cc_op(s1
, CC_OP_DECB
+ ot
);
1507 gen_op_mov_reg_T0(ot
, d
);
1509 gen_op_st_T0_A0(s1
, ot
);
1510 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
1513 static void gen_shift_flags(DisasContext
*s
, int ot
, TCGv result
, TCGv shm1
,
1514 TCGv count
, bool is_right
)
1516 TCGv_i32 z32
, s32
, oldop
;
1519 /* Store the results into the CC variables. If we know that the
1520 variable must be dead, store unconditionally. Otherwise we'll
1521 need to not disrupt the current contents. */
1522 z_tl
= tcg_const_tl(0);
1523 if (cc_op_live
[s
->cc_op
] & USES_CC_DST
) {
1524 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_dst
, count
, z_tl
,
1525 result
, cpu_cc_dst
);
1527 tcg_gen_mov_tl(cpu_cc_dst
, result
);
1529 if (cc_op_live
[s
->cc_op
] & USES_CC_SRC
) {
1530 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_cc_src
, count
, z_tl
,
1533 tcg_gen_mov_tl(cpu_cc_src
, shm1
);
1535 tcg_temp_free(z_tl
);
1537 /* Get the two potential CC_OP values into temporaries. */
1538 tcg_gen_movi_i32(cpu_tmp2_i32
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1539 if (s
->cc_op
== CC_OP_DYNAMIC
) {
1542 tcg_gen_movi_i32(cpu_tmp3_i32
, s
->cc_op
);
1543 oldop
= cpu_tmp3_i32
;
1546 /* Conditionally store the CC_OP value. */
1547 z32
= tcg_const_i32(0);
1548 s32
= tcg_temp_new_i32();
1549 tcg_gen_trunc_tl_i32(s32
, count
);
1550 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, s32
, z32
, cpu_tmp2_i32
, oldop
);
1551 tcg_temp_free_i32(z32
);
1552 tcg_temp_free_i32(s32
);
1554 /* The CC_OP value is no longer predictable. */
1555 set_cc_op(s
, CC_OP_DYNAMIC
);
1558 static void gen_shift_rm_T1(DisasContext
*s
, int ot
, int op1
,
1559 int is_right
, int is_arith
)
1561 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1564 if (op1
== OR_TMP0
) {
1565 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1567 gen_op_mov_TN_reg(ot
, 0, op1
);
1570 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], mask
);
1571 tcg_gen_subi_tl(cpu_tmp0
, cpu_T
[1], 1);
1575 gen_exts(ot
, cpu_T
[0]);
1576 tcg_gen_sar_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1577 tcg_gen_sar_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1579 gen_extu(ot
, cpu_T
[0]);
1580 tcg_gen_shr_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1581 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1584 tcg_gen_shl_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1585 tcg_gen_shl_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1589 if (op1
== OR_TMP0
) {
1590 gen_op_st_T0_A0(s
, ot
);
1592 gen_op_mov_reg_T0(ot
, op1
);
1595 gen_shift_flags(s
, ot
, cpu_T
[0], cpu_tmp0
, cpu_T
[1], is_right
);
1598 static void gen_shift_rm_im(DisasContext
*s
, int ot
, int op1
, int op2
,
1599 int is_right
, int is_arith
)
1601 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1605 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1607 gen_op_mov_TN_reg(ot
, 0, op1
);
1613 gen_exts(ot
, cpu_T
[0]);
1614 tcg_gen_sari_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1615 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], op2
);
1617 gen_extu(ot
, cpu_T
[0]);
1618 tcg_gen_shri_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1619 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], op2
);
1622 tcg_gen_shli_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1623 tcg_gen_shli_tl(cpu_T
[0], cpu_T
[0], op2
);
1629 gen_op_st_T0_A0(s
, ot
);
1631 gen_op_mov_reg_T0(ot
, op1
);
1633 /* update eflags if non zero shift */
1635 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
1636 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
1637 set_cc_op(s
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1641 static inline void tcg_gen_lshift(TCGv ret
, TCGv arg1
, target_long arg2
)
1644 tcg_gen_shli_tl(ret
, arg1
, arg2
);
1646 tcg_gen_shri_tl(ret
, arg1
, -arg2
);
1649 static void gen_rot_rm_T1(DisasContext
*s
, int ot
, int op1
, int is_right
)
1651 target_ulong mask
= (ot
== MO_64
? 0x3f : 0x1f);
1655 if (op1
== OR_TMP0
) {
1656 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1658 gen_op_mov_TN_reg(ot
, 0, op1
);
1661 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], mask
);
1665 /* Replicate the 8-bit input so that a 32-bit rotate works. */
1666 tcg_gen_ext8u_tl(cpu_T
[0], cpu_T
[0]);
1667 tcg_gen_muli_tl(cpu_T
[0], cpu_T
[0], 0x01010101);
1670 /* Replicate the 16-bit input so that a 32-bit rotate works. */
1671 tcg_gen_deposit_tl(cpu_T
[0], cpu_T
[0], cpu_T
[0], 16, 16);
1674 #ifdef TARGET_X86_64
1676 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
1677 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
1679 tcg_gen_rotr_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1681 tcg_gen_rotl_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1683 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
1688 tcg_gen_rotr_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1690 tcg_gen_rotl_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1696 if (op1
== OR_TMP0
) {
1697 gen_op_st_T0_A0(s
, ot
);
1699 gen_op_mov_reg_T0(ot
, op1
);
1702 /* We'll need the flags computed into CC_SRC. */
1703 gen_compute_eflags(s
);
1705 /* The value that was "rotated out" is now present at the other end
1706 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1707 since we've computed the flags into CC_SRC, these variables are
1710 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T
[0], mask
- 1);
1711 tcg_gen_shri_tl(cpu_cc_dst
, cpu_T
[0], mask
);
1712 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1714 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T
[0], mask
);
1715 tcg_gen_andi_tl(cpu_cc_dst
, cpu_T
[0], 1);
1717 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1718 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1720 /* Now conditionally store the new CC_OP value. If the shift count
1721 is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1722 Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1723 exactly as we computed above. */
1724 t0
= tcg_const_i32(0);
1725 t1
= tcg_temp_new_i32();
1726 tcg_gen_trunc_tl_i32(t1
, cpu_T
[1]);
1727 tcg_gen_movi_i32(cpu_tmp2_i32
, CC_OP_ADCOX
);
1728 tcg_gen_movi_i32(cpu_tmp3_i32
, CC_OP_EFLAGS
);
1729 tcg_gen_movcond_i32(TCG_COND_NE
, cpu_cc_op
, t1
, t0
,
1730 cpu_tmp2_i32
, cpu_tmp3_i32
);
1731 tcg_temp_free_i32(t0
);
1732 tcg_temp_free_i32(t1
);
1734 /* The CC_OP value is no longer predictable. */
1735 set_cc_op(s
, CC_OP_DYNAMIC
);
1738 static void gen_rot_rm_im(DisasContext
*s
, int ot
, int op1
, int op2
,
1741 int mask
= (ot
== MO_64
? 0x3f : 0x1f);
1745 if (op1
== OR_TMP0
) {
1746 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1748 gen_op_mov_TN_reg(ot
, 0, op1
);
1754 #ifdef TARGET_X86_64
1756 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
1758 tcg_gen_rotri_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, op2
);
1760 tcg_gen_rotli_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, op2
);
1762 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
1767 tcg_gen_rotri_tl(cpu_T
[0], cpu_T
[0], op2
);
1769 tcg_gen_rotli_tl(cpu_T
[0], cpu_T
[0], op2
);
1780 shift
= mask
+ 1 - shift
;
1782 gen_extu(ot
, cpu_T
[0]);
1783 tcg_gen_shli_tl(cpu_tmp0
, cpu_T
[0], shift
);
1784 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], mask
+ 1 - shift
);
1785 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
1791 if (op1
== OR_TMP0
) {
1792 gen_op_st_T0_A0(s
, ot
);
1794 gen_op_mov_reg_T0(ot
, op1
);
1798 /* Compute the flags into CC_SRC. */
1799 gen_compute_eflags(s
);
1801 /* The value that was "rotated out" is now present at the other end
1802 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1803 since we've computed the flags into CC_SRC, these variables are
1806 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T
[0], mask
- 1);
1807 tcg_gen_shri_tl(cpu_cc_dst
, cpu_T
[0], mask
);
1808 tcg_gen_andi_tl(cpu_cc_dst
, cpu_cc_dst
, 1);
1810 tcg_gen_shri_tl(cpu_cc_src2
, cpu_T
[0], mask
);
1811 tcg_gen_andi_tl(cpu_cc_dst
, cpu_T
[0], 1);
1813 tcg_gen_andi_tl(cpu_cc_src2
, cpu_cc_src2
, 1);
1814 tcg_gen_xor_tl(cpu_cc_src2
, cpu_cc_src2
, cpu_cc_dst
);
1815 set_cc_op(s
, CC_OP_ADCOX
);
1819 /* XXX: add faster immediate = 1 case */
1820 static void gen_rotc_rm_T1(DisasContext
*s
, int ot
, int op1
,
1823 gen_compute_eflags(s
);
1824 assert(s
->cc_op
== CC_OP_EFLAGS
);
1828 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1830 gen_op_mov_TN_reg(ot
, 0, op1
);
1835 gen_helper_rcrb(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1838 gen_helper_rcrw(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1841 gen_helper_rcrl(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1843 #ifdef TARGET_X86_64
1845 gen_helper_rcrq(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1852 gen_helper_rclb(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1855 gen_helper_rclw(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1858 gen_helper_rcll(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1860 #ifdef TARGET_X86_64
1862 gen_helper_rclq(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1869 gen_op_st_T0_A0(s
, ot
);
1871 gen_op_mov_reg_T0(ot
, op1
);
1874 /* XXX: add faster immediate case */
1875 static void gen_shiftd_rm_T1(DisasContext
*s
, int ot
, int op1
,
1876 bool is_right
, TCGv count_in
)
1878 target_ulong mask
= (ot
== MO_64
? 63 : 31);
1882 if (op1
== OR_TMP0
) {
1883 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
1885 gen_op_mov_TN_reg(ot
, 0, op1
);
1888 count
= tcg_temp_new();
1889 tcg_gen_andi_tl(count
, count_in
, mask
);
1893 /* Note: we implement the Intel behaviour for shift count > 16.
1894 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A
1895 portion by constructing it as a 32-bit value. */
1897 tcg_gen_deposit_tl(cpu_tmp0
, cpu_T
[0], cpu_T
[1], 16, 16);
1898 tcg_gen_mov_tl(cpu_T
[1], cpu_T
[0]);
1899 tcg_gen_mov_tl(cpu_T
[0], cpu_tmp0
);
1901 tcg_gen_deposit_tl(cpu_T
[1], cpu_T
[0], cpu_T
[1], 16, 16);
1904 #ifdef TARGET_X86_64
1906 /* Concatenate the two 32-bit values and use a 64-bit shift. */
1907 tcg_gen_subi_tl(cpu_tmp0
, count
, 1);
1909 tcg_gen_concat_tl_i64(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1910 tcg_gen_shr_i64(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1911 tcg_gen_shr_i64(cpu_T
[0], cpu_T
[0], count
);
1913 tcg_gen_concat_tl_i64(cpu_T
[0], cpu_T
[1], cpu_T
[0]);
1914 tcg_gen_shl_i64(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1915 tcg_gen_shl_i64(cpu_T
[0], cpu_T
[0], count
);
1916 tcg_gen_shri_i64(cpu_tmp0
, cpu_tmp0
, 32);
1917 tcg_gen_shri_i64(cpu_T
[0], cpu_T
[0], 32);
1922 tcg_gen_subi_tl(cpu_tmp0
, count
, 1);
1924 tcg_gen_shr_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1926 tcg_gen_subfi_tl(cpu_tmp4
, mask
+ 1, count
);
1927 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], count
);
1928 tcg_gen_shl_tl(cpu_T
[1], cpu_T
[1], cpu_tmp4
);
1930 tcg_gen_shl_tl(cpu_tmp0
, cpu_T
[0], cpu_tmp0
);
1932 /* Only needed if count > 16, for Intel behaviour. */
1933 tcg_gen_subfi_tl(cpu_tmp4
, 33, count
);
1934 tcg_gen_shr_tl(cpu_tmp4
, cpu_T
[1], cpu_tmp4
);
1935 tcg_gen_or_tl(cpu_tmp0
, cpu_tmp0
, cpu_tmp4
);
1938 tcg_gen_subfi_tl(cpu_tmp4
, mask
+ 1, count
);
1939 tcg_gen_shl_tl(cpu_T
[0], cpu_T
[0], count
);
1940 tcg_gen_shr_tl(cpu_T
[1], cpu_T
[1], cpu_tmp4
);
1942 tcg_gen_movi_tl(cpu_tmp4
, 0);
1943 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_T
[1], count
, cpu_tmp4
,
1944 cpu_tmp4
, cpu_T
[1]);
1945 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1950 if (op1
== OR_TMP0
) {
1951 gen_op_st_T0_A0(s
, ot
);
1953 gen_op_mov_reg_T0(ot
, op1
);
1956 gen_shift_flags(s
, ot
, cpu_T
[0], cpu_tmp0
, count
, is_right
);
1957 tcg_temp_free(count
);
1960 static void gen_shift(DisasContext
*s1
, int op
, int ot
, int d
, int s
)
1963 gen_op_mov_TN_reg(ot
, 1, s
);
1966 gen_rot_rm_T1(s1
, ot
, d
, 0);
1969 gen_rot_rm_T1(s1
, ot
, d
, 1);
1973 gen_shift_rm_T1(s1
, ot
, d
, 0, 0);
1976 gen_shift_rm_T1(s1
, ot
, d
, 1, 0);
1979 gen_shift_rm_T1(s1
, ot
, d
, 1, 1);
1982 gen_rotc_rm_T1(s1
, ot
, d
, 0);
1985 gen_rotc_rm_T1(s1
, ot
, d
, 1);
1990 static void gen_shifti(DisasContext
*s1
, int op
, int ot
, int d
, int c
)
1994 gen_rot_rm_im(s1
, ot
, d
, c
, 0);
1997 gen_rot_rm_im(s1
, ot
, d
, c
, 1);
2001 gen_shift_rm_im(s1
, ot
, d
, c
, 0, 0);
2004 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 0);
2007 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 1);
2010 /* currently not optimized */
2011 gen_op_movl_T1_im(c
);
2012 gen_shift(s1
, op
, ot
, d
, OR_TMP1
);
2017 static void gen_lea_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2018 int *reg_ptr
, int *offset_ptr
)
2026 int mod
, rm
, code
, override
, must_add_seg
;
2029 override
= s
->override
;
2030 must_add_seg
= s
->addseg
;
2033 mod
= (modrm
>> 6) & 3;
2044 code
= cpu_ldub_code(env
, s
->pc
++);
2045 scale
= (code
>> 6) & 3;
2046 index
= ((code
>> 3) & 7) | REX_X(s
);
2048 index
= -1; /* no index */
2056 if ((base
& 7) == 5) {
2058 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
2060 if (CODE64(s
) && !havesib
) {
2061 disp
+= s
->pc
+ s
->rip_offset
;
2068 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
2072 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
2077 /* For correct popl handling with esp. */
2078 if (base
== R_ESP
&& s
->popl_esp_hack
) {
2079 disp
+= s
->popl_esp_hack
;
2082 /* Compute the address, with a minimum number of TCG ops. */
2086 sum
= cpu_regs
[index
];
2088 tcg_gen_shli_tl(cpu_A0
, cpu_regs
[index
], scale
);
2092 tcg_gen_add_tl(cpu_A0
, sum
, cpu_regs
[base
]);
2095 } else if (base
>= 0) {
2096 sum
= cpu_regs
[base
];
2098 if (TCGV_IS_UNUSED(sum
)) {
2099 tcg_gen_movi_tl(cpu_A0
, disp
);
2101 tcg_gen_addi_tl(cpu_A0
, sum
, disp
);
2106 if (base
== R_EBP
|| base
== R_ESP
) {
2113 tcg_gen_ld_tl(cpu_tmp0
, cpu_env
,
2114 offsetof(CPUX86State
, segs
[override
].base
));
2116 if (s
->aflag
!= 2) {
2117 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
2119 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
2123 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
2126 if (s
->aflag
!= 2) {
2127 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
2133 disp
= cpu_lduw_code(env
, s
->pc
);
2135 gen_op_movl_A0_im(disp
);
2136 rm
= 0; /* avoid SS override */
2143 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
2147 disp
= cpu_lduw_code(env
, s
->pc
);
2153 gen_op_movl_A0_reg(R_EBX
);
2154 gen_op_addl_A0_reg_sN(0, R_ESI
);
2157 gen_op_movl_A0_reg(R_EBX
);
2158 gen_op_addl_A0_reg_sN(0, R_EDI
);
2161 gen_op_movl_A0_reg(R_EBP
);
2162 gen_op_addl_A0_reg_sN(0, R_ESI
);
2165 gen_op_movl_A0_reg(R_EBP
);
2166 gen_op_addl_A0_reg_sN(0, R_EDI
);
2169 gen_op_movl_A0_reg(R_ESI
);
2172 gen_op_movl_A0_reg(R_EDI
);
2175 gen_op_movl_A0_reg(R_EBP
);
2179 gen_op_movl_A0_reg(R_EBX
);
2183 gen_op_addl_A0_im(disp
);
2184 gen_op_andl_A0_ffff();
2188 if (rm
== 2 || rm
== 3 || rm
== 6)
2193 gen_op_addl_A0_seg(s
, override
);
2204 static void gen_nop_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2206 int mod
, rm
, base
, code
;
2208 mod
= (modrm
>> 6) & 3;
2218 code
= cpu_ldub_code(env
, s
->pc
++);
2254 /* used for LEA and MOV AX, mem */
2255 static void gen_add_A0_ds_seg(DisasContext
*s
)
2257 int override
, must_add_seg
;
2258 must_add_seg
= s
->addseg
;
2260 if (s
->override
>= 0) {
2261 override
= s
->override
;
2265 #ifdef TARGET_X86_64
2267 gen_op_addq_A0_seg(override
);
2271 gen_op_addl_A0_seg(s
, override
);
2276 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2278 static void gen_ldst_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2279 int ot
, int reg
, int is_store
)
2281 int mod
, rm
, opreg
, disp
;
2283 mod
= (modrm
>> 6) & 3;
2284 rm
= (modrm
& 7) | REX_B(s
);
2288 gen_op_mov_TN_reg(ot
, 0, reg
);
2289 gen_op_mov_reg_T0(ot
, rm
);
2291 gen_op_mov_TN_reg(ot
, 0, rm
);
2293 gen_op_mov_reg_T0(ot
, reg
);
2296 gen_lea_modrm(env
, s
, modrm
, &opreg
, &disp
);
2299 gen_op_mov_TN_reg(ot
, 0, reg
);
2300 gen_op_st_T0_A0(s
, ot
);
2302 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
2304 gen_op_mov_reg_T0(ot
, reg
);
2309 static inline uint32_t insn_get(CPUX86State
*env
, DisasContext
*s
, int ot
)
2315 ret
= cpu_ldub_code(env
, s
->pc
);
2319 ret
= cpu_lduw_code(env
, s
->pc
);
2324 ret
= cpu_ldl_code(env
, s
->pc
);
2331 static inline int insn_const_size(unsigned int ot
)
2340 static inline void gen_goto_tb(DisasContext
*s
, int tb_num
, target_ulong eip
)
2342 TranslationBlock
*tb
;
2345 pc
= s
->cs_base
+ eip
;
2347 /* NOTE: we handle the case where the TB spans two pages here */
2348 if ((pc
& TARGET_PAGE_MASK
) == (tb
->pc
& TARGET_PAGE_MASK
) ||
2349 (pc
& TARGET_PAGE_MASK
) == ((s
->pc
- 1) & TARGET_PAGE_MASK
)) {
2350 /* jump to same page: we can use a direct jump */
2351 tcg_gen_goto_tb(tb_num
);
2353 tcg_gen_exit_tb((uintptr_t)tb
+ tb_num
);
2355 /* jump to another page: currently not optimized */
2361 static inline void gen_jcc(DisasContext
*s
, int b
,
2362 target_ulong val
, target_ulong next_eip
)
2367 l1
= gen_new_label();
2370 gen_goto_tb(s
, 0, next_eip
);
2373 gen_goto_tb(s
, 1, val
);
2374 s
->is_jmp
= DISAS_TB_JUMP
;
2376 l1
= gen_new_label();
2377 l2
= gen_new_label();
2380 gen_jmp_im(next_eip
);
2390 static void gen_cmovcc1(CPUX86State
*env
, DisasContext
*s
, int ot
, int b
,
2395 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
2397 cc
= gen_prepare_cc(s
, b
, cpu_T
[1]);
2398 if (cc
.mask
!= -1) {
2399 TCGv t0
= tcg_temp_new();
2400 tcg_gen_andi_tl(t0
, cc
.reg
, cc
.mask
);
2404 cc
.reg2
= tcg_const_tl(cc
.imm
);
2407 tcg_gen_movcond_tl(cc
.cond
, cpu_T
[0], cc
.reg
, cc
.reg2
,
2408 cpu_T
[0], cpu_regs
[reg
]);
2409 gen_op_mov_reg_T0(ot
, reg
);
2411 if (cc
.mask
!= -1) {
2412 tcg_temp_free(cc
.reg
);
2415 tcg_temp_free(cc
.reg2
);
2419 static inline void gen_op_movl_T0_seg(int seg_reg
)
2421 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
,
2422 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2425 static inline void gen_op_movl_seg_T0_vm(int seg_reg
)
2427 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffff);
2428 tcg_gen_st32_tl(cpu_T
[0], cpu_env
,
2429 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2430 tcg_gen_shli_tl(cpu_T
[0], cpu_T
[0], 4);
2431 tcg_gen_st_tl(cpu_T
[0], cpu_env
,
2432 offsetof(CPUX86State
,segs
[seg_reg
].base
));
2435 /* move T0 to seg_reg and compute if the CPU state may change. Never
2436 call this function with seg_reg == R_CS */
2437 static void gen_movl_seg_T0(DisasContext
*s
, int seg_reg
, target_ulong cur_eip
)
2439 if (s
->pe
&& !s
->vm86
) {
2440 /* XXX: optimize by finding processor state dynamically */
2441 gen_update_cc_op(s
);
2442 gen_jmp_im(cur_eip
);
2443 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
2444 gen_helper_load_seg(cpu_env
, tcg_const_i32(seg_reg
), cpu_tmp2_i32
);
2445 /* abort translation because the addseg value may change or
2446 because ss32 may change. For R_SS, translation must always
2447 stop as a special handling must be done to disable hardware
2448 interrupts for the next instruction */
2449 if (seg_reg
== R_SS
|| (s
->code32
&& seg_reg
< R_FS
))
2450 s
->is_jmp
= DISAS_TB_JUMP
;
2452 gen_op_movl_seg_T0_vm(seg_reg
);
2453 if (seg_reg
== R_SS
)
2454 s
->is_jmp
= DISAS_TB_JUMP
;
2458 static inline int svm_is_rep(int prefixes
)
2460 return ((prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) ? 8 : 0);
2464 gen_svm_check_intercept_param(DisasContext
*s
, target_ulong pc_start
,
2465 uint32_t type
, uint64_t param
)
2467 /* no SVM activated; fast case */
2468 if (likely(!(s
->flags
& HF_SVMI_MASK
)))
2470 gen_update_cc_op(s
);
2471 gen_jmp_im(pc_start
- s
->cs_base
);
2472 gen_helper_svm_check_intercept_param(cpu_env
, tcg_const_i32(type
),
2473 tcg_const_i64(param
));
2477 gen_svm_check_intercept(DisasContext
*s
, target_ulong pc_start
, uint64_t type
)
2479 gen_svm_check_intercept_param(s
, pc_start
, type
, 0);
2482 static inline void gen_stack_update(DisasContext
*s
, int addend
)
2484 #ifdef TARGET_X86_64
2486 gen_op_add_reg_im(2, R_ESP
, addend
);
2490 gen_op_add_reg_im(1, R_ESP
, addend
);
2492 gen_op_add_reg_im(0, R_ESP
, addend
);
2496 /* generate a push. It depends on ss32, addseg and dflag */
2497 static void gen_push_T0(DisasContext
*s
)
2499 #ifdef TARGET_X86_64
2501 gen_op_movq_A0_reg(R_ESP
);
2503 gen_op_addq_A0_im(-8);
2504 gen_op_st_T0_A0(s
, MO_64
);
2506 gen_op_addq_A0_im(-2);
2507 gen_op_st_T0_A0(s
, MO_16
);
2509 gen_op_mov_reg_A0(2, R_ESP
);
2513 gen_op_movl_A0_reg(R_ESP
);
2515 gen_op_addl_A0_im(-2);
2517 gen_op_addl_A0_im(-4);
2520 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2521 gen_op_addl_A0_seg(s
, R_SS
);
2524 gen_op_andl_A0_ffff();
2525 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2526 gen_op_addl_A0_seg(s
, R_SS
);
2528 gen_op_st_T0_A0(s
, s
->dflag
+ 1);
2529 if (s
->ss32
&& !s
->addseg
)
2530 gen_op_mov_reg_A0(1, R_ESP
);
2532 gen_op_mov_reg_T1(s
->ss32
+ 1, R_ESP
);
2536 /* generate a push. It depends on ss32, addseg and dflag */
2537 /* slower version for T1, only used for call Ev */
2538 static void gen_push_T1(DisasContext
*s
)
2540 #ifdef TARGET_X86_64
2542 gen_op_movq_A0_reg(R_ESP
);
2544 gen_op_addq_A0_im(-8);
2545 gen_op_st_T1_A0(s
, MO_64
);
2547 gen_op_addq_A0_im(-2);
2548 gen_op_st_T0_A0(s
, MO_16
);
2550 gen_op_mov_reg_A0(2, R_ESP
);
2554 gen_op_movl_A0_reg(R_ESP
);
2556 gen_op_addl_A0_im(-2);
2558 gen_op_addl_A0_im(-4);
2561 gen_op_addl_A0_seg(s
, R_SS
);
2564 gen_op_andl_A0_ffff();
2565 gen_op_addl_A0_seg(s
, R_SS
);
2567 gen_op_st_T1_A0(s
, s
->dflag
+ 1);
2569 if (s
->ss32
&& !s
->addseg
)
2570 gen_op_mov_reg_A0(1, R_ESP
);
2572 gen_stack_update(s
, (-2) << s
->dflag
);
2576 /* two step pop is necessary for precise exceptions */
2577 static void gen_pop_T0(DisasContext
*s
)
2579 #ifdef TARGET_X86_64
2581 gen_op_movq_A0_reg(R_ESP
);
2582 gen_op_ld_v(s
, s
->dflag
? MO_64
: MO_16
, cpu_T
[0], cpu_A0
);
2586 gen_op_movl_A0_reg(R_ESP
);
2589 gen_op_addl_A0_seg(s
, R_SS
);
2591 gen_op_andl_A0_ffff();
2592 gen_op_addl_A0_seg(s
, R_SS
);
2594 gen_op_ld_v(s
, s
->dflag
+ 1, cpu_T
[0], cpu_A0
);
2598 static void gen_pop_update(DisasContext
*s
)
2600 #ifdef TARGET_X86_64
2601 if (CODE64(s
) && s
->dflag
) {
2602 gen_stack_update(s
, 8);
2606 gen_stack_update(s
, 2 << s
->dflag
);
2610 static void gen_stack_A0(DisasContext
*s
)
2612 gen_op_movl_A0_reg(R_ESP
);
2614 gen_op_andl_A0_ffff();
2615 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2617 gen_op_addl_A0_seg(s
, R_SS
);
2620 /* NOTE: wrap around in 16 bit not fully handled */
2621 static void gen_pusha(DisasContext
*s
)
2624 gen_op_movl_A0_reg(R_ESP
);
2625 gen_op_addl_A0_im(-16 << s
->dflag
);
2627 gen_op_andl_A0_ffff();
2628 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2630 gen_op_addl_A0_seg(s
, R_SS
);
2631 for(i
= 0;i
< 8; i
++) {
2632 gen_op_mov_TN_reg(MO_32
, 0, 7 - i
);
2633 gen_op_st_T0_A0(s
, MO_16
+ s
->dflag
);
2634 gen_op_addl_A0_im(2 << s
->dflag
);
2636 gen_op_mov_reg_T1(MO_16
+ s
->ss32
, R_ESP
);
2639 /* NOTE: wrap around in 16 bit not fully handled */
2640 static void gen_popa(DisasContext
*s
)
2643 gen_op_movl_A0_reg(R_ESP
);
2645 gen_op_andl_A0_ffff();
2646 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2647 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], 16 << s
->dflag
);
2649 gen_op_addl_A0_seg(s
, R_SS
);
2650 for(i
= 0;i
< 8; i
++) {
2651 /* ESP is not reloaded */
2653 gen_op_ld_v(s
, MO_16
+ s
->dflag
, cpu_T
[0], cpu_A0
);
2654 gen_op_mov_reg_T0(MO_16
+ s
->dflag
, 7 - i
);
2656 gen_op_addl_A0_im(2 << s
->dflag
);
2658 gen_op_mov_reg_T1(MO_16
+ s
->ss32
, R_ESP
);
2661 static void gen_enter(DisasContext
*s
, int esp_addend
, int level
)
2666 #ifdef TARGET_X86_64
2668 ot
= s
->dflag
? MO_64
: MO_16
;
2671 gen_op_movl_A0_reg(R_ESP
);
2672 gen_op_addq_A0_im(-opsize
);
2673 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2676 gen_op_mov_TN_reg(MO_32
, 0, R_EBP
);
2677 gen_op_st_T0_A0(s
, ot
);
2679 /* XXX: must save state */
2680 gen_helper_enter64_level(cpu_env
, tcg_const_i32(level
),
2681 tcg_const_i32((ot
== MO_64
)),
2684 gen_op_mov_reg_T1(ot
, R_EBP
);
2685 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], -esp_addend
+ (-opsize
* level
));
2686 gen_op_mov_reg_T1(MO_64
, R_ESP
);
2690 ot
= s
->dflag
+ MO_16
;
2691 opsize
= 2 << s
->dflag
;
2693 gen_op_movl_A0_reg(R_ESP
);
2694 gen_op_addl_A0_im(-opsize
);
2696 gen_op_andl_A0_ffff();
2697 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2699 gen_op_addl_A0_seg(s
, R_SS
);
2701 gen_op_mov_TN_reg(MO_32
, 0, R_EBP
);
2702 gen_op_st_T0_A0(s
, ot
);
2704 /* XXX: must save state */
2705 gen_helper_enter_level(cpu_env
, tcg_const_i32(level
),
2706 tcg_const_i32(s
->dflag
),
2709 gen_op_mov_reg_T1(ot
, R_EBP
);
2710 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], -esp_addend
+ (-opsize
* level
));
2711 gen_op_mov_reg_T1(MO_16
+ s
->ss32
, R_ESP
);
2715 static void gen_exception(DisasContext
*s
, int trapno
, target_ulong cur_eip
)
2717 gen_update_cc_op(s
);
2718 gen_jmp_im(cur_eip
);
2719 gen_helper_raise_exception(cpu_env
, tcg_const_i32(trapno
));
2720 s
->is_jmp
= DISAS_TB_JUMP
;
2723 /* an interrupt is different from an exception because of the
2725 static void gen_interrupt(DisasContext
*s
, int intno
,
2726 target_ulong cur_eip
, target_ulong next_eip
)
2728 gen_update_cc_op(s
);
2729 gen_jmp_im(cur_eip
);
2730 gen_helper_raise_interrupt(cpu_env
, tcg_const_i32(intno
),
2731 tcg_const_i32(next_eip
- cur_eip
));
2732 s
->is_jmp
= DISAS_TB_JUMP
;
2735 static void gen_debug(DisasContext
*s
, target_ulong cur_eip
)
2737 gen_update_cc_op(s
);
2738 gen_jmp_im(cur_eip
);
2739 gen_helper_debug(cpu_env
);
2740 s
->is_jmp
= DISAS_TB_JUMP
;
2743 /* generate a generic end of block. Trace exception is also generated
2745 static void gen_eob(DisasContext
*s
)
2747 gen_update_cc_op(s
);
2748 if (s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
) {
2749 gen_helper_reset_inhibit_irq(cpu_env
);
2751 if (s
->tb
->flags
& HF_RF_MASK
) {
2752 gen_helper_reset_rf(cpu_env
);
2754 if (s
->singlestep_enabled
) {
2755 gen_helper_debug(cpu_env
);
2757 gen_helper_single_step(cpu_env
);
2761 s
->is_jmp
= DISAS_TB_JUMP
;
2764 /* generate a jump to eip. No segment change must happen before as a
2765 direct call to the next block may occur */
2766 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
)
2768 gen_update_cc_op(s
);
2769 set_cc_op(s
, CC_OP_DYNAMIC
);
2771 gen_goto_tb(s
, tb_num
, eip
);
2772 s
->is_jmp
= DISAS_TB_JUMP
;
2779 static void gen_jmp(DisasContext
*s
, target_ulong eip
)
2781 gen_jmp_tb(s
, eip
, 0);
2784 static inline void gen_ldq_env_A0(DisasContext
*s
, int offset
)
2786 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
2787 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2790 static inline void gen_stq_env_A0(DisasContext
*s
, int offset
)
2792 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2793 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
2796 static inline void gen_ldo_env_A0(DisasContext
*s
, int offset
)
2798 int mem_index
= s
->mem_index
;
2799 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, mem_index
, MO_LEQ
);
2800 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(0)));
2801 tcg_gen_addi_tl(cpu_tmp0
, cpu_A0
, 8);
2802 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
, MO_LEQ
);
2803 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(1)));
2806 static inline void gen_sto_env_A0(DisasContext
*s
, int offset
)
2808 int mem_index
= s
->mem_index
;
2809 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(0)));
2810 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, mem_index
, MO_LEQ
);
2811 tcg_gen_addi_tl(cpu_tmp0
, cpu_A0
, 8);
2812 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(1)));
2813 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
, MO_LEQ
);
2816 static inline void gen_op_movo(int d_offset
, int s_offset
)
2818 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
);
2819 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2820 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
+ 8);
2821 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
+ 8);
2824 static inline void gen_op_movq(int d_offset
, int s_offset
)
2826 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
);
2827 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2830 static inline void gen_op_movl(int d_offset
, int s_offset
)
2832 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
, s_offset
);
2833 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, d_offset
);
2836 static inline void gen_op_movq_env_0(int d_offset
)
2838 tcg_gen_movi_i64(cpu_tmp1_i64
, 0);
2839 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2842 typedef void (*SSEFunc_i_ep
)(TCGv_i32 val
, TCGv_ptr env
, TCGv_ptr reg
);
2843 typedef void (*SSEFunc_l_ep
)(TCGv_i64 val
, TCGv_ptr env
, TCGv_ptr reg
);
2844 typedef void (*SSEFunc_0_epi
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i32 val
);
2845 typedef void (*SSEFunc_0_epl
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i64 val
);
2846 typedef void (*SSEFunc_0_epp
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
);
2847 typedef void (*SSEFunc_0_eppi
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2849 typedef void (*SSEFunc_0_ppi
)(TCGv_ptr reg_a
, TCGv_ptr reg_b
, TCGv_i32 val
);
2850 typedef void (*SSEFunc_0_eppt
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2853 #define SSE_SPECIAL ((void *)1)
2854 #define SSE_DUMMY ((void *)2)
2856 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2857 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2858 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2860 static const SSEFunc_0_epp sse_op_table1
[256][4] = {
2861 /* 3DNow! extensions */
2862 [0x0e] = { SSE_DUMMY
}, /* femms */
2863 [0x0f] = { SSE_DUMMY
}, /* pf... */
2864 /* pure SSE operations */
2865 [0x10] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2866 [0x11] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2867 [0x12] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd, movsldup, movddup */
2868 [0x13] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd */
2869 [0x14] = { gen_helper_punpckldq_xmm
, gen_helper_punpcklqdq_xmm
},
2870 [0x15] = { gen_helper_punpckhdq_xmm
, gen_helper_punpckhqdq_xmm
},
2871 [0x16] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd, movshdup */
2872 [0x17] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd */
2874 [0x28] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2875 [0x29] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2876 [0x2a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2877 [0x2b] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movntps, movntpd, movntss, movntsd */
2878 [0x2c] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2879 [0x2d] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2880 [0x2e] = { gen_helper_ucomiss
, gen_helper_ucomisd
},
2881 [0x2f] = { gen_helper_comiss
, gen_helper_comisd
},
2882 [0x50] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movmskps, movmskpd */
2883 [0x51] = SSE_FOP(sqrt
),
2884 [0x52] = { gen_helper_rsqrtps
, NULL
, gen_helper_rsqrtss
, NULL
},
2885 [0x53] = { gen_helper_rcpps
, NULL
, gen_helper_rcpss
, NULL
},
2886 [0x54] = { gen_helper_pand_xmm
, gen_helper_pand_xmm
}, /* andps, andpd */
2887 [0x55] = { gen_helper_pandn_xmm
, gen_helper_pandn_xmm
}, /* andnps, andnpd */
2888 [0x56] = { gen_helper_por_xmm
, gen_helper_por_xmm
}, /* orps, orpd */
2889 [0x57] = { gen_helper_pxor_xmm
, gen_helper_pxor_xmm
}, /* xorps, xorpd */
2890 [0x58] = SSE_FOP(add
),
2891 [0x59] = SSE_FOP(mul
),
2892 [0x5a] = { gen_helper_cvtps2pd
, gen_helper_cvtpd2ps
,
2893 gen_helper_cvtss2sd
, gen_helper_cvtsd2ss
},
2894 [0x5b] = { gen_helper_cvtdq2ps
, gen_helper_cvtps2dq
, gen_helper_cvttps2dq
},
2895 [0x5c] = SSE_FOP(sub
),
2896 [0x5d] = SSE_FOP(min
),
2897 [0x5e] = SSE_FOP(div
),
2898 [0x5f] = SSE_FOP(max
),
2900 [0xc2] = SSE_FOP(cmpeq
),
2901 [0xc6] = { (SSEFunc_0_epp
)gen_helper_shufps
,
2902 (SSEFunc_0_epp
)gen_helper_shufpd
}, /* XXX: casts */
2904 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */
2905 [0x38] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2906 [0x3a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2908 /* MMX ops and their SSE extensions */
2909 [0x60] = MMX_OP2(punpcklbw
),
2910 [0x61] = MMX_OP2(punpcklwd
),
2911 [0x62] = MMX_OP2(punpckldq
),
2912 [0x63] = MMX_OP2(packsswb
),
2913 [0x64] = MMX_OP2(pcmpgtb
),
2914 [0x65] = MMX_OP2(pcmpgtw
),
2915 [0x66] = MMX_OP2(pcmpgtl
),
2916 [0x67] = MMX_OP2(packuswb
),
2917 [0x68] = MMX_OP2(punpckhbw
),
2918 [0x69] = MMX_OP2(punpckhwd
),
2919 [0x6a] = MMX_OP2(punpckhdq
),
2920 [0x6b] = MMX_OP2(packssdw
),
2921 [0x6c] = { NULL
, gen_helper_punpcklqdq_xmm
},
2922 [0x6d] = { NULL
, gen_helper_punpckhqdq_xmm
},
2923 [0x6e] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movd mm, ea */
2924 [0x6f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, , movqdu */
2925 [0x70] = { (SSEFunc_0_epp
)gen_helper_pshufw_mmx
,
2926 (SSEFunc_0_epp
)gen_helper_pshufd_xmm
,
2927 (SSEFunc_0_epp
)gen_helper_pshufhw_xmm
,
2928 (SSEFunc_0_epp
)gen_helper_pshuflw_xmm
}, /* XXX: casts */
2929 [0x71] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftw */
2930 [0x72] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftd */
2931 [0x73] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftq */
2932 [0x74] = MMX_OP2(pcmpeqb
),
2933 [0x75] = MMX_OP2(pcmpeqw
),
2934 [0x76] = MMX_OP2(pcmpeql
),
2935 [0x77] = { SSE_DUMMY
}, /* emms */
2936 [0x78] = { NULL
, SSE_SPECIAL
, NULL
, SSE_SPECIAL
}, /* extrq_i, insertq_i */
2937 [0x79] = { NULL
, gen_helper_extrq_r
, NULL
, gen_helper_insertq_r
},
2938 [0x7c] = { NULL
, gen_helper_haddpd
, NULL
, gen_helper_haddps
},
2939 [0x7d] = { NULL
, gen_helper_hsubpd
, NULL
, gen_helper_hsubps
},
2940 [0x7e] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movd, movd, , movq */
2941 [0x7f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, movdqu */
2942 [0xc4] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pinsrw */
2943 [0xc5] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pextrw */
2944 [0xd0] = { NULL
, gen_helper_addsubpd
, NULL
, gen_helper_addsubps
},
2945 [0xd1] = MMX_OP2(psrlw
),
2946 [0xd2] = MMX_OP2(psrld
),
2947 [0xd3] = MMX_OP2(psrlq
),
2948 [0xd4] = MMX_OP2(paddq
),
2949 [0xd5] = MMX_OP2(pmullw
),
2950 [0xd6] = { NULL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2951 [0xd7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pmovmskb */
2952 [0xd8] = MMX_OP2(psubusb
),
2953 [0xd9] = MMX_OP2(psubusw
),
2954 [0xda] = MMX_OP2(pminub
),
2955 [0xdb] = MMX_OP2(pand
),
2956 [0xdc] = MMX_OP2(paddusb
),
2957 [0xdd] = MMX_OP2(paddusw
),
2958 [0xde] = MMX_OP2(pmaxub
),
2959 [0xdf] = MMX_OP2(pandn
),
2960 [0xe0] = MMX_OP2(pavgb
),
2961 [0xe1] = MMX_OP2(psraw
),
2962 [0xe2] = MMX_OP2(psrad
),
2963 [0xe3] = MMX_OP2(pavgw
),
2964 [0xe4] = MMX_OP2(pmulhuw
),
2965 [0xe5] = MMX_OP2(pmulhw
),
2966 [0xe6] = { NULL
, gen_helper_cvttpd2dq
, gen_helper_cvtdq2pd
, gen_helper_cvtpd2dq
},
2967 [0xe7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movntq, movntq */
2968 [0xe8] = MMX_OP2(psubsb
),
2969 [0xe9] = MMX_OP2(psubsw
),
2970 [0xea] = MMX_OP2(pminsw
),
2971 [0xeb] = MMX_OP2(por
),
2972 [0xec] = MMX_OP2(paddsb
),
2973 [0xed] = MMX_OP2(paddsw
),
2974 [0xee] = MMX_OP2(pmaxsw
),
2975 [0xef] = MMX_OP2(pxor
),
2976 [0xf0] = { NULL
, NULL
, NULL
, SSE_SPECIAL
}, /* lddqu */
2977 [0xf1] = MMX_OP2(psllw
),
2978 [0xf2] = MMX_OP2(pslld
),
2979 [0xf3] = MMX_OP2(psllq
),
2980 [0xf4] = MMX_OP2(pmuludq
),
2981 [0xf5] = MMX_OP2(pmaddwd
),
2982 [0xf6] = MMX_OP2(psadbw
),
2983 [0xf7] = { (SSEFunc_0_epp
)gen_helper_maskmov_mmx
,
2984 (SSEFunc_0_epp
)gen_helper_maskmov_xmm
}, /* XXX: casts */
2985 [0xf8] = MMX_OP2(psubb
),
2986 [0xf9] = MMX_OP2(psubw
),
2987 [0xfa] = MMX_OP2(psubl
),
2988 [0xfb] = MMX_OP2(psubq
),
2989 [0xfc] = MMX_OP2(paddb
),
2990 [0xfd] = MMX_OP2(paddw
),
2991 [0xfe] = MMX_OP2(paddl
),
2994 static const SSEFunc_0_epp sse_op_table2
[3 * 8][2] = {
2995 [0 + 2] = MMX_OP2(psrlw
),
2996 [0 + 4] = MMX_OP2(psraw
),
2997 [0 + 6] = MMX_OP2(psllw
),
2998 [8 + 2] = MMX_OP2(psrld
),
2999 [8 + 4] = MMX_OP2(psrad
),
3000 [8 + 6] = MMX_OP2(pslld
),
3001 [16 + 2] = MMX_OP2(psrlq
),
3002 [16 + 3] = { NULL
, gen_helper_psrldq_xmm
},
3003 [16 + 6] = MMX_OP2(psllq
),
3004 [16 + 7] = { NULL
, gen_helper_pslldq_xmm
},
3007 static const SSEFunc_0_epi sse_op_table3ai
[] = {
3008 gen_helper_cvtsi2ss
,
3012 #ifdef TARGET_X86_64
3013 static const SSEFunc_0_epl sse_op_table3aq
[] = {
3014 gen_helper_cvtsq2ss
,
3019 static const SSEFunc_i_ep sse_op_table3bi
[] = {
3020 gen_helper_cvttss2si
,
3021 gen_helper_cvtss2si
,
3022 gen_helper_cvttsd2si
,
3026 #ifdef TARGET_X86_64
3027 static const SSEFunc_l_ep sse_op_table3bq
[] = {
3028 gen_helper_cvttss2sq
,
3029 gen_helper_cvtss2sq
,
3030 gen_helper_cvttsd2sq
,
3035 static const SSEFunc_0_epp sse_op_table4
[8][4] = {
3046 static const SSEFunc_0_epp sse_op_table5
[256] = {
3047 [0x0c] = gen_helper_pi2fw
,
3048 [0x0d] = gen_helper_pi2fd
,
3049 [0x1c] = gen_helper_pf2iw
,
3050 [0x1d] = gen_helper_pf2id
,
3051 [0x8a] = gen_helper_pfnacc
,
3052 [0x8e] = gen_helper_pfpnacc
,
3053 [0x90] = gen_helper_pfcmpge
,
3054 [0x94] = gen_helper_pfmin
,
3055 [0x96] = gen_helper_pfrcp
,
3056 [0x97] = gen_helper_pfrsqrt
,
3057 [0x9a] = gen_helper_pfsub
,
3058 [0x9e] = gen_helper_pfadd
,
3059 [0xa0] = gen_helper_pfcmpgt
,
3060 [0xa4] = gen_helper_pfmax
,
3061 [0xa6] = gen_helper_movq
, /* pfrcpit1; no need to actually increase precision */
3062 [0xa7] = gen_helper_movq
, /* pfrsqit1 */
3063 [0xaa] = gen_helper_pfsubr
,
3064 [0xae] = gen_helper_pfacc
,
3065 [0xb0] = gen_helper_pfcmpeq
,
3066 [0xb4] = gen_helper_pfmul
,
3067 [0xb6] = gen_helper_movq
, /* pfrcpit2 */
3068 [0xb7] = gen_helper_pmulhrw_mmx
,
3069 [0xbb] = gen_helper_pswapd
,
3070 [0xbf] = gen_helper_pavgb_mmx
/* pavgusb */
3073 struct SSEOpHelper_epp
{
3074 SSEFunc_0_epp op
[2];
3078 struct SSEOpHelper_eppi
{
3079 SSEFunc_0_eppi op
[2];
3083 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
3084 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
3085 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
3086 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
3087 #define PCLMULQDQ_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, \
3088 CPUID_EXT_PCLMULQDQ }
3089 #define AESNI_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_AES }
3091 static const struct SSEOpHelper_epp sse_op_table6
[256] = {
3092 [0x00] = SSSE3_OP(pshufb
),
3093 [0x01] = SSSE3_OP(phaddw
),
3094 [0x02] = SSSE3_OP(phaddd
),
3095 [0x03] = SSSE3_OP(phaddsw
),
3096 [0x04] = SSSE3_OP(pmaddubsw
),
3097 [0x05] = SSSE3_OP(phsubw
),
3098 [0x06] = SSSE3_OP(phsubd
),
3099 [0x07] = SSSE3_OP(phsubsw
),
3100 [0x08] = SSSE3_OP(psignb
),
3101 [0x09] = SSSE3_OP(psignw
),
3102 [0x0a] = SSSE3_OP(psignd
),
3103 [0x0b] = SSSE3_OP(pmulhrsw
),
3104 [0x10] = SSE41_OP(pblendvb
),
3105 [0x14] = SSE41_OP(blendvps
),
3106 [0x15] = SSE41_OP(blendvpd
),
3107 [0x17] = SSE41_OP(ptest
),
3108 [0x1c] = SSSE3_OP(pabsb
),
3109 [0x1d] = SSSE3_OP(pabsw
),
3110 [0x1e] = SSSE3_OP(pabsd
),
3111 [0x20] = SSE41_OP(pmovsxbw
),
3112 [0x21] = SSE41_OP(pmovsxbd
),
3113 [0x22] = SSE41_OP(pmovsxbq
),
3114 [0x23] = SSE41_OP(pmovsxwd
),
3115 [0x24] = SSE41_OP(pmovsxwq
),
3116 [0x25] = SSE41_OP(pmovsxdq
),
3117 [0x28] = SSE41_OP(pmuldq
),
3118 [0x29] = SSE41_OP(pcmpeqq
),
3119 [0x2a] = SSE41_SPECIAL
, /* movntqda */
3120 [0x2b] = SSE41_OP(packusdw
),
3121 [0x30] = SSE41_OP(pmovzxbw
),
3122 [0x31] = SSE41_OP(pmovzxbd
),
3123 [0x32] = SSE41_OP(pmovzxbq
),
3124 [0x33] = SSE41_OP(pmovzxwd
),
3125 [0x34] = SSE41_OP(pmovzxwq
),
3126 [0x35] = SSE41_OP(pmovzxdq
),
3127 [0x37] = SSE42_OP(pcmpgtq
),
3128 [0x38] = SSE41_OP(pminsb
),
3129 [0x39] = SSE41_OP(pminsd
),
3130 [0x3a] = SSE41_OP(pminuw
),
3131 [0x3b] = SSE41_OP(pminud
),
3132 [0x3c] = SSE41_OP(pmaxsb
),
3133 [0x3d] = SSE41_OP(pmaxsd
),
3134 [0x3e] = SSE41_OP(pmaxuw
),
3135 [0x3f] = SSE41_OP(pmaxud
),
3136 [0x40] = SSE41_OP(pmulld
),
3137 [0x41] = SSE41_OP(phminposuw
),
3138 [0xdb] = AESNI_OP(aesimc
),
3139 [0xdc] = AESNI_OP(aesenc
),
3140 [0xdd] = AESNI_OP(aesenclast
),
3141 [0xde] = AESNI_OP(aesdec
),
3142 [0xdf] = AESNI_OP(aesdeclast
),
3145 static const struct SSEOpHelper_eppi sse_op_table7
[256] = {
3146 [0x08] = SSE41_OP(roundps
),
3147 [0x09] = SSE41_OP(roundpd
),
3148 [0x0a] = SSE41_OP(roundss
),
3149 [0x0b] = SSE41_OP(roundsd
),
3150 [0x0c] = SSE41_OP(blendps
),
3151 [0x0d] = SSE41_OP(blendpd
),
3152 [0x0e] = SSE41_OP(pblendw
),
3153 [0x0f] = SSSE3_OP(palignr
),
3154 [0x14] = SSE41_SPECIAL
, /* pextrb */
3155 [0x15] = SSE41_SPECIAL
, /* pextrw */
3156 [0x16] = SSE41_SPECIAL
, /* pextrd/pextrq */
3157 [0x17] = SSE41_SPECIAL
, /* extractps */
3158 [0x20] = SSE41_SPECIAL
, /* pinsrb */
3159 [0x21] = SSE41_SPECIAL
, /* insertps */
3160 [0x22] = SSE41_SPECIAL
, /* pinsrd/pinsrq */
3161 [0x40] = SSE41_OP(dpps
),
3162 [0x41] = SSE41_OP(dppd
),
3163 [0x42] = SSE41_OP(mpsadbw
),
3164 [0x44] = PCLMULQDQ_OP(pclmulqdq
),
3165 [0x60] = SSE42_OP(pcmpestrm
),
3166 [0x61] = SSE42_OP(pcmpestri
),
3167 [0x62] = SSE42_OP(pcmpistrm
),
3168 [0x63] = SSE42_OP(pcmpistri
),
3169 [0xdf] = AESNI_OP(aeskeygenassist
),
3172 static void gen_sse(CPUX86State
*env
, DisasContext
*s
, int b
,
3173 target_ulong pc_start
, int rex_r
)
3175 int b1
, op1_offset
, op2_offset
, is_xmm
, val
, ot
;
3176 int modrm
, mod
, rm
, reg
, reg_addr
, offset_addr
;
3177 SSEFunc_0_epp sse_fn_epp
;
3178 SSEFunc_0_eppi sse_fn_eppi
;
3179 SSEFunc_0_ppi sse_fn_ppi
;
3180 SSEFunc_0_eppt sse_fn_eppt
;
3183 if (s
->prefix
& PREFIX_DATA
)
3185 else if (s
->prefix
& PREFIX_REPZ
)
3187 else if (s
->prefix
& PREFIX_REPNZ
)
3191 sse_fn_epp
= sse_op_table1
[b
][b1
];
3195 if ((b
<= 0x5f && b
>= 0x10) || b
== 0xc6 || b
== 0xc2) {
3205 /* simple MMX/SSE operation */
3206 if (s
->flags
& HF_TS_MASK
) {
3207 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
3210 if (s
->flags
& HF_EM_MASK
) {
3212 gen_exception(s
, EXCP06_ILLOP
, pc_start
- s
->cs_base
);
3215 if (is_xmm
&& !(s
->flags
& HF_OSFXSR_MASK
))
3216 if ((b
!= 0x38 && b
!= 0x3a) || (s
->prefix
& PREFIX_DATA
))
3219 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
))
3222 gen_helper_emms(cpu_env
);
3227 gen_helper_emms(cpu_env
);
3230 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3231 the static cpu state) */
3233 gen_helper_enter_mmx(cpu_env
);
3236 modrm
= cpu_ldub_code(env
, s
->pc
++);
3237 reg
= ((modrm
>> 3) & 7);
3240 mod
= (modrm
>> 6) & 3;
3241 if (sse_fn_epp
== SSE_SPECIAL
) {
3244 case 0x0e7: /* movntq */
3247 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3248 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3250 case 0x1e7: /* movntdq */
3251 case 0x02b: /* movntps */
3252 case 0x12b: /* movntps */
3255 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3256 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3258 case 0x3f0: /* lddqu */
3261 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3262 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3264 case 0x22b: /* movntss */
3265 case 0x32b: /* movntsd */
3268 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3270 gen_stq_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3272 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
3273 xmm_regs
[reg
].XMM_L(0)));
3274 gen_op_st_T0_A0(s
, MO_32
);
3277 case 0x6e: /* movd mm, ea */
3278 #ifdef TARGET_X86_64
3279 if (s
->dflag
== 2) {
3280 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3281 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3285 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3286 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3287 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3288 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3289 gen_helper_movl_mm_T0_mmx(cpu_ptr0
, cpu_tmp2_i32
);
3292 case 0x16e: /* movd xmm, ea */
3293 #ifdef TARGET_X86_64
3294 if (s
->dflag
== 2) {
3295 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 0);
3296 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3297 offsetof(CPUX86State
,xmm_regs
[reg
]));
3298 gen_helper_movq_mm_T0_xmm(cpu_ptr0
, cpu_T
[0]);
3302 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 0);
3303 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3304 offsetof(CPUX86State
,xmm_regs
[reg
]));
3305 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3306 gen_helper_movl_mm_T0_xmm(cpu_ptr0
, cpu_tmp2_i32
);
3309 case 0x6f: /* movq mm, ea */
3311 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3312 gen_ldq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3315 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
3316 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3317 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
3318 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3321 case 0x010: /* movups */
3322 case 0x110: /* movupd */
3323 case 0x028: /* movaps */
3324 case 0x128: /* movapd */
3325 case 0x16f: /* movdqa xmm, ea */
3326 case 0x26f: /* movdqu xmm, ea */
3328 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3329 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3331 rm
= (modrm
& 7) | REX_B(s
);
3332 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[reg
]),
3333 offsetof(CPUX86State
,xmm_regs
[rm
]));
3336 case 0x210: /* movss xmm, ea */
3338 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3339 gen_op_ld_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
3340 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3342 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(1)));
3343 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)));
3344 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)));
3346 rm
= (modrm
& 7) | REX_B(s
);
3347 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)),
3348 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(0)));
3351 case 0x310: /* movsd xmm, ea */
3353 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3354 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3355 xmm_regs
[reg
].XMM_Q(0)));
3357 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)));
3358 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)));
3360 rm
= (modrm
& 7) | REX_B(s
);
3361 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3362 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3365 case 0x012: /* movlps */
3366 case 0x112: /* movlpd */
3368 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3369 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3370 xmm_regs
[reg
].XMM_Q(0)));
3373 rm
= (modrm
& 7) | REX_B(s
);
3374 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3375 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(1)));
3378 case 0x212: /* movsldup */
3380 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3381 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3383 rm
= (modrm
& 7) | REX_B(s
);
3384 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)),
3385 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(0)));
3386 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)),
3387 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(2)));
3389 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(1)),
3390 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3391 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)),
3392 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)));
3394 case 0x312: /* movddup */
3396 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3397 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3398 xmm_regs
[reg
].XMM_Q(0)));
3400 rm
= (modrm
& 7) | REX_B(s
);
3401 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3402 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3404 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)),
3405 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3407 case 0x016: /* movhps */
3408 case 0x116: /* movhpd */
3410 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3411 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3412 xmm_regs
[reg
].XMM_Q(1)));
3415 rm
= (modrm
& 7) | REX_B(s
);
3416 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)),
3417 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3420 case 0x216: /* movshdup */
3422 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3423 gen_ldo_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3425 rm
= (modrm
& 7) | REX_B(s
);
3426 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(1)),
3427 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(1)));
3428 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)),
3429 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(3)));
3431 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)),
3432 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(1)));
3433 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)),
3434 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)));
3439 int bit_index
, field_length
;
3441 if (b1
== 1 && reg
!= 0)
3443 field_length
= cpu_ldub_code(env
, s
->pc
++) & 0x3F;
3444 bit_index
= cpu_ldub_code(env
, s
->pc
++) & 0x3F;
3445 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3446 offsetof(CPUX86State
,xmm_regs
[reg
]));
3448 gen_helper_extrq_i(cpu_env
, cpu_ptr0
,
3449 tcg_const_i32(bit_index
),
3450 tcg_const_i32(field_length
));
3452 gen_helper_insertq_i(cpu_env
, cpu_ptr0
,
3453 tcg_const_i32(bit_index
),
3454 tcg_const_i32(field_length
));
3457 case 0x7e: /* movd ea, mm */
3458 #ifdef TARGET_X86_64
3459 if (s
->dflag
== 2) {
3460 tcg_gen_ld_i64(cpu_T
[0], cpu_env
,
3461 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3462 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3466 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
,
3467 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_L(0)));
3468 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3471 case 0x17e: /* movd ea, xmm */
3472 #ifdef TARGET_X86_64
3473 if (s
->dflag
== 2) {
3474 tcg_gen_ld_i64(cpu_T
[0], cpu_env
,
3475 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3476 gen_ldst_modrm(env
, s
, modrm
, MO_64
, OR_TMP0
, 1);
3480 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
,
3481 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3482 gen_ldst_modrm(env
, s
, modrm
, MO_32
, OR_TMP0
, 1);
3485 case 0x27e: /* movq xmm, ea */
3487 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3488 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
3489 xmm_regs
[reg
].XMM_Q(0)));
3491 rm
= (modrm
& 7) | REX_B(s
);
3492 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3493 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3495 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)));
3497 case 0x7f: /* movq ea, mm */
3499 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3500 gen_stq_env_A0(s
, offsetof(CPUX86State
, fpregs
[reg
].mmx
));
3503 gen_op_movq(offsetof(CPUX86State
,fpregs
[rm
].mmx
),
3504 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3507 case 0x011: /* movups */
3508 case 0x111: /* movupd */
3509 case 0x029: /* movaps */
3510 case 0x129: /* movapd */
3511 case 0x17f: /* movdqa ea, xmm */
3512 case 0x27f: /* movdqu ea, xmm */
3514 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3515 gen_sto_env_A0(s
, offsetof(CPUX86State
, xmm_regs
[reg
]));
3517 rm
= (modrm
& 7) | REX_B(s
);
3518 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[rm
]),
3519 offsetof(CPUX86State
,xmm_regs
[reg
]));
3522 case 0x211: /* movss ea, xmm */
3524 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3525 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3526 gen_op_st_T0_A0(s
, MO_32
);
3528 rm
= (modrm
& 7) | REX_B(s
);
3529 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(0)),
3530 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3533 case 0x311: /* movsd ea, xmm */
3535 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3536 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3537 xmm_regs
[reg
].XMM_Q(0)));
3539 rm
= (modrm
& 7) | REX_B(s
);
3540 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)),
3541 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3544 case 0x013: /* movlps */
3545 case 0x113: /* movlpd */
3547 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3548 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3549 xmm_regs
[reg
].XMM_Q(0)));
3554 case 0x017: /* movhps */
3555 case 0x117: /* movhpd */
3557 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3558 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3559 xmm_regs
[reg
].XMM_Q(1)));
3564 case 0x71: /* shift mm, im */
3567 case 0x171: /* shift xmm, im */
3573 val
= cpu_ldub_code(env
, s
->pc
++);
3575 gen_op_movl_T0_im(val
);
3576 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.XMM_L(0)));
3578 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.XMM_L(1)));
3579 op1_offset
= offsetof(CPUX86State
,xmm_t0
);
3581 gen_op_movl_T0_im(val
);
3582 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,mmx_t0
.MMX_L(0)));
3584 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,mmx_t0
.MMX_L(1)));
3585 op1_offset
= offsetof(CPUX86State
,mmx_t0
);
3587 sse_fn_epp
= sse_op_table2
[((b
- 1) & 3) * 8 +
3588 (((modrm
>> 3)) & 7)][b1
];
3593 rm
= (modrm
& 7) | REX_B(s
);
3594 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3597 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3599 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3600 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op1_offset
);
3601 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3603 case 0x050: /* movmskps */
3604 rm
= (modrm
& 7) | REX_B(s
);
3605 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3606 offsetof(CPUX86State
,xmm_regs
[rm
]));
3607 gen_helper_movmskps(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3608 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
3609 gen_op_mov_reg_T0(MO_32
, reg
);
3611 case 0x150: /* movmskpd */
3612 rm
= (modrm
& 7) | REX_B(s
);
3613 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3614 offsetof(CPUX86State
,xmm_regs
[rm
]));
3615 gen_helper_movmskpd(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3616 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
3617 gen_op_mov_reg_T0(MO_32
, reg
);
3619 case 0x02a: /* cvtpi2ps */
3620 case 0x12a: /* cvtpi2pd */
3621 gen_helper_enter_mmx(cpu_env
);
3623 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3624 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3625 gen_ldq_env_A0(s
, op2_offset
);
3628 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3630 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3631 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3632 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3635 gen_helper_cvtpi2ps(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3639 gen_helper_cvtpi2pd(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3643 case 0x22a: /* cvtsi2ss */
3644 case 0x32a: /* cvtsi2sd */
3645 ot
= (s
->dflag
== 2) ? MO_64
: MO_32
;
3646 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3647 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3648 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3650 SSEFunc_0_epi sse_fn_epi
= sse_op_table3ai
[(b
>> 8) & 1];
3651 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3652 sse_fn_epi(cpu_env
, cpu_ptr0
, cpu_tmp2_i32
);
3654 #ifdef TARGET_X86_64
3655 SSEFunc_0_epl sse_fn_epl
= sse_op_table3aq
[(b
>> 8) & 1];
3656 sse_fn_epl(cpu_env
, cpu_ptr0
, cpu_T
[0]);
3662 case 0x02c: /* cvttps2pi */
3663 case 0x12c: /* cvttpd2pi */
3664 case 0x02d: /* cvtps2pi */
3665 case 0x12d: /* cvtpd2pi */
3666 gen_helper_enter_mmx(cpu_env
);
3668 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3669 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3670 gen_ldo_env_A0(s
, op2_offset
);
3672 rm
= (modrm
& 7) | REX_B(s
);
3673 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3675 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
);
3676 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3677 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3680 gen_helper_cvttps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3683 gen_helper_cvttpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3686 gen_helper_cvtps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3689 gen_helper_cvtpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3693 case 0x22c: /* cvttss2si */
3694 case 0x32c: /* cvttsd2si */
3695 case 0x22d: /* cvtss2si */
3696 case 0x32d: /* cvtsd2si */
3697 ot
= (s
->dflag
== 2) ? MO_64
: MO_32
;
3699 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3701 gen_ldq_env_A0(s
, offsetof(CPUX86State
, xmm_t0
.XMM_Q(0)));
3703 gen_op_ld_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
3704 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.XMM_L(0)));
3706 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3708 rm
= (modrm
& 7) | REX_B(s
);
3709 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3711 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3713 SSEFunc_i_ep sse_fn_i_ep
=
3714 sse_op_table3bi
[((b
>> 7) & 2) | (b
& 1)];
3715 sse_fn_i_ep(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3716 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
3718 #ifdef TARGET_X86_64
3719 SSEFunc_l_ep sse_fn_l_ep
=
3720 sse_op_table3bq
[((b
>> 7) & 2) | (b
& 1)];
3721 sse_fn_l_ep(cpu_T
[0], cpu_env
, cpu_ptr0
);
3726 gen_op_mov_reg_T0(ot
, reg
);
3728 case 0xc4: /* pinsrw */
3731 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
3732 val
= cpu_ldub_code(env
, s
->pc
++);
3735 tcg_gen_st16_tl(cpu_T
[0], cpu_env
,
3736 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_W(val
)));
3739 tcg_gen_st16_tl(cpu_T
[0], cpu_env
,
3740 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_W(val
)));
3743 case 0xc5: /* pextrw */
3747 ot
= (s
->dflag
== 2) ? MO_64
: MO_32
;
3748 val
= cpu_ldub_code(env
, s
->pc
++);
3751 rm
= (modrm
& 7) | REX_B(s
);
3752 tcg_gen_ld16u_tl(cpu_T
[0], cpu_env
,
3753 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_W(val
)));
3757 tcg_gen_ld16u_tl(cpu_T
[0], cpu_env
,
3758 offsetof(CPUX86State
,fpregs
[rm
].mmx
.MMX_W(val
)));
3760 reg
= ((modrm
>> 3) & 7) | rex_r
;
3761 gen_op_mov_reg_T0(ot
, reg
);
3763 case 0x1d6: /* movq ea, xmm */
3765 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3766 gen_stq_env_A0(s
, offsetof(CPUX86State
,
3767 xmm_regs
[reg
].XMM_Q(0)));
3769 rm
= (modrm
& 7) | REX_B(s
);
3770 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)),
3771 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3772 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(1)));
3775 case 0x2d6: /* movq2dq */
3776 gen_helper_enter_mmx(cpu_env
);
3778 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3779 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3780 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)));
3782 case 0x3d6: /* movdq2q */
3783 gen_helper_enter_mmx(cpu_env
);
3784 rm
= (modrm
& 7) | REX_B(s
);
3785 gen_op_movq(offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
),
3786 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3788 case 0xd7: /* pmovmskb */
3793 rm
= (modrm
& 7) | REX_B(s
);
3794 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[rm
]));
3795 gen_helper_pmovmskb_xmm(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3798 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3799 gen_helper_pmovmskb_mmx(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3801 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
3802 reg
= ((modrm
>> 3) & 7) | rex_r
;
3803 gen_op_mov_reg_T0(MO_32
, reg
);
3809 if ((b
& 0xf0) == 0xf0) {
3812 modrm
= cpu_ldub_code(env
, s
->pc
++);
3814 reg
= ((modrm
>> 3) & 7) | rex_r
;
3815 mod
= (modrm
>> 6) & 3;
3820 sse_fn_epp
= sse_op_table6
[b
].op
[b1
];
3824 if (!(s
->cpuid_ext_features
& sse_op_table6
[b
].ext_mask
))
3828 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3830 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
3832 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3833 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3835 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3836 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3837 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3838 gen_ldq_env_A0(s
, op2_offset
+
3839 offsetof(XMMReg
, XMM_Q(0)));
3841 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3842 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3843 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
3844 s
->mem_index
, MO_LEUL
);
3845 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, op2_offset
+
3846 offsetof(XMMReg
, XMM_L(0)));
3848 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3849 tcg_gen_qemu_ld_tl(cpu_tmp0
, cpu_A0
,
3850 s
->mem_index
, MO_LEUW
);
3851 tcg_gen_st16_tl(cpu_tmp0
, cpu_env
, op2_offset
+
3852 offsetof(XMMReg
, XMM_W(0)));
3854 case 0x2a: /* movntqda */
3855 gen_ldo_env_A0(s
, op1_offset
);
3858 gen_ldo_env_A0(s
, op2_offset
);
3862 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
3864 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3866 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3867 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3868 gen_ldq_env_A0(s
, op2_offset
);
3871 if (sse_fn_epp
== SSE_SPECIAL
) {
3875 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3876 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3877 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3880 set_cc_op(s
, CC_OP_EFLAGS
);
3887 /* Various integer extensions at 0f 38 f[0-f]. */
3888 b
= modrm
| (b1
<< 8);
3889 modrm
= cpu_ldub_code(env
, s
->pc
++);
3890 reg
= ((modrm
>> 3) & 7) | rex_r
;
3893 case 0x3f0: /* crc32 Gd,Eb */
3894 case 0x3f1: /* crc32 Gd,Ey */
3896 if (!(s
->cpuid_ext_features
& CPUID_EXT_SSE42
)) {
3899 if ((b
& 0xff) == 0xf0) {
3901 } else if (s
->dflag
!= 2) {
3902 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3907 gen_op_mov_TN_reg(MO_32
, 0, reg
);
3908 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3909 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3910 gen_helper_crc32(cpu_T
[0], cpu_tmp2_i32
,
3911 cpu_T
[0], tcg_const_i32(8 << ot
));
3913 ot
= (s
->dflag
== 2) ? MO_64
: MO_32
;
3914 gen_op_mov_reg_T0(ot
, reg
);
3917 case 0x1f0: /* crc32 or movbe */
3919 /* For these insns, the f3 prefix is supposed to have priority
3920 over the 66 prefix, but that's not what we implement above
3922 if (s
->prefix
& PREFIX_REPNZ
) {
3926 case 0x0f0: /* movbe Gy,My */
3927 case 0x0f1: /* movbe My,Gy */
3928 if (!(s
->cpuid_ext_features
& CPUID_EXT_MOVBE
)) {
3931 if (s
->dflag
!= 2) {
3932 ot
= (s
->prefix
& PREFIX_DATA
? MO_16
: MO_32
);
3937 /* Load the data incoming to the bswap. Note that the TCG
3938 implementation of bswap requires the input be zero
3939 extended. In the case of the loads, we simply know that
3940 gen_op_ld_v via gen_ldst_modrm does that already. */
3942 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3946 tcg_gen_ext16u_tl(cpu_T
[0], cpu_regs
[reg
]);
3949 tcg_gen_ext32u_tl(cpu_T
[0], cpu_regs
[reg
]);
3952 tcg_gen_mov_tl(cpu_T
[0], cpu_regs
[reg
]);
3959 tcg_gen_bswap16_tl(cpu_T
[0], cpu_T
[0]);
3962 tcg_gen_bswap32_tl(cpu_T
[0], cpu_T
[0]);
3964 #ifdef TARGET_X86_64
3966 tcg_gen_bswap64_tl(cpu_T
[0], cpu_T
[0]);
3972 gen_op_mov_reg_T0(ot
, reg
);
3974 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
3978 case 0x0f2: /* andn Gy, By, Ey */
3979 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3980 || !(s
->prefix
& PREFIX_VEX
)
3984 ot
= s
->dflag
== 2 ? MO_64
: MO_32
;
3985 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3986 tcg_gen_andc_tl(cpu_T
[0], cpu_regs
[s
->vex_v
], cpu_T
[0]);
3987 gen_op_mov_reg_T0(ot
, reg
);
3988 gen_op_update1_cc();
3989 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
3992 case 0x0f7: /* bextr Gy, Ey, By */
3993 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
3994 || !(s
->prefix
& PREFIX_VEX
)
3998 ot
= s
->dflag
== 2 ? MO_64
: MO_32
;
4002 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4003 /* Extract START, and shift the operand.
4004 Shifts larger than operand size get zeros. */
4005 tcg_gen_ext8u_tl(cpu_A0
, cpu_regs
[s
->vex_v
]);
4006 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], cpu_A0
);
4008 bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
4009 zero
= tcg_const_tl(0);
4010 tcg_gen_movcond_tl(TCG_COND_LEU
, cpu_T
[0], cpu_A0
, bound
,
4012 tcg_temp_free(zero
);
4014 /* Extract the LEN into a mask. Lengths larger than
4015 operand size get all ones. */
4016 tcg_gen_shri_tl(cpu_A0
, cpu_regs
[s
->vex_v
], 8);
4017 tcg_gen_ext8u_tl(cpu_A0
, cpu_A0
);
4018 tcg_gen_movcond_tl(TCG_COND_LEU
, cpu_A0
, cpu_A0
, bound
,
4020 tcg_temp_free(bound
);
4021 tcg_gen_movi_tl(cpu_T
[1], 1);
4022 tcg_gen_shl_tl(cpu_T
[1], cpu_T
[1], cpu_A0
);
4023 tcg_gen_subi_tl(cpu_T
[1], cpu_T
[1], 1);
4024 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4026 gen_op_mov_reg_T0(ot
, reg
);
4027 gen_op_update1_cc();
4028 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4032 case 0x0f5: /* bzhi Gy, Ey, By */
4033 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4034 || !(s
->prefix
& PREFIX_VEX
)
4038 ot
= s
->dflag
== 2 ? MO_64
: MO_32
;
4039 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4040 tcg_gen_ext8u_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
4042 TCGv bound
= tcg_const_tl(ot
== MO_64
? 63 : 31);
4043 /* Note that since we're using BMILG (in order to get O
4044 cleared) we need to store the inverse into C. */
4045 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_cc_src
,
4047 tcg_gen_movcond_tl(TCG_COND_GT
, cpu_T
[1], cpu_T
[1],
4048 bound
, bound
, cpu_T
[1]);
4049 tcg_temp_free(bound
);
4051 tcg_gen_movi_tl(cpu_A0
, -1);
4052 tcg_gen_shl_tl(cpu_A0
, cpu_A0
, cpu_T
[1]);
4053 tcg_gen_andc_tl(cpu_T
[0], cpu_T
[0], cpu_A0
);
4054 gen_op_mov_reg_T0(ot
, reg
);
4055 gen_op_update1_cc();
4056 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4059 case 0x3f6: /* mulx By, Gy, rdx, Ey */
4060 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4061 || !(s
->prefix
& PREFIX_VEX
)
4065 ot
= s
->dflag
== 2 ? MO_64
: MO_32
;
4066 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4069 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4070 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EDX
]);
4071 tcg_gen_mulu2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4072 cpu_tmp2_i32
, cpu_tmp3_i32
);
4073 tcg_gen_extu_i32_tl(cpu_regs
[s
->vex_v
], cpu_tmp2_i32
);
4074 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp3_i32
);
4076 #ifdef TARGET_X86_64
4078 tcg_gen_mulu2_i64(cpu_regs
[s
->vex_v
], cpu_regs
[reg
],
4079 cpu_T
[0], cpu_regs
[R_EDX
]);
4085 case 0x3f5: /* pdep Gy, By, Ey */
4086 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4087 || !(s
->prefix
& PREFIX_VEX
)
4091 ot
= s
->dflag
== 2 ? MO_64
: MO_32
;
4092 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4093 /* Note that by zero-extending the mask operand, we
4094 automatically handle zero-extending the result. */
4095 if (s
->dflag
== 2) {
4096 tcg_gen_mov_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
4098 tcg_gen_ext32u_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
4100 gen_helper_pdep(cpu_regs
[reg
], cpu_T
[0], cpu_T
[1]);
4103 case 0x2f5: /* pext Gy, By, Ey */
4104 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4105 || !(s
->prefix
& PREFIX_VEX
)
4109 ot
= s
->dflag
== 2 ? MO_64
: MO_32
;
4110 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4111 /* Note that by zero-extending the mask operand, we
4112 automatically handle zero-extending the result. */
4113 if (s
->dflag
== 2) {
4114 tcg_gen_mov_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
4116 tcg_gen_ext32u_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
4118 gen_helper_pext(cpu_regs
[reg
], cpu_T
[0], cpu_T
[1]);
4121 case 0x1f6: /* adcx Gy, Ey */
4122 case 0x2f6: /* adox Gy, Ey */
4123 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_ADX
)) {
4126 TCGv carry_in
, carry_out
, zero
;
4129 ot
= (s
->dflag
== 2 ? MO_64
: MO_32
);
4130 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4132 /* Re-use the carry-out from a previous round. */
4133 TCGV_UNUSED(carry_in
);
4134 carry_out
= (b
== 0x1f6 ? cpu_cc_dst
: cpu_cc_src2
);
4138 carry_in
= cpu_cc_dst
;
4139 end_op
= CC_OP_ADCX
;
4141 end_op
= CC_OP_ADCOX
;
4146 end_op
= CC_OP_ADCOX
;
4148 carry_in
= cpu_cc_src2
;
4149 end_op
= CC_OP_ADOX
;
4153 end_op
= CC_OP_ADCOX
;
4154 carry_in
= carry_out
;
4157 end_op
= (b
== 0x1f6 ? CC_OP_ADCX
: CC_OP_ADOX
);
4160 /* If we can't reuse carry-out, get it out of EFLAGS. */
4161 if (TCGV_IS_UNUSED(carry_in
)) {
4162 if (s
->cc_op
!= CC_OP_ADCX
&& s
->cc_op
!= CC_OP_ADOX
) {
4163 gen_compute_eflags(s
);
4165 carry_in
= cpu_tmp0
;
4166 tcg_gen_shri_tl(carry_in
, cpu_cc_src
,
4167 ctz32(b
== 0x1f6 ? CC_C
: CC_O
));
4168 tcg_gen_andi_tl(carry_in
, carry_in
, 1);
4172 #ifdef TARGET_X86_64
4174 /* If we know TL is 64-bit, and we want a 32-bit
4175 result, just do everything in 64-bit arithmetic. */
4176 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_regs
[reg
]);
4177 tcg_gen_ext32u_i64(cpu_T
[0], cpu_T
[0]);
4178 tcg_gen_add_i64(cpu_T
[0], cpu_T
[0], cpu_regs
[reg
]);
4179 tcg_gen_add_i64(cpu_T
[0], cpu_T
[0], carry_in
);
4180 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_T
[0]);
4181 tcg_gen_shri_i64(carry_out
, cpu_T
[0], 32);
4185 /* Otherwise compute the carry-out in two steps. */
4186 zero
= tcg_const_tl(0);
4187 tcg_gen_add2_tl(cpu_T
[0], carry_out
,
4190 tcg_gen_add2_tl(cpu_regs
[reg
], carry_out
,
4191 cpu_regs
[reg
], carry_out
,
4193 tcg_temp_free(zero
);
4196 set_cc_op(s
, end_op
);
4200 case 0x1f7: /* shlx Gy, Ey, By */
4201 case 0x2f7: /* sarx Gy, Ey, By */
4202 case 0x3f7: /* shrx Gy, Ey, By */
4203 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4204 || !(s
->prefix
& PREFIX_VEX
)
4208 ot
= (s
->dflag
== 2 ? MO_64
: MO_32
);
4209 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4211 tcg_gen_andi_tl(cpu_T
[1], cpu_regs
[s
->vex_v
], 63);
4213 tcg_gen_andi_tl(cpu_T
[1], cpu_regs
[s
->vex_v
], 31);
4216 tcg_gen_shl_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4217 } else if (b
== 0x2f7) {
4219 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
4221 tcg_gen_sar_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4224 tcg_gen_ext32u_tl(cpu_T
[0], cpu_T
[0]);
4226 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4228 gen_op_mov_reg_T0(ot
, reg
);
4234 case 0x3f3: /* Group 17 */
4235 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
4236 || !(s
->prefix
& PREFIX_VEX
)
4240 ot
= s
->dflag
== 2 ? MO_64
: MO_32
;
4241 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4244 case 1: /* blsr By,Ey */
4245 tcg_gen_neg_tl(cpu_T
[1], cpu_T
[0]);
4246 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4247 gen_op_mov_reg_T0(ot
, s
->vex_v
);
4248 gen_op_update2_cc();
4249 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4252 case 2: /* blsmsk By,Ey */
4253 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
4254 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], 1);
4255 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_cc_src
);
4256 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4257 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4260 case 3: /* blsi By, Ey */
4261 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
4262 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], 1);
4263 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_cc_src
);
4264 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4265 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4281 modrm
= cpu_ldub_code(env
, s
->pc
++);
4283 reg
= ((modrm
>> 3) & 7) | rex_r
;
4284 mod
= (modrm
>> 6) & 3;
4289 sse_fn_eppi
= sse_op_table7
[b
].op
[b1
];
4293 if (!(s
->cpuid_ext_features
& sse_op_table7
[b
].ext_mask
))
4296 if (sse_fn_eppi
== SSE_SPECIAL
) {
4297 ot
= (s
->dflag
== 2) ? MO_64
: MO_32
;
4298 rm
= (modrm
& 7) | REX_B(s
);
4300 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4301 reg
= ((modrm
>> 3) & 7) | rex_r
;
4302 val
= cpu_ldub_code(env
, s
->pc
++);
4304 case 0x14: /* pextrb */
4305 tcg_gen_ld8u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4306 xmm_regs
[reg
].XMM_B(val
& 15)));
4308 gen_op_mov_reg_T0(ot
, rm
);
4310 tcg_gen_qemu_st_tl(cpu_T
[0], cpu_A0
,
4311 s
->mem_index
, MO_UB
);
4314 case 0x15: /* pextrw */
4315 tcg_gen_ld16u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4316 xmm_regs
[reg
].XMM_W(val
& 7)));
4318 gen_op_mov_reg_T0(ot
, rm
);
4320 tcg_gen_qemu_st_tl(cpu_T
[0], cpu_A0
,
4321 s
->mem_index
, MO_LEUW
);
4325 if (ot
== MO_32
) { /* pextrd */
4326 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4327 offsetof(CPUX86State
,
4328 xmm_regs
[reg
].XMM_L(val
& 3)));
4329 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
4331 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4333 tcg_gen_qemu_st_tl(cpu_T
[0], cpu_A0
,
4334 s
->mem_index
, MO_LEUL
);
4336 } else { /* pextrq */
4337 #ifdef TARGET_X86_64
4338 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
4339 offsetof(CPUX86State
,
4340 xmm_regs
[reg
].XMM_Q(val
& 1)));
4342 gen_op_mov_reg_v(ot
, rm
, cpu_tmp1_i64
);
4344 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
4345 s
->mem_index
, MO_LEQ
);
4352 case 0x17: /* extractps */
4353 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4354 xmm_regs
[reg
].XMM_L(val
& 3)));
4356 gen_op_mov_reg_T0(ot
, rm
);
4358 tcg_gen_qemu_st_tl(cpu_T
[0], cpu_A0
,
4359 s
->mem_index
, MO_LEUL
);
4362 case 0x20: /* pinsrb */
4364 gen_op_mov_TN_reg(MO_32
, 0, rm
);
4366 tcg_gen_qemu_ld_tl(cpu_T
[0], cpu_A0
,
4367 s
->mem_index
, MO_UB
);
4369 tcg_gen_st8_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4370 xmm_regs
[reg
].XMM_B(val
& 15)));
4372 case 0x21: /* insertps */
4374 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4375 offsetof(CPUX86State
,xmm_regs
[rm
]
4376 .XMM_L((val
>> 6) & 3)));
4378 tcg_gen_qemu_ld_i32(cpu_tmp2_i32
, cpu_A0
,
4379 s
->mem_index
, MO_LEUL
);
4381 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4382 offsetof(CPUX86State
,xmm_regs
[reg
]
4383 .XMM_L((val
>> 4) & 3)));
4385 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4386 cpu_env
, offsetof(CPUX86State
,
4387 xmm_regs
[reg
].XMM_L(0)));
4389 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4390 cpu_env
, offsetof(CPUX86State
,
4391 xmm_regs
[reg
].XMM_L(1)));
4393 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4394 cpu_env
, offsetof(CPUX86State
,
4395 xmm_regs
[reg
].XMM_L(2)));
4397 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4398 cpu_env
, offsetof(CPUX86State
,
4399 xmm_regs
[reg
].XMM_L(3)));
4402 if (ot
== MO_32
) { /* pinsrd */
4404 gen_op_mov_v_reg(ot
, cpu_tmp0
, rm
);
4406 tcg_gen_qemu_ld_tl(cpu_tmp0
, cpu_A0
,
4407 s
->mem_index
, MO_LEUL
);
4409 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_tmp0
);
4410 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4411 offsetof(CPUX86State
,
4412 xmm_regs
[reg
].XMM_L(val
& 3)));
4413 } else { /* pinsrq */
4414 #ifdef TARGET_X86_64
4416 gen_op_mov_v_reg(ot
, cpu_tmp1_i64
, rm
);
4418 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
4419 s
->mem_index
, MO_LEQ
);
4421 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
4422 offsetof(CPUX86State
,
4423 xmm_regs
[reg
].XMM_Q(val
& 1)));
4434 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4436 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
4438 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4439 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4440 gen_ldo_env_A0(s
, op2_offset
);
4443 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4445 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4447 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4448 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4449 gen_ldq_env_A0(s
, op2_offset
);
4452 val
= cpu_ldub_code(env
, s
->pc
++);
4454 if ((b
& 0xfc) == 0x60) { /* pcmpXstrX */
4455 set_cc_op(s
, CC_OP_EFLAGS
);
4458 /* The helper must use entire 64-bit gp registers */
4462 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4463 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4464 sse_fn_eppi(cpu_env
, cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4468 /* Various integer extensions at 0f 3a f[0-f]. */
4469 b
= modrm
| (b1
<< 8);
4470 modrm
= cpu_ldub_code(env
, s
->pc
++);
4471 reg
= ((modrm
>> 3) & 7) | rex_r
;
4474 case 0x3f0: /* rorx Gy,Ey, Ib */
4475 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4476 || !(s
->prefix
& PREFIX_VEX
)
4480 ot
= s
->dflag
== 2 ? MO_64
: MO_32
;
4481 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4482 b
= cpu_ldub_code(env
, s
->pc
++);
4484 tcg_gen_rotri_tl(cpu_T
[0], cpu_T
[0], b
& 63);
4486 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4487 tcg_gen_rotri_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, b
& 31);
4488 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
4490 gen_op_mov_reg_T0(ot
, reg
);
4502 /* generic MMX or SSE operation */
4504 case 0x70: /* pshufx insn */
4505 case 0xc6: /* pshufx insn */
4506 case 0xc2: /* compare insns */
4513 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4515 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4516 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4517 if (b1
>= 2 && ((b
>= 0x50 && b
<= 0x5f && b
!= 0x5b) ||
4519 /* specific case for SSE single instructions */
4522 gen_op_ld_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
4523 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.XMM_L(0)));
4526 gen_ldq_env_A0(s
, offsetof(CPUX86State
,
4530 gen_ldo_env_A0(s
, op2_offset
);
4533 rm
= (modrm
& 7) | REX_B(s
);
4534 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
4537 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4539 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4540 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4541 gen_ldq_env_A0(s
, op2_offset
);
4544 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4548 case 0x0f: /* 3DNow! data insns */
4549 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
))
4551 val
= cpu_ldub_code(env
, s
->pc
++);
4552 sse_fn_epp
= sse_op_table5
[val
];
4556 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4557 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4558 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4560 case 0x70: /* pshufx insn */
4561 case 0xc6: /* pshufx insn */
4562 val
= cpu_ldub_code(env
, s
->pc
++);
4563 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4564 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4565 /* XXX: introduce a new table? */
4566 sse_fn_ppi
= (SSEFunc_0_ppi
)sse_fn_epp
;
4567 sse_fn_ppi(cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4571 val
= cpu_ldub_code(env
, s
->pc
++);
4574 sse_fn_epp
= sse_op_table4
[val
][b1
];
4576 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4577 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4578 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4581 /* maskmov : we must prepare A0 */
4584 #ifdef TARGET_X86_64
4585 if (s
->aflag
== 2) {
4586 gen_op_movq_A0_reg(R_EDI
);
4590 gen_op_movl_A0_reg(R_EDI
);
4592 gen_op_andl_A0_ffff();
4594 gen_add_A0_ds_seg(s
);
4596 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4597 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4598 /* XXX: introduce a new table? */
4599 sse_fn_eppt
= (SSEFunc_0_eppt
)sse_fn_epp
;
4600 sse_fn_eppt(cpu_env
, cpu_ptr0
, cpu_ptr1
, cpu_A0
);
4603 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4604 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4605 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4608 if (b
== 0x2e || b
== 0x2f) {
4609 set_cc_op(s
, CC_OP_EFLAGS
);
4614 /* convert one instruction. s->is_jmp is set if the translation must
4615 be stopped. Return the next pc value */
4616 static target_ulong
disas_insn(CPUX86State
*env
, DisasContext
*s
,
4617 target_ulong pc_start
)
4619 int b
, prefixes
, aflag
, dflag
;
4621 int modrm
, reg
, rm
, mod
, reg_addr
, op
, opreg
, offset_addr
, val
;
4622 target_ulong next_eip
, tval
;
4625 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
4626 tcg_gen_debug_insn_start(pc_start
);
4633 #ifdef TARGET_X86_64
4638 s
->rip_offset
= 0; /* for relative ip address */
4642 b
= cpu_ldub_code(env
, s
->pc
);
4644 /* Collect prefixes. */
4647 prefixes
|= PREFIX_REPZ
;
4650 prefixes
|= PREFIX_REPNZ
;
4653 prefixes
|= PREFIX_LOCK
;
4674 prefixes
|= PREFIX_DATA
;
4677 prefixes
|= PREFIX_ADR
;
4679 #ifdef TARGET_X86_64
4683 rex_w
= (b
>> 3) & 1;
4684 rex_r
= (b
& 0x4) << 1;
4685 s
->rex_x
= (b
& 0x2) << 2;
4686 REX_B(s
) = (b
& 0x1) << 3;
4687 x86_64_hregs
= 1; /* select uniform byte register addressing */
4692 case 0xc5: /* 2-byte VEX */
4693 case 0xc4: /* 3-byte VEX */
4694 /* VEX prefixes cannot be used except in 32-bit mode.
4695 Otherwise the instruction is LES or LDS. */
4696 if (s
->code32
&& !s
->vm86
) {
4697 static const int pp_prefix
[4] = {
4698 0, PREFIX_DATA
, PREFIX_REPZ
, PREFIX_REPNZ
4700 int vex3
, vex2
= cpu_ldub_code(env
, s
->pc
);
4702 if (!CODE64(s
) && (vex2
& 0xc0) != 0xc0) {
4703 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4704 otherwise the instruction is LES or LDS. */
4709 /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
4710 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
4711 | PREFIX_LOCK
| PREFIX_DATA
)) {
4714 #ifdef TARGET_X86_64
4719 rex_r
= (~vex2
>> 4) & 8;
4722 b
= cpu_ldub_code(env
, s
->pc
++);
4724 #ifdef TARGET_X86_64
4725 s
->rex_x
= (~vex2
>> 3) & 8;
4726 s
->rex_b
= (~vex2
>> 2) & 8;
4728 vex3
= cpu_ldub_code(env
, s
->pc
++);
4729 rex_w
= (vex3
>> 7) & 1;
4730 switch (vex2
& 0x1f) {
4731 case 0x01: /* Implied 0f leading opcode bytes. */
4732 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4734 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4737 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4740 default: /* Reserved for future use. */
4744 s
->vex_v
= (~vex3
>> 3) & 0xf;
4745 s
->vex_l
= (vex3
>> 2) & 1;
4746 prefixes
|= pp_prefix
[vex3
& 3] | PREFIX_VEX
;
4751 /* Post-process prefixes. */
4753 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit
4754 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4755 over 0x66 if both are present. */
4756 dflag
= (rex_w
> 0 ? 2 : prefixes
& PREFIX_DATA
? 0 : 1);
4757 /* In 64-bit mode, 0x67 selects 32-bit addressing. */
4758 aflag
= (prefixes
& PREFIX_ADR
? 1 : 2);
4760 /* In 16/32-bit mode, 0x66 selects the opposite data size. */
4762 if (prefixes
& PREFIX_DATA
) {
4765 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */
4767 if (prefixes
& PREFIX_ADR
) {
4772 s
->prefix
= prefixes
;
4776 /* lock generation */
4777 if (prefixes
& PREFIX_LOCK
)
4780 /* now check op code */
4784 /**************************/
4785 /* extended op code */
4786 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4789 /**************************/
4810 case 0: /* OP Ev, Gv */
4811 modrm
= cpu_ldub_code(env
, s
->pc
++);
4812 reg
= ((modrm
>> 3) & 7) | rex_r
;
4813 mod
= (modrm
>> 6) & 3;
4814 rm
= (modrm
& 7) | REX_B(s
);
4816 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4818 } else if (op
== OP_XORL
&& rm
== reg
) {
4820 /* xor reg, reg optimisation */
4821 set_cc_op(s
, CC_OP_CLR
);
4823 gen_op_mov_reg_T0(ot
, reg
);
4828 gen_op_mov_TN_reg(ot
, 1, reg
);
4829 gen_op(s
, op
, ot
, opreg
);
4831 case 1: /* OP Gv, Ev */
4832 modrm
= cpu_ldub_code(env
, s
->pc
++);
4833 mod
= (modrm
>> 6) & 3;
4834 reg
= ((modrm
>> 3) & 7) | rex_r
;
4835 rm
= (modrm
& 7) | REX_B(s
);
4837 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4838 gen_op_ld_T1_A0(s
, ot
);
4839 } else if (op
== OP_XORL
&& rm
== reg
) {
4842 gen_op_mov_TN_reg(ot
, 1, rm
);
4844 gen_op(s
, op
, ot
, reg
);
4846 case 2: /* OP A, Iv */
4847 val
= insn_get(env
, s
, ot
);
4848 gen_op_movl_T1_im(val
);
4849 gen_op(s
, op
, ot
, OR_EAX
);
4858 case 0x80: /* GRP1 */
4869 modrm
= cpu_ldub_code(env
, s
->pc
++);
4870 mod
= (modrm
>> 6) & 3;
4871 rm
= (modrm
& 7) | REX_B(s
);
4872 op
= (modrm
>> 3) & 7;
4878 s
->rip_offset
= insn_const_size(ot
);
4879 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4890 val
= insn_get(env
, s
, ot
);
4893 val
= (int8_t)insn_get(env
, s
, MO_8
);
4896 gen_op_movl_T1_im(val
);
4897 gen_op(s
, op
, ot
, opreg
);
4901 /**************************/
4902 /* inc, dec, and other misc arith */
4903 case 0x40 ... 0x47: /* inc Gv */
4904 ot
= dflag
? MO_32
: MO_16
;
4905 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), 1);
4907 case 0x48 ... 0x4f: /* dec Gv */
4908 ot
= dflag
? MO_32
: MO_16
;
4909 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), -1);
4911 case 0xf6: /* GRP3 */
4918 modrm
= cpu_ldub_code(env
, s
->pc
++);
4919 mod
= (modrm
>> 6) & 3;
4920 rm
= (modrm
& 7) | REX_B(s
);
4921 op
= (modrm
>> 3) & 7;
4924 s
->rip_offset
= insn_const_size(ot
);
4925 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4926 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
4928 gen_op_mov_TN_reg(ot
, 0, rm
);
4933 val
= insn_get(env
, s
, ot
);
4934 gen_op_movl_T1_im(val
);
4935 gen_op_testl_T0_T1_cc();
4936 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4939 tcg_gen_not_tl(cpu_T
[0], cpu_T
[0]);
4941 gen_op_st_T0_A0(s
, ot
);
4943 gen_op_mov_reg_T0(ot
, rm
);
4947 tcg_gen_neg_tl(cpu_T
[0], cpu_T
[0]);
4949 gen_op_st_T0_A0(s
, ot
);
4951 gen_op_mov_reg_T0(ot
, rm
);
4953 gen_op_update_neg_cc();
4954 set_cc_op(s
, CC_OP_SUBB
+ ot
);
4959 gen_op_mov_TN_reg(MO_8
, 1, R_EAX
);
4960 tcg_gen_ext8u_tl(cpu_T
[0], cpu_T
[0]);
4961 tcg_gen_ext8u_tl(cpu_T
[1], cpu_T
[1]);
4962 /* XXX: use 32 bit mul which could be faster */
4963 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4964 gen_op_mov_reg_T0(MO_16
, R_EAX
);
4965 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4966 tcg_gen_andi_tl(cpu_cc_src
, cpu_T
[0], 0xff00);
4967 set_cc_op(s
, CC_OP_MULB
);
4970 gen_op_mov_TN_reg(MO_16
, 1, R_EAX
);
4971 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
4972 tcg_gen_ext16u_tl(cpu_T
[1], cpu_T
[1]);
4973 /* XXX: use 32 bit mul which could be faster */
4974 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4975 gen_op_mov_reg_T0(MO_16
, R_EAX
);
4976 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4977 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], 16);
4978 gen_op_mov_reg_T0(MO_16
, R_EDX
);
4979 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
4980 set_cc_op(s
, CC_OP_MULW
);
4984 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4985 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
4986 tcg_gen_mulu2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
4987 cpu_tmp2_i32
, cpu_tmp3_i32
);
4988 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
4989 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
4990 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4991 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
4992 set_cc_op(s
, CC_OP_MULL
);
4994 #ifdef TARGET_X86_64
4996 tcg_gen_mulu2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
4997 cpu_T
[0], cpu_regs
[R_EAX
]);
4998 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
4999 tcg_gen_mov_tl(cpu_cc_src
, cpu_regs
[R_EDX
]);
5000 set_cc_op(s
, CC_OP_MULQ
);
5008 gen_op_mov_TN_reg(MO_8
, 1, R_EAX
);
5009 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
5010 tcg_gen_ext8s_tl(cpu_T
[1], cpu_T
[1]);
5011 /* XXX: use 32 bit mul which could be faster */
5012 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5013 gen_op_mov_reg_T0(MO_16
, R_EAX
);
5014 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5015 tcg_gen_ext8s_tl(cpu_tmp0
, cpu_T
[0]);
5016 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
5017 set_cc_op(s
, CC_OP_MULB
);
5020 gen_op_mov_TN_reg(MO_16
, 1, R_EAX
);
5021 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5022 tcg_gen_ext16s_tl(cpu_T
[1], cpu_T
[1]);
5023 /* XXX: use 32 bit mul which could be faster */
5024 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5025 gen_op_mov_reg_T0(MO_16
, R_EAX
);
5026 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5027 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T
[0]);
5028 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
5029 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], 16);
5030 gen_op_mov_reg_T0(MO_16
, R_EDX
);
5031 set_cc_op(s
, CC_OP_MULW
);
5035 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5036 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_regs
[R_EAX
]);
5037 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
5038 cpu_tmp2_i32
, cpu_tmp3_i32
);
5039 tcg_gen_extu_i32_tl(cpu_regs
[R_EAX
], cpu_tmp2_i32
);
5040 tcg_gen_extu_i32_tl(cpu_regs
[R_EDX
], cpu_tmp3_i32
);
5041 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
5042 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
5043 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
5044 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
5045 set_cc_op(s
, CC_OP_MULL
);
5047 #ifdef TARGET_X86_64
5049 tcg_gen_muls2_i64(cpu_regs
[R_EAX
], cpu_regs
[R_EDX
],
5050 cpu_T
[0], cpu_regs
[R_EAX
]);
5051 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[R_EAX
]);
5052 tcg_gen_sari_tl(cpu_cc_src
, cpu_regs
[R_EAX
], 63);
5053 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_regs
[R_EDX
]);
5054 set_cc_op(s
, CC_OP_MULQ
);
5062 gen_jmp_im(pc_start
- s
->cs_base
);
5063 gen_helper_divb_AL(cpu_env
, cpu_T
[0]);
5066 gen_jmp_im(pc_start
- s
->cs_base
);
5067 gen_helper_divw_AX(cpu_env
, cpu_T
[0]);
5071 gen_jmp_im(pc_start
- s
->cs_base
);
5072 gen_helper_divl_EAX(cpu_env
, cpu_T
[0]);
5074 #ifdef TARGET_X86_64
5076 gen_jmp_im(pc_start
- s
->cs_base
);
5077 gen_helper_divq_EAX(cpu_env
, cpu_T
[0]);
5085 gen_jmp_im(pc_start
- s
->cs_base
);
5086 gen_helper_idivb_AL(cpu_env
, cpu_T
[0]);
5089 gen_jmp_im(pc_start
- s
->cs_base
);
5090 gen_helper_idivw_AX(cpu_env
, cpu_T
[0]);
5094 gen_jmp_im(pc_start
- s
->cs_base
);
5095 gen_helper_idivl_EAX(cpu_env
, cpu_T
[0]);
5097 #ifdef TARGET_X86_64
5099 gen_jmp_im(pc_start
- s
->cs_base
);
5100 gen_helper_idivq_EAX(cpu_env
, cpu_T
[0]);
5110 case 0xfe: /* GRP4 */
5111 case 0xff: /* GRP5 */
5117 modrm
= cpu_ldub_code(env
, s
->pc
++);
5118 mod
= (modrm
>> 6) & 3;
5119 rm
= (modrm
& 7) | REX_B(s
);
5120 op
= (modrm
>> 3) & 7;
5121 if (op
>= 2 && b
== 0xfe) {
5125 if (op
== 2 || op
== 4) {
5126 /* operand size for jumps is 64 bit */
5128 } else if (op
== 3 || op
== 5) {
5129 ot
= dflag
? MO_32
+ (rex_w
== 1) : MO_16
;
5130 } else if (op
== 6) {
5131 /* default push size is 64 bit */
5132 ot
= dflag
? MO_64
: MO_16
;
5136 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5137 if (op
>= 2 && op
!= 3 && op
!= 5)
5138 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
5140 gen_op_mov_TN_reg(ot
, 0, rm
);
5144 case 0: /* inc Ev */
5149 gen_inc(s
, ot
, opreg
, 1);
5151 case 1: /* dec Ev */
5156 gen_inc(s
, ot
, opreg
, -1);
5158 case 2: /* call Ev */
5159 /* XXX: optimize if memory (no 'and' is necessary) */
5161 gen_op_andl_T0_ffff();
5162 next_eip
= s
->pc
- s
->cs_base
;
5163 gen_movtl_T1_im(next_eip
);
5168 case 3: /* lcall Ev */
5169 gen_op_ld_T1_A0(s
, ot
);
5170 gen_add_A0_im(s
, 1 << (ot
- MO_16
+ 1));
5171 gen_op_ld_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
5173 if (s
->pe
&& !s
->vm86
) {
5174 gen_update_cc_op(s
);
5175 gen_jmp_im(pc_start
- s
->cs_base
);
5176 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5177 gen_helper_lcall_protected(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
5178 tcg_const_i32(dflag
),
5179 tcg_const_i32(s
->pc
- pc_start
));
5181 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5182 gen_helper_lcall_real(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
5183 tcg_const_i32(dflag
),
5184 tcg_const_i32(s
->pc
- s
->cs_base
));
5188 case 4: /* jmp Ev */
5190 gen_op_andl_T0_ffff();
5194 case 5: /* ljmp Ev */
5195 gen_op_ld_T1_A0(s
, ot
);
5196 gen_add_A0_im(s
, 1 << (ot
- MO_16
+ 1));
5197 gen_op_ld_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
5199 if (s
->pe
&& !s
->vm86
) {
5200 gen_update_cc_op(s
);
5201 gen_jmp_im(pc_start
- s
->cs_base
);
5202 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5203 gen_helper_ljmp_protected(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
5204 tcg_const_i32(s
->pc
- pc_start
));
5206 gen_op_movl_seg_T0_vm(R_CS
);
5207 gen_op_movl_T0_T1();
5212 case 6: /* push Ev */
5220 case 0x84: /* test Ev, Gv */
5227 modrm
= cpu_ldub_code(env
, s
->pc
++);
5228 reg
= ((modrm
>> 3) & 7) | rex_r
;
5230 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5231 gen_op_mov_TN_reg(ot
, 1, reg
);
5232 gen_op_testl_T0_T1_cc();
5233 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5236 case 0xa8: /* test eAX, Iv */
5242 val
= insn_get(env
, s
, ot
);
5244 gen_op_mov_TN_reg(ot
, 0, OR_EAX
);
5245 gen_op_movl_T1_im(val
);
5246 gen_op_testl_T0_T1_cc();
5247 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5250 case 0x98: /* CWDE/CBW */
5251 #ifdef TARGET_X86_64
5253 gen_op_mov_TN_reg(MO_32
, 0, R_EAX
);
5254 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
5255 gen_op_mov_reg_T0(MO_64
, R_EAX
);
5259 gen_op_mov_TN_reg(MO_16
, 0, R_EAX
);
5260 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5261 gen_op_mov_reg_T0(MO_32
, R_EAX
);
5263 gen_op_mov_TN_reg(MO_8
, 0, R_EAX
);
5264 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
5265 gen_op_mov_reg_T0(MO_16
, R_EAX
);
5268 case 0x99: /* CDQ/CWD */
5269 #ifdef TARGET_X86_64
5271 gen_op_mov_TN_reg(MO_64
, 0, R_EAX
);
5272 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 63);
5273 gen_op_mov_reg_T0(MO_64
, R_EDX
);
5277 gen_op_mov_TN_reg(MO_32
, 0, R_EAX
);
5278 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
5279 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 31);
5280 gen_op_mov_reg_T0(MO_32
, R_EDX
);
5282 gen_op_mov_TN_reg(MO_16
, 0, R_EAX
);
5283 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5284 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 15);
5285 gen_op_mov_reg_T0(MO_16
, R_EDX
);
5288 case 0x1af: /* imul Gv, Ev */
5289 case 0x69: /* imul Gv, Ev, I */
5292 modrm
= cpu_ldub_code(env
, s
->pc
++);
5293 reg
= ((modrm
>> 3) & 7) | rex_r
;
5295 s
->rip_offset
= insn_const_size(ot
);
5298 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5300 val
= insn_get(env
, s
, ot
);
5301 gen_op_movl_T1_im(val
);
5302 } else if (b
== 0x6b) {
5303 val
= (int8_t)insn_get(env
, s
, MO_8
);
5304 gen_op_movl_T1_im(val
);
5306 gen_op_mov_TN_reg(ot
, 1, reg
);
5309 #ifdef TARGET_X86_64
5311 tcg_gen_muls2_i64(cpu_regs
[reg
], cpu_T
[1], cpu_T
[0], cpu_T
[1]);
5312 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5313 tcg_gen_sari_tl(cpu_cc_src
, cpu_cc_dst
, 63);
5314 tcg_gen_sub_tl(cpu_cc_src
, cpu_cc_src
, cpu_T
[1]);
5318 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5319 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
5320 tcg_gen_muls2_i32(cpu_tmp2_i32
, cpu_tmp3_i32
,
5321 cpu_tmp2_i32
, cpu_tmp3_i32
);
5322 tcg_gen_extu_i32_tl(cpu_regs
[reg
], cpu_tmp2_i32
);
5323 tcg_gen_sari_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 31);
5324 tcg_gen_mov_tl(cpu_cc_dst
, cpu_regs
[reg
]);
5325 tcg_gen_sub_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, cpu_tmp3_i32
);
5326 tcg_gen_extu_i32_tl(cpu_cc_src
, cpu_tmp2_i32
);
5329 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5330 tcg_gen_ext16s_tl(cpu_T
[1], cpu_T
[1]);
5331 /* XXX: use 32 bit mul which could be faster */
5332 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5333 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5334 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T
[0]);
5335 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
5336 gen_op_mov_reg_T0(ot
, reg
);
5339 set_cc_op(s
, CC_OP_MULB
+ ot
);
5342 case 0x1c1: /* xadd Ev, Gv */
5347 modrm
= cpu_ldub_code(env
, s
->pc
++);
5348 reg
= ((modrm
>> 3) & 7) | rex_r
;
5349 mod
= (modrm
>> 6) & 3;
5351 rm
= (modrm
& 7) | REX_B(s
);
5352 gen_op_mov_TN_reg(ot
, 0, reg
);
5353 gen_op_mov_TN_reg(ot
, 1, rm
);
5354 gen_op_addl_T0_T1();
5355 gen_op_mov_reg_T1(ot
, reg
);
5356 gen_op_mov_reg_T0(ot
, rm
);
5358 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5359 gen_op_mov_TN_reg(ot
, 0, reg
);
5360 gen_op_ld_T1_A0(s
, ot
);
5361 gen_op_addl_T0_T1();
5362 gen_op_st_T0_A0(s
, ot
);
5363 gen_op_mov_reg_T1(ot
, reg
);
5365 gen_op_update2_cc();
5366 set_cc_op(s
, CC_OP_ADDB
+ ot
);
5369 case 0x1b1: /* cmpxchg Ev, Gv */
5372 TCGv t0
, t1
, t2
, a0
;
5378 modrm
= cpu_ldub_code(env
, s
->pc
++);
5379 reg
= ((modrm
>> 3) & 7) | rex_r
;
5380 mod
= (modrm
>> 6) & 3;
5381 t0
= tcg_temp_local_new();
5382 t1
= tcg_temp_local_new();
5383 t2
= tcg_temp_local_new();
5384 a0
= tcg_temp_local_new();
5385 gen_op_mov_v_reg(ot
, t1
, reg
);
5387 rm
= (modrm
& 7) | REX_B(s
);
5388 gen_op_mov_v_reg(ot
, t0
, rm
);
5390 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5391 tcg_gen_mov_tl(a0
, cpu_A0
);
5392 gen_op_ld_v(s
, ot
, t0
, a0
);
5393 rm
= 0; /* avoid warning */
5395 label1
= gen_new_label();
5396 tcg_gen_mov_tl(t2
, cpu_regs
[R_EAX
]);
5399 tcg_gen_brcond_tl(TCG_COND_EQ
, t2
, t0
, label1
);
5400 label2
= gen_new_label();
5402 gen_op_mov_reg_v(ot
, R_EAX
, t0
);
5404 gen_set_label(label1
);
5405 gen_op_mov_reg_v(ot
, rm
, t1
);
5407 /* perform no-op store cycle like physical cpu; must be
5408 before changing accumulator to ensure idempotency if
5409 the store faults and the instruction is restarted */
5410 gen_op_st_v(s
, ot
, t0
, a0
);
5411 gen_op_mov_reg_v(ot
, R_EAX
, t0
);
5413 gen_set_label(label1
);
5414 gen_op_st_v(s
, ot
, t1
, a0
);
5416 gen_set_label(label2
);
5417 tcg_gen_mov_tl(cpu_cc_src
, t0
);
5418 tcg_gen_mov_tl(cpu_cc_srcT
, t2
);
5419 tcg_gen_sub_tl(cpu_cc_dst
, t2
, t0
);
5420 set_cc_op(s
, CC_OP_SUBB
+ ot
);
5427 case 0x1c7: /* cmpxchg8b */
5428 modrm
= cpu_ldub_code(env
, s
->pc
++);
5429 mod
= (modrm
>> 6) & 3;
5430 if ((mod
== 3) || ((modrm
& 0x38) != 0x8))
5432 #ifdef TARGET_X86_64
5434 if (!(s
->cpuid_ext_features
& CPUID_EXT_CX16
))
5436 gen_jmp_im(pc_start
- s
->cs_base
);
5437 gen_update_cc_op(s
);
5438 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5439 gen_helper_cmpxchg16b(cpu_env
, cpu_A0
);
5443 if (!(s
->cpuid_features
& CPUID_CX8
))
5445 gen_jmp_im(pc_start
- s
->cs_base
);
5446 gen_update_cc_op(s
);
5447 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5448 gen_helper_cmpxchg8b(cpu_env
, cpu_A0
);
5450 set_cc_op(s
, CC_OP_EFLAGS
);
5453 /**************************/
5455 case 0x50 ... 0x57: /* push */
5456 gen_op_mov_TN_reg(MO_32
, 0, (b
& 7) | REX_B(s
));
5459 case 0x58 ... 0x5f: /* pop */
5461 ot
= dflag
? MO_64
: MO_16
;
5466 /* NOTE: order is important for pop %sp */
5468 gen_op_mov_reg_T0(ot
, (b
& 7) | REX_B(s
));
5470 case 0x60: /* pusha */
5475 case 0x61: /* popa */
5480 case 0x68: /* push Iv */
5483 ot
= dflag
? MO_64
: MO_16
;
5488 val
= insn_get(env
, s
, ot
);
5490 val
= (int8_t)insn_get(env
, s
, MO_8
);
5491 gen_op_movl_T0_im(val
);
5494 case 0x8f: /* pop Ev */
5496 ot
= dflag
? MO_64
: MO_16
;
5500 modrm
= cpu_ldub_code(env
, s
->pc
++);
5501 mod
= (modrm
>> 6) & 3;
5504 /* NOTE: order is important for pop %sp */
5506 rm
= (modrm
& 7) | REX_B(s
);
5507 gen_op_mov_reg_T0(ot
, rm
);
5509 /* NOTE: order is important too for MMU exceptions */
5510 s
->popl_esp_hack
= 1 << ot
;
5511 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5512 s
->popl_esp_hack
= 0;
5516 case 0xc8: /* enter */
5519 val
= cpu_lduw_code(env
, s
->pc
);
5521 level
= cpu_ldub_code(env
, s
->pc
++);
5522 gen_enter(s
, val
, level
);
5525 case 0xc9: /* leave */
5526 /* XXX: exception not precise (ESP is updated before potential exception) */
5528 gen_op_mov_TN_reg(MO_64
, 0, R_EBP
);
5529 gen_op_mov_reg_T0(MO_64
, R_ESP
);
5530 } else if (s
->ss32
) {
5531 gen_op_mov_TN_reg(MO_32
, 0, R_EBP
);
5532 gen_op_mov_reg_T0(MO_32
, R_ESP
);
5534 gen_op_mov_TN_reg(MO_16
, 0, R_EBP
);
5535 gen_op_mov_reg_T0(MO_16
, R_ESP
);
5539 ot
= dflag
? MO_64
: MO_16
;
5543 gen_op_mov_reg_T0(ot
, R_EBP
);
5546 case 0x06: /* push es */
5547 case 0x0e: /* push cs */
5548 case 0x16: /* push ss */
5549 case 0x1e: /* push ds */
5552 gen_op_movl_T0_seg(b
>> 3);
5555 case 0x1a0: /* push fs */
5556 case 0x1a8: /* push gs */
5557 gen_op_movl_T0_seg((b
>> 3) & 7);
5560 case 0x07: /* pop es */
5561 case 0x17: /* pop ss */
5562 case 0x1f: /* pop ds */
5567 gen_movl_seg_T0(s
, reg
, pc_start
- s
->cs_base
);
5570 /* if reg == SS, inhibit interrupts/trace. */
5571 /* If several instructions disable interrupts, only the
5573 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
5574 gen_helper_set_inhibit_irq(cpu_env
);
5578 gen_jmp_im(s
->pc
- s
->cs_base
);
5582 case 0x1a1: /* pop fs */
5583 case 0x1a9: /* pop gs */
5585 gen_movl_seg_T0(s
, (b
>> 3) & 7, pc_start
- s
->cs_base
);
5588 gen_jmp_im(s
->pc
- s
->cs_base
);
5593 /**************************/
5596 case 0x89: /* mov Gv, Ev */
5601 modrm
= cpu_ldub_code(env
, s
->pc
++);
5602 reg
= ((modrm
>> 3) & 7) | rex_r
;
5604 /* generate a generic store */
5605 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
5608 case 0xc7: /* mov Ev, Iv */
5613 modrm
= cpu_ldub_code(env
, s
->pc
++);
5614 mod
= (modrm
>> 6) & 3;
5616 s
->rip_offset
= insn_const_size(ot
);
5617 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5619 val
= insn_get(env
, s
, ot
);
5620 gen_op_movl_T0_im(val
);
5622 gen_op_st_T0_A0(s
, ot
);
5624 gen_op_mov_reg_T0(ot
, (modrm
& 7) | REX_B(s
));
5627 case 0x8b: /* mov Ev, Gv */
5632 modrm
= cpu_ldub_code(env
, s
->pc
++);
5633 reg
= ((modrm
>> 3) & 7) | rex_r
;
5635 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5636 gen_op_mov_reg_T0(ot
, reg
);
5638 case 0x8e: /* mov seg, Gv */
5639 modrm
= cpu_ldub_code(env
, s
->pc
++);
5640 reg
= (modrm
>> 3) & 7;
5641 if (reg
>= 6 || reg
== R_CS
)
5643 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
5644 gen_movl_seg_T0(s
, reg
, pc_start
- s
->cs_base
);
5646 /* if reg == SS, inhibit interrupts/trace */
5647 /* If several instructions disable interrupts, only the
5649 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
5650 gen_helper_set_inhibit_irq(cpu_env
);
5654 gen_jmp_im(s
->pc
- s
->cs_base
);
5658 case 0x8c: /* mov Gv, seg */
5659 modrm
= cpu_ldub_code(env
, s
->pc
++);
5660 reg
= (modrm
>> 3) & 7;
5661 mod
= (modrm
>> 6) & 3;
5664 gen_op_movl_T0_seg(reg
);
5669 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5672 case 0x1b6: /* movzbS Gv, Eb */
5673 case 0x1b7: /* movzwS Gv, Eb */
5674 case 0x1be: /* movsbS Gv, Eb */
5675 case 0x1bf: /* movswS Gv, Eb */
5678 /* d_ot is the size of destination */
5679 d_ot
= dflag
+ MO_16
;
5680 /* ot is the size of source */
5681 ot
= (b
& 1) + MO_8
;
5682 modrm
= cpu_ldub_code(env
, s
->pc
++);
5683 reg
= ((modrm
>> 3) & 7) | rex_r
;
5684 mod
= (modrm
>> 6) & 3;
5685 rm
= (modrm
& 7) | REX_B(s
);
5688 gen_op_mov_TN_reg(ot
, 0, rm
);
5689 switch(ot
| (b
& 8)) {
5691 tcg_gen_ext8u_tl(cpu_T
[0], cpu_T
[0]);
5694 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
5697 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
5701 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5704 gen_op_mov_reg_T0(d_ot
, reg
);
5706 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5708 gen_op_lds_T0_A0(s
, ot
);
5710 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
5712 gen_op_mov_reg_T0(d_ot
, reg
);
5717 case 0x8d: /* lea */
5719 modrm
= cpu_ldub_code(env
, s
->pc
++);
5720 mod
= (modrm
>> 6) & 3;
5723 reg
= ((modrm
>> 3) & 7) | rex_r
;
5724 /* we must ensure that no segment is added */
5728 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5730 gen_op_mov_reg_A0(ot
- MO_16
, reg
);
5733 case 0xa0: /* mov EAX, Ov */
5735 case 0xa2: /* mov Ov, EAX */
5738 target_ulong offset_addr
;
5744 #ifdef TARGET_X86_64
5745 if (s
->aflag
== 2) {
5746 offset_addr
= cpu_ldq_code(env
, s
->pc
);
5748 gen_op_movq_A0_im(offset_addr
);
5753 offset_addr
= insn_get(env
, s
, MO_32
);
5755 offset_addr
= insn_get(env
, s
, MO_16
);
5757 gen_op_movl_A0_im(offset_addr
);
5759 gen_add_A0_ds_seg(s
);
5761 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
5762 gen_op_mov_reg_T0(ot
, R_EAX
);
5764 gen_op_mov_TN_reg(ot
, 0, R_EAX
);
5765 gen_op_st_T0_A0(s
, ot
);
5769 case 0xd7: /* xlat */
5770 #ifdef TARGET_X86_64
5771 if (s
->aflag
== 2) {
5772 gen_op_movq_A0_reg(R_EBX
);
5773 gen_op_mov_TN_reg(MO_64
, 0, R_EAX
);
5774 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xff);
5775 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_T
[0]);
5779 gen_op_movl_A0_reg(R_EBX
);
5780 gen_op_mov_TN_reg(MO_32
, 0, R_EAX
);
5781 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xff);
5782 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_T
[0]);
5784 gen_op_andl_A0_ffff();
5786 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffffffff);
5788 gen_add_A0_ds_seg(s
);
5789 gen_op_ld_v(s
, MO_8
, cpu_T
[0], cpu_A0
);
5790 gen_op_mov_reg_T0(MO_8
, R_EAX
);
5792 case 0xb0 ... 0xb7: /* mov R, Ib */
5793 val
= insn_get(env
, s
, MO_8
);
5794 gen_op_movl_T0_im(val
);
5795 gen_op_mov_reg_T0(MO_8
, (b
& 7) | REX_B(s
));
5797 case 0xb8 ... 0xbf: /* mov R, Iv */
5798 #ifdef TARGET_X86_64
5802 tmp
= cpu_ldq_code(env
, s
->pc
);
5804 reg
= (b
& 7) | REX_B(s
);
5805 gen_movtl_T0_im(tmp
);
5806 gen_op_mov_reg_T0(MO_64
, reg
);
5810 ot
= dflag
? MO_32
: MO_16
;
5811 val
= insn_get(env
, s
, ot
);
5812 reg
= (b
& 7) | REX_B(s
);
5813 gen_op_movl_T0_im(val
);
5814 gen_op_mov_reg_T0(ot
, reg
);
5818 case 0x91 ... 0x97: /* xchg R, EAX */
5821 reg
= (b
& 7) | REX_B(s
);
5825 case 0x87: /* xchg Ev, Gv */
5830 modrm
= cpu_ldub_code(env
, s
->pc
++);
5831 reg
= ((modrm
>> 3) & 7) | rex_r
;
5832 mod
= (modrm
>> 6) & 3;
5834 rm
= (modrm
& 7) | REX_B(s
);
5836 gen_op_mov_TN_reg(ot
, 0, reg
);
5837 gen_op_mov_TN_reg(ot
, 1, rm
);
5838 gen_op_mov_reg_T0(ot
, rm
);
5839 gen_op_mov_reg_T1(ot
, reg
);
5841 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5842 gen_op_mov_TN_reg(ot
, 0, reg
);
5843 /* for xchg, lock is implicit */
5844 if (!(prefixes
& PREFIX_LOCK
))
5846 gen_op_ld_T1_A0(s
, ot
);
5847 gen_op_st_T0_A0(s
, ot
);
5848 if (!(prefixes
& PREFIX_LOCK
))
5849 gen_helper_unlock();
5850 gen_op_mov_reg_T1(ot
, reg
);
5853 case 0xc4: /* les Gv */
5854 /* In CODE64 this is VEX3; see above. */
5857 case 0xc5: /* lds Gv */
5858 /* In CODE64 this is VEX2; see above. */
5861 case 0x1b2: /* lss Gv */
5864 case 0x1b4: /* lfs Gv */
5867 case 0x1b5: /* lgs Gv */
5870 ot
= dflag
? MO_32
: MO_16
;
5871 modrm
= cpu_ldub_code(env
, s
->pc
++);
5872 reg
= ((modrm
>> 3) & 7) | rex_r
;
5873 mod
= (modrm
>> 6) & 3;
5876 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5877 gen_op_ld_T1_A0(s
, ot
);
5878 gen_add_A0_im(s
, 1 << (ot
- MO_16
+ 1));
5879 /* load the segment first to handle exceptions properly */
5880 gen_op_ld_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
5881 gen_movl_seg_T0(s
, op
, pc_start
- s
->cs_base
);
5882 /* then put the data */
5883 gen_op_mov_reg_T1(ot
, reg
);
5885 gen_jmp_im(s
->pc
- s
->cs_base
);
5890 /************************/
5903 modrm
= cpu_ldub_code(env
, s
->pc
++);
5904 mod
= (modrm
>> 6) & 3;
5905 op
= (modrm
>> 3) & 7;
5911 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5914 opreg
= (modrm
& 7) | REX_B(s
);
5919 gen_shift(s
, op
, ot
, opreg
, OR_ECX
);
5922 shift
= cpu_ldub_code(env
, s
->pc
++);
5924 gen_shifti(s
, op
, ot
, opreg
, shift
);
5939 case 0x1a4: /* shld imm */
5943 case 0x1a5: /* shld cl */
5947 case 0x1ac: /* shrd imm */
5951 case 0x1ad: /* shrd cl */
5956 modrm
= cpu_ldub_code(env
, s
->pc
++);
5957 mod
= (modrm
>> 6) & 3;
5958 rm
= (modrm
& 7) | REX_B(s
);
5959 reg
= ((modrm
>> 3) & 7) | rex_r
;
5961 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5966 gen_op_mov_TN_reg(ot
, 1, reg
);
5969 TCGv imm
= tcg_const_tl(cpu_ldub_code(env
, s
->pc
++));
5970 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, imm
);
5973 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, cpu_regs
[R_ECX
]);
5977 /************************/
5980 if (s
->flags
& (HF_EM_MASK
| HF_TS_MASK
)) {
5981 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5982 /* XXX: what to do if illegal op ? */
5983 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
5986 modrm
= cpu_ldub_code(env
, s
->pc
++);
5987 mod
= (modrm
>> 6) & 3;
5989 op
= ((b
& 7) << 3) | ((modrm
>> 3) & 7);
5992 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5994 case 0x00 ... 0x07: /* fxxxs */
5995 case 0x10 ... 0x17: /* fixxxl */
5996 case 0x20 ... 0x27: /* fxxxl */
5997 case 0x30 ... 0x37: /* fixxx */
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_flds_FT0(cpu_env
, cpu_tmp2_i32
);
6009 gen_op_ld_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
6010 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6011 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
6014 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
6015 s
->mem_index
, MO_LEQ
);
6016 gen_helper_fldl_FT0(cpu_env
, cpu_tmp1_i64
);
6020 gen_op_lds_T0_A0(s
, MO_16
);
6021 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6022 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
6026 gen_helper_fp_arith_ST0_FT0(op1
);
6028 /* fcomp needs pop */
6029 gen_helper_fpop(cpu_env
);
6033 case 0x08: /* flds */
6034 case 0x0a: /* fsts */
6035 case 0x0b: /* fstps */
6036 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
6037 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
6038 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
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_flds_ST0(cpu_env
, cpu_tmp2_i32
);
6048 gen_op_ld_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
6049 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6050 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
6053 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
,
6054 s
->mem_index
, MO_LEQ
);
6055 gen_helper_fldl_ST0(cpu_env
, cpu_tmp1_i64
);
6059 gen_op_lds_T0_A0(s
, MO_16
);
6060 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6061 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
6066 /* XXX: the corresponding CPUID bit must be tested ! */
6069 gen_helper_fisttl_ST0(cpu_tmp2_i32
, cpu_env
);
6070 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6071 gen_op_st_T0_A0(s
, MO_32
);
6074 gen_helper_fisttll_ST0(cpu_tmp1_i64
, cpu_env
);
6075 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
6076 s
->mem_index
, MO_LEQ
);
6080 gen_helper_fistt_ST0(cpu_tmp2_i32
, cpu_env
);
6081 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6082 gen_op_st_T0_A0(s
, MO_16
);
6085 gen_helper_fpop(cpu_env
);
6090 gen_helper_fsts_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_fistl_ST0(cpu_tmp2_i32
, cpu_env
);
6096 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6097 gen_op_st_T0_A0(s
, MO_32
);
6100 gen_helper_fstl_ST0(cpu_tmp1_i64
, cpu_env
);
6101 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
,
6102 s
->mem_index
, MO_LEQ
);
6106 gen_helper_fist_ST0(cpu_tmp2_i32
, cpu_env
);
6107 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6108 gen_op_st_T0_A0(s
, MO_16
);
6112 gen_helper_fpop(cpu_env
);
6116 case 0x0c: /* fldenv mem */
6117 gen_update_cc_op(s
);
6118 gen_jmp_im(pc_start
- s
->cs_base
);
6119 gen_helper_fldenv(cpu_env
, cpu_A0
, tcg_const_i32(s
->dflag
));
6121 case 0x0d: /* fldcw mem */
6122 gen_op_ld_v(s
, MO_16
, cpu_T
[0], cpu_A0
);
6123 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6124 gen_helper_fldcw(cpu_env
, cpu_tmp2_i32
);
6126 case 0x0e: /* fnstenv mem */
6127 gen_update_cc_op(s
);
6128 gen_jmp_im(pc_start
- s
->cs_base
);
6129 gen_helper_fstenv(cpu_env
, cpu_A0
, tcg_const_i32(s
->dflag
));
6131 case 0x0f: /* fnstcw mem */
6132 gen_helper_fnstcw(cpu_tmp2_i32
, cpu_env
);
6133 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6134 gen_op_st_T0_A0(s
, MO_16
);
6136 case 0x1d: /* fldt mem */
6137 gen_update_cc_op(s
);
6138 gen_jmp_im(pc_start
- s
->cs_base
);
6139 gen_helper_fldt_ST0(cpu_env
, cpu_A0
);
6141 case 0x1f: /* fstpt mem */
6142 gen_update_cc_op(s
);
6143 gen_jmp_im(pc_start
- s
->cs_base
);
6144 gen_helper_fstt_ST0(cpu_env
, cpu_A0
);
6145 gen_helper_fpop(cpu_env
);
6147 case 0x2c: /* frstor mem */
6148 gen_update_cc_op(s
);
6149 gen_jmp_im(pc_start
- s
->cs_base
);
6150 gen_helper_frstor(cpu_env
, cpu_A0
, tcg_const_i32(s
->dflag
));
6152 case 0x2e: /* fnsave mem */
6153 gen_update_cc_op(s
);
6154 gen_jmp_im(pc_start
- s
->cs_base
);
6155 gen_helper_fsave(cpu_env
, cpu_A0
, tcg_const_i32(s
->dflag
));
6157 case 0x2f: /* fnstsw mem */
6158 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
6159 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6160 gen_op_st_T0_A0(s
, MO_16
);
6162 case 0x3c: /* fbld */
6163 gen_update_cc_op(s
);
6164 gen_jmp_im(pc_start
- s
->cs_base
);
6165 gen_helper_fbld_ST0(cpu_env
, cpu_A0
);
6167 case 0x3e: /* fbstp */
6168 gen_update_cc_op(s
);
6169 gen_jmp_im(pc_start
- s
->cs_base
);
6170 gen_helper_fbst_ST0(cpu_env
, cpu_A0
);
6171 gen_helper_fpop(cpu_env
);
6173 case 0x3d: /* fildll */
6174 tcg_gen_qemu_ld_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
6175 gen_helper_fildll_ST0(cpu_env
, cpu_tmp1_i64
);
6177 case 0x3f: /* fistpll */
6178 gen_helper_fistll_ST0(cpu_tmp1_i64
, cpu_env
);
6179 tcg_gen_qemu_st_i64(cpu_tmp1_i64
, cpu_A0
, s
->mem_index
, MO_LEQ
);
6180 gen_helper_fpop(cpu_env
);
6186 /* register float ops */
6190 case 0x08: /* fld sti */
6191 gen_helper_fpush(cpu_env
);
6192 gen_helper_fmov_ST0_STN(cpu_env
,
6193 tcg_const_i32((opreg
+ 1) & 7));
6195 case 0x09: /* fxchg sti */
6196 case 0x29: /* fxchg4 sti, undocumented op */
6197 case 0x39: /* fxchg7 sti, undocumented op */
6198 gen_helper_fxchg_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6200 case 0x0a: /* grp d9/2 */
6203 /* check exceptions (FreeBSD FPU probe) */
6204 gen_update_cc_op(s
);
6205 gen_jmp_im(pc_start
- s
->cs_base
);
6206 gen_helper_fwait(cpu_env
);
6212 case 0x0c: /* grp d9/4 */
6215 gen_helper_fchs_ST0(cpu_env
);
6218 gen_helper_fabs_ST0(cpu_env
);
6221 gen_helper_fldz_FT0(cpu_env
);
6222 gen_helper_fcom_ST0_FT0(cpu_env
);
6225 gen_helper_fxam_ST0(cpu_env
);
6231 case 0x0d: /* grp d9/5 */
6235 gen_helper_fpush(cpu_env
);
6236 gen_helper_fld1_ST0(cpu_env
);
6239 gen_helper_fpush(cpu_env
);
6240 gen_helper_fldl2t_ST0(cpu_env
);
6243 gen_helper_fpush(cpu_env
);
6244 gen_helper_fldl2e_ST0(cpu_env
);
6247 gen_helper_fpush(cpu_env
);
6248 gen_helper_fldpi_ST0(cpu_env
);
6251 gen_helper_fpush(cpu_env
);
6252 gen_helper_fldlg2_ST0(cpu_env
);
6255 gen_helper_fpush(cpu_env
);
6256 gen_helper_fldln2_ST0(cpu_env
);
6259 gen_helper_fpush(cpu_env
);
6260 gen_helper_fldz_ST0(cpu_env
);
6267 case 0x0e: /* grp d9/6 */
6270 gen_helper_f2xm1(cpu_env
);
6273 gen_helper_fyl2x(cpu_env
);
6276 gen_helper_fptan(cpu_env
);
6278 case 3: /* fpatan */
6279 gen_helper_fpatan(cpu_env
);
6281 case 4: /* fxtract */
6282 gen_helper_fxtract(cpu_env
);
6284 case 5: /* fprem1 */
6285 gen_helper_fprem1(cpu_env
);
6287 case 6: /* fdecstp */
6288 gen_helper_fdecstp(cpu_env
);
6291 case 7: /* fincstp */
6292 gen_helper_fincstp(cpu_env
);
6296 case 0x0f: /* grp d9/7 */
6299 gen_helper_fprem(cpu_env
);
6301 case 1: /* fyl2xp1 */
6302 gen_helper_fyl2xp1(cpu_env
);
6305 gen_helper_fsqrt(cpu_env
);
6307 case 3: /* fsincos */
6308 gen_helper_fsincos(cpu_env
);
6310 case 5: /* fscale */
6311 gen_helper_fscale(cpu_env
);
6313 case 4: /* frndint */
6314 gen_helper_frndint(cpu_env
);
6317 gen_helper_fsin(cpu_env
);
6321 gen_helper_fcos(cpu_env
);
6325 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6326 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6327 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6333 gen_helper_fp_arith_STN_ST0(op1
, opreg
);
6335 gen_helper_fpop(cpu_env
);
6337 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6338 gen_helper_fp_arith_ST0_FT0(op1
);
6342 case 0x02: /* fcom */
6343 case 0x22: /* fcom2, undocumented op */
6344 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6345 gen_helper_fcom_ST0_FT0(cpu_env
);
6347 case 0x03: /* fcomp */
6348 case 0x23: /* fcomp3, undocumented op */
6349 case 0x32: /* fcomp5, undocumented op */
6350 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6351 gen_helper_fcom_ST0_FT0(cpu_env
);
6352 gen_helper_fpop(cpu_env
);
6354 case 0x15: /* da/5 */
6356 case 1: /* fucompp */
6357 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6358 gen_helper_fucom_ST0_FT0(cpu_env
);
6359 gen_helper_fpop(cpu_env
);
6360 gen_helper_fpop(cpu_env
);
6368 case 0: /* feni (287 only, just do nop here) */
6370 case 1: /* fdisi (287 only, just do nop here) */
6373 gen_helper_fclex(cpu_env
);
6375 case 3: /* fninit */
6376 gen_helper_fninit(cpu_env
);
6378 case 4: /* fsetpm (287 only, just do nop here) */
6384 case 0x1d: /* fucomi */
6385 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6388 gen_update_cc_op(s
);
6389 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6390 gen_helper_fucomi_ST0_FT0(cpu_env
);
6391 set_cc_op(s
, CC_OP_EFLAGS
);
6393 case 0x1e: /* fcomi */
6394 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6397 gen_update_cc_op(s
);
6398 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6399 gen_helper_fcomi_ST0_FT0(cpu_env
);
6400 set_cc_op(s
, CC_OP_EFLAGS
);
6402 case 0x28: /* ffree sti */
6403 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6405 case 0x2a: /* fst sti */
6406 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6408 case 0x2b: /* fstp sti */
6409 case 0x0b: /* fstp1 sti, undocumented op */
6410 case 0x3a: /* fstp8 sti, undocumented op */
6411 case 0x3b: /* fstp9 sti, undocumented op */
6412 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6413 gen_helper_fpop(cpu_env
);
6415 case 0x2c: /* fucom st(i) */
6416 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6417 gen_helper_fucom_ST0_FT0(cpu_env
);
6419 case 0x2d: /* fucomp st(i) */
6420 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6421 gen_helper_fucom_ST0_FT0(cpu_env
);
6422 gen_helper_fpop(cpu_env
);
6424 case 0x33: /* de/3 */
6426 case 1: /* fcompp */
6427 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6428 gen_helper_fcom_ST0_FT0(cpu_env
);
6429 gen_helper_fpop(cpu_env
);
6430 gen_helper_fpop(cpu_env
);
6436 case 0x38: /* ffreep sti, undocumented op */
6437 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6438 gen_helper_fpop(cpu_env
);
6440 case 0x3c: /* df/4 */
6443 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
6444 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6445 gen_op_mov_reg_T0(MO_16
, R_EAX
);
6451 case 0x3d: /* fucomip */
6452 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6455 gen_update_cc_op(s
);
6456 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6457 gen_helper_fucomi_ST0_FT0(cpu_env
);
6458 gen_helper_fpop(cpu_env
);
6459 set_cc_op(s
, CC_OP_EFLAGS
);
6461 case 0x3e: /* fcomip */
6462 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6465 gen_update_cc_op(s
);
6466 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6467 gen_helper_fcomi_ST0_FT0(cpu_env
);
6468 gen_helper_fpop(cpu_env
);
6469 set_cc_op(s
, CC_OP_EFLAGS
);
6471 case 0x10 ... 0x13: /* fcmovxx */
6475 static const uint8_t fcmov_cc
[8] = {
6482 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6485 op1
= fcmov_cc
[op
& 3] | (((op
>> 3) & 1) ^ 1);
6486 l1
= gen_new_label();
6487 gen_jcc1_noeob(s
, op1
, l1
);
6488 gen_helper_fmov_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6497 /************************/
6500 case 0xa4: /* movsS */
6507 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6508 gen_repz_movs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6514 case 0xaa: /* stosS */
6521 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6522 gen_repz_stos(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6527 case 0xac: /* lodsS */
6533 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6534 gen_repz_lods(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6539 case 0xae: /* scasS */
6545 if (prefixes
& PREFIX_REPNZ
) {
6546 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6547 } else if (prefixes
& PREFIX_REPZ
) {
6548 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6554 case 0xa6: /* cmpsS */
6560 if (prefixes
& PREFIX_REPNZ
) {
6561 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6562 } else if (prefixes
& PREFIX_REPZ
) {
6563 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6568 case 0x6c: /* insS */
6573 ot
= dflag
? MO_32
: MO_16
;
6574 gen_op_mov_TN_reg(MO_16
, 0, R_EDX
);
6575 gen_op_andl_T0_ffff();
6576 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6577 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
) | 4);
6578 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6579 gen_repz_ins(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6583 gen_jmp(s
, s
->pc
- s
->cs_base
);
6587 case 0x6e: /* outsS */
6592 ot
= dflag
? MO_32
: MO_16
;
6593 gen_op_mov_TN_reg(MO_16
, 0, R_EDX
);
6594 gen_op_andl_T0_ffff();
6595 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6596 svm_is_rep(prefixes
) | 4);
6597 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6598 gen_repz_outs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6602 gen_jmp(s
, s
->pc
- s
->cs_base
);
6607 /************************/
6615 ot
= dflag
? MO_32
: MO_16
;
6616 val
= cpu_ldub_code(env
, s
->pc
++);
6617 gen_op_movl_T0_im(val
);
6618 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6619 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6622 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6623 gen_helper_in_func(ot
, cpu_T
[1], cpu_tmp2_i32
);
6624 gen_op_mov_reg_T1(ot
, R_EAX
);
6627 gen_jmp(s
, s
->pc
- s
->cs_base
);
6635 ot
= dflag
? MO_32
: MO_16
;
6636 val
= cpu_ldub_code(env
, s
->pc
++);
6637 gen_op_movl_T0_im(val
);
6638 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6639 svm_is_rep(prefixes
));
6640 gen_op_mov_TN_reg(ot
, 1, R_EAX
);
6644 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6645 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
6646 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6649 gen_jmp(s
, s
->pc
- s
->cs_base
);
6657 ot
= dflag
? MO_32
: MO_16
;
6658 gen_op_mov_TN_reg(MO_16
, 0, R_EDX
);
6659 gen_op_andl_T0_ffff();
6660 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6661 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6664 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6665 gen_helper_in_func(ot
, cpu_T
[1], cpu_tmp2_i32
);
6666 gen_op_mov_reg_T1(ot
, R_EAX
);
6669 gen_jmp(s
, s
->pc
- s
->cs_base
);
6677 ot
= dflag
? MO_32
: MO_16
;
6678 gen_op_mov_TN_reg(MO_16
, 0, R_EDX
);
6679 gen_op_andl_T0_ffff();
6680 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6681 svm_is_rep(prefixes
));
6682 gen_op_mov_TN_reg(ot
, 1, R_EAX
);
6686 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6687 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
6688 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6691 gen_jmp(s
, s
->pc
- s
->cs_base
);
6695 /************************/
6697 case 0xc2: /* ret im */
6698 val
= cpu_ldsw_code(env
, s
->pc
);
6701 if (CODE64(s
) && s
->dflag
)
6703 gen_stack_update(s
, val
+ (2 << s
->dflag
));
6705 gen_op_andl_T0_ffff();
6709 case 0xc3: /* ret */
6713 gen_op_andl_T0_ffff();
6717 case 0xca: /* lret im */
6718 val
= cpu_ldsw_code(env
, s
->pc
);
6721 if (s
->pe
&& !s
->vm86
) {
6722 gen_update_cc_op(s
);
6723 gen_jmp_im(pc_start
- s
->cs_base
);
6724 gen_helper_lret_protected(cpu_env
, tcg_const_i32(s
->dflag
),
6725 tcg_const_i32(val
));
6729 gen_op_ld_v(s
, 1 + s
->dflag
, cpu_T
[0], cpu_A0
);
6731 gen_op_andl_T0_ffff();
6732 /* NOTE: keeping EIP updated is not a problem in case of
6736 gen_op_addl_A0_im(2 << s
->dflag
);
6737 gen_op_ld_v(s
, 1 + s
->dflag
, cpu_T
[0], cpu_A0
);
6738 gen_op_movl_seg_T0_vm(R_CS
);
6739 /* add stack offset */
6740 gen_stack_update(s
, val
+ (4 << s
->dflag
));
6744 case 0xcb: /* lret */
6747 case 0xcf: /* iret */
6748 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IRET
);
6751 gen_helper_iret_real(cpu_env
, tcg_const_i32(s
->dflag
));
6752 set_cc_op(s
, CC_OP_EFLAGS
);
6753 } else if (s
->vm86
) {
6755 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6757 gen_helper_iret_real(cpu_env
, tcg_const_i32(s
->dflag
));
6758 set_cc_op(s
, CC_OP_EFLAGS
);
6761 gen_update_cc_op(s
);
6762 gen_jmp_im(pc_start
- s
->cs_base
);
6763 gen_helper_iret_protected(cpu_env
, tcg_const_i32(s
->dflag
),
6764 tcg_const_i32(s
->pc
- s
->cs_base
));
6765 set_cc_op(s
, CC_OP_EFLAGS
);
6769 case 0xe8: /* call im */
6772 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6774 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6775 next_eip
= s
->pc
- s
->cs_base
;
6781 gen_movtl_T0_im(next_eip
);
6786 case 0x9a: /* lcall im */
6788 unsigned int selector
, offset
;
6792 ot
= dflag
? MO_32
: MO_16
;
6793 offset
= insn_get(env
, s
, ot
);
6794 selector
= insn_get(env
, s
, MO_16
);
6796 gen_op_movl_T0_im(selector
);
6797 gen_op_movl_T1_imu(offset
);
6800 case 0xe9: /* jmp im */
6802 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6804 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6805 tval
+= s
->pc
- s
->cs_base
;
6812 case 0xea: /* ljmp im */
6814 unsigned int selector
, offset
;
6818 ot
= dflag
? MO_32
: MO_16
;
6819 offset
= insn_get(env
, s
, ot
);
6820 selector
= insn_get(env
, s
, MO_16
);
6822 gen_op_movl_T0_im(selector
);
6823 gen_op_movl_T1_imu(offset
);
6826 case 0xeb: /* jmp Jb */
6827 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6828 tval
+= s
->pc
- s
->cs_base
;
6833 case 0x70 ... 0x7f: /* jcc Jb */
6834 tval
= (int8_t)insn_get(env
, s
, MO_8
);
6836 case 0x180 ... 0x18f: /* jcc Jv */
6838 tval
= (int32_t)insn_get(env
, s
, MO_32
);
6840 tval
= (int16_t)insn_get(env
, s
, MO_16
);
6843 next_eip
= s
->pc
- s
->cs_base
;
6847 gen_jcc(s
, b
, tval
, next_eip
);
6850 case 0x190 ... 0x19f: /* setcc Gv */
6851 modrm
= cpu_ldub_code(env
, s
->pc
++);
6852 gen_setcc1(s
, b
, cpu_T
[0]);
6853 gen_ldst_modrm(env
, s
, modrm
, MO_8
, OR_TMP0
, 1);
6855 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6856 if (!(s
->cpuid_features
& CPUID_CMOV
)) {
6860 modrm
= cpu_ldub_code(env
, s
->pc
++);
6861 reg
= ((modrm
>> 3) & 7) | rex_r
;
6862 gen_cmovcc1(env
, s
, ot
, b
, modrm
, reg
);
6865 /************************/
6867 case 0x9c: /* pushf */
6868 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_PUSHF
);
6869 if (s
->vm86
&& s
->iopl
!= 3) {
6870 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6872 gen_update_cc_op(s
);
6873 gen_helper_read_eflags(cpu_T
[0], cpu_env
);
6877 case 0x9d: /* popf */
6878 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_POPF
);
6879 if (s
->vm86
&& s
->iopl
!= 3) {
6880 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6885 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6886 tcg_const_i32((TF_MASK
| AC_MASK
|
6891 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6892 tcg_const_i32((TF_MASK
| AC_MASK
|
6894 IF_MASK
| IOPL_MASK
)
6898 if (s
->cpl
<= s
->iopl
) {
6900 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6901 tcg_const_i32((TF_MASK
|
6907 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6908 tcg_const_i32((TF_MASK
|
6917 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6918 tcg_const_i32((TF_MASK
| AC_MASK
|
6919 ID_MASK
| NT_MASK
)));
6921 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6922 tcg_const_i32((TF_MASK
| AC_MASK
|
6929 set_cc_op(s
, CC_OP_EFLAGS
);
6930 /* abort translation because TF/AC flag may change */
6931 gen_jmp_im(s
->pc
- s
->cs_base
);
6935 case 0x9e: /* sahf */
6936 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6938 gen_op_mov_TN_reg(MO_8
, 0, R_AH
);
6939 gen_compute_eflags(s
);
6940 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, CC_O
);
6941 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], CC_S
| CC_Z
| CC_A
| CC_P
| CC_C
);
6942 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, cpu_T
[0]);
6944 case 0x9f: /* lahf */
6945 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6947 gen_compute_eflags(s
);
6948 /* Note: gen_compute_eflags() only gives the condition codes */
6949 tcg_gen_ori_tl(cpu_T
[0], cpu_cc_src
, 0x02);
6950 gen_op_mov_reg_T0(MO_8
, R_AH
);
6952 case 0xf5: /* cmc */
6953 gen_compute_eflags(s
);
6954 tcg_gen_xori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6956 case 0xf8: /* clc */
6957 gen_compute_eflags(s
);
6958 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_C
);
6960 case 0xf9: /* stc */
6961 gen_compute_eflags(s
);
6962 tcg_gen_ori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6964 case 0xfc: /* cld */
6965 tcg_gen_movi_i32(cpu_tmp2_i32
, 1);
6966 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6968 case 0xfd: /* std */
6969 tcg_gen_movi_i32(cpu_tmp2_i32
, -1);
6970 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6973 /************************/
6974 /* bit operations */
6975 case 0x1ba: /* bt/bts/btr/btc Gv, im */
6977 modrm
= cpu_ldub_code(env
, s
->pc
++);
6978 op
= (modrm
>> 3) & 7;
6979 mod
= (modrm
>> 6) & 3;
6980 rm
= (modrm
& 7) | REX_B(s
);
6983 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
6984 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
6986 gen_op_mov_TN_reg(ot
, 0, rm
);
6989 val
= cpu_ldub_code(env
, s
->pc
++);
6990 gen_op_movl_T1_im(val
);
6995 case 0x1a3: /* bt Gv, Ev */
6998 case 0x1ab: /* bts */
7001 case 0x1b3: /* btr */
7004 case 0x1bb: /* btc */
7008 modrm
= cpu_ldub_code(env
, s
->pc
++);
7009 reg
= ((modrm
>> 3) & 7) | rex_r
;
7010 mod
= (modrm
>> 6) & 3;
7011 rm
= (modrm
& 7) | REX_B(s
);
7012 gen_op_mov_TN_reg(MO_32
, 1, reg
);
7014 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7015 /* specific case: we need to add a displacement */
7016 gen_exts(ot
, cpu_T
[1]);
7017 tcg_gen_sari_tl(cpu_tmp0
, cpu_T
[1], 3 + ot
);
7018 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, ot
);
7019 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
7020 gen_op_ld_v(s
, ot
, cpu_T
[0], cpu_A0
);
7022 gen_op_mov_TN_reg(ot
, 0, rm
);
7025 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], (1 << (3 + ot
)) - 1);
7028 tcg_gen_shr_tl(cpu_cc_src
, cpu_T
[0], cpu_T
[1]);
7029 tcg_gen_movi_tl(cpu_cc_dst
, 0);
7032 tcg_gen_shr_tl(cpu_tmp4
, cpu_T
[0], cpu_T
[1]);
7033 tcg_gen_movi_tl(cpu_tmp0
, 1);
7034 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
7035 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
7038 tcg_gen_shr_tl(cpu_tmp4
, cpu_T
[0], cpu_T
[1]);
7039 tcg_gen_movi_tl(cpu_tmp0
, 1);
7040 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
7041 tcg_gen_not_tl(cpu_tmp0
, cpu_tmp0
);
7042 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
7046 tcg_gen_shr_tl(cpu_tmp4
, cpu_T
[0], cpu_T
[1]);
7047 tcg_gen_movi_tl(cpu_tmp0
, 1);
7048 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
7049 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
7052 set_cc_op(s
, CC_OP_SARB
+ ot
);
7055 gen_op_st_T0_A0(s
, ot
);
7057 gen_op_mov_reg_T0(ot
, rm
);
7058 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
7059 tcg_gen_movi_tl(cpu_cc_dst
, 0);
7062 case 0x1bc: /* bsf / tzcnt */
7063 case 0x1bd: /* bsr / lzcnt */
7065 modrm
= cpu_ldub_code(env
, s
->pc
++);
7066 reg
= ((modrm
>> 3) & 7) | rex_r
;
7067 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
7068 gen_extu(ot
, cpu_T
[0]);
7070 /* Note that lzcnt and tzcnt are in different extensions. */
7071 if ((prefixes
& PREFIX_REPZ
)
7073 ? s
->cpuid_ext3_features
& CPUID_EXT3_ABM
7074 : s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)) {
7076 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
7078 /* For lzcnt, reduce the target_ulong result by the
7079 number of zeros that we expect to find at the top. */
7080 gen_helper_clz(cpu_T
[0], cpu_T
[0]);
7081 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], TARGET_LONG_BITS
- size
);
7083 /* For tzcnt, a zero input must return the operand size:
7084 force all bits outside the operand size to 1. */
7085 target_ulong mask
= (target_ulong
)-2 << (size
- 1);
7086 tcg_gen_ori_tl(cpu_T
[0], cpu_T
[0], mask
);
7087 gen_helper_ctz(cpu_T
[0], cpu_T
[0]);
7089 /* For lzcnt/tzcnt, C and Z bits are defined and are
7090 related to the result. */
7091 gen_op_update1_cc();
7092 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
7094 /* For bsr/bsf, only the Z bit is defined and it is related
7095 to the input and not the result. */
7096 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
7097 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
7099 /* For bsr, return the bit index of the first 1 bit,
7100 not the count of leading zeros. */
7101 gen_helper_clz(cpu_T
[0], cpu_T
[0]);
7102 tcg_gen_xori_tl(cpu_T
[0], cpu_T
[0], TARGET_LONG_BITS
- 1);
7104 gen_helper_ctz(cpu_T
[0], cpu_T
[0]);
7106 /* ??? The manual says that the output is undefined when the
7107 input is zero, but real hardware leaves it unchanged, and
7108 real programs appear to depend on that. */
7109 tcg_gen_movi_tl(cpu_tmp0
, 0);
7110 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_T
[0], cpu_cc_dst
, cpu_tmp0
,
7111 cpu_regs
[reg
], cpu_T
[0]);
7113 gen_op_mov_reg_T0(ot
, reg
);
7115 /************************/
7117 case 0x27: /* daa */
7120 gen_update_cc_op(s
);
7121 gen_helper_daa(cpu_env
);
7122 set_cc_op(s
, CC_OP_EFLAGS
);
7124 case 0x2f: /* das */
7127 gen_update_cc_op(s
);
7128 gen_helper_das(cpu_env
);
7129 set_cc_op(s
, CC_OP_EFLAGS
);
7131 case 0x37: /* aaa */
7134 gen_update_cc_op(s
);
7135 gen_helper_aaa(cpu_env
);
7136 set_cc_op(s
, CC_OP_EFLAGS
);
7138 case 0x3f: /* aas */
7141 gen_update_cc_op(s
);
7142 gen_helper_aas(cpu_env
);
7143 set_cc_op(s
, CC_OP_EFLAGS
);
7145 case 0xd4: /* aam */
7148 val
= cpu_ldub_code(env
, s
->pc
++);
7150 gen_exception(s
, EXCP00_DIVZ
, pc_start
- s
->cs_base
);
7152 gen_helper_aam(cpu_env
, tcg_const_i32(val
));
7153 set_cc_op(s
, CC_OP_LOGICB
);
7156 case 0xd5: /* aad */
7159 val
= cpu_ldub_code(env
, s
->pc
++);
7160 gen_helper_aad(cpu_env
, tcg_const_i32(val
));
7161 set_cc_op(s
, CC_OP_LOGICB
);
7163 /************************/
7165 case 0x90: /* nop */
7166 /* XXX: correct lock test for all insn */
7167 if (prefixes
& PREFIX_LOCK
) {
7170 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
7172 goto do_xchg_reg_eax
;
7174 if (prefixes
& PREFIX_REPZ
) {
7175 gen_update_cc_op(s
);
7176 gen_jmp_im(pc_start
- s
->cs_base
);
7177 gen_helper_pause(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7178 s
->is_jmp
= DISAS_TB_JUMP
;
7181 case 0x9b: /* fwait */
7182 if ((s
->flags
& (HF_MP_MASK
| HF_TS_MASK
)) ==
7183 (HF_MP_MASK
| HF_TS_MASK
)) {
7184 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7186 gen_update_cc_op(s
);
7187 gen_jmp_im(pc_start
- s
->cs_base
);
7188 gen_helper_fwait(cpu_env
);
7191 case 0xcc: /* int3 */
7192 gen_interrupt(s
, EXCP03_INT3
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
7194 case 0xcd: /* int N */
7195 val
= cpu_ldub_code(env
, s
->pc
++);
7196 if (s
->vm86
&& s
->iopl
!= 3) {
7197 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7199 gen_interrupt(s
, val
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
7202 case 0xce: /* into */
7205 gen_update_cc_op(s
);
7206 gen_jmp_im(pc_start
- s
->cs_base
);
7207 gen_helper_into(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7210 case 0xf1: /* icebp (undocumented, exits to external debugger) */
7211 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_ICEBP
);
7213 gen_debug(s
, pc_start
- s
->cs_base
);
7217 qemu_set_log(CPU_LOG_INT
| CPU_LOG_TB_IN_ASM
);
7221 case 0xfa: /* cli */
7223 if (s
->cpl
<= s
->iopl
) {
7224 gen_helper_cli(cpu_env
);
7226 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7230 gen_helper_cli(cpu_env
);
7232 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7236 case 0xfb: /* sti */
7238 if (s
->cpl
<= s
->iopl
) {
7240 gen_helper_sti(cpu_env
);
7241 /* interruptions are enabled only the first insn after sti */
7242 /* If several instructions disable interrupts, only the
7244 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
7245 gen_helper_set_inhibit_irq(cpu_env
);
7246 /* give a chance to handle pending irqs */
7247 gen_jmp_im(s
->pc
- s
->cs_base
);
7250 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7256 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7260 case 0x62: /* bound */
7263 ot
= dflag
? MO_32
: MO_16
;
7264 modrm
= cpu_ldub_code(env
, s
->pc
++);
7265 reg
= (modrm
>> 3) & 7;
7266 mod
= (modrm
>> 6) & 3;
7269 gen_op_mov_TN_reg(ot
, 0, reg
);
7270 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7271 gen_jmp_im(pc_start
- s
->cs_base
);
7272 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
7274 gen_helper_boundw(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
7276 gen_helper_boundl(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
7279 case 0x1c8 ... 0x1cf: /* bswap reg */
7280 reg
= (b
& 7) | REX_B(s
);
7281 #ifdef TARGET_X86_64
7283 gen_op_mov_TN_reg(MO_64
, 0, reg
);
7284 tcg_gen_bswap64_i64(cpu_T
[0], cpu_T
[0]);
7285 gen_op_mov_reg_T0(MO_64
, reg
);
7289 gen_op_mov_TN_reg(MO_32
, 0, reg
);
7290 tcg_gen_ext32u_tl(cpu_T
[0], cpu_T
[0]);
7291 tcg_gen_bswap32_tl(cpu_T
[0], cpu_T
[0]);
7292 gen_op_mov_reg_T0(MO_32
, reg
);
7295 case 0xd6: /* salc */
7298 gen_compute_eflags_c(s
, cpu_T
[0]);
7299 tcg_gen_neg_tl(cpu_T
[0], cpu_T
[0]);
7300 gen_op_mov_reg_T0(MO_8
, R_EAX
);
7302 case 0xe0: /* loopnz */
7303 case 0xe1: /* loopz */
7304 case 0xe2: /* loop */
7305 case 0xe3: /* jecxz */
7309 tval
= (int8_t)insn_get(env
, s
, MO_8
);
7310 next_eip
= s
->pc
- s
->cs_base
;
7315 l1
= gen_new_label();
7316 l2
= gen_new_label();
7317 l3
= gen_new_label();
7320 case 0: /* loopnz */
7322 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
7323 gen_op_jz_ecx(s
->aflag
, l3
);
7324 gen_jcc1(s
, (JCC_Z
<< 1) | (b
^ 1), l1
);
7327 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
7328 gen_op_jnz_ecx(s
->aflag
, l1
);
7332 gen_op_jz_ecx(s
->aflag
, l1
);
7337 gen_jmp_im(next_eip
);
7346 case 0x130: /* wrmsr */
7347 case 0x132: /* rdmsr */
7349 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7351 gen_update_cc_op(s
);
7352 gen_jmp_im(pc_start
- s
->cs_base
);
7354 gen_helper_rdmsr(cpu_env
);
7356 gen_helper_wrmsr(cpu_env
);
7360 case 0x131: /* rdtsc */
7361 gen_update_cc_op(s
);
7362 gen_jmp_im(pc_start
- s
->cs_base
);
7365 gen_helper_rdtsc(cpu_env
);
7368 gen_jmp(s
, s
->pc
- s
->cs_base
);
7371 case 0x133: /* rdpmc */
7372 gen_update_cc_op(s
);
7373 gen_jmp_im(pc_start
- s
->cs_base
);
7374 gen_helper_rdpmc(cpu_env
);
7376 case 0x134: /* sysenter */
7377 /* For Intel SYSENTER is valid on 64-bit */
7378 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7381 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7383 gen_update_cc_op(s
);
7384 gen_jmp_im(pc_start
- s
->cs_base
);
7385 gen_helper_sysenter(cpu_env
);
7389 case 0x135: /* sysexit */
7390 /* For Intel SYSEXIT is valid on 64-bit */
7391 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7394 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7396 gen_update_cc_op(s
);
7397 gen_jmp_im(pc_start
- s
->cs_base
);
7398 gen_helper_sysexit(cpu_env
, tcg_const_i32(dflag
));
7402 #ifdef TARGET_X86_64
7403 case 0x105: /* syscall */
7404 /* XXX: is it usable in real mode ? */
7405 gen_update_cc_op(s
);
7406 gen_jmp_im(pc_start
- s
->cs_base
);
7407 gen_helper_syscall(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7410 case 0x107: /* sysret */
7412 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7414 gen_update_cc_op(s
);
7415 gen_jmp_im(pc_start
- s
->cs_base
);
7416 gen_helper_sysret(cpu_env
, tcg_const_i32(s
->dflag
));
7417 /* condition codes are modified only in long mode */
7419 set_cc_op(s
, CC_OP_EFLAGS
);
7425 case 0x1a2: /* cpuid */
7426 gen_update_cc_op(s
);
7427 gen_jmp_im(pc_start
- s
->cs_base
);
7428 gen_helper_cpuid(cpu_env
);
7430 case 0xf4: /* hlt */
7432 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7434 gen_update_cc_op(s
);
7435 gen_jmp_im(pc_start
- s
->cs_base
);
7436 gen_helper_hlt(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7437 s
->is_jmp
= DISAS_TB_JUMP
;
7441 modrm
= cpu_ldub_code(env
, s
->pc
++);
7442 mod
= (modrm
>> 6) & 3;
7443 op
= (modrm
>> 3) & 7;
7446 if (!s
->pe
|| s
->vm86
)
7448 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_READ
);
7449 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,ldt
.selector
));
7453 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7456 if (!s
->pe
|| s
->vm86
)
7459 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7461 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_WRITE
);
7462 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7463 gen_jmp_im(pc_start
- s
->cs_base
);
7464 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
7465 gen_helper_lldt(cpu_env
, cpu_tmp2_i32
);
7469 if (!s
->pe
|| s
->vm86
)
7471 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_READ
);
7472 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,tr
.selector
));
7476 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7479 if (!s
->pe
|| s
->vm86
)
7482 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7484 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_WRITE
);
7485 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7486 gen_jmp_im(pc_start
- s
->cs_base
);
7487 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
7488 gen_helper_ltr(cpu_env
, cpu_tmp2_i32
);
7493 if (!s
->pe
|| s
->vm86
)
7495 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7496 gen_update_cc_op(s
);
7498 gen_helper_verr(cpu_env
, cpu_T
[0]);
7500 gen_helper_verw(cpu_env
, cpu_T
[0]);
7502 set_cc_op(s
, CC_OP_EFLAGS
);
7509 modrm
= cpu_ldub_code(env
, s
->pc
++);
7510 mod
= (modrm
>> 6) & 3;
7511 op
= (modrm
>> 3) & 7;
7517 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_READ
);
7518 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7519 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7520 gen_op_st_T0_A0(s
, MO_16
);
7521 gen_add_A0_im(s
, 2);
7522 tcg_gen_ld_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7524 gen_op_andl_T0_im(0xffffff);
7525 gen_op_st_T0_A0(s
, CODE64(s
) + MO_32
);
7530 case 0: /* monitor */
7531 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) ||
7534 gen_update_cc_op(s
);
7535 gen_jmp_im(pc_start
- s
->cs_base
);
7536 #ifdef TARGET_X86_64
7537 if (s
->aflag
== 2) {
7538 gen_op_movq_A0_reg(R_EAX
);
7542 gen_op_movl_A0_reg(R_EAX
);
7544 gen_op_andl_A0_ffff();
7546 gen_add_A0_ds_seg(s
);
7547 gen_helper_monitor(cpu_env
, cpu_A0
);
7550 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) ||
7553 gen_update_cc_op(s
);
7554 gen_jmp_im(pc_start
- s
->cs_base
);
7555 gen_helper_mwait(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7559 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
) ||
7563 gen_helper_clac(cpu_env
);
7564 gen_jmp_im(s
->pc
- s
->cs_base
);
7568 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
) ||
7572 gen_helper_stac(cpu_env
);
7573 gen_jmp_im(s
->pc
- s
->cs_base
);
7580 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_READ
);
7581 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7582 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7583 gen_op_st_T0_A0(s
, MO_16
);
7584 gen_add_A0_im(s
, 2);
7585 tcg_gen_ld_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, idt
.base
));
7587 gen_op_andl_T0_im(0xffffff);
7588 gen_op_st_T0_A0(s
, CODE64(s
) + MO_32
);
7594 gen_update_cc_op(s
);
7595 gen_jmp_im(pc_start
- s
->cs_base
);
7598 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7601 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7604 gen_helper_vmrun(cpu_env
, tcg_const_i32(s
->aflag
),
7605 tcg_const_i32(s
->pc
- pc_start
));
7607 s
->is_jmp
= DISAS_TB_JUMP
;
7610 case 1: /* VMMCALL */
7611 if (!(s
->flags
& HF_SVME_MASK
))
7613 gen_helper_vmmcall(cpu_env
);
7615 case 2: /* VMLOAD */
7616 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7619 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7622 gen_helper_vmload(cpu_env
, tcg_const_i32(s
->aflag
));
7625 case 3: /* VMSAVE */
7626 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7629 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7632 gen_helper_vmsave(cpu_env
, tcg_const_i32(s
->aflag
));
7636 if ((!(s
->flags
& HF_SVME_MASK
) &&
7637 !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
)) ||
7641 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7644 gen_helper_stgi(cpu_env
);
7648 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7651 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7654 gen_helper_clgi(cpu_env
);
7657 case 6: /* SKINIT */
7658 if ((!(s
->flags
& HF_SVME_MASK
) &&
7659 !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
)) ||
7662 gen_helper_skinit(cpu_env
);
7664 case 7: /* INVLPGA */
7665 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7668 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7671 gen_helper_invlpga(cpu_env
, tcg_const_i32(s
->aflag
));
7677 } else if (s
->cpl
!= 0) {
7678 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7680 gen_svm_check_intercept(s
, pc_start
,
7681 op
==2 ? SVM_EXIT_GDTR_WRITE
: SVM_EXIT_IDTR_WRITE
);
7682 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7683 gen_op_ld_T1_A0(s
, MO_16
);
7684 gen_add_A0_im(s
, 2);
7685 gen_op_ld_v(s
, CODE64(s
) + MO_32
, cpu_T
[0], cpu_A0
);
7687 gen_op_andl_T0_im(0xffffff);
7689 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,gdt
.base
));
7690 tcg_gen_st32_tl(cpu_T
[1], cpu_env
, offsetof(CPUX86State
,gdt
.limit
));
7692 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,idt
.base
));
7693 tcg_gen_st32_tl(cpu_T
[1], cpu_env
, offsetof(CPUX86State
,idt
.limit
));
7698 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_CR0
);
7699 #if defined TARGET_X86_64 && defined HOST_WORDS_BIGENDIAN
7700 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,cr
[0]) + 4);
7702 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,cr
[0]));
7704 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 1);
7708 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7710 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7711 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7712 gen_helper_lmsw(cpu_env
, cpu_T
[0]);
7713 gen_jmp_im(s
->pc
- s
->cs_base
);
7718 if (mod
!= 3) { /* invlpg */
7720 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7722 gen_update_cc_op(s
);
7723 gen_jmp_im(pc_start
- s
->cs_base
);
7724 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7725 gen_helper_invlpg(cpu_env
, cpu_A0
);
7726 gen_jmp_im(s
->pc
- s
->cs_base
);
7731 case 0: /* swapgs */
7732 #ifdef TARGET_X86_64
7735 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7737 tcg_gen_ld_tl(cpu_T
[0], cpu_env
,
7738 offsetof(CPUX86State
,segs
[R_GS
].base
));
7739 tcg_gen_ld_tl(cpu_T
[1], cpu_env
,
7740 offsetof(CPUX86State
,kernelgsbase
));
7741 tcg_gen_st_tl(cpu_T
[1], cpu_env
,
7742 offsetof(CPUX86State
,segs
[R_GS
].base
));
7743 tcg_gen_st_tl(cpu_T
[0], cpu_env
,
7744 offsetof(CPUX86State
,kernelgsbase
));
7752 case 1: /* rdtscp */
7753 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_RDTSCP
))
7755 gen_update_cc_op(s
);
7756 gen_jmp_im(pc_start
- s
->cs_base
);
7759 gen_helper_rdtscp(cpu_env
);
7762 gen_jmp(s
, s
->pc
- s
->cs_base
);
7774 case 0x108: /* invd */
7775 case 0x109: /* wbinvd */
7777 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7779 gen_svm_check_intercept(s
, pc_start
, (b
& 2) ? SVM_EXIT_INVD
: SVM_EXIT_WBINVD
);
7783 case 0x63: /* arpl or movslS (x86_64) */
7784 #ifdef TARGET_X86_64
7787 /* d_ot is the size of destination */
7788 d_ot
= dflag
+ MO_16
;
7790 modrm
= cpu_ldub_code(env
, s
->pc
++);
7791 reg
= ((modrm
>> 3) & 7) | rex_r
;
7792 mod
= (modrm
>> 6) & 3;
7793 rm
= (modrm
& 7) | REX_B(s
);
7796 gen_op_mov_TN_reg(MO_32
, 0, rm
);
7798 if (d_ot
== MO_64
) {
7799 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
7801 gen_op_mov_reg_T0(d_ot
, reg
);
7803 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7804 if (d_ot
== MO_64
) {
7805 gen_op_lds_T0_A0(s
, MO_32
);
7807 gen_op_ld_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
7809 gen_op_mov_reg_T0(d_ot
, reg
);
7815 TCGv t0
, t1
, t2
, a0
;
7817 if (!s
->pe
|| s
->vm86
)
7819 t0
= tcg_temp_local_new();
7820 t1
= tcg_temp_local_new();
7821 t2
= tcg_temp_local_new();
7823 modrm
= cpu_ldub_code(env
, s
->pc
++);
7824 reg
= (modrm
>> 3) & 7;
7825 mod
= (modrm
>> 6) & 3;
7828 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7829 gen_op_ld_v(s
, ot
, t0
, cpu_A0
);
7830 a0
= tcg_temp_local_new();
7831 tcg_gen_mov_tl(a0
, cpu_A0
);
7833 gen_op_mov_v_reg(ot
, t0
, rm
);
7836 gen_op_mov_v_reg(ot
, t1
, reg
);
7837 tcg_gen_andi_tl(cpu_tmp0
, t0
, 3);
7838 tcg_gen_andi_tl(t1
, t1
, 3);
7839 tcg_gen_movi_tl(t2
, 0);
7840 label1
= gen_new_label();
7841 tcg_gen_brcond_tl(TCG_COND_GE
, cpu_tmp0
, t1
, label1
);
7842 tcg_gen_andi_tl(t0
, t0
, ~3);
7843 tcg_gen_or_tl(t0
, t0
, t1
);
7844 tcg_gen_movi_tl(t2
, CC_Z
);
7845 gen_set_label(label1
);
7847 gen_op_st_v(s
, ot
, t0
, a0
);
7850 gen_op_mov_reg_v(ot
, rm
, t0
);
7852 gen_compute_eflags(s
);
7853 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_Z
);
7854 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, t2
);
7860 case 0x102: /* lar */
7861 case 0x103: /* lsl */
7865 if (!s
->pe
|| s
->vm86
)
7867 ot
= dflag
? MO_32
: MO_16
;
7868 modrm
= cpu_ldub_code(env
, s
->pc
++);
7869 reg
= ((modrm
>> 3) & 7) | rex_r
;
7870 gen_ldst_modrm(env
, s
, modrm
, MO_16
, OR_TMP0
, 0);
7871 t0
= tcg_temp_local_new();
7872 gen_update_cc_op(s
);
7874 gen_helper_lar(t0
, cpu_env
, cpu_T
[0]);
7876 gen_helper_lsl(t0
, cpu_env
, cpu_T
[0]);
7878 tcg_gen_andi_tl(cpu_tmp0
, cpu_cc_src
, CC_Z
);
7879 label1
= gen_new_label();
7880 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
7881 gen_op_mov_reg_v(ot
, reg
, t0
);
7882 gen_set_label(label1
);
7883 set_cc_op(s
, CC_OP_EFLAGS
);
7888 modrm
= cpu_ldub_code(env
, s
->pc
++);
7889 mod
= (modrm
>> 6) & 3;
7890 op
= (modrm
>> 3) & 7;
7892 case 0: /* prefetchnta */
7893 case 1: /* prefetchnt0 */
7894 case 2: /* prefetchnt0 */
7895 case 3: /* prefetchnt0 */
7898 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7899 /* nothing more to do */
7901 default: /* nop (multi byte) */
7902 gen_nop_modrm(env
, s
, modrm
);
7906 case 0x119 ... 0x11f: /* nop (multi byte) */
7907 modrm
= cpu_ldub_code(env
, s
->pc
++);
7908 gen_nop_modrm(env
, s
, modrm
);
7910 case 0x120: /* mov reg, crN */
7911 case 0x122: /* mov crN, reg */
7913 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7915 modrm
= cpu_ldub_code(env
, s
->pc
++);
7916 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7917 * AMD documentation (24594.pdf) and testing of
7918 * intel 386 and 486 processors all show that the mod bits
7919 * are assumed to be 1's, regardless of actual values.
7921 rm
= (modrm
& 7) | REX_B(s
);
7922 reg
= ((modrm
>> 3) & 7) | rex_r
;
7927 if ((prefixes
& PREFIX_LOCK
) && (reg
== 0) &&
7928 (s
->cpuid_ext3_features
& CPUID_EXT3_CR8LEG
)) {
7937 gen_update_cc_op(s
);
7938 gen_jmp_im(pc_start
- s
->cs_base
);
7940 gen_op_mov_TN_reg(ot
, 0, rm
);
7941 gen_helper_write_crN(cpu_env
, tcg_const_i32(reg
),
7943 gen_jmp_im(s
->pc
- s
->cs_base
);
7946 gen_helper_read_crN(cpu_T
[0], cpu_env
, tcg_const_i32(reg
));
7947 gen_op_mov_reg_T0(ot
, rm
);
7955 case 0x121: /* mov reg, drN */
7956 case 0x123: /* mov drN, reg */
7958 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7960 modrm
= cpu_ldub_code(env
, s
->pc
++);
7961 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7962 * AMD documentation (24594.pdf) and testing of
7963 * intel 386 and 486 processors all show that the mod bits
7964 * are assumed to be 1's, regardless of actual values.
7966 rm
= (modrm
& 7) | REX_B(s
);
7967 reg
= ((modrm
>> 3) & 7) | rex_r
;
7972 /* XXX: do it dynamically with CR4.DE bit */
7973 if (reg
== 4 || reg
== 5 || reg
>= 8)
7976 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_DR0
+ reg
);
7977 gen_op_mov_TN_reg(ot
, 0, rm
);
7978 gen_helper_movl_drN_T0(cpu_env
, tcg_const_i32(reg
), cpu_T
[0]);
7979 gen_jmp_im(s
->pc
- s
->cs_base
);
7982 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_DR0
+ reg
);
7983 tcg_gen_ld_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,dr
[reg
]));
7984 gen_op_mov_reg_T0(ot
, rm
);
7988 case 0x106: /* clts */
7990 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7992 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7993 gen_helper_clts(cpu_env
);
7994 /* abort block because static cpu state changed */
7995 gen_jmp_im(s
->pc
- s
->cs_base
);
7999 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
8000 case 0x1c3: /* MOVNTI reg, mem */
8001 if (!(s
->cpuid_features
& CPUID_SSE2
))
8003 ot
= s
->dflag
== 2 ? MO_64
: MO_32
;
8004 modrm
= cpu_ldub_code(env
, s
->pc
++);
8005 mod
= (modrm
>> 6) & 3;
8008 reg
= ((modrm
>> 3) & 7) | rex_r
;
8009 /* generate a generic store */
8010 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
8013 modrm
= cpu_ldub_code(env
, s
->pc
++);
8014 mod
= (modrm
>> 6) & 3;
8015 op
= (modrm
>> 3) & 7;
8017 case 0: /* fxsave */
8018 if (mod
== 3 || !(s
->cpuid_features
& CPUID_FXSR
) ||
8019 (s
->prefix
& PREFIX_LOCK
))
8021 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
8022 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8025 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
8026 gen_update_cc_op(s
);
8027 gen_jmp_im(pc_start
- s
->cs_base
);
8028 gen_helper_fxsave(cpu_env
, cpu_A0
, tcg_const_i32((s
->dflag
== 2)));
8030 case 1: /* fxrstor */
8031 if (mod
== 3 || !(s
->cpuid_features
& CPUID_FXSR
) ||
8032 (s
->prefix
& PREFIX_LOCK
))
8034 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
8035 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8038 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
8039 gen_update_cc_op(s
);
8040 gen_jmp_im(pc_start
- s
->cs_base
);
8041 gen_helper_fxrstor(cpu_env
, cpu_A0
,
8042 tcg_const_i32((s
->dflag
== 2)));
8044 case 2: /* ldmxcsr */
8045 case 3: /* stmxcsr */
8046 if (s
->flags
& HF_TS_MASK
) {
8047 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8050 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
) ||
8053 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
8055 gen_op_ld_v(s
, MO_32
, cpu_T
[0], cpu_A0
);
8056 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
8057 gen_helper_ldmxcsr(cpu_env
, cpu_tmp2_i32
);
8059 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, mxcsr
));
8060 gen_op_st_T0_A0(s
, MO_32
);
8063 case 5: /* lfence */
8064 case 6: /* mfence */
8065 if ((modrm
& 0xc7) != 0xc0 || !(s
->cpuid_features
& CPUID_SSE2
))
8068 case 7: /* sfence / clflush */
8069 if ((modrm
& 0xc7) == 0xc0) {
8071 /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX */
8072 if (!(s
->cpuid_features
& CPUID_SSE
))
8076 if (!(s
->cpuid_features
& CPUID_CLFLUSH
))
8078 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
8085 case 0x10d: /* 3DNow! prefetch(w) */
8086 modrm
= cpu_ldub_code(env
, s
->pc
++);
8087 mod
= (modrm
>> 6) & 3;
8090 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
8091 /* ignore for now */
8093 case 0x1aa: /* rsm */
8094 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_RSM
);
8095 if (!(s
->flags
& HF_SMM_MASK
))
8097 gen_update_cc_op(s
);
8098 gen_jmp_im(s
->pc
- s
->cs_base
);
8099 gen_helper_rsm(cpu_env
);
8102 case 0x1b8: /* SSE4.2 popcnt */
8103 if ((prefixes
& (PREFIX_REPZ
| PREFIX_LOCK
| PREFIX_REPNZ
)) !=
8106 if (!(s
->cpuid_ext_features
& CPUID_EXT_POPCNT
))
8109 modrm
= cpu_ldub_code(env
, s
->pc
++);
8110 reg
= ((modrm
>> 3) & 7) | rex_r
;
8112 if (s
->prefix
& PREFIX_DATA
)
8114 else if (s
->dflag
!= 2)
8119 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
8120 gen_helper_popcnt(cpu_T
[0], cpu_env
, cpu_T
[0], tcg_const_i32(ot
));
8121 gen_op_mov_reg_T0(ot
, reg
);
8123 set_cc_op(s
, CC_OP_EFLAGS
);
8125 case 0x10e ... 0x10f:
8126 /* 3DNow! instructions, ignore prefixes */
8127 s
->prefix
&= ~(PREFIX_REPZ
| PREFIX_REPNZ
| PREFIX_DATA
);
8128 case 0x110 ... 0x117:
8129 case 0x128 ... 0x12f:
8130 case 0x138 ... 0x13a:
8131 case 0x150 ... 0x179:
8132 case 0x17c ... 0x17f:
8134 case 0x1c4 ... 0x1c6:
8135 case 0x1d0 ... 0x1fe:
8136 gen_sse(env
, s
, b
, pc_start
, rex_r
);
8141 /* lock generation */
8142 if (s
->prefix
& PREFIX_LOCK
)
8143 gen_helper_unlock();
8146 if (s
->prefix
& PREFIX_LOCK
)
8147 gen_helper_unlock();
8148 /* XXX: ensure that no lock was generated */
8149 gen_exception(s
, EXCP06_ILLOP
, pc_start
- s
->cs_base
);
8153 void optimize_flags_init(void)
8155 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
8156 cpu_cc_op
= tcg_global_mem_new_i32(TCG_AREG0
,
8157 offsetof(CPUX86State
, cc_op
), "cc_op");
8158 cpu_cc_dst
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_dst
),
8160 cpu_cc_src
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_src
),
8162 cpu_cc_src2
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_src2
),
8165 #ifdef TARGET_X86_64
8166 cpu_regs
[R_EAX
] = tcg_global_mem_new_i64(TCG_AREG0
,
8167 offsetof(CPUX86State
, regs
[R_EAX
]), "rax");
8168 cpu_regs
[R_ECX
] = tcg_global_mem_new_i64(TCG_AREG0
,
8169 offsetof(CPUX86State
, regs
[R_ECX
]), "rcx");
8170 cpu_regs
[R_EDX
] = tcg_global_mem_new_i64(TCG_AREG0
,
8171 offsetof(CPUX86State
, regs
[R_EDX
]), "rdx");
8172 cpu_regs
[R_EBX
] = tcg_global_mem_new_i64(TCG_AREG0
,
8173 offsetof(CPUX86State
, regs
[R_EBX
]), "rbx");
8174 cpu_regs
[R_ESP
] = tcg_global_mem_new_i64(TCG_AREG0
,
8175 offsetof(CPUX86State
, regs
[R_ESP
]), "rsp");
8176 cpu_regs
[R_EBP
] = tcg_global_mem_new_i64(TCG_AREG0
,
8177 offsetof(CPUX86State
, regs
[R_EBP
]), "rbp");
8178 cpu_regs
[R_ESI
] = tcg_global_mem_new_i64(TCG_AREG0
,
8179 offsetof(CPUX86State
, regs
[R_ESI
]), "rsi");
8180 cpu_regs
[R_EDI
] = tcg_global_mem_new_i64(TCG_AREG0
,
8181 offsetof(CPUX86State
, regs
[R_EDI
]), "rdi");
8182 cpu_regs
[8] = tcg_global_mem_new_i64(TCG_AREG0
,
8183 offsetof(CPUX86State
, regs
[8]), "r8");
8184 cpu_regs
[9] = tcg_global_mem_new_i64(TCG_AREG0
,
8185 offsetof(CPUX86State
, regs
[9]), "r9");
8186 cpu_regs
[10] = tcg_global_mem_new_i64(TCG_AREG0
,
8187 offsetof(CPUX86State
, regs
[10]), "r10");
8188 cpu_regs
[11] = tcg_global_mem_new_i64(TCG_AREG0
,
8189 offsetof(CPUX86State
, regs
[11]), "r11");
8190 cpu_regs
[12] = tcg_global_mem_new_i64(TCG_AREG0
,
8191 offsetof(CPUX86State
, regs
[12]), "r12");
8192 cpu_regs
[13] = tcg_global_mem_new_i64(TCG_AREG0
,
8193 offsetof(CPUX86State
, regs
[13]), "r13");
8194 cpu_regs
[14] = tcg_global_mem_new_i64(TCG_AREG0
,
8195 offsetof(CPUX86State
, regs
[14]), "r14");
8196 cpu_regs
[15] = tcg_global_mem_new_i64(TCG_AREG0
,
8197 offsetof(CPUX86State
, regs
[15]), "r15");
8199 cpu_regs
[R_EAX
] = tcg_global_mem_new_i32(TCG_AREG0
,
8200 offsetof(CPUX86State
, regs
[R_EAX
]), "eax");
8201 cpu_regs
[R_ECX
] = tcg_global_mem_new_i32(TCG_AREG0
,
8202 offsetof(CPUX86State
, regs
[R_ECX
]), "ecx");
8203 cpu_regs
[R_EDX
] = tcg_global_mem_new_i32(TCG_AREG0
,
8204 offsetof(CPUX86State
, regs
[R_EDX
]), "edx");
8205 cpu_regs
[R_EBX
] = tcg_global_mem_new_i32(TCG_AREG0
,
8206 offsetof(CPUX86State
, regs
[R_EBX
]), "ebx");
8207 cpu_regs
[R_ESP
] = tcg_global_mem_new_i32(TCG_AREG0
,
8208 offsetof(CPUX86State
, regs
[R_ESP
]), "esp");
8209 cpu_regs
[R_EBP
] = tcg_global_mem_new_i32(TCG_AREG0
,
8210 offsetof(CPUX86State
, regs
[R_EBP
]), "ebp");
8211 cpu_regs
[R_ESI
] = tcg_global_mem_new_i32(TCG_AREG0
,
8212 offsetof(CPUX86State
, regs
[R_ESI
]), "esi");
8213 cpu_regs
[R_EDI
] = tcg_global_mem_new_i32(TCG_AREG0
,
8214 offsetof(CPUX86State
, regs
[R_EDI
]), "edi");
8218 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
8219 basic block 'tb'. If search_pc is TRUE, also generate PC
8220 information for each intermediate instruction. */
8221 static inline void gen_intermediate_code_internal(X86CPU
*cpu
,
8222 TranslationBlock
*tb
,
8225 CPUState
*cs
= CPU(cpu
);
8226 CPUX86State
*env
= &cpu
->env
;
8227 DisasContext dc1
, *dc
= &dc1
;
8228 target_ulong pc_ptr
;
8229 uint16_t *gen_opc_end
;
8233 target_ulong pc_start
;
8234 target_ulong cs_base
;
8238 /* generate intermediate code */
8240 cs_base
= tb
->cs_base
;
8243 dc
->pe
= (flags
>> HF_PE_SHIFT
) & 1;
8244 dc
->code32
= (flags
>> HF_CS32_SHIFT
) & 1;
8245 dc
->ss32
= (flags
>> HF_SS32_SHIFT
) & 1;
8246 dc
->addseg
= (flags
>> HF_ADDSEG_SHIFT
) & 1;
8248 dc
->vm86
= (flags
>> VM_SHIFT
) & 1;
8249 dc
->cpl
= (flags
>> HF_CPL_SHIFT
) & 3;
8250 dc
->iopl
= (flags
>> IOPL_SHIFT
) & 3;
8251 dc
->tf
= (flags
>> TF_SHIFT
) & 1;
8252 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
8253 dc
->cc_op
= CC_OP_DYNAMIC
;
8254 dc
->cc_op_dirty
= false;
8255 dc
->cs_base
= cs_base
;
8257 dc
->popl_esp_hack
= 0;
8258 /* select memory access functions */
8260 if (flags
& HF_SOFTMMU_MASK
) {
8261 dc
->mem_index
= cpu_mmu_index(env
);
8263 dc
->cpuid_features
= env
->features
[FEAT_1_EDX
];
8264 dc
->cpuid_ext_features
= env
->features
[FEAT_1_ECX
];
8265 dc
->cpuid_ext2_features
= env
->features
[FEAT_8000_0001_EDX
];
8266 dc
->cpuid_ext3_features
= env
->features
[FEAT_8000_0001_ECX
];
8267 dc
->cpuid_7_0_ebx_features
= env
->features
[FEAT_7_0_EBX
];
8268 #ifdef TARGET_X86_64
8269 dc
->lma
= (flags
>> HF_LMA_SHIFT
) & 1;
8270 dc
->code64
= (flags
>> HF_CS64_SHIFT
) & 1;
8273 dc
->jmp_opt
= !(dc
->tf
|| cs
->singlestep_enabled
||
8274 (flags
& HF_INHIBIT_IRQ_MASK
)
8275 #ifndef CONFIG_SOFTMMU
8276 || (flags
& HF_SOFTMMU_MASK
)
8280 /* check addseg logic */
8281 if (!dc
->addseg
&& (dc
->vm86
|| !dc
->pe
|| !dc
->code32
))
8282 printf("ERROR addseg\n");
8285 cpu_T
[0] = tcg_temp_new();
8286 cpu_T
[1] = tcg_temp_new();
8287 cpu_A0
= tcg_temp_new();
8289 cpu_tmp0
= tcg_temp_new();
8290 cpu_tmp1_i64
= tcg_temp_new_i64();
8291 cpu_tmp2_i32
= tcg_temp_new_i32();
8292 cpu_tmp3_i32
= tcg_temp_new_i32();
8293 cpu_tmp4
= tcg_temp_new();
8294 cpu_ptr0
= tcg_temp_new_ptr();
8295 cpu_ptr1
= tcg_temp_new_ptr();
8296 cpu_cc_srcT
= tcg_temp_local_new();
8298 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
8300 dc
->is_jmp
= DISAS_NEXT
;
8304 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
8306 max_insns
= CF_COUNT_MASK
;
8310 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
8311 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
8312 if (bp
->pc
== pc_ptr
&&
8313 !((bp
->flags
& BP_CPU
) && (tb
->flags
& HF_RF_MASK
))) {
8314 gen_debug(dc
, pc_ptr
- dc
->cs_base
);
8320 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
8324 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
8326 tcg_ctx
.gen_opc_pc
[lj
] = pc_ptr
;
8327 gen_opc_cc_op
[lj
] = dc
->cc_op
;
8328 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
8329 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
8331 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
8334 pc_ptr
= disas_insn(env
, dc
, pc_ptr
);
8336 /* stop translation if indicated */
8339 /* if single step mode, we generate only one instruction and
8340 generate an exception */
8341 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
8342 the flag and abort the translation to give the irqs a
8343 change to be happen */
8344 if (dc
->tf
|| dc
->singlestep_enabled
||
8345 (flags
& HF_INHIBIT_IRQ_MASK
)) {
8346 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8350 /* if too long translation, stop generation too */
8351 if (tcg_ctx
.gen_opc_ptr
>= gen_opc_end
||
8352 (pc_ptr
- pc_start
) >= (TARGET_PAGE_SIZE
- 32) ||
8353 num_insns
>= max_insns
) {
8354 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8359 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8364 if (tb
->cflags
& CF_LAST_IO
)
8366 gen_tb_end(tb
, num_insns
);
8367 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
8368 /* we don't forget to fill the last values */
8370 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
8373 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
8377 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
8379 qemu_log("----------------\n");
8380 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
8381 #ifdef TARGET_X86_64
8386 disas_flags
= !dc
->code32
;
8387 log_target_disas(env
, pc_start
, pc_ptr
- pc_start
, disas_flags
);
8393 tb
->size
= pc_ptr
- pc_start
;
8394 tb
->icount
= num_insns
;
8398 void gen_intermediate_code(CPUX86State
*env
, TranslationBlock
*tb
)
8400 gen_intermediate_code_internal(x86_env_get_cpu(env
), tb
, false);
8403 void gen_intermediate_code_pc(CPUX86State
*env
, TranslationBlock
*tb
)
8405 gen_intermediate_code_internal(x86_env_get_cpu(env
), tb
, true);
8408 void restore_state_to_opc(CPUX86State
*env
, TranslationBlock
*tb
, int pc_pos
)
8412 if (qemu_loglevel_mask(CPU_LOG_TB_OP
)) {
8414 qemu_log("RESTORE:\n");
8415 for(i
= 0;i
<= pc_pos
; i
++) {
8416 if (tcg_ctx
.gen_opc_instr_start
[i
]) {
8417 qemu_log("0x%04x: " TARGET_FMT_lx
"\n", i
,
8418 tcg_ctx
.gen_opc_pc
[i
]);
8421 qemu_log("pc_pos=0x%x eip=" TARGET_FMT_lx
" cs_base=%x\n",
8422 pc_pos
, tcg_ctx
.gen_opc_pc
[pc_pos
] - tb
->cs_base
,
8423 (uint32_t)tb
->cs_base
);
8426 env
->eip
= tcg_ctx
.gen_opc_pc
[pc_pos
] - tb
->cs_base
;
8427 cc_op
= gen_opc_cc_op
[pc_pos
];
8428 if (cc_op
!= CC_OP_DYNAMIC
)