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
;
77 static uint8_t gen_opc_cc_op
[OPC_BUF_SIZE
];
79 #include "exec/gen-icount.h"
82 static int x86_64_hregs
;
85 typedef struct DisasContext
{
86 /* current insn context */
87 int override
; /* -1 if no override */
90 target_ulong pc
; /* pc = eip + cs_base */
91 int is_jmp
; /* 1 = means jump (stop translation), 2 means CPU
92 static state change (stop translation) */
93 /* current block context */
94 target_ulong cs_base
; /* base of CS segment */
95 int pe
; /* protected mode */
96 int code32
; /* 32 bit code segment */
98 int lma
; /* long mode active */
99 int code64
; /* 64 bit code segment */
102 int vex_l
; /* vex vector length */
103 int vex_v
; /* vex vvvv register, without 1's compliment. */
104 int ss32
; /* 32 bit stack segment */
105 CCOp cc_op
; /* current CC operation */
107 int addseg
; /* non zero if either DS/ES/SS have a non zero base */
108 int f_st
; /* currently unused */
109 int vm86
; /* vm86 mode */
112 int tf
; /* TF cpu flag */
113 int singlestep_enabled
; /* "hardware" single step enabled */
114 int jmp_opt
; /* use direct block chaining for direct jumps */
115 int mem_index
; /* select memory access functions */
116 uint64_t flags
; /* all execution flags */
117 struct TranslationBlock
*tb
;
118 int popl_esp_hack
; /* for correct popl with esp base handling */
119 int rip_offset
; /* only used in x86_64, but left for simplicity */
121 int cpuid_ext_features
;
122 int cpuid_ext2_features
;
123 int cpuid_ext3_features
;
124 int cpuid_7_0_ebx_features
;
127 static void gen_eob(DisasContext
*s
);
128 static void gen_jmp(DisasContext
*s
, target_ulong eip
);
129 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
);
130 static void gen_op(DisasContext
*s1
, int op
, int ot
, int d
);
132 /* i386 arith/logic operations */
152 OP_SHL1
, /* undocumented */
176 /* I386 int registers */
177 OR_EAX
, /* MUST be even numbered */
186 OR_TMP0
= 16, /* temporary operand register */
188 OR_A0
, /* temporary register used when doing address evaluation */
198 /* Bit set if the global variable is live after setting CC_OP to X. */
199 static const uint8_t cc_op_live
[CC_OP_NB
] = {
200 [CC_OP_DYNAMIC
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
201 [CC_OP_EFLAGS
] = USES_CC_SRC
,
202 [CC_OP_MULB
... CC_OP_MULQ
] = USES_CC_DST
| USES_CC_SRC
,
203 [CC_OP_ADDB
... CC_OP_ADDQ
] = USES_CC_DST
| USES_CC_SRC
,
204 [CC_OP_ADCB
... CC_OP_ADCQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
205 [CC_OP_SUBB
... CC_OP_SUBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRCT
,
206 [CC_OP_SBBB
... CC_OP_SBBQ
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
207 [CC_OP_LOGICB
... CC_OP_LOGICQ
] = USES_CC_DST
,
208 [CC_OP_INCB
... CC_OP_INCQ
] = USES_CC_DST
| USES_CC_SRC
,
209 [CC_OP_DECB
... CC_OP_DECQ
] = USES_CC_DST
| USES_CC_SRC
,
210 [CC_OP_SHLB
... CC_OP_SHLQ
] = USES_CC_DST
| USES_CC_SRC
,
211 [CC_OP_SARB
... CC_OP_SARQ
] = USES_CC_DST
| USES_CC_SRC
,
212 [CC_OP_BMILGB
... CC_OP_BMILGQ
] = USES_CC_DST
| USES_CC_SRC
,
215 static void set_cc_op(DisasContext
*s
, CCOp op
)
219 if (s
->cc_op
== op
) {
223 /* Discard CC computation that will no longer be used. */
224 dead
= cc_op_live
[s
->cc_op
] & ~cc_op_live
[op
];
225 if (dead
& USES_CC_DST
) {
226 tcg_gen_discard_tl(cpu_cc_dst
);
228 if (dead
& USES_CC_SRC
) {
229 tcg_gen_discard_tl(cpu_cc_src
);
231 if (dead
& USES_CC_SRC2
) {
232 tcg_gen_discard_tl(cpu_cc_src2
);
234 if (dead
& USES_CC_SRCT
) {
235 tcg_gen_discard_tl(cpu_cc_srcT
);
239 /* The DYNAMIC setting is translator only, and should never be
240 stored. Thus we always consider it clean. */
241 s
->cc_op_dirty
= (op
!= CC_OP_DYNAMIC
);
244 static void gen_update_cc_op(DisasContext
*s
)
246 if (s
->cc_op_dirty
) {
247 tcg_gen_movi_i32(cpu_cc_op
, s
->cc_op
);
248 s
->cc_op_dirty
= false;
252 static inline void gen_op_movl_T0_0(void)
254 tcg_gen_movi_tl(cpu_T
[0], 0);
257 static inline void gen_op_movl_T0_im(int32_t val
)
259 tcg_gen_movi_tl(cpu_T
[0], val
);
262 static inline void gen_op_movl_T0_imu(uint32_t val
)
264 tcg_gen_movi_tl(cpu_T
[0], val
);
267 static inline void gen_op_movl_T1_im(int32_t val
)
269 tcg_gen_movi_tl(cpu_T
[1], val
);
272 static inline void gen_op_movl_T1_imu(uint32_t val
)
274 tcg_gen_movi_tl(cpu_T
[1], val
);
277 static inline void gen_op_movl_A0_im(uint32_t val
)
279 tcg_gen_movi_tl(cpu_A0
, val
);
283 static inline void gen_op_movq_A0_im(int64_t val
)
285 tcg_gen_movi_tl(cpu_A0
, val
);
289 static inline void gen_movtl_T0_im(target_ulong val
)
291 tcg_gen_movi_tl(cpu_T
[0], val
);
294 static inline void gen_movtl_T1_im(target_ulong val
)
296 tcg_gen_movi_tl(cpu_T
[1], val
);
299 static inline void gen_op_andl_T0_ffff(void)
301 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffff);
304 static inline void gen_op_andl_T0_im(uint32_t val
)
306 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], val
);
309 static inline void gen_op_movl_T0_T1(void)
311 tcg_gen_mov_tl(cpu_T
[0], cpu_T
[1]);
314 static inline void gen_op_andl_A0_ffff(void)
316 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffff);
321 #define NB_OP_SIZES 4
323 #else /* !TARGET_X86_64 */
325 #define NB_OP_SIZES 3
327 #endif /* !TARGET_X86_64 */
329 #if defined(HOST_WORDS_BIGENDIAN)
330 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
331 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
332 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
333 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
334 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
336 #define REG_B_OFFSET 0
337 #define REG_H_OFFSET 1
338 #define REG_W_OFFSET 0
339 #define REG_L_OFFSET 0
340 #define REG_LH_OFFSET 4
343 /* In instruction encodings for byte register accesses the
344 * register number usually indicates "low 8 bits of register N";
345 * however there are some special cases where N 4..7 indicates
346 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
347 * true for this special case, false otherwise.
349 static inline bool byte_reg_is_xH(int reg
)
355 if (reg
>= 8 || x86_64_hregs
) {
362 static inline void gen_op_mov_reg_v(int ot
, int reg
, TCGv t0
)
366 if (!byte_reg_is_xH(reg
)) {
367 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 8);
369 tcg_gen_deposit_tl(cpu_regs
[reg
- 4], cpu_regs
[reg
- 4], t0
, 8, 8);
373 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 16);
375 default: /* XXX this shouldn't be reached; abort? */
377 /* For x86_64, this sets the higher half of register to zero.
378 For i386, this is equivalent to a mov. */
379 tcg_gen_ext32u_tl(cpu_regs
[reg
], t0
);
383 tcg_gen_mov_tl(cpu_regs
[reg
], t0
);
389 static inline void gen_op_mov_reg_T0(int ot
, int reg
)
391 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
394 static inline void gen_op_mov_reg_T1(int ot
, int reg
)
396 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
399 static inline void gen_op_mov_reg_A0(int size
, int reg
)
403 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], cpu_A0
, 0, 16);
405 default: /* XXX this shouldn't be reached; abort? */
407 /* For x86_64, this sets the higher half of register to zero.
408 For i386, this is equivalent to a mov. */
409 tcg_gen_ext32u_tl(cpu_regs
[reg
], cpu_A0
);
413 tcg_gen_mov_tl(cpu_regs
[reg
], cpu_A0
);
419 static inline void gen_op_mov_v_reg(int ot
, TCGv t0
, int reg
)
421 if (ot
== OT_BYTE
&& byte_reg_is_xH(reg
)) {
422 tcg_gen_shri_tl(t0
, cpu_regs
[reg
- 4], 8);
423 tcg_gen_ext8u_tl(t0
, t0
);
425 tcg_gen_mov_tl(t0
, cpu_regs
[reg
]);
429 static inline void gen_op_mov_TN_reg(int ot
, int t_index
, int reg
)
431 gen_op_mov_v_reg(ot
, cpu_T
[t_index
], reg
);
434 static inline void gen_op_movl_A0_reg(int reg
)
436 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[reg
]);
439 static inline void gen_op_addl_A0_im(int32_t val
)
441 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, val
);
443 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffffffff);
448 static inline void gen_op_addq_A0_im(int64_t val
)
450 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, val
);
454 static void gen_add_A0_im(DisasContext
*s
, int val
)
458 gen_op_addq_A0_im(val
);
461 gen_op_addl_A0_im(val
);
464 static inline void gen_op_addl_T0_T1(void)
466 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
469 static inline void gen_op_jmp_T0(void)
471 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, eip
));
474 static inline void gen_op_add_reg_im(int size
, int reg
, int32_t val
)
478 tcg_gen_addi_tl(cpu_tmp0
, cpu_regs
[reg
], val
);
479 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], cpu_tmp0
, 0, 16);
482 tcg_gen_addi_tl(cpu_tmp0
, cpu_regs
[reg
], val
);
483 /* For x86_64, this sets the higher half of register to zero.
484 For i386, this is equivalent to a nop. */
485 tcg_gen_ext32u_tl(cpu_tmp0
, cpu_tmp0
);
486 tcg_gen_mov_tl(cpu_regs
[reg
], cpu_tmp0
);
490 tcg_gen_addi_tl(cpu_regs
[reg
], cpu_regs
[reg
], val
);
496 static inline void gen_op_add_reg_T0(int size
, int reg
)
500 tcg_gen_add_tl(cpu_tmp0
, cpu_regs
[reg
], cpu_T
[0]);
501 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], cpu_tmp0
, 0, 16);
504 tcg_gen_add_tl(cpu_tmp0
, cpu_regs
[reg
], cpu_T
[0]);
505 /* For x86_64, this sets the higher half of register to zero.
506 For i386, this is equivalent to a nop. */
507 tcg_gen_ext32u_tl(cpu_tmp0
, cpu_tmp0
);
508 tcg_gen_mov_tl(cpu_regs
[reg
], cpu_tmp0
);
512 tcg_gen_add_tl(cpu_regs
[reg
], cpu_regs
[reg
], cpu_T
[0]);
518 static inline void gen_op_addl_A0_reg_sN(int shift
, int reg
)
520 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[reg
]);
522 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, shift
);
523 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
524 /* For x86_64, this sets the higher half of register to zero.
525 For i386, this is equivalent to a nop. */
526 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
529 static inline void gen_op_movl_A0_seg(int reg
)
531 tcg_gen_ld32u_tl(cpu_A0
, cpu_env
, offsetof(CPUX86State
, segs
[reg
].base
) + REG_L_OFFSET
);
534 static inline void gen_op_addl_A0_seg(DisasContext
*s
, int reg
)
536 tcg_gen_ld_tl(cpu_tmp0
, cpu_env
, offsetof(CPUX86State
, segs
[reg
].base
));
539 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffffffff);
540 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
542 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
543 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffffffff);
546 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
551 static inline void gen_op_movq_A0_seg(int reg
)
553 tcg_gen_ld_tl(cpu_A0
, cpu_env
, offsetof(CPUX86State
, segs
[reg
].base
));
556 static inline void gen_op_addq_A0_seg(int reg
)
558 tcg_gen_ld_tl(cpu_tmp0
, cpu_env
, offsetof(CPUX86State
, segs
[reg
].base
));
559 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
562 static inline void gen_op_movq_A0_reg(int reg
)
564 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[reg
]);
567 static inline void gen_op_addq_A0_reg_sN(int shift
, int reg
)
569 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[reg
]);
571 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, shift
);
572 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
576 static inline void gen_op_lds_T0_A0(int idx
)
578 int mem_index
= (idx
>> 2) - 1;
581 tcg_gen_qemu_ld8s(cpu_T
[0], cpu_A0
, mem_index
);
584 tcg_gen_qemu_ld16s(cpu_T
[0], cpu_A0
, mem_index
);
588 tcg_gen_qemu_ld32s(cpu_T
[0], cpu_A0
, mem_index
);
593 static inline void gen_op_ld_v(int idx
, TCGv t0
, TCGv a0
)
595 int mem_index
= (idx
>> 2) - 1;
598 tcg_gen_qemu_ld8u(t0
, a0
, mem_index
);
601 tcg_gen_qemu_ld16u(t0
, a0
, mem_index
);
604 tcg_gen_qemu_ld32u(t0
, a0
, mem_index
);
608 /* Should never happen on 32-bit targets. */
610 tcg_gen_qemu_ld64(t0
, a0
, mem_index
);
616 /* XXX: always use ldu or lds */
617 static inline void gen_op_ld_T0_A0(int idx
)
619 gen_op_ld_v(idx
, cpu_T
[0], cpu_A0
);
622 static inline void gen_op_ldu_T0_A0(int idx
)
624 gen_op_ld_v(idx
, cpu_T
[0], cpu_A0
);
627 static inline void gen_op_ld_T1_A0(int idx
)
629 gen_op_ld_v(idx
, cpu_T
[1], cpu_A0
);
632 static inline void gen_op_st_v(int idx
, TCGv t0
, TCGv a0
)
634 int mem_index
= (idx
>> 2) - 1;
637 tcg_gen_qemu_st8(t0
, a0
, mem_index
);
640 tcg_gen_qemu_st16(t0
, a0
, mem_index
);
643 tcg_gen_qemu_st32(t0
, a0
, mem_index
);
647 /* Should never happen on 32-bit targets. */
649 tcg_gen_qemu_st64(t0
, a0
, mem_index
);
655 static inline void gen_op_st_T0_A0(int idx
)
657 gen_op_st_v(idx
, cpu_T
[0], cpu_A0
);
660 static inline void gen_op_st_T1_A0(int idx
)
662 gen_op_st_v(idx
, cpu_T
[1], cpu_A0
);
665 static inline void gen_jmp_im(target_ulong pc
)
667 tcg_gen_movi_tl(cpu_tmp0
, pc
);
668 tcg_gen_st_tl(cpu_tmp0
, cpu_env
, offsetof(CPUX86State
, eip
));
671 static inline void gen_string_movl_A0_ESI(DisasContext
*s
)
675 override
= s
->override
;
679 gen_op_movq_A0_seg(override
);
680 gen_op_addq_A0_reg_sN(0, R_ESI
);
682 gen_op_movq_A0_reg(R_ESI
);
688 if (s
->addseg
&& override
< 0)
691 gen_op_movl_A0_seg(override
);
692 gen_op_addl_A0_reg_sN(0, R_ESI
);
694 gen_op_movl_A0_reg(R_ESI
);
697 /* 16 address, always override */
700 gen_op_movl_A0_reg(R_ESI
);
701 gen_op_andl_A0_ffff();
702 gen_op_addl_A0_seg(s
, override
);
706 static inline void gen_string_movl_A0_EDI(DisasContext
*s
)
710 gen_op_movq_A0_reg(R_EDI
);
715 gen_op_movl_A0_seg(R_ES
);
716 gen_op_addl_A0_reg_sN(0, R_EDI
);
718 gen_op_movl_A0_reg(R_EDI
);
721 gen_op_movl_A0_reg(R_EDI
);
722 gen_op_andl_A0_ffff();
723 gen_op_addl_A0_seg(s
, R_ES
);
727 static inline void gen_op_movl_T0_Dshift(int ot
)
729 tcg_gen_ld32s_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, df
));
730 tcg_gen_shli_tl(cpu_T
[0], cpu_T
[0], ot
);
733 static TCGv
gen_ext_tl(TCGv dst
, TCGv src
, int size
, bool sign
)
738 tcg_gen_ext8s_tl(dst
, src
);
740 tcg_gen_ext8u_tl(dst
, src
);
745 tcg_gen_ext16s_tl(dst
, src
);
747 tcg_gen_ext16u_tl(dst
, src
);
753 tcg_gen_ext32s_tl(dst
, src
);
755 tcg_gen_ext32u_tl(dst
, src
);
764 static void gen_extu(int ot
, TCGv reg
)
766 gen_ext_tl(reg
, reg
, ot
, false);
769 static void gen_exts(int ot
, TCGv reg
)
771 gen_ext_tl(reg
, reg
, ot
, true);
774 static inline void gen_op_jnz_ecx(int size
, int label1
)
776 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[R_ECX
]);
777 gen_extu(size
+ 1, cpu_tmp0
);
778 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_tmp0
, 0, label1
);
781 static inline void gen_op_jz_ecx(int size
, int label1
)
783 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[R_ECX
]);
784 gen_extu(size
+ 1, cpu_tmp0
);
785 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
788 static void gen_helper_in_func(int ot
, TCGv v
, TCGv_i32 n
)
792 gen_helper_inb(v
, n
);
795 gen_helper_inw(v
, n
);
798 gen_helper_inl(v
, n
);
803 static void gen_helper_out_func(int ot
, TCGv_i32 v
, TCGv_i32 n
)
807 gen_helper_outb(v
, n
);
810 gen_helper_outw(v
, n
);
813 gen_helper_outl(v
, n
);
818 static void gen_check_io(DisasContext
*s
, int ot
, target_ulong cur_eip
,
822 target_ulong next_eip
;
825 if (s
->pe
&& (s
->cpl
> s
->iopl
|| s
->vm86
)) {
829 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
832 gen_helper_check_iob(cpu_env
, cpu_tmp2_i32
);
835 gen_helper_check_iow(cpu_env
, cpu_tmp2_i32
);
838 gen_helper_check_iol(cpu_env
, cpu_tmp2_i32
);
842 if(s
->flags
& HF_SVMI_MASK
) {
847 svm_flags
|= (1 << (4 + ot
));
848 next_eip
= s
->pc
- s
->cs_base
;
849 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
850 gen_helper_svm_check_io(cpu_env
, cpu_tmp2_i32
,
851 tcg_const_i32(svm_flags
),
852 tcg_const_i32(next_eip
- cur_eip
));
856 static inline void gen_movs(DisasContext
*s
, int ot
)
858 gen_string_movl_A0_ESI(s
);
859 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
860 gen_string_movl_A0_EDI(s
);
861 gen_op_st_T0_A0(ot
+ s
->mem_index
);
862 gen_op_movl_T0_Dshift(ot
);
863 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
864 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
867 static void gen_op_update1_cc(void)
869 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
872 static void gen_op_update2_cc(void)
874 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
875 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
878 static void gen_op_update3_cc(TCGv reg
)
880 tcg_gen_mov_tl(cpu_cc_src2
, reg
);
881 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
882 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
885 static inline void gen_op_testl_T0_T1_cc(void)
887 tcg_gen_and_tl(cpu_cc_dst
, cpu_T
[0], cpu_T
[1]);
890 static void gen_op_update_neg_cc(void)
892 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
893 tcg_gen_neg_tl(cpu_cc_src
, cpu_T
[0]);
894 tcg_gen_movi_tl(cpu_cc_srcT
, 0);
897 /* compute all eflags to cc_src */
898 static void gen_compute_eflags(DisasContext
*s
)
900 TCGv zero
, dst
, src1
, src2
;
903 if (s
->cc_op
== CC_OP_EFLAGS
) {
912 /* Take care to not read values that are not live. */
913 live
= cc_op_live
[s
->cc_op
] & ~USES_CC_SRCT
;
914 dead
= live
^ (USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
);
916 zero
= tcg_const_tl(0);
917 if (dead
& USES_CC_DST
) {
920 if (dead
& USES_CC_SRC
) {
923 if (dead
& USES_CC_SRC2
) {
929 gen_helper_cc_compute_all(cpu_cc_src
, dst
, src1
, src2
, cpu_cc_op
);
930 set_cc_op(s
, CC_OP_EFLAGS
);
937 typedef struct CCPrepare
{
947 /* compute eflags.C to reg */
948 static CCPrepare
gen_prepare_eflags_c(DisasContext
*s
, TCGv reg
)
954 case CC_OP_SUBB
... CC_OP_SUBQ
:
955 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
956 size
= s
->cc_op
- CC_OP_SUBB
;
957 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
958 /* If no temporary was used, be careful not to alias t1 and t0. */
959 t0
= TCGV_EQUAL(t1
, cpu_cc_src
) ? cpu_tmp0
: reg
;
960 tcg_gen_mov_tl(t0
, cpu_cc_srcT
);
964 case CC_OP_ADDB
... CC_OP_ADDQ
:
965 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
966 size
= s
->cc_op
- CC_OP_ADDB
;
967 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
968 t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
970 return (CCPrepare
) { .cond
= TCG_COND_LTU
, .reg
= t0
,
971 .reg2
= t1
, .mask
= -1, .use_reg2
= true };
973 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
974 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
976 case CC_OP_INCB
... CC_OP_INCQ
:
977 case CC_OP_DECB
... CC_OP_DECQ
:
978 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
979 .mask
= -1, .no_setcond
= true };
981 case CC_OP_SHLB
... CC_OP_SHLQ
:
982 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
983 size
= s
->cc_op
- CC_OP_SHLB
;
984 shift
= (8 << size
) - 1;
985 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
986 .mask
= (target_ulong
)1 << shift
};
988 case CC_OP_MULB
... CC_OP_MULQ
:
989 return (CCPrepare
) { .cond
= TCG_COND_NE
,
990 .reg
= cpu_cc_src
, .mask
= -1 };
992 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
993 size
= s
->cc_op
- CC_OP_BMILGB
;
994 t0
= gen_ext_tl(reg
, cpu_cc_src
, size
, false);
995 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
998 case CC_OP_SARB
... CC_OP_SARQ
:
1000 return (CCPrepare
) { .cond
= TCG_COND_NE
,
1001 .reg
= cpu_cc_src
, .mask
= CC_C
};
1004 /* The need to compute only C from CC_OP_DYNAMIC is important
1005 in efficiently implementing e.g. INC at the start of a TB. */
1006 gen_update_cc_op(s
);
1007 gen_helper_cc_compute_c(reg
, cpu_cc_dst
, cpu_cc_src
,
1008 cpu_cc_src2
, cpu_cc_op
);
1009 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
1010 .mask
= -1, .no_setcond
= true };
1014 /* compute eflags.P to reg */
1015 static CCPrepare
gen_prepare_eflags_p(DisasContext
*s
, TCGv reg
)
1017 gen_compute_eflags(s
);
1018 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
1022 /* compute eflags.S to reg */
1023 static CCPrepare
gen_prepare_eflags_s(DisasContext
*s
, TCGv reg
)
1027 gen_compute_eflags(s
);
1030 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
1034 int size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
1035 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, true);
1036 return (CCPrepare
) { .cond
= TCG_COND_LT
, .reg
= t0
, .mask
= -1 };
1041 /* compute eflags.O to reg */
1042 static CCPrepare
gen_prepare_eflags_o(DisasContext
*s
, TCGv reg
)
1044 gen_compute_eflags(s
);
1045 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
1049 /* compute eflags.Z to reg */
1050 static CCPrepare
gen_prepare_eflags_z(DisasContext
*s
, TCGv reg
)
1054 gen_compute_eflags(s
);
1057 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
1061 int size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
1062 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
1063 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
1068 /* perform a conditional store into register 'reg' according to jump opcode
1069 value 'b'. In the fast case, T0 is guaranted not to be used. */
1070 static CCPrepare
gen_prepare_cc(DisasContext
*s
, int b
, TCGv reg
)
1072 int inv
, jcc_op
, size
, cond
;
1077 jcc_op
= (b
>> 1) & 7;
1080 case CC_OP_SUBB
... CC_OP_SUBQ
:
1081 /* We optimize relational operators for the cmp/jcc case. */
1082 size
= s
->cc_op
- CC_OP_SUBB
;
1085 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
1086 gen_extu(size
, cpu_tmp4
);
1087 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
1088 cc
= (CCPrepare
) { .cond
= TCG_COND_LEU
, .reg
= cpu_tmp4
,
1089 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
1098 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
1099 gen_exts(size
, cpu_tmp4
);
1100 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, true);
1101 cc
= (CCPrepare
) { .cond
= cond
, .reg
= cpu_tmp4
,
1102 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
1112 /* This actually generates good code for JC, JZ and JS. */
1115 cc
= gen_prepare_eflags_o(s
, reg
);
1118 cc
= gen_prepare_eflags_c(s
, reg
);
1121 cc
= gen_prepare_eflags_z(s
, reg
);
1124 gen_compute_eflags(s
);
1125 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
1126 .mask
= CC_Z
| CC_C
};
1129 cc
= gen_prepare_eflags_s(s
, reg
);
1132 cc
= gen_prepare_eflags_p(s
, reg
);
1135 gen_compute_eflags(s
);
1136 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
1139 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
1140 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
1141 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
1146 gen_compute_eflags(s
);
1147 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
1150 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
1151 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
1152 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
1153 .mask
= CC_S
| CC_Z
};
1160 cc
.cond
= tcg_invert_cond(cc
.cond
);
1165 static void gen_setcc1(DisasContext
*s
, int b
, TCGv reg
)
1167 CCPrepare cc
= gen_prepare_cc(s
, b
, reg
);
1169 if (cc
.no_setcond
) {
1170 if (cc
.cond
== TCG_COND_EQ
) {
1171 tcg_gen_xori_tl(reg
, cc
.reg
, 1);
1173 tcg_gen_mov_tl(reg
, cc
.reg
);
1178 if (cc
.cond
== TCG_COND_NE
&& !cc
.use_reg2
&& cc
.imm
== 0 &&
1179 cc
.mask
!= 0 && (cc
.mask
& (cc
.mask
- 1)) == 0) {
1180 tcg_gen_shri_tl(reg
, cc
.reg
, ctztl(cc
.mask
));
1181 tcg_gen_andi_tl(reg
, reg
, 1);
1184 if (cc
.mask
!= -1) {
1185 tcg_gen_andi_tl(reg
, cc
.reg
, cc
.mask
);
1189 tcg_gen_setcond_tl(cc
.cond
, reg
, cc
.reg
, cc
.reg2
);
1191 tcg_gen_setcondi_tl(cc
.cond
, reg
, cc
.reg
, cc
.imm
);
1195 static inline void gen_compute_eflags_c(DisasContext
*s
, TCGv reg
)
1197 gen_setcc1(s
, JCC_B
<< 1, reg
);
1200 /* generate a conditional jump to label 'l1' according to jump opcode
1201 value 'b'. In the fast case, T0 is guaranted not to be used. */
1202 static inline void gen_jcc1_noeob(DisasContext
*s
, int b
, int l1
)
1204 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T
[0]);
1206 if (cc
.mask
!= -1) {
1207 tcg_gen_andi_tl(cpu_T
[0], cc
.reg
, cc
.mask
);
1211 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1213 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1217 /* Generate a conditional jump to label 'l1' according to jump opcode
1218 value 'b'. In the fast case, T0 is guaranted not to be used.
1219 A translation block must end soon. */
1220 static inline void gen_jcc1(DisasContext
*s
, int b
, int l1
)
1222 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T
[0]);
1224 gen_update_cc_op(s
);
1225 if (cc
.mask
!= -1) {
1226 tcg_gen_andi_tl(cpu_T
[0], cc
.reg
, cc
.mask
);
1229 set_cc_op(s
, CC_OP_DYNAMIC
);
1231 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1233 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1237 /* XXX: does not work with gdbstub "ice" single step - not a
1239 static int gen_jz_ecx_string(DisasContext
*s
, target_ulong next_eip
)
1243 l1
= gen_new_label();
1244 l2
= gen_new_label();
1245 gen_op_jnz_ecx(s
->aflag
, l1
);
1247 gen_jmp_tb(s
, next_eip
, 1);
1252 static inline void gen_stos(DisasContext
*s
, int ot
)
1254 gen_op_mov_TN_reg(OT_LONG
, 0, R_EAX
);
1255 gen_string_movl_A0_EDI(s
);
1256 gen_op_st_T0_A0(ot
+ s
->mem_index
);
1257 gen_op_movl_T0_Dshift(ot
);
1258 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1261 static inline void gen_lods(DisasContext
*s
, int ot
)
1263 gen_string_movl_A0_ESI(s
);
1264 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
1265 gen_op_mov_reg_T0(ot
, R_EAX
);
1266 gen_op_movl_T0_Dshift(ot
);
1267 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1270 static inline void gen_scas(DisasContext
*s
, int ot
)
1272 gen_string_movl_A0_EDI(s
);
1273 gen_op_ld_T1_A0(ot
+ s
->mem_index
);
1274 gen_op(s
, OP_CMPL
, ot
, R_EAX
);
1275 gen_op_movl_T0_Dshift(ot
);
1276 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1279 static inline void gen_cmps(DisasContext
*s
, int ot
)
1281 gen_string_movl_A0_EDI(s
);
1282 gen_op_ld_T1_A0(ot
+ s
->mem_index
);
1283 gen_string_movl_A0_ESI(s
);
1284 gen_op(s
, OP_CMPL
, ot
, OR_TMP0
);
1285 gen_op_movl_T0_Dshift(ot
);
1286 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1287 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1290 static inline void gen_ins(DisasContext
*s
, int ot
)
1294 gen_string_movl_A0_EDI(s
);
1295 /* Note: we must do this dummy write first to be restartable in
1296 case of page fault. */
1298 gen_op_st_T0_A0(ot
+ s
->mem_index
);
1299 gen_op_mov_TN_reg(OT_WORD
, 1, R_EDX
);
1300 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[1]);
1301 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1302 gen_helper_in_func(ot
, cpu_T
[0], cpu_tmp2_i32
);
1303 gen_op_st_T0_A0(ot
+ s
->mem_index
);
1304 gen_op_movl_T0_Dshift(ot
);
1305 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1310 static inline void gen_outs(DisasContext
*s
, int ot
)
1314 gen_string_movl_A0_ESI(s
);
1315 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
1317 gen_op_mov_TN_reg(OT_WORD
, 1, R_EDX
);
1318 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[1]);
1319 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1320 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[0]);
1321 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1323 gen_op_movl_T0_Dshift(ot
);
1324 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1329 /* same method as Valgrind : we generate jumps to current or next
1331 #define GEN_REPZ(op) \
1332 static inline void gen_repz_ ## op(DisasContext *s, int ot, \
1333 target_ulong cur_eip, target_ulong next_eip) \
1336 gen_update_cc_op(s); \
1337 l2 = gen_jz_ecx_string(s, next_eip); \
1338 gen_ ## op(s, ot); \
1339 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1340 /* a loop would cause two single step exceptions if ECX = 1 \
1341 before rep string_insn */ \
1343 gen_op_jz_ecx(s->aflag, l2); \
1344 gen_jmp(s, cur_eip); \
1347 #define GEN_REPZ2(op) \
1348 static inline void gen_repz_ ## op(DisasContext *s, int ot, \
1349 target_ulong cur_eip, \
1350 target_ulong next_eip, \
1354 gen_update_cc_op(s); \
1355 l2 = gen_jz_ecx_string(s, next_eip); \
1356 gen_ ## op(s, ot); \
1357 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1358 gen_update_cc_op(s); \
1359 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
1361 gen_op_jz_ecx(s->aflag, l2); \
1362 gen_jmp(s, cur_eip); \
1373 static void gen_helper_fp_arith_ST0_FT0(int op
)
1377 gen_helper_fadd_ST0_FT0(cpu_env
);
1380 gen_helper_fmul_ST0_FT0(cpu_env
);
1383 gen_helper_fcom_ST0_FT0(cpu_env
);
1386 gen_helper_fcom_ST0_FT0(cpu_env
);
1389 gen_helper_fsub_ST0_FT0(cpu_env
);
1392 gen_helper_fsubr_ST0_FT0(cpu_env
);
1395 gen_helper_fdiv_ST0_FT0(cpu_env
);
1398 gen_helper_fdivr_ST0_FT0(cpu_env
);
1403 /* NOTE the exception in "r" op ordering */
1404 static void gen_helper_fp_arith_STN_ST0(int op
, int opreg
)
1406 TCGv_i32 tmp
= tcg_const_i32(opreg
);
1409 gen_helper_fadd_STN_ST0(cpu_env
, tmp
);
1412 gen_helper_fmul_STN_ST0(cpu_env
, tmp
);
1415 gen_helper_fsubr_STN_ST0(cpu_env
, tmp
);
1418 gen_helper_fsub_STN_ST0(cpu_env
, tmp
);
1421 gen_helper_fdivr_STN_ST0(cpu_env
, tmp
);
1424 gen_helper_fdiv_STN_ST0(cpu_env
, tmp
);
1429 /* if d == OR_TMP0, it means memory operand (address in A0) */
1430 static void gen_op(DisasContext
*s1
, int op
, int ot
, int d
)
1433 gen_op_mov_TN_reg(ot
, 0, d
);
1435 gen_op_ld_T0_A0(ot
+ s1
->mem_index
);
1439 gen_compute_eflags_c(s1
, cpu_tmp4
);
1440 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1441 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_tmp4
);
1443 gen_op_mov_reg_T0(ot
, d
);
1445 gen_op_st_T0_A0(ot
+ s1
->mem_index
);
1446 gen_op_update3_cc(cpu_tmp4
);
1447 set_cc_op(s1
, CC_OP_ADCB
+ ot
);
1450 gen_compute_eflags_c(s1
, cpu_tmp4
);
1451 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1452 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_tmp4
);
1454 gen_op_mov_reg_T0(ot
, d
);
1456 gen_op_st_T0_A0(ot
+ s1
->mem_index
);
1457 gen_op_update3_cc(cpu_tmp4
);
1458 set_cc_op(s1
, CC_OP_SBBB
+ ot
);
1461 gen_op_addl_T0_T1();
1463 gen_op_mov_reg_T0(ot
, d
);
1465 gen_op_st_T0_A0(ot
+ s1
->mem_index
);
1466 gen_op_update2_cc();
1467 set_cc_op(s1
, CC_OP_ADDB
+ ot
);
1470 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T
[0]);
1471 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1473 gen_op_mov_reg_T0(ot
, d
);
1475 gen_op_st_T0_A0(ot
+ s1
->mem_index
);
1476 gen_op_update2_cc();
1477 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1481 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1483 gen_op_mov_reg_T0(ot
, d
);
1485 gen_op_st_T0_A0(ot
+ s1
->mem_index
);
1486 gen_op_update1_cc();
1487 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1490 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1492 gen_op_mov_reg_T0(ot
, d
);
1494 gen_op_st_T0_A0(ot
+ s1
->mem_index
);
1495 gen_op_update1_cc();
1496 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1499 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1501 gen_op_mov_reg_T0(ot
, d
);
1503 gen_op_st_T0_A0(ot
+ s1
->mem_index
);
1504 gen_op_update1_cc();
1505 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1508 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
1509 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T
[0]);
1510 tcg_gen_sub_tl(cpu_cc_dst
, cpu_T
[0], cpu_T
[1]);
1511 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1516 /* if d == OR_TMP0, it means memory operand (address in A0) */
1517 static void gen_inc(DisasContext
*s1
, int ot
, int d
, int c
)
1520 gen_op_mov_TN_reg(ot
, 0, d
);
1522 gen_op_ld_T0_A0(ot
+ s1
->mem_index
);
1523 gen_compute_eflags_c(s1
, cpu_cc_src
);
1525 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], 1);
1526 set_cc_op(s1
, CC_OP_INCB
+ ot
);
1528 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], -1);
1529 set_cc_op(s1
, CC_OP_DECB
+ ot
);
1532 gen_op_mov_reg_T0(ot
, d
);
1534 gen_op_st_T0_A0(ot
+ s1
->mem_index
);
1535 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
1538 static void gen_shift_rm_T1(DisasContext
*s
, int ot
, int op1
,
1539 int is_right
, int is_arith
)
1545 if (ot
== OT_QUAD
) {
1552 if (op1
== OR_TMP0
) {
1553 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
1555 gen_op_mov_TN_reg(ot
, 0, op1
);
1558 t0
= tcg_temp_local_new();
1559 t1
= tcg_temp_local_new();
1560 t2
= tcg_temp_local_new();
1562 tcg_gen_andi_tl(t2
, cpu_T
[1], mask
);
1566 gen_exts(ot
, cpu_T
[0]);
1567 tcg_gen_mov_tl(t0
, cpu_T
[0]);
1568 tcg_gen_sar_tl(cpu_T
[0], cpu_T
[0], t2
);
1570 gen_extu(ot
, cpu_T
[0]);
1571 tcg_gen_mov_tl(t0
, cpu_T
[0]);
1572 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], t2
);
1575 tcg_gen_mov_tl(t0
, cpu_T
[0]);
1576 tcg_gen_shl_tl(cpu_T
[0], cpu_T
[0], t2
);
1580 if (op1
== OR_TMP0
) {
1581 gen_op_st_T0_A0(ot
+ s
->mem_index
);
1583 gen_op_mov_reg_T0(ot
, op1
);
1586 /* Update eflags data because we cannot predict flags afterward. */
1587 gen_update_cc_op(s
);
1588 set_cc_op(s
, CC_OP_DYNAMIC
);
1590 tcg_gen_mov_tl(t1
, cpu_T
[0]);
1592 shift_label
= gen_new_label();
1593 tcg_gen_brcondi_tl(TCG_COND_EQ
, t2
, 0, shift_label
);
1595 tcg_gen_addi_tl(t2
, t2
, -1);
1596 tcg_gen_mov_tl(cpu_cc_dst
, t1
);
1600 tcg_gen_sar_tl(cpu_cc_src
, t0
, t2
);
1602 tcg_gen_shr_tl(cpu_cc_src
, t0
, t2
);
1605 tcg_gen_shl_tl(cpu_cc_src
, t0
, t2
);
1609 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_SARB
+ ot
);
1611 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_SHLB
+ ot
);
1614 gen_set_label(shift_label
);
1621 static void gen_shift_rm_im(DisasContext
*s
, int ot
, int op1
, int op2
,
1622 int is_right
, int is_arith
)
1633 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
1635 gen_op_mov_TN_reg(ot
, 0, op1
);
1641 gen_exts(ot
, cpu_T
[0]);
1642 tcg_gen_sari_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1643 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], op2
);
1645 gen_extu(ot
, cpu_T
[0]);
1646 tcg_gen_shri_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1647 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], op2
);
1650 tcg_gen_shli_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1651 tcg_gen_shli_tl(cpu_T
[0], cpu_T
[0], op2
);
1657 gen_op_st_T0_A0(ot
+ s
->mem_index
);
1659 gen_op_mov_reg_T0(ot
, op1
);
1661 /* update eflags if non zero shift */
1663 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
1664 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
1665 set_cc_op(s
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1669 static inline void tcg_gen_lshift(TCGv ret
, TCGv arg1
, target_long arg2
)
1672 tcg_gen_shli_tl(ret
, arg1
, arg2
);
1674 tcg_gen_shri_tl(ret
, arg1
, -arg2
);
1677 static void gen_rot_rm_T1(DisasContext
*s
, int ot
, int op1
,
1681 int label1
, label2
, data_bits
;
1682 TCGv t0
, t1
, t2
, a0
;
1684 /* XXX: inefficient, but we must use local temps */
1685 t0
= tcg_temp_local_new();
1686 t1
= tcg_temp_local_new();
1687 t2
= tcg_temp_local_new();
1688 a0
= tcg_temp_local_new();
1696 if (op1
== OR_TMP0
) {
1697 tcg_gen_mov_tl(a0
, cpu_A0
);
1698 gen_op_ld_v(ot
+ s
->mem_index
, t0
, a0
);
1700 gen_op_mov_v_reg(ot
, t0
, op1
);
1703 tcg_gen_mov_tl(t1
, cpu_T
[1]);
1705 tcg_gen_andi_tl(t1
, t1
, mask
);
1707 /* Must test zero case to avoid using undefined behaviour in TCG
1709 label1
= gen_new_label();
1710 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, label1
);
1713 tcg_gen_andi_tl(cpu_tmp0
, t1
, (1 << (3 + ot
)) - 1);
1715 tcg_gen_mov_tl(cpu_tmp0
, t1
);
1718 tcg_gen_mov_tl(t2
, t0
);
1720 data_bits
= 8 << ot
;
1721 /* XXX: rely on behaviour of shifts when operand 2 overflows (XXX:
1722 fix TCG definition) */
1724 tcg_gen_shr_tl(cpu_tmp4
, t0
, cpu_tmp0
);
1725 tcg_gen_subfi_tl(cpu_tmp0
, data_bits
, cpu_tmp0
);
1726 tcg_gen_shl_tl(t0
, t0
, cpu_tmp0
);
1728 tcg_gen_shl_tl(cpu_tmp4
, t0
, cpu_tmp0
);
1729 tcg_gen_subfi_tl(cpu_tmp0
, data_bits
, cpu_tmp0
);
1730 tcg_gen_shr_tl(t0
, t0
, cpu_tmp0
);
1732 tcg_gen_or_tl(t0
, t0
, cpu_tmp4
);
1734 gen_set_label(label1
);
1736 if (op1
== OR_TMP0
) {
1737 gen_op_st_v(ot
+ s
->mem_index
, t0
, a0
);
1739 gen_op_mov_reg_v(ot
, op1
, t0
);
1742 /* update eflags. It is needed anyway most of the time, do it always. */
1743 gen_compute_eflags(s
);
1744 assert(s
->cc_op
== CC_OP_EFLAGS
);
1746 label2
= gen_new_label();
1747 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, label2
);
1749 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~(CC_O
| CC_C
));
1750 tcg_gen_xor_tl(cpu_tmp0
, t2
, t0
);
1751 tcg_gen_lshift(cpu_tmp0
, cpu_tmp0
, 11 - (data_bits
- 1));
1752 tcg_gen_andi_tl(cpu_tmp0
, cpu_tmp0
, CC_O
);
1753 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, cpu_tmp0
);
1755 tcg_gen_shri_tl(t0
, t0
, data_bits
- 1);
1757 tcg_gen_andi_tl(t0
, t0
, CC_C
);
1758 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, t0
);
1760 gen_set_label(label2
);
1768 static void gen_rot_rm_im(DisasContext
*s
, int ot
, int op1
, int op2
,
1775 /* XXX: inefficient, but we must use local temps */
1776 t0
= tcg_temp_local_new();
1777 t1
= tcg_temp_local_new();
1778 a0
= tcg_temp_local_new();
1786 if (op1
== OR_TMP0
) {
1787 tcg_gen_mov_tl(a0
, cpu_A0
);
1788 gen_op_ld_v(ot
+ s
->mem_index
, t0
, a0
);
1790 gen_op_mov_v_reg(ot
, t0
, op1
);
1794 tcg_gen_mov_tl(t1
, t0
);
1797 data_bits
= 8 << ot
;
1799 int shift
= op2
& ((1 << (3 + ot
)) - 1);
1801 tcg_gen_shri_tl(cpu_tmp4
, t0
, shift
);
1802 tcg_gen_shli_tl(t0
, t0
, data_bits
- shift
);
1805 tcg_gen_shli_tl(cpu_tmp4
, t0
, shift
);
1806 tcg_gen_shri_tl(t0
, t0
, data_bits
- shift
);
1808 tcg_gen_or_tl(t0
, t0
, cpu_tmp4
);
1812 if (op1
== OR_TMP0
) {
1813 gen_op_st_v(ot
+ s
->mem_index
, t0
, a0
);
1815 gen_op_mov_reg_v(ot
, op1
, t0
);
1820 gen_compute_eflags(s
);
1821 assert(s
->cc_op
== CC_OP_EFLAGS
);
1823 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~(CC_O
| CC_C
));
1824 tcg_gen_xor_tl(cpu_tmp0
, t1
, t0
);
1825 tcg_gen_lshift(cpu_tmp0
, cpu_tmp0
, 11 - (data_bits
- 1));
1826 tcg_gen_andi_tl(cpu_tmp0
, cpu_tmp0
, CC_O
);
1827 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, cpu_tmp0
);
1829 tcg_gen_shri_tl(t0
, t0
, data_bits
- 1);
1831 tcg_gen_andi_tl(t0
, t0
, CC_C
);
1832 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, t0
);
1840 /* XXX: add faster immediate = 1 case */
1841 static void gen_rotc_rm_T1(DisasContext
*s
, int ot
, int op1
,
1844 gen_compute_eflags(s
);
1845 assert(s
->cc_op
== CC_OP_EFLAGS
);
1849 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
1851 gen_op_mov_TN_reg(ot
, 0, op1
);
1856 gen_helper_rcrb(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1859 gen_helper_rcrw(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1862 gen_helper_rcrl(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1864 #ifdef TARGET_X86_64
1866 gen_helper_rcrq(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1873 gen_helper_rclb(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1876 gen_helper_rclw(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1879 gen_helper_rcll(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1881 #ifdef TARGET_X86_64
1883 gen_helper_rclq(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1890 gen_op_st_T0_A0(ot
+ s
->mem_index
);
1892 gen_op_mov_reg_T0(ot
, op1
);
1895 /* XXX: add faster immediate case */
1896 static void gen_shiftd_rm_T1(DisasContext
*s
, int ot
, int op1
,
1897 int is_right
, TCGv count
)
1899 int label1
, label2
, data_bits
;
1901 TCGv t0
, t1
, t2
, a0
;
1903 t0
= tcg_temp_local_new();
1904 t1
= tcg_temp_local_new();
1905 t2
= tcg_temp_local_new();
1906 a0
= tcg_temp_local_new();
1914 if (op1
== OR_TMP0
) {
1915 tcg_gen_mov_tl(a0
, cpu_A0
);
1916 gen_op_ld_v(ot
+ s
->mem_index
, t0
, a0
);
1918 gen_op_mov_v_reg(ot
, t0
, op1
);
1921 tcg_gen_andi_tl(t2
, count
, mask
);
1922 tcg_gen_mov_tl(t1
, cpu_T
[1]);
1924 /* Must test zero case to avoid using undefined behaviour in TCG
1926 label1
= gen_new_label();
1927 tcg_gen_brcondi_tl(TCG_COND_EQ
, t2
, 0, label1
);
1929 tcg_gen_addi_tl(cpu_tmp5
, t2
, -1);
1930 if (ot
== OT_WORD
) {
1931 /* Note: we implement the Intel behaviour for shift count > 16 */
1933 tcg_gen_andi_tl(t0
, t0
, 0xffff);
1934 tcg_gen_shli_tl(cpu_tmp0
, t1
, 16);
1935 tcg_gen_or_tl(t0
, t0
, cpu_tmp0
);
1936 tcg_gen_ext32u_tl(t0
, t0
);
1938 tcg_gen_shr_tl(cpu_tmp4
, t0
, cpu_tmp5
);
1940 /* only needed if count > 16, but a test would complicate */
1941 tcg_gen_subfi_tl(cpu_tmp5
, 32, t2
);
1942 tcg_gen_shl_tl(cpu_tmp0
, t0
, cpu_tmp5
);
1944 tcg_gen_shr_tl(t0
, t0
, t2
);
1946 tcg_gen_or_tl(t0
, t0
, cpu_tmp0
);
1948 /* XXX: not optimal */
1949 tcg_gen_andi_tl(t0
, t0
, 0xffff);
1950 tcg_gen_shli_tl(t1
, t1
, 16);
1951 tcg_gen_or_tl(t1
, t1
, t0
);
1952 tcg_gen_ext32u_tl(t1
, t1
);
1954 tcg_gen_shl_tl(cpu_tmp4
, t0
, cpu_tmp5
);
1955 tcg_gen_subfi_tl(cpu_tmp0
, 32, cpu_tmp5
);
1956 tcg_gen_shr_tl(cpu_tmp5
, t1
, cpu_tmp0
);
1957 tcg_gen_or_tl(cpu_tmp4
, cpu_tmp4
, cpu_tmp5
);
1959 tcg_gen_shl_tl(t0
, t0
, t2
);
1960 tcg_gen_subfi_tl(cpu_tmp5
, 32, t2
);
1961 tcg_gen_shr_tl(t1
, t1
, cpu_tmp5
);
1962 tcg_gen_or_tl(t0
, t0
, t1
);
1965 data_bits
= 8 << ot
;
1968 tcg_gen_ext32u_tl(t0
, t0
);
1970 tcg_gen_shr_tl(cpu_tmp4
, t0
, cpu_tmp5
);
1972 tcg_gen_shr_tl(t0
, t0
, t2
);
1973 tcg_gen_subfi_tl(cpu_tmp5
, data_bits
, t2
);
1974 tcg_gen_shl_tl(t1
, t1
, cpu_tmp5
);
1975 tcg_gen_or_tl(t0
, t0
, t1
);
1979 tcg_gen_ext32u_tl(t1
, t1
);
1981 tcg_gen_shl_tl(cpu_tmp4
, t0
, cpu_tmp5
);
1983 tcg_gen_shl_tl(t0
, t0
, t2
);
1984 tcg_gen_subfi_tl(cpu_tmp5
, data_bits
, t2
);
1985 tcg_gen_shr_tl(t1
, t1
, cpu_tmp5
);
1986 tcg_gen_or_tl(t0
, t0
, t1
);
1989 tcg_gen_mov_tl(t1
, cpu_tmp4
);
1991 gen_set_label(label1
);
1993 if (op1
== OR_TMP0
) {
1994 gen_op_st_v(ot
+ s
->mem_index
, t0
, a0
);
1996 gen_op_mov_reg_v(ot
, op1
, t0
);
1999 /* Update eflags data because we cannot predict flags afterward. */
2000 gen_update_cc_op(s
);
2001 set_cc_op(s
, CC_OP_DYNAMIC
);
2003 label2
= gen_new_label();
2004 tcg_gen_brcondi_tl(TCG_COND_EQ
, t2
, 0, label2
);
2006 tcg_gen_mov_tl(cpu_cc_src
, t1
);
2007 tcg_gen_mov_tl(cpu_cc_dst
, t0
);
2009 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_SARB
+ ot
);
2011 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_SHLB
+ ot
);
2013 gen_set_label(label2
);
2021 static void gen_shift(DisasContext
*s1
, int op
, int ot
, int d
, int s
)
2024 gen_op_mov_TN_reg(ot
, 1, s
);
2027 gen_rot_rm_T1(s1
, ot
, d
, 0);
2030 gen_rot_rm_T1(s1
, ot
, d
, 1);
2034 gen_shift_rm_T1(s1
, ot
, d
, 0, 0);
2037 gen_shift_rm_T1(s1
, ot
, d
, 1, 0);
2040 gen_shift_rm_T1(s1
, ot
, d
, 1, 1);
2043 gen_rotc_rm_T1(s1
, ot
, d
, 0);
2046 gen_rotc_rm_T1(s1
, ot
, d
, 1);
2051 static void gen_shifti(DisasContext
*s1
, int op
, int ot
, int d
, int c
)
2055 gen_rot_rm_im(s1
, ot
, d
, c
, 0);
2058 gen_rot_rm_im(s1
, ot
, d
, c
, 1);
2062 gen_shift_rm_im(s1
, ot
, d
, c
, 0, 0);
2065 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 0);
2068 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 1);
2071 /* currently not optimized */
2072 gen_op_movl_T1_im(c
);
2073 gen_shift(s1
, op
, ot
, d
, OR_TMP1
);
2078 static void gen_lea_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2079 int *reg_ptr
, int *offset_ptr
)
2087 int mod
, rm
, code
, override
, must_add_seg
;
2089 override
= s
->override
;
2090 must_add_seg
= s
->addseg
;
2093 mod
= (modrm
>> 6) & 3;
2105 code
= cpu_ldub_code(env
, s
->pc
++);
2106 scale
= (code
>> 6) & 3;
2107 index
= ((code
>> 3) & 7) | REX_X(s
);
2114 if ((base
& 7) == 5) {
2116 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
2118 if (CODE64(s
) && !havesib
) {
2119 disp
+= s
->pc
+ s
->rip_offset
;
2126 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
2130 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
2136 /* for correct popl handling with esp */
2137 if (base
== 4 && s
->popl_esp_hack
)
2138 disp
+= s
->popl_esp_hack
;
2139 #ifdef TARGET_X86_64
2140 if (s
->aflag
== 2) {
2141 gen_op_movq_A0_reg(base
);
2143 gen_op_addq_A0_im(disp
);
2148 gen_op_movl_A0_reg(base
);
2150 gen_op_addl_A0_im(disp
);
2153 #ifdef TARGET_X86_64
2154 if (s
->aflag
== 2) {
2155 gen_op_movq_A0_im(disp
);
2159 gen_op_movl_A0_im(disp
);
2162 /* index == 4 means no index */
2163 if (havesib
&& (index
!= 4)) {
2164 #ifdef TARGET_X86_64
2165 if (s
->aflag
== 2) {
2166 gen_op_addq_A0_reg_sN(scale
, index
);
2170 gen_op_addl_A0_reg_sN(scale
, index
);
2175 if (base
== R_EBP
|| base
== R_ESP
)
2180 #ifdef TARGET_X86_64
2181 if (s
->aflag
== 2) {
2182 gen_op_addq_A0_seg(override
);
2186 gen_op_addl_A0_seg(s
, override
);
2193 disp
= cpu_lduw_code(env
, s
->pc
);
2195 gen_op_movl_A0_im(disp
);
2196 rm
= 0; /* avoid SS override */
2203 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
2207 disp
= cpu_lduw_code(env
, s
->pc
);
2213 gen_op_movl_A0_reg(R_EBX
);
2214 gen_op_addl_A0_reg_sN(0, R_ESI
);
2217 gen_op_movl_A0_reg(R_EBX
);
2218 gen_op_addl_A0_reg_sN(0, R_EDI
);
2221 gen_op_movl_A0_reg(R_EBP
);
2222 gen_op_addl_A0_reg_sN(0, R_ESI
);
2225 gen_op_movl_A0_reg(R_EBP
);
2226 gen_op_addl_A0_reg_sN(0, R_EDI
);
2229 gen_op_movl_A0_reg(R_ESI
);
2232 gen_op_movl_A0_reg(R_EDI
);
2235 gen_op_movl_A0_reg(R_EBP
);
2239 gen_op_movl_A0_reg(R_EBX
);
2243 gen_op_addl_A0_im(disp
);
2244 gen_op_andl_A0_ffff();
2248 if (rm
== 2 || rm
== 3 || rm
== 6)
2253 gen_op_addl_A0_seg(s
, override
);
2263 static void gen_nop_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2265 int mod
, rm
, base
, code
;
2267 mod
= (modrm
>> 6) & 3;
2277 code
= cpu_ldub_code(env
, s
->pc
++);
2313 /* used for LEA and MOV AX, mem */
2314 static void gen_add_A0_ds_seg(DisasContext
*s
)
2316 int override
, must_add_seg
;
2317 must_add_seg
= s
->addseg
;
2319 if (s
->override
>= 0) {
2320 override
= s
->override
;
2324 #ifdef TARGET_X86_64
2326 gen_op_addq_A0_seg(override
);
2330 gen_op_addl_A0_seg(s
, override
);
2335 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2337 static void gen_ldst_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2338 int ot
, int reg
, int is_store
)
2340 int mod
, rm
, opreg
, disp
;
2342 mod
= (modrm
>> 6) & 3;
2343 rm
= (modrm
& 7) | REX_B(s
);
2347 gen_op_mov_TN_reg(ot
, 0, reg
);
2348 gen_op_mov_reg_T0(ot
, rm
);
2350 gen_op_mov_TN_reg(ot
, 0, rm
);
2352 gen_op_mov_reg_T0(ot
, reg
);
2355 gen_lea_modrm(env
, s
, modrm
, &opreg
, &disp
);
2358 gen_op_mov_TN_reg(ot
, 0, reg
);
2359 gen_op_st_T0_A0(ot
+ s
->mem_index
);
2361 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
2363 gen_op_mov_reg_T0(ot
, reg
);
2368 static inline uint32_t insn_get(CPUX86State
*env
, DisasContext
*s
, int ot
)
2374 ret
= cpu_ldub_code(env
, s
->pc
);
2378 ret
= cpu_lduw_code(env
, s
->pc
);
2383 ret
= cpu_ldl_code(env
, s
->pc
);
2390 static inline int insn_const_size(unsigned int ot
)
2398 static inline void gen_goto_tb(DisasContext
*s
, int tb_num
, target_ulong eip
)
2400 TranslationBlock
*tb
;
2403 pc
= s
->cs_base
+ eip
;
2405 /* NOTE: we handle the case where the TB spans two pages here */
2406 if ((pc
& TARGET_PAGE_MASK
) == (tb
->pc
& TARGET_PAGE_MASK
) ||
2407 (pc
& TARGET_PAGE_MASK
) == ((s
->pc
- 1) & TARGET_PAGE_MASK
)) {
2408 /* jump to same page: we can use a direct jump */
2409 tcg_gen_goto_tb(tb_num
);
2411 tcg_gen_exit_tb((tcg_target_long
)tb
+ tb_num
);
2413 /* jump to another page: currently not optimized */
2419 static inline void gen_jcc(DisasContext
*s
, int b
,
2420 target_ulong val
, target_ulong next_eip
)
2425 l1
= gen_new_label();
2428 gen_goto_tb(s
, 0, next_eip
);
2431 gen_goto_tb(s
, 1, val
);
2432 s
->is_jmp
= DISAS_TB_JUMP
;
2434 l1
= gen_new_label();
2435 l2
= gen_new_label();
2438 gen_jmp_im(next_eip
);
2448 static void gen_cmovcc1(CPUX86State
*env
, DisasContext
*s
, int ot
, int b
,
2453 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
2455 cc
= gen_prepare_cc(s
, b
, cpu_T
[1]);
2456 if (cc
.mask
!= -1) {
2457 TCGv t0
= tcg_temp_new();
2458 tcg_gen_andi_tl(t0
, cc
.reg
, cc
.mask
);
2462 cc
.reg2
= tcg_const_tl(cc
.imm
);
2465 tcg_gen_movcond_tl(cc
.cond
, cpu_T
[0], cc
.reg
, cc
.reg2
,
2466 cpu_T
[0], cpu_regs
[reg
]);
2467 gen_op_mov_reg_T0(ot
, reg
);
2469 if (cc
.mask
!= -1) {
2470 tcg_temp_free(cc
.reg
);
2473 tcg_temp_free(cc
.reg2
);
2477 static inline void gen_op_movl_T0_seg(int seg_reg
)
2479 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
,
2480 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2483 static inline void gen_op_movl_seg_T0_vm(int seg_reg
)
2485 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffff);
2486 tcg_gen_st32_tl(cpu_T
[0], cpu_env
,
2487 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2488 tcg_gen_shli_tl(cpu_T
[0], cpu_T
[0], 4);
2489 tcg_gen_st_tl(cpu_T
[0], cpu_env
,
2490 offsetof(CPUX86State
,segs
[seg_reg
].base
));
2493 /* move T0 to seg_reg and compute if the CPU state may change. Never
2494 call this function with seg_reg == R_CS */
2495 static void gen_movl_seg_T0(DisasContext
*s
, int seg_reg
, target_ulong cur_eip
)
2497 if (s
->pe
&& !s
->vm86
) {
2498 /* XXX: optimize by finding processor state dynamically */
2499 gen_update_cc_op(s
);
2500 gen_jmp_im(cur_eip
);
2501 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
2502 gen_helper_load_seg(cpu_env
, tcg_const_i32(seg_reg
), cpu_tmp2_i32
);
2503 /* abort translation because the addseg value may change or
2504 because ss32 may change. For R_SS, translation must always
2505 stop as a special handling must be done to disable hardware
2506 interrupts for the next instruction */
2507 if (seg_reg
== R_SS
|| (s
->code32
&& seg_reg
< R_FS
))
2508 s
->is_jmp
= DISAS_TB_JUMP
;
2510 gen_op_movl_seg_T0_vm(seg_reg
);
2511 if (seg_reg
== R_SS
)
2512 s
->is_jmp
= DISAS_TB_JUMP
;
2516 static inline int svm_is_rep(int prefixes
)
2518 return ((prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) ? 8 : 0);
2522 gen_svm_check_intercept_param(DisasContext
*s
, target_ulong pc_start
,
2523 uint32_t type
, uint64_t param
)
2525 /* no SVM activated; fast case */
2526 if (likely(!(s
->flags
& HF_SVMI_MASK
)))
2528 gen_update_cc_op(s
);
2529 gen_jmp_im(pc_start
- s
->cs_base
);
2530 gen_helper_svm_check_intercept_param(cpu_env
, tcg_const_i32(type
),
2531 tcg_const_i64(param
));
2535 gen_svm_check_intercept(DisasContext
*s
, target_ulong pc_start
, uint64_t type
)
2537 gen_svm_check_intercept_param(s
, pc_start
, type
, 0);
2540 static inline void gen_stack_update(DisasContext
*s
, int addend
)
2542 #ifdef TARGET_X86_64
2544 gen_op_add_reg_im(2, R_ESP
, addend
);
2548 gen_op_add_reg_im(1, R_ESP
, addend
);
2550 gen_op_add_reg_im(0, R_ESP
, addend
);
2554 /* generate a push. It depends on ss32, addseg and dflag */
2555 static void gen_push_T0(DisasContext
*s
)
2557 #ifdef TARGET_X86_64
2559 gen_op_movq_A0_reg(R_ESP
);
2561 gen_op_addq_A0_im(-8);
2562 gen_op_st_T0_A0(OT_QUAD
+ s
->mem_index
);
2564 gen_op_addq_A0_im(-2);
2565 gen_op_st_T0_A0(OT_WORD
+ s
->mem_index
);
2567 gen_op_mov_reg_A0(2, R_ESP
);
2571 gen_op_movl_A0_reg(R_ESP
);
2573 gen_op_addl_A0_im(-2);
2575 gen_op_addl_A0_im(-4);
2578 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2579 gen_op_addl_A0_seg(s
, R_SS
);
2582 gen_op_andl_A0_ffff();
2583 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2584 gen_op_addl_A0_seg(s
, R_SS
);
2586 gen_op_st_T0_A0(s
->dflag
+ 1 + s
->mem_index
);
2587 if (s
->ss32
&& !s
->addseg
)
2588 gen_op_mov_reg_A0(1, R_ESP
);
2590 gen_op_mov_reg_T1(s
->ss32
+ 1, R_ESP
);
2594 /* generate a push. It depends on ss32, addseg and dflag */
2595 /* slower version for T1, only used for call Ev */
2596 static void gen_push_T1(DisasContext
*s
)
2598 #ifdef TARGET_X86_64
2600 gen_op_movq_A0_reg(R_ESP
);
2602 gen_op_addq_A0_im(-8);
2603 gen_op_st_T1_A0(OT_QUAD
+ s
->mem_index
);
2605 gen_op_addq_A0_im(-2);
2606 gen_op_st_T0_A0(OT_WORD
+ s
->mem_index
);
2608 gen_op_mov_reg_A0(2, R_ESP
);
2612 gen_op_movl_A0_reg(R_ESP
);
2614 gen_op_addl_A0_im(-2);
2616 gen_op_addl_A0_im(-4);
2619 gen_op_addl_A0_seg(s
, R_SS
);
2622 gen_op_andl_A0_ffff();
2623 gen_op_addl_A0_seg(s
, R_SS
);
2625 gen_op_st_T1_A0(s
->dflag
+ 1 + s
->mem_index
);
2627 if (s
->ss32
&& !s
->addseg
)
2628 gen_op_mov_reg_A0(1, R_ESP
);
2630 gen_stack_update(s
, (-2) << s
->dflag
);
2634 /* two step pop is necessary for precise exceptions */
2635 static void gen_pop_T0(DisasContext
*s
)
2637 #ifdef TARGET_X86_64
2639 gen_op_movq_A0_reg(R_ESP
);
2640 gen_op_ld_T0_A0((s
->dflag
? OT_QUAD
: OT_WORD
) + s
->mem_index
);
2644 gen_op_movl_A0_reg(R_ESP
);
2647 gen_op_addl_A0_seg(s
, R_SS
);
2649 gen_op_andl_A0_ffff();
2650 gen_op_addl_A0_seg(s
, R_SS
);
2652 gen_op_ld_T0_A0(s
->dflag
+ 1 + s
->mem_index
);
2656 static void gen_pop_update(DisasContext
*s
)
2658 #ifdef TARGET_X86_64
2659 if (CODE64(s
) && s
->dflag
) {
2660 gen_stack_update(s
, 8);
2664 gen_stack_update(s
, 2 << s
->dflag
);
2668 static void gen_stack_A0(DisasContext
*s
)
2670 gen_op_movl_A0_reg(R_ESP
);
2672 gen_op_andl_A0_ffff();
2673 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2675 gen_op_addl_A0_seg(s
, R_SS
);
2678 /* NOTE: wrap around in 16 bit not fully handled */
2679 static void gen_pusha(DisasContext
*s
)
2682 gen_op_movl_A0_reg(R_ESP
);
2683 gen_op_addl_A0_im(-16 << s
->dflag
);
2685 gen_op_andl_A0_ffff();
2686 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2688 gen_op_addl_A0_seg(s
, R_SS
);
2689 for(i
= 0;i
< 8; i
++) {
2690 gen_op_mov_TN_reg(OT_LONG
, 0, 7 - i
);
2691 gen_op_st_T0_A0(OT_WORD
+ s
->dflag
+ s
->mem_index
);
2692 gen_op_addl_A0_im(2 << s
->dflag
);
2694 gen_op_mov_reg_T1(OT_WORD
+ s
->ss32
, R_ESP
);
2697 /* NOTE: wrap around in 16 bit not fully handled */
2698 static void gen_popa(DisasContext
*s
)
2701 gen_op_movl_A0_reg(R_ESP
);
2703 gen_op_andl_A0_ffff();
2704 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2705 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], 16 << s
->dflag
);
2707 gen_op_addl_A0_seg(s
, R_SS
);
2708 for(i
= 0;i
< 8; i
++) {
2709 /* ESP is not reloaded */
2711 gen_op_ld_T0_A0(OT_WORD
+ s
->dflag
+ s
->mem_index
);
2712 gen_op_mov_reg_T0(OT_WORD
+ s
->dflag
, 7 - i
);
2714 gen_op_addl_A0_im(2 << s
->dflag
);
2716 gen_op_mov_reg_T1(OT_WORD
+ s
->ss32
, R_ESP
);
2719 static void gen_enter(DisasContext
*s
, int esp_addend
, int level
)
2724 #ifdef TARGET_X86_64
2726 ot
= s
->dflag
? OT_QUAD
: OT_WORD
;
2729 gen_op_movl_A0_reg(R_ESP
);
2730 gen_op_addq_A0_im(-opsize
);
2731 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2734 gen_op_mov_TN_reg(OT_LONG
, 0, R_EBP
);
2735 gen_op_st_T0_A0(ot
+ s
->mem_index
);
2737 /* XXX: must save state */
2738 gen_helper_enter64_level(cpu_env
, tcg_const_i32(level
),
2739 tcg_const_i32((ot
== OT_QUAD
)),
2742 gen_op_mov_reg_T1(ot
, R_EBP
);
2743 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], -esp_addend
+ (-opsize
* level
));
2744 gen_op_mov_reg_T1(OT_QUAD
, R_ESP
);
2748 ot
= s
->dflag
+ OT_WORD
;
2749 opsize
= 2 << s
->dflag
;
2751 gen_op_movl_A0_reg(R_ESP
);
2752 gen_op_addl_A0_im(-opsize
);
2754 gen_op_andl_A0_ffff();
2755 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2757 gen_op_addl_A0_seg(s
, R_SS
);
2759 gen_op_mov_TN_reg(OT_LONG
, 0, R_EBP
);
2760 gen_op_st_T0_A0(ot
+ s
->mem_index
);
2762 /* XXX: must save state */
2763 gen_helper_enter_level(cpu_env
, tcg_const_i32(level
),
2764 tcg_const_i32(s
->dflag
),
2767 gen_op_mov_reg_T1(ot
, R_EBP
);
2768 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], -esp_addend
+ (-opsize
* level
));
2769 gen_op_mov_reg_T1(OT_WORD
+ s
->ss32
, R_ESP
);
2773 static void gen_exception(DisasContext
*s
, int trapno
, target_ulong cur_eip
)
2775 gen_update_cc_op(s
);
2776 gen_jmp_im(cur_eip
);
2777 gen_helper_raise_exception(cpu_env
, tcg_const_i32(trapno
));
2778 s
->is_jmp
= DISAS_TB_JUMP
;
2781 /* an interrupt is different from an exception because of the
2783 static void gen_interrupt(DisasContext
*s
, int intno
,
2784 target_ulong cur_eip
, target_ulong next_eip
)
2786 gen_update_cc_op(s
);
2787 gen_jmp_im(cur_eip
);
2788 gen_helper_raise_interrupt(cpu_env
, tcg_const_i32(intno
),
2789 tcg_const_i32(next_eip
- cur_eip
));
2790 s
->is_jmp
= DISAS_TB_JUMP
;
2793 static void gen_debug(DisasContext
*s
, target_ulong cur_eip
)
2795 gen_update_cc_op(s
);
2796 gen_jmp_im(cur_eip
);
2797 gen_helper_debug(cpu_env
);
2798 s
->is_jmp
= DISAS_TB_JUMP
;
2801 /* generate a generic end of block. Trace exception is also generated
2803 static void gen_eob(DisasContext
*s
)
2805 gen_update_cc_op(s
);
2806 if (s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
) {
2807 gen_helper_reset_inhibit_irq(cpu_env
);
2809 if (s
->tb
->flags
& HF_RF_MASK
) {
2810 gen_helper_reset_rf(cpu_env
);
2812 if (s
->singlestep_enabled
) {
2813 gen_helper_debug(cpu_env
);
2815 gen_helper_single_step(cpu_env
);
2819 s
->is_jmp
= DISAS_TB_JUMP
;
2822 /* generate a jump to eip. No segment change must happen before as a
2823 direct call to the next block may occur */
2824 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
)
2826 gen_update_cc_op(s
);
2827 set_cc_op(s
, CC_OP_DYNAMIC
);
2829 gen_goto_tb(s
, tb_num
, eip
);
2830 s
->is_jmp
= DISAS_TB_JUMP
;
2837 static void gen_jmp(DisasContext
*s
, target_ulong eip
)
2839 gen_jmp_tb(s
, eip
, 0);
2842 static inline void gen_ldq_env_A0(int idx
, int offset
)
2844 int mem_index
= (idx
>> 2) - 1;
2845 tcg_gen_qemu_ld64(cpu_tmp1_i64
, cpu_A0
, mem_index
);
2846 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2849 static inline void gen_stq_env_A0(int idx
, int offset
)
2851 int mem_index
= (idx
>> 2) - 1;
2852 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2853 tcg_gen_qemu_st64(cpu_tmp1_i64
, cpu_A0
, mem_index
);
2856 static inline void gen_ldo_env_A0(int idx
, int offset
)
2858 int mem_index
= (idx
>> 2) - 1;
2859 tcg_gen_qemu_ld64(cpu_tmp1_i64
, cpu_A0
, mem_index
);
2860 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(0)));
2861 tcg_gen_addi_tl(cpu_tmp0
, cpu_A0
, 8);
2862 tcg_gen_qemu_ld64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
);
2863 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(1)));
2866 static inline void gen_sto_env_A0(int idx
, int offset
)
2868 int mem_index
= (idx
>> 2) - 1;
2869 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(0)));
2870 tcg_gen_qemu_st64(cpu_tmp1_i64
, cpu_A0
, mem_index
);
2871 tcg_gen_addi_tl(cpu_tmp0
, cpu_A0
, 8);
2872 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(1)));
2873 tcg_gen_qemu_st64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
);
2876 static inline void gen_op_movo(int d_offset
, int s_offset
)
2878 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
);
2879 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2880 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
+ 8);
2881 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
+ 8);
2884 static inline void gen_op_movq(int d_offset
, int s_offset
)
2886 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
);
2887 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2890 static inline void gen_op_movl(int d_offset
, int s_offset
)
2892 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
, s_offset
);
2893 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, d_offset
);
2896 static inline void gen_op_movq_env_0(int d_offset
)
2898 tcg_gen_movi_i64(cpu_tmp1_i64
, 0);
2899 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2902 typedef void (*SSEFunc_i_ep
)(TCGv_i32 val
, TCGv_ptr env
, TCGv_ptr reg
);
2903 typedef void (*SSEFunc_l_ep
)(TCGv_i64 val
, TCGv_ptr env
, TCGv_ptr reg
);
2904 typedef void (*SSEFunc_0_epi
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i32 val
);
2905 typedef void (*SSEFunc_0_epl
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i64 val
);
2906 typedef void (*SSEFunc_0_epp
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
);
2907 typedef void (*SSEFunc_0_eppi
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2909 typedef void (*SSEFunc_0_ppi
)(TCGv_ptr reg_a
, TCGv_ptr reg_b
, TCGv_i32 val
);
2910 typedef void (*SSEFunc_0_eppt
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2913 #define SSE_SPECIAL ((void *)1)
2914 #define SSE_DUMMY ((void *)2)
2916 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2917 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2918 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2920 static const SSEFunc_0_epp sse_op_table1
[256][4] = {
2921 /* 3DNow! extensions */
2922 [0x0e] = { SSE_DUMMY
}, /* femms */
2923 [0x0f] = { SSE_DUMMY
}, /* pf... */
2924 /* pure SSE operations */
2925 [0x10] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2926 [0x11] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2927 [0x12] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd, movsldup, movddup */
2928 [0x13] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd */
2929 [0x14] = { gen_helper_punpckldq_xmm
, gen_helper_punpcklqdq_xmm
},
2930 [0x15] = { gen_helper_punpckhdq_xmm
, gen_helper_punpckhqdq_xmm
},
2931 [0x16] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd, movshdup */
2932 [0x17] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd */
2934 [0x28] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2935 [0x29] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2936 [0x2a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2937 [0x2b] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movntps, movntpd, movntss, movntsd */
2938 [0x2c] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2939 [0x2d] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2940 [0x2e] = { gen_helper_ucomiss
, gen_helper_ucomisd
},
2941 [0x2f] = { gen_helper_comiss
, gen_helper_comisd
},
2942 [0x50] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movmskps, movmskpd */
2943 [0x51] = SSE_FOP(sqrt
),
2944 [0x52] = { gen_helper_rsqrtps
, NULL
, gen_helper_rsqrtss
, NULL
},
2945 [0x53] = { gen_helper_rcpps
, NULL
, gen_helper_rcpss
, NULL
},
2946 [0x54] = { gen_helper_pand_xmm
, gen_helper_pand_xmm
}, /* andps, andpd */
2947 [0x55] = { gen_helper_pandn_xmm
, gen_helper_pandn_xmm
}, /* andnps, andnpd */
2948 [0x56] = { gen_helper_por_xmm
, gen_helper_por_xmm
}, /* orps, orpd */
2949 [0x57] = { gen_helper_pxor_xmm
, gen_helper_pxor_xmm
}, /* xorps, xorpd */
2950 [0x58] = SSE_FOP(add
),
2951 [0x59] = SSE_FOP(mul
),
2952 [0x5a] = { gen_helper_cvtps2pd
, gen_helper_cvtpd2ps
,
2953 gen_helper_cvtss2sd
, gen_helper_cvtsd2ss
},
2954 [0x5b] = { gen_helper_cvtdq2ps
, gen_helper_cvtps2dq
, gen_helper_cvttps2dq
},
2955 [0x5c] = SSE_FOP(sub
),
2956 [0x5d] = SSE_FOP(min
),
2957 [0x5e] = SSE_FOP(div
),
2958 [0x5f] = SSE_FOP(max
),
2960 [0xc2] = SSE_FOP(cmpeq
),
2961 [0xc6] = { (SSEFunc_0_epp
)gen_helper_shufps
,
2962 (SSEFunc_0_epp
)gen_helper_shufpd
}, /* XXX: casts */
2964 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */
2965 [0x38] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2966 [0x3a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2968 /* MMX ops and their SSE extensions */
2969 [0x60] = MMX_OP2(punpcklbw
),
2970 [0x61] = MMX_OP2(punpcklwd
),
2971 [0x62] = MMX_OP2(punpckldq
),
2972 [0x63] = MMX_OP2(packsswb
),
2973 [0x64] = MMX_OP2(pcmpgtb
),
2974 [0x65] = MMX_OP2(pcmpgtw
),
2975 [0x66] = MMX_OP2(pcmpgtl
),
2976 [0x67] = MMX_OP2(packuswb
),
2977 [0x68] = MMX_OP2(punpckhbw
),
2978 [0x69] = MMX_OP2(punpckhwd
),
2979 [0x6a] = MMX_OP2(punpckhdq
),
2980 [0x6b] = MMX_OP2(packssdw
),
2981 [0x6c] = { NULL
, gen_helper_punpcklqdq_xmm
},
2982 [0x6d] = { NULL
, gen_helper_punpckhqdq_xmm
},
2983 [0x6e] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movd mm, ea */
2984 [0x6f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, , movqdu */
2985 [0x70] = { (SSEFunc_0_epp
)gen_helper_pshufw_mmx
,
2986 (SSEFunc_0_epp
)gen_helper_pshufd_xmm
,
2987 (SSEFunc_0_epp
)gen_helper_pshufhw_xmm
,
2988 (SSEFunc_0_epp
)gen_helper_pshuflw_xmm
}, /* XXX: casts */
2989 [0x71] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftw */
2990 [0x72] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftd */
2991 [0x73] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftq */
2992 [0x74] = MMX_OP2(pcmpeqb
),
2993 [0x75] = MMX_OP2(pcmpeqw
),
2994 [0x76] = MMX_OP2(pcmpeql
),
2995 [0x77] = { SSE_DUMMY
}, /* emms */
2996 [0x78] = { NULL
, SSE_SPECIAL
, NULL
, SSE_SPECIAL
}, /* extrq_i, insertq_i */
2997 [0x79] = { NULL
, gen_helper_extrq_r
, NULL
, gen_helper_insertq_r
},
2998 [0x7c] = { NULL
, gen_helper_haddpd
, NULL
, gen_helper_haddps
},
2999 [0x7d] = { NULL
, gen_helper_hsubpd
, NULL
, gen_helper_hsubps
},
3000 [0x7e] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movd, movd, , movq */
3001 [0x7f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, movdqu */
3002 [0xc4] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pinsrw */
3003 [0xc5] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pextrw */
3004 [0xd0] = { NULL
, gen_helper_addsubpd
, NULL
, gen_helper_addsubps
},
3005 [0xd1] = MMX_OP2(psrlw
),
3006 [0xd2] = MMX_OP2(psrld
),
3007 [0xd3] = MMX_OP2(psrlq
),
3008 [0xd4] = MMX_OP2(paddq
),
3009 [0xd5] = MMX_OP2(pmullw
),
3010 [0xd6] = { NULL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
3011 [0xd7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pmovmskb */
3012 [0xd8] = MMX_OP2(psubusb
),
3013 [0xd9] = MMX_OP2(psubusw
),
3014 [0xda] = MMX_OP2(pminub
),
3015 [0xdb] = MMX_OP2(pand
),
3016 [0xdc] = MMX_OP2(paddusb
),
3017 [0xdd] = MMX_OP2(paddusw
),
3018 [0xde] = MMX_OP2(pmaxub
),
3019 [0xdf] = MMX_OP2(pandn
),
3020 [0xe0] = MMX_OP2(pavgb
),
3021 [0xe1] = MMX_OP2(psraw
),
3022 [0xe2] = MMX_OP2(psrad
),
3023 [0xe3] = MMX_OP2(pavgw
),
3024 [0xe4] = MMX_OP2(pmulhuw
),
3025 [0xe5] = MMX_OP2(pmulhw
),
3026 [0xe6] = { NULL
, gen_helper_cvttpd2dq
, gen_helper_cvtdq2pd
, gen_helper_cvtpd2dq
},
3027 [0xe7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movntq, movntq */
3028 [0xe8] = MMX_OP2(psubsb
),
3029 [0xe9] = MMX_OP2(psubsw
),
3030 [0xea] = MMX_OP2(pminsw
),
3031 [0xeb] = MMX_OP2(por
),
3032 [0xec] = MMX_OP2(paddsb
),
3033 [0xed] = MMX_OP2(paddsw
),
3034 [0xee] = MMX_OP2(pmaxsw
),
3035 [0xef] = MMX_OP2(pxor
),
3036 [0xf0] = { NULL
, NULL
, NULL
, SSE_SPECIAL
}, /* lddqu */
3037 [0xf1] = MMX_OP2(psllw
),
3038 [0xf2] = MMX_OP2(pslld
),
3039 [0xf3] = MMX_OP2(psllq
),
3040 [0xf4] = MMX_OP2(pmuludq
),
3041 [0xf5] = MMX_OP2(pmaddwd
),
3042 [0xf6] = MMX_OP2(psadbw
),
3043 [0xf7] = { (SSEFunc_0_epp
)gen_helper_maskmov_mmx
,
3044 (SSEFunc_0_epp
)gen_helper_maskmov_xmm
}, /* XXX: casts */
3045 [0xf8] = MMX_OP2(psubb
),
3046 [0xf9] = MMX_OP2(psubw
),
3047 [0xfa] = MMX_OP2(psubl
),
3048 [0xfb] = MMX_OP2(psubq
),
3049 [0xfc] = MMX_OP2(paddb
),
3050 [0xfd] = MMX_OP2(paddw
),
3051 [0xfe] = MMX_OP2(paddl
),
3054 static const SSEFunc_0_epp sse_op_table2
[3 * 8][2] = {
3055 [0 + 2] = MMX_OP2(psrlw
),
3056 [0 + 4] = MMX_OP2(psraw
),
3057 [0 + 6] = MMX_OP2(psllw
),
3058 [8 + 2] = MMX_OP2(psrld
),
3059 [8 + 4] = MMX_OP2(psrad
),
3060 [8 + 6] = MMX_OP2(pslld
),
3061 [16 + 2] = MMX_OP2(psrlq
),
3062 [16 + 3] = { NULL
, gen_helper_psrldq_xmm
},
3063 [16 + 6] = MMX_OP2(psllq
),
3064 [16 + 7] = { NULL
, gen_helper_pslldq_xmm
},
3067 static const SSEFunc_0_epi sse_op_table3ai
[] = {
3068 gen_helper_cvtsi2ss
,
3072 #ifdef TARGET_X86_64
3073 static const SSEFunc_0_epl sse_op_table3aq
[] = {
3074 gen_helper_cvtsq2ss
,
3079 static const SSEFunc_i_ep sse_op_table3bi
[] = {
3080 gen_helper_cvttss2si
,
3081 gen_helper_cvtss2si
,
3082 gen_helper_cvttsd2si
,
3086 #ifdef TARGET_X86_64
3087 static const SSEFunc_l_ep sse_op_table3bq
[] = {
3088 gen_helper_cvttss2sq
,
3089 gen_helper_cvtss2sq
,
3090 gen_helper_cvttsd2sq
,
3095 static const SSEFunc_0_epp sse_op_table4
[8][4] = {
3106 static const SSEFunc_0_epp sse_op_table5
[256] = {
3107 [0x0c] = gen_helper_pi2fw
,
3108 [0x0d] = gen_helper_pi2fd
,
3109 [0x1c] = gen_helper_pf2iw
,
3110 [0x1d] = gen_helper_pf2id
,
3111 [0x8a] = gen_helper_pfnacc
,
3112 [0x8e] = gen_helper_pfpnacc
,
3113 [0x90] = gen_helper_pfcmpge
,
3114 [0x94] = gen_helper_pfmin
,
3115 [0x96] = gen_helper_pfrcp
,
3116 [0x97] = gen_helper_pfrsqrt
,
3117 [0x9a] = gen_helper_pfsub
,
3118 [0x9e] = gen_helper_pfadd
,
3119 [0xa0] = gen_helper_pfcmpgt
,
3120 [0xa4] = gen_helper_pfmax
,
3121 [0xa6] = gen_helper_movq
, /* pfrcpit1; no need to actually increase precision */
3122 [0xa7] = gen_helper_movq
, /* pfrsqit1 */
3123 [0xaa] = gen_helper_pfsubr
,
3124 [0xae] = gen_helper_pfacc
,
3125 [0xb0] = gen_helper_pfcmpeq
,
3126 [0xb4] = gen_helper_pfmul
,
3127 [0xb6] = gen_helper_movq
, /* pfrcpit2 */
3128 [0xb7] = gen_helper_pmulhrw_mmx
,
3129 [0xbb] = gen_helper_pswapd
,
3130 [0xbf] = gen_helper_pavgb_mmx
/* pavgusb */
3133 struct SSEOpHelper_epp
{
3134 SSEFunc_0_epp op
[2];
3138 struct SSEOpHelper_eppi
{
3139 SSEFunc_0_eppi op
[2];
3143 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
3144 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
3145 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
3146 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
3148 static const struct SSEOpHelper_epp sse_op_table6
[256] = {
3149 [0x00] = SSSE3_OP(pshufb
),
3150 [0x01] = SSSE3_OP(phaddw
),
3151 [0x02] = SSSE3_OP(phaddd
),
3152 [0x03] = SSSE3_OP(phaddsw
),
3153 [0x04] = SSSE3_OP(pmaddubsw
),
3154 [0x05] = SSSE3_OP(phsubw
),
3155 [0x06] = SSSE3_OP(phsubd
),
3156 [0x07] = SSSE3_OP(phsubsw
),
3157 [0x08] = SSSE3_OP(psignb
),
3158 [0x09] = SSSE3_OP(psignw
),
3159 [0x0a] = SSSE3_OP(psignd
),
3160 [0x0b] = SSSE3_OP(pmulhrsw
),
3161 [0x10] = SSE41_OP(pblendvb
),
3162 [0x14] = SSE41_OP(blendvps
),
3163 [0x15] = SSE41_OP(blendvpd
),
3164 [0x17] = SSE41_OP(ptest
),
3165 [0x1c] = SSSE3_OP(pabsb
),
3166 [0x1d] = SSSE3_OP(pabsw
),
3167 [0x1e] = SSSE3_OP(pabsd
),
3168 [0x20] = SSE41_OP(pmovsxbw
),
3169 [0x21] = SSE41_OP(pmovsxbd
),
3170 [0x22] = SSE41_OP(pmovsxbq
),
3171 [0x23] = SSE41_OP(pmovsxwd
),
3172 [0x24] = SSE41_OP(pmovsxwq
),
3173 [0x25] = SSE41_OP(pmovsxdq
),
3174 [0x28] = SSE41_OP(pmuldq
),
3175 [0x29] = SSE41_OP(pcmpeqq
),
3176 [0x2a] = SSE41_SPECIAL
, /* movntqda */
3177 [0x2b] = SSE41_OP(packusdw
),
3178 [0x30] = SSE41_OP(pmovzxbw
),
3179 [0x31] = SSE41_OP(pmovzxbd
),
3180 [0x32] = SSE41_OP(pmovzxbq
),
3181 [0x33] = SSE41_OP(pmovzxwd
),
3182 [0x34] = SSE41_OP(pmovzxwq
),
3183 [0x35] = SSE41_OP(pmovzxdq
),
3184 [0x37] = SSE42_OP(pcmpgtq
),
3185 [0x38] = SSE41_OP(pminsb
),
3186 [0x39] = SSE41_OP(pminsd
),
3187 [0x3a] = SSE41_OP(pminuw
),
3188 [0x3b] = SSE41_OP(pminud
),
3189 [0x3c] = SSE41_OP(pmaxsb
),
3190 [0x3d] = SSE41_OP(pmaxsd
),
3191 [0x3e] = SSE41_OP(pmaxuw
),
3192 [0x3f] = SSE41_OP(pmaxud
),
3193 [0x40] = SSE41_OP(pmulld
),
3194 [0x41] = SSE41_OP(phminposuw
),
3197 static const struct SSEOpHelper_eppi sse_op_table7
[256] = {
3198 [0x08] = SSE41_OP(roundps
),
3199 [0x09] = SSE41_OP(roundpd
),
3200 [0x0a] = SSE41_OP(roundss
),
3201 [0x0b] = SSE41_OP(roundsd
),
3202 [0x0c] = SSE41_OP(blendps
),
3203 [0x0d] = SSE41_OP(blendpd
),
3204 [0x0e] = SSE41_OP(pblendw
),
3205 [0x0f] = SSSE3_OP(palignr
),
3206 [0x14] = SSE41_SPECIAL
, /* pextrb */
3207 [0x15] = SSE41_SPECIAL
, /* pextrw */
3208 [0x16] = SSE41_SPECIAL
, /* pextrd/pextrq */
3209 [0x17] = SSE41_SPECIAL
, /* extractps */
3210 [0x20] = SSE41_SPECIAL
, /* pinsrb */
3211 [0x21] = SSE41_SPECIAL
, /* insertps */
3212 [0x22] = SSE41_SPECIAL
, /* pinsrd/pinsrq */
3213 [0x40] = SSE41_OP(dpps
),
3214 [0x41] = SSE41_OP(dppd
),
3215 [0x42] = SSE41_OP(mpsadbw
),
3216 [0x60] = SSE42_OP(pcmpestrm
),
3217 [0x61] = SSE42_OP(pcmpestri
),
3218 [0x62] = SSE42_OP(pcmpistrm
),
3219 [0x63] = SSE42_OP(pcmpistri
),
3222 static void gen_sse(CPUX86State
*env
, DisasContext
*s
, int b
,
3223 target_ulong pc_start
, int rex_r
)
3225 int b1
, op1_offset
, op2_offset
, is_xmm
, val
, ot
;
3226 int modrm
, mod
, rm
, reg
, reg_addr
, offset_addr
;
3227 SSEFunc_0_epp sse_fn_epp
;
3228 SSEFunc_0_eppi sse_fn_eppi
;
3229 SSEFunc_0_ppi sse_fn_ppi
;
3230 SSEFunc_0_eppt sse_fn_eppt
;
3233 if (s
->prefix
& PREFIX_DATA
)
3235 else if (s
->prefix
& PREFIX_REPZ
)
3237 else if (s
->prefix
& PREFIX_REPNZ
)
3241 sse_fn_epp
= sse_op_table1
[b
][b1
];
3245 if ((b
<= 0x5f && b
>= 0x10) || b
== 0xc6 || b
== 0xc2) {
3255 /* simple MMX/SSE operation */
3256 if (s
->flags
& HF_TS_MASK
) {
3257 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
3260 if (s
->flags
& HF_EM_MASK
) {
3262 gen_exception(s
, EXCP06_ILLOP
, pc_start
- s
->cs_base
);
3265 if (is_xmm
&& !(s
->flags
& HF_OSFXSR_MASK
))
3266 if ((b
!= 0x38 && b
!= 0x3a) || (s
->prefix
& PREFIX_DATA
))
3269 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
))
3272 gen_helper_emms(cpu_env
);
3277 gen_helper_emms(cpu_env
);
3280 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3281 the static cpu state) */
3283 gen_helper_enter_mmx(cpu_env
);
3286 modrm
= cpu_ldub_code(env
, s
->pc
++);
3287 reg
= ((modrm
>> 3) & 7);
3290 mod
= (modrm
>> 6) & 3;
3291 if (sse_fn_epp
== SSE_SPECIAL
) {
3294 case 0x0e7: /* movntq */
3297 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3298 gen_stq_env_A0(s
->mem_index
, offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3300 case 0x1e7: /* movntdq */
3301 case 0x02b: /* movntps */
3302 case 0x12b: /* movntps */
3305 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3306 gen_sto_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
]));
3308 case 0x3f0: /* lddqu */
3311 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3312 gen_ldo_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
]));
3314 case 0x22b: /* movntss */
3315 case 0x32b: /* movntsd */
3318 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3320 gen_stq_env_A0(s
->mem_index
, offsetof(CPUX86State
,
3323 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
3324 xmm_regs
[reg
].XMM_L(0)));
3325 gen_op_st_T0_A0(OT_LONG
+ s
->mem_index
);
3328 case 0x6e: /* movd mm, ea */
3329 #ifdef TARGET_X86_64
3330 if (s
->dflag
== 2) {
3331 gen_ldst_modrm(env
, s
, modrm
, OT_QUAD
, OR_TMP0
, 0);
3332 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3336 gen_ldst_modrm(env
, s
, modrm
, OT_LONG
, OR_TMP0
, 0);
3337 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3338 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3339 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3340 gen_helper_movl_mm_T0_mmx(cpu_ptr0
, cpu_tmp2_i32
);
3343 case 0x16e: /* movd xmm, ea */
3344 #ifdef TARGET_X86_64
3345 if (s
->dflag
== 2) {
3346 gen_ldst_modrm(env
, s
, modrm
, OT_QUAD
, OR_TMP0
, 0);
3347 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3348 offsetof(CPUX86State
,xmm_regs
[reg
]));
3349 gen_helper_movq_mm_T0_xmm(cpu_ptr0
, cpu_T
[0]);
3353 gen_ldst_modrm(env
, s
, modrm
, OT_LONG
, OR_TMP0
, 0);
3354 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3355 offsetof(CPUX86State
,xmm_regs
[reg
]));
3356 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3357 gen_helper_movl_mm_T0_xmm(cpu_ptr0
, cpu_tmp2_i32
);
3360 case 0x6f: /* movq mm, ea */
3362 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3363 gen_ldq_env_A0(s
->mem_index
, offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3366 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
3367 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3368 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
3369 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3372 case 0x010: /* movups */
3373 case 0x110: /* movupd */
3374 case 0x028: /* movaps */
3375 case 0x128: /* movapd */
3376 case 0x16f: /* movdqa xmm, ea */
3377 case 0x26f: /* movdqu xmm, ea */
3379 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3380 gen_ldo_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
]));
3382 rm
= (modrm
& 7) | REX_B(s
);
3383 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[reg
]),
3384 offsetof(CPUX86State
,xmm_regs
[rm
]));
3387 case 0x210: /* movss xmm, ea */
3389 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3390 gen_op_ld_T0_A0(OT_LONG
+ s
->mem_index
);
3391 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3393 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(1)));
3394 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)));
3395 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)));
3397 rm
= (modrm
& 7) | REX_B(s
);
3398 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)),
3399 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(0)));
3402 case 0x310: /* movsd xmm, ea */
3404 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3405 gen_ldq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3407 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)));
3408 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)));
3410 rm
= (modrm
& 7) | REX_B(s
);
3411 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3412 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3415 case 0x012: /* movlps */
3416 case 0x112: /* movlpd */
3418 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3419 gen_ldq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3422 rm
= (modrm
& 7) | REX_B(s
);
3423 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3424 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(1)));
3427 case 0x212: /* movsldup */
3429 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3430 gen_ldo_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
]));
3432 rm
= (modrm
& 7) | REX_B(s
);
3433 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)),
3434 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(0)));
3435 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)),
3436 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(2)));
3438 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(1)),
3439 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3440 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)),
3441 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)));
3443 case 0x312: /* movddup */
3445 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3446 gen_ldq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3448 rm
= (modrm
& 7) | REX_B(s
);
3449 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3450 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3452 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)),
3453 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3455 case 0x016: /* movhps */
3456 case 0x116: /* movhpd */
3458 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3459 gen_ldq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)));
3462 rm
= (modrm
& 7) | REX_B(s
);
3463 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)),
3464 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3467 case 0x216: /* movshdup */
3469 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3470 gen_ldo_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
]));
3472 rm
= (modrm
& 7) | REX_B(s
);
3473 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(1)),
3474 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(1)));
3475 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)),
3476 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(3)));
3478 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)),
3479 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(1)));
3480 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)),
3481 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)));
3486 int bit_index
, field_length
;
3488 if (b1
== 1 && reg
!= 0)
3490 field_length
= cpu_ldub_code(env
, s
->pc
++) & 0x3F;
3491 bit_index
= cpu_ldub_code(env
, s
->pc
++) & 0x3F;
3492 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3493 offsetof(CPUX86State
,xmm_regs
[reg
]));
3495 gen_helper_extrq_i(cpu_env
, cpu_ptr0
,
3496 tcg_const_i32(bit_index
),
3497 tcg_const_i32(field_length
));
3499 gen_helper_insertq_i(cpu_env
, cpu_ptr0
,
3500 tcg_const_i32(bit_index
),
3501 tcg_const_i32(field_length
));
3504 case 0x7e: /* movd ea, mm */
3505 #ifdef TARGET_X86_64
3506 if (s
->dflag
== 2) {
3507 tcg_gen_ld_i64(cpu_T
[0], cpu_env
,
3508 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3509 gen_ldst_modrm(env
, s
, modrm
, OT_QUAD
, OR_TMP0
, 1);
3513 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
,
3514 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_L(0)));
3515 gen_ldst_modrm(env
, s
, modrm
, OT_LONG
, OR_TMP0
, 1);
3518 case 0x17e: /* movd ea, xmm */
3519 #ifdef TARGET_X86_64
3520 if (s
->dflag
== 2) {
3521 tcg_gen_ld_i64(cpu_T
[0], cpu_env
,
3522 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3523 gen_ldst_modrm(env
, s
, modrm
, OT_QUAD
, OR_TMP0
, 1);
3527 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
,
3528 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3529 gen_ldst_modrm(env
, s
, modrm
, OT_LONG
, OR_TMP0
, 1);
3532 case 0x27e: /* movq xmm, ea */
3534 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3535 gen_ldq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3537 rm
= (modrm
& 7) | REX_B(s
);
3538 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3539 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3541 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)));
3543 case 0x7f: /* movq ea, mm */
3545 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3546 gen_stq_env_A0(s
->mem_index
, offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3549 gen_op_movq(offsetof(CPUX86State
,fpregs
[rm
].mmx
),
3550 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3553 case 0x011: /* movups */
3554 case 0x111: /* movupd */
3555 case 0x029: /* movaps */
3556 case 0x129: /* movapd */
3557 case 0x17f: /* movdqa ea, xmm */
3558 case 0x27f: /* movdqu ea, xmm */
3560 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3561 gen_sto_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
]));
3563 rm
= (modrm
& 7) | REX_B(s
);
3564 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[rm
]),
3565 offsetof(CPUX86State
,xmm_regs
[reg
]));
3568 case 0x211: /* movss ea, xmm */
3570 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3571 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3572 gen_op_st_T0_A0(OT_LONG
+ s
->mem_index
);
3574 rm
= (modrm
& 7) | REX_B(s
);
3575 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(0)),
3576 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3579 case 0x311: /* movsd ea, xmm */
3581 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3582 gen_stq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3584 rm
= (modrm
& 7) | REX_B(s
);
3585 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)),
3586 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3589 case 0x013: /* movlps */
3590 case 0x113: /* movlpd */
3592 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3593 gen_stq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3598 case 0x017: /* movhps */
3599 case 0x117: /* movhpd */
3601 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3602 gen_stq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)));
3607 case 0x71: /* shift mm, im */
3610 case 0x171: /* shift xmm, im */
3616 val
= cpu_ldub_code(env
, s
->pc
++);
3618 gen_op_movl_T0_im(val
);
3619 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.XMM_L(0)));
3621 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.XMM_L(1)));
3622 op1_offset
= offsetof(CPUX86State
,xmm_t0
);
3624 gen_op_movl_T0_im(val
);
3625 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,mmx_t0
.MMX_L(0)));
3627 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,mmx_t0
.MMX_L(1)));
3628 op1_offset
= offsetof(CPUX86State
,mmx_t0
);
3630 sse_fn_epp
= sse_op_table2
[((b
- 1) & 3) * 8 +
3631 (((modrm
>> 3)) & 7)][b1
];
3636 rm
= (modrm
& 7) | REX_B(s
);
3637 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3640 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3642 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3643 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op1_offset
);
3644 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3646 case 0x050: /* movmskps */
3647 rm
= (modrm
& 7) | REX_B(s
);
3648 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3649 offsetof(CPUX86State
,xmm_regs
[rm
]));
3650 gen_helper_movmskps(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3651 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
3652 gen_op_mov_reg_T0(OT_LONG
, reg
);
3654 case 0x150: /* movmskpd */
3655 rm
= (modrm
& 7) | REX_B(s
);
3656 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3657 offsetof(CPUX86State
,xmm_regs
[rm
]));
3658 gen_helper_movmskpd(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3659 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
3660 gen_op_mov_reg_T0(OT_LONG
, reg
);
3662 case 0x02a: /* cvtpi2ps */
3663 case 0x12a: /* cvtpi2pd */
3664 gen_helper_enter_mmx(cpu_env
);
3666 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3667 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3668 gen_ldq_env_A0(s
->mem_index
, op2_offset
);
3671 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3673 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3674 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3675 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3678 gen_helper_cvtpi2ps(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3682 gen_helper_cvtpi2pd(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3686 case 0x22a: /* cvtsi2ss */
3687 case 0x32a: /* cvtsi2sd */
3688 ot
= (s
->dflag
== 2) ? OT_QUAD
: OT_LONG
;
3689 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3690 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3691 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3692 if (ot
== OT_LONG
) {
3693 SSEFunc_0_epi sse_fn_epi
= sse_op_table3ai
[(b
>> 8) & 1];
3694 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3695 sse_fn_epi(cpu_env
, cpu_ptr0
, cpu_tmp2_i32
);
3697 #ifdef TARGET_X86_64
3698 SSEFunc_0_epl sse_fn_epl
= sse_op_table3aq
[(b
>> 8) & 1];
3699 sse_fn_epl(cpu_env
, cpu_ptr0
, cpu_T
[0]);
3705 case 0x02c: /* cvttps2pi */
3706 case 0x12c: /* cvttpd2pi */
3707 case 0x02d: /* cvtps2pi */
3708 case 0x12d: /* cvtpd2pi */
3709 gen_helper_enter_mmx(cpu_env
);
3711 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3712 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3713 gen_ldo_env_A0(s
->mem_index
, op2_offset
);
3715 rm
= (modrm
& 7) | REX_B(s
);
3716 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3718 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
);
3719 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3720 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3723 gen_helper_cvttps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3726 gen_helper_cvttpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3729 gen_helper_cvtps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3732 gen_helper_cvtpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3736 case 0x22c: /* cvttss2si */
3737 case 0x32c: /* cvttsd2si */
3738 case 0x22d: /* cvtss2si */
3739 case 0x32d: /* cvtsd2si */
3740 ot
= (s
->dflag
== 2) ? OT_QUAD
: OT_LONG
;
3742 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3744 gen_ldq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_t0
.XMM_Q(0)));
3746 gen_op_ld_T0_A0(OT_LONG
+ s
->mem_index
);
3747 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.XMM_L(0)));
3749 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3751 rm
= (modrm
& 7) | REX_B(s
);
3752 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3754 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3755 if (ot
== OT_LONG
) {
3756 SSEFunc_i_ep sse_fn_i_ep
=
3757 sse_op_table3bi
[((b
>> 7) & 2) | (b
& 1)];
3758 sse_fn_i_ep(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3759 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
3761 #ifdef TARGET_X86_64
3762 SSEFunc_l_ep sse_fn_l_ep
=
3763 sse_op_table3bq
[((b
>> 7) & 2) | (b
& 1)];
3764 sse_fn_l_ep(cpu_T
[0], cpu_env
, cpu_ptr0
);
3769 gen_op_mov_reg_T0(ot
, reg
);
3771 case 0xc4: /* pinsrw */
3774 gen_ldst_modrm(env
, s
, modrm
, OT_WORD
, OR_TMP0
, 0);
3775 val
= cpu_ldub_code(env
, s
->pc
++);
3778 tcg_gen_st16_tl(cpu_T
[0], cpu_env
,
3779 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_W(val
)));
3782 tcg_gen_st16_tl(cpu_T
[0], cpu_env
,
3783 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_W(val
)));
3786 case 0xc5: /* pextrw */
3790 ot
= (s
->dflag
== 2) ? OT_QUAD
: OT_LONG
;
3791 val
= cpu_ldub_code(env
, s
->pc
++);
3794 rm
= (modrm
& 7) | REX_B(s
);
3795 tcg_gen_ld16u_tl(cpu_T
[0], cpu_env
,
3796 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_W(val
)));
3800 tcg_gen_ld16u_tl(cpu_T
[0], cpu_env
,
3801 offsetof(CPUX86State
,fpregs
[rm
].mmx
.MMX_W(val
)));
3803 reg
= ((modrm
>> 3) & 7) | rex_r
;
3804 gen_op_mov_reg_T0(ot
, reg
);
3806 case 0x1d6: /* movq ea, xmm */
3808 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3809 gen_stq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3811 rm
= (modrm
& 7) | REX_B(s
);
3812 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)),
3813 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3814 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(1)));
3817 case 0x2d6: /* movq2dq */
3818 gen_helper_enter_mmx(cpu_env
);
3820 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3821 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3822 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)));
3824 case 0x3d6: /* movdq2q */
3825 gen_helper_enter_mmx(cpu_env
);
3826 rm
= (modrm
& 7) | REX_B(s
);
3827 gen_op_movq(offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
),
3828 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3830 case 0xd7: /* pmovmskb */
3835 rm
= (modrm
& 7) | REX_B(s
);
3836 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[rm
]));
3837 gen_helper_pmovmskb_xmm(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3840 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3841 gen_helper_pmovmskb_mmx(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3843 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
3844 reg
= ((modrm
>> 3) & 7) | rex_r
;
3845 gen_op_mov_reg_T0(OT_LONG
, reg
);
3851 if ((b
& 0xf0) == 0xf0) {
3854 modrm
= cpu_ldub_code(env
, s
->pc
++);
3856 reg
= ((modrm
>> 3) & 7) | rex_r
;
3857 mod
= (modrm
>> 6) & 3;
3862 sse_fn_epp
= sse_op_table6
[b
].op
[b1
];
3866 if (!(s
->cpuid_ext_features
& sse_op_table6
[b
].ext_mask
))
3870 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3872 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
3874 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3875 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3877 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3878 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3879 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3880 gen_ldq_env_A0(s
->mem_index
, op2_offset
+
3881 offsetof(XMMReg
, XMM_Q(0)));
3883 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3884 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3885 tcg_gen_qemu_ld32u(cpu_tmp0
, cpu_A0
,
3886 (s
->mem_index
>> 2) - 1);
3887 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_tmp0
);
3888 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, op2_offset
+
3889 offsetof(XMMReg
, XMM_L(0)));
3891 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3892 tcg_gen_qemu_ld16u(cpu_tmp0
, cpu_A0
,
3893 (s
->mem_index
>> 2) - 1);
3894 tcg_gen_st16_tl(cpu_tmp0
, cpu_env
, op2_offset
+
3895 offsetof(XMMReg
, XMM_W(0)));
3897 case 0x2a: /* movntqda */
3898 gen_ldo_env_A0(s
->mem_index
, op1_offset
);
3901 gen_ldo_env_A0(s
->mem_index
, op2_offset
);
3905 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
3907 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3909 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3910 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3911 gen_ldq_env_A0(s
->mem_index
, op2_offset
);
3914 if (sse_fn_epp
== SSE_SPECIAL
) {
3918 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3919 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3920 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3923 set_cc_op(s
, CC_OP_EFLAGS
);
3930 /* Various integer extensions at 0f 38 f[0-f]. */
3931 b
= modrm
| (b1
<< 8);
3932 modrm
= cpu_ldub_code(env
, s
->pc
++);
3933 reg
= ((modrm
>> 3) & 7) | rex_r
;
3936 case 0x3f0: /* crc32 Gd,Eb */
3937 case 0x3f1: /* crc32 Gd,Ey */
3939 if (!(s
->cpuid_ext_features
& CPUID_EXT_SSE42
)) {
3942 if ((b
& 0xff) == 0xf0) {
3944 } else if (s
->dflag
!= 2) {
3945 ot
= (s
->prefix
& PREFIX_DATA
? OT_WORD
: OT_LONG
);
3950 gen_op_mov_TN_reg(OT_LONG
, 0, reg
);
3951 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3952 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3953 gen_helper_crc32(cpu_T
[0], cpu_tmp2_i32
,
3954 cpu_T
[0], tcg_const_i32(8 << ot
));
3956 ot
= (s
->dflag
== 2) ? OT_QUAD
: OT_LONG
;
3957 gen_op_mov_reg_T0(ot
, reg
);
3960 case 0x1f0: /* crc32 or movbe */
3962 /* For these insns, the f3 prefix is supposed to have priority
3963 over the 66 prefix, but that's not what we implement above
3965 if (s
->prefix
& PREFIX_REPNZ
) {
3969 case 0x0f0: /* movbe Gy,My */
3970 case 0x0f1: /* movbe My,Gy */
3971 if (!(s
->cpuid_ext_features
& CPUID_EXT_MOVBE
)) {
3974 if (s
->dflag
!= 2) {
3975 ot
= (s
->prefix
& PREFIX_DATA
? OT_WORD
: OT_LONG
);
3980 /* Load the data incoming to the bswap. Note that the TCG
3981 implementation of bswap requires the input be zero
3982 extended. In the case of the loads, we simply know that
3983 gen_op_ld_v via gen_ldst_modrm does that already. */
3985 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3989 tcg_gen_ext16u_tl(cpu_T
[0], cpu_regs
[reg
]);
3992 tcg_gen_ext32u_tl(cpu_T
[0], cpu_regs
[reg
]);
3995 tcg_gen_mov_tl(cpu_T
[0], cpu_regs
[reg
]);
4002 tcg_gen_bswap16_tl(cpu_T
[0], cpu_T
[0]);
4005 tcg_gen_bswap32_tl(cpu_T
[0], cpu_T
[0]);
4007 #ifdef TARGET_X86_64
4009 tcg_gen_bswap64_tl(cpu_T
[0], cpu_T
[0]);
4015 gen_op_mov_reg_T0(ot
, reg
);
4017 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
4021 case 0x0f2: /* andn Gy, By, Ey */
4022 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
4023 || !(s
->prefix
& PREFIX_VEX
)
4027 ot
= s
->dflag
== 2 ? OT_QUAD
: OT_LONG
;
4028 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4029 tcg_gen_andc_tl(cpu_T
[0], cpu_regs
[s
->vex_v
], cpu_T
[0]);
4030 gen_op_mov_reg_T0(ot
, reg
);
4031 gen_op_update1_cc();
4032 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4035 case 0x0f7: /* bextr Gy, Ey, By */
4036 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
4037 || !(s
->prefix
& PREFIX_VEX
)
4041 ot
= s
->dflag
== 2 ? OT_QUAD
: OT_LONG
;
4045 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4046 /* Extract START, and shift the operand.
4047 Shifts larger than operand size get zeros. */
4048 tcg_gen_ext8u_tl(cpu_A0
, cpu_regs
[s
->vex_v
]);
4049 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], cpu_A0
);
4051 bound
= tcg_const_tl(ot
== OT_QUAD
? 63 : 31);
4052 zero
= tcg_const_tl(0);
4053 tcg_gen_movcond_tl(TCG_COND_LEU
, cpu_T
[0], cpu_A0
, bound
,
4055 tcg_temp_free(zero
);
4057 /* Extract the LEN into a mask. Lengths larger than
4058 operand size get all ones. */
4059 tcg_gen_shri_tl(cpu_A0
, cpu_regs
[s
->vex_v
], 8);
4060 tcg_gen_ext8u_tl(cpu_A0
, cpu_A0
);
4061 tcg_gen_movcond_tl(TCG_COND_LEU
, cpu_A0
, cpu_A0
, bound
,
4063 tcg_temp_free(bound
);
4064 tcg_gen_movi_tl(cpu_T
[1], 1);
4065 tcg_gen_shl_tl(cpu_T
[1], cpu_T
[1], cpu_A0
);
4066 tcg_gen_subi_tl(cpu_T
[1], cpu_T
[1], 1);
4067 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4069 gen_op_mov_reg_T0(ot
, reg
);
4070 gen_op_update1_cc();
4071 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4075 case 0x0f5: /* bzhi Gy, Ey, By */
4076 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4077 || !(s
->prefix
& PREFIX_VEX
)
4081 ot
= s
->dflag
== 2 ? OT_QUAD
: OT_LONG
;
4082 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4083 tcg_gen_ext8u_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
4085 TCGv bound
= tcg_const_tl(ot
== OT_QUAD
? 63 : 31);
4086 /* Note that since we're using BMILG (in order to get O
4087 cleared) we need to store the inverse into C. */
4088 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_cc_src
,
4090 tcg_gen_movcond_tl(TCG_COND_GT
, cpu_T
[1], cpu_T
[1],
4091 bound
, bound
, cpu_T
[1]);
4092 tcg_temp_free(bound
);
4094 tcg_gen_movi_tl(cpu_A0
, -1);
4095 tcg_gen_shl_tl(cpu_A0
, cpu_A0
, cpu_T
[1]);
4096 tcg_gen_andc_tl(cpu_T
[0], cpu_T
[0], cpu_A0
);
4097 gen_op_mov_reg_T0(ot
, reg
);
4098 gen_op_update1_cc();
4099 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4102 case 0x3f6: /* mulx By, Gy, rdx, Ey */
4103 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4104 || !(s
->prefix
& PREFIX_VEX
)
4108 ot
= s
->dflag
== 2 ? OT_QUAD
: OT_LONG
;
4109 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4113 t0
= tcg_temp_new_i64();
4114 t1
= tcg_temp_new_i64();
4115 #ifdef TARGET_X86_64
4116 tcg_gen_ext32u_i64(t0
, cpu_T
[0]);
4117 tcg_gen_ext32u_i64(t1
, cpu_regs
[R_EDX
]);
4119 tcg_gen_extu_i32_i64(t0
, cpu_T
[0]);
4120 tcg_gen_extu_i32_i64(t0
, cpu_regs
[R_EDX
]);
4122 tcg_gen_mul_i64(t0
, t0
, t1
);
4123 tcg_gen_trunc_i64_tl(cpu_T
[0], t0
);
4124 tcg_gen_shri_i64(t0
, t0
, 32);
4125 tcg_gen_trunc_i64_tl(cpu_T
[1], t0
);
4126 tcg_temp_free_i64(t0
);
4127 tcg_temp_free_i64(t1
);
4128 gen_op_mov_reg_T0(OT_LONG
, s
->vex_v
);
4129 gen_op_mov_reg_T1(OT_LONG
, reg
);
4131 #ifdef TARGET_X86_64
4133 tcg_gen_mov_tl(cpu_T
[1], cpu_regs
[R_EDX
]);
4134 tcg_gen_mul_tl(cpu_regs
[s
->vex_v
], cpu_T
[0], cpu_T
[1]);
4135 gen_helper_umulh(cpu_regs
[reg
], cpu_T
[0], cpu_T
[1]);
4141 case 0x3f5: /* pdep Gy, By, Ey */
4142 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4143 || !(s
->prefix
& PREFIX_VEX
)
4147 ot
= s
->dflag
== 2 ? OT_QUAD
: OT_LONG
;
4148 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4149 /* Note that by zero-extending the mask operand, we
4150 automatically handle zero-extending the result. */
4151 if (s
->dflag
== 2) {
4152 tcg_gen_mov_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
4154 tcg_gen_ext32u_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
4156 gen_helper_pdep(cpu_regs
[reg
], cpu_T
[0], cpu_T
[1]);
4159 case 0x2f5: /* pext Gy, By, Ey */
4160 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4161 || !(s
->prefix
& PREFIX_VEX
)
4165 ot
= s
->dflag
== 2 ? OT_QUAD
: OT_LONG
;
4166 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4167 /* Note that by zero-extending the mask operand, we
4168 automatically handle zero-extending the result. */
4169 if (s
->dflag
== 2) {
4170 tcg_gen_mov_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
4172 tcg_gen_ext32u_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
4174 gen_helper_pext(cpu_regs
[reg
], cpu_T
[0], cpu_T
[1]);
4180 case 0x3f3: /* Group 17 */
4181 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
4182 || !(s
->prefix
& PREFIX_VEX
)
4186 ot
= s
->dflag
== 2 ? OT_QUAD
: OT_LONG
;
4187 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4190 case 1: /* blsr By,Ey */
4191 tcg_gen_neg_tl(cpu_T
[1], cpu_T
[0]);
4192 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4193 gen_op_mov_reg_T0(ot
, s
->vex_v
);
4194 gen_op_update2_cc();
4195 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4198 case 2: /* blsmsk By,Ey */
4199 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
4200 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], 1);
4201 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_cc_src
);
4202 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4203 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4206 case 3: /* blsi By, Ey */
4207 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
4208 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], 1);
4209 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_cc_src
);
4210 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4211 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4227 modrm
= cpu_ldub_code(env
, s
->pc
++);
4229 reg
= ((modrm
>> 3) & 7) | rex_r
;
4230 mod
= (modrm
>> 6) & 3;
4235 sse_fn_eppi
= sse_op_table7
[b
].op
[b1
];
4239 if (!(s
->cpuid_ext_features
& sse_op_table7
[b
].ext_mask
))
4242 if (sse_fn_eppi
== SSE_SPECIAL
) {
4243 ot
= (s
->dflag
== 2) ? OT_QUAD
: OT_LONG
;
4244 rm
= (modrm
& 7) | REX_B(s
);
4246 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4247 reg
= ((modrm
>> 3) & 7) | rex_r
;
4248 val
= cpu_ldub_code(env
, s
->pc
++);
4250 case 0x14: /* pextrb */
4251 tcg_gen_ld8u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4252 xmm_regs
[reg
].XMM_B(val
& 15)));
4254 gen_op_mov_reg_T0(ot
, rm
);
4256 tcg_gen_qemu_st8(cpu_T
[0], cpu_A0
,
4257 (s
->mem_index
>> 2) - 1);
4259 case 0x15: /* pextrw */
4260 tcg_gen_ld16u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4261 xmm_regs
[reg
].XMM_W(val
& 7)));
4263 gen_op_mov_reg_T0(ot
, rm
);
4265 tcg_gen_qemu_st16(cpu_T
[0], cpu_A0
,
4266 (s
->mem_index
>> 2) - 1);
4269 if (ot
== OT_LONG
) { /* pextrd */
4270 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4271 offsetof(CPUX86State
,
4272 xmm_regs
[reg
].XMM_L(val
& 3)));
4273 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
4275 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4277 tcg_gen_qemu_st32(cpu_T
[0], cpu_A0
,
4278 (s
->mem_index
>> 2) - 1);
4279 } else { /* pextrq */
4280 #ifdef TARGET_X86_64
4281 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
4282 offsetof(CPUX86State
,
4283 xmm_regs
[reg
].XMM_Q(val
& 1)));
4285 gen_op_mov_reg_v(ot
, rm
, cpu_tmp1_i64
);
4287 tcg_gen_qemu_st64(cpu_tmp1_i64
, cpu_A0
,
4288 (s
->mem_index
>> 2) - 1);
4294 case 0x17: /* extractps */
4295 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4296 xmm_regs
[reg
].XMM_L(val
& 3)));
4298 gen_op_mov_reg_T0(ot
, rm
);
4300 tcg_gen_qemu_st32(cpu_T
[0], cpu_A0
,
4301 (s
->mem_index
>> 2) - 1);
4303 case 0x20: /* pinsrb */
4305 gen_op_mov_TN_reg(OT_LONG
, 0, rm
);
4307 tcg_gen_qemu_ld8u(cpu_tmp0
, cpu_A0
,
4308 (s
->mem_index
>> 2) - 1);
4309 tcg_gen_st8_tl(cpu_tmp0
, cpu_env
, offsetof(CPUX86State
,
4310 xmm_regs
[reg
].XMM_B(val
& 15)));
4312 case 0x21: /* insertps */
4314 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4315 offsetof(CPUX86State
,xmm_regs
[rm
]
4316 .XMM_L((val
>> 6) & 3)));
4318 tcg_gen_qemu_ld32u(cpu_tmp0
, cpu_A0
,
4319 (s
->mem_index
>> 2) - 1);
4320 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_tmp0
);
4322 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4323 offsetof(CPUX86State
,xmm_regs
[reg
]
4324 .XMM_L((val
>> 4) & 3)));
4326 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4327 cpu_env
, offsetof(CPUX86State
,
4328 xmm_regs
[reg
].XMM_L(0)));
4330 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4331 cpu_env
, offsetof(CPUX86State
,
4332 xmm_regs
[reg
].XMM_L(1)));
4334 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4335 cpu_env
, offsetof(CPUX86State
,
4336 xmm_regs
[reg
].XMM_L(2)));
4338 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4339 cpu_env
, offsetof(CPUX86State
,
4340 xmm_regs
[reg
].XMM_L(3)));
4343 if (ot
== OT_LONG
) { /* pinsrd */
4345 gen_op_mov_v_reg(ot
, cpu_tmp0
, rm
);
4347 tcg_gen_qemu_ld32u(cpu_tmp0
, cpu_A0
,
4348 (s
->mem_index
>> 2) - 1);
4349 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_tmp0
);
4350 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4351 offsetof(CPUX86State
,
4352 xmm_regs
[reg
].XMM_L(val
& 3)));
4353 } else { /* pinsrq */
4354 #ifdef TARGET_X86_64
4356 gen_op_mov_v_reg(ot
, cpu_tmp1_i64
, rm
);
4358 tcg_gen_qemu_ld64(cpu_tmp1_i64
, cpu_A0
,
4359 (s
->mem_index
>> 2) - 1);
4360 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
4361 offsetof(CPUX86State
,
4362 xmm_regs
[reg
].XMM_Q(val
& 1)));
4373 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4375 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
4377 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4378 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4379 gen_ldo_env_A0(s
->mem_index
, op2_offset
);
4382 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4384 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4386 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4387 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4388 gen_ldq_env_A0(s
->mem_index
, op2_offset
);
4391 val
= cpu_ldub_code(env
, s
->pc
++);
4393 if ((b
& 0xfc) == 0x60) { /* pcmpXstrX */
4394 set_cc_op(s
, CC_OP_EFLAGS
);
4397 /* The helper must use entire 64-bit gp registers */
4401 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4402 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4403 sse_fn_eppi(cpu_env
, cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4409 /* generic MMX or SSE operation */
4411 case 0x70: /* pshufx insn */
4412 case 0xc6: /* pshufx insn */
4413 case 0xc2: /* compare insns */
4420 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4422 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4423 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4424 if (b1
>= 2 && ((b
>= 0x50 && b
<= 0x5f && b
!= 0x5b) ||
4426 /* specific case for SSE single instructions */
4429 gen_op_ld_T0_A0(OT_LONG
+ s
->mem_index
);
4430 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.XMM_L(0)));
4433 gen_ldq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_t0
.XMM_D(0)));
4436 gen_ldo_env_A0(s
->mem_index
, op2_offset
);
4439 rm
= (modrm
& 7) | REX_B(s
);
4440 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
4443 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4445 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4446 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4447 gen_ldq_env_A0(s
->mem_index
, op2_offset
);
4450 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4454 case 0x0f: /* 3DNow! data insns */
4455 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
))
4457 val
= cpu_ldub_code(env
, s
->pc
++);
4458 sse_fn_epp
= sse_op_table5
[val
];
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_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4466 case 0x70: /* pshufx insn */
4467 case 0xc6: /* pshufx insn */
4468 val
= cpu_ldub_code(env
, s
->pc
++);
4469 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4470 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4471 /* XXX: introduce a new table? */
4472 sse_fn_ppi
= (SSEFunc_0_ppi
)sse_fn_epp
;
4473 sse_fn_ppi(cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4477 val
= cpu_ldub_code(env
, s
->pc
++);
4480 sse_fn_epp
= sse_op_table4
[val
][b1
];
4482 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4483 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4484 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4487 /* maskmov : we must prepare A0 */
4490 #ifdef TARGET_X86_64
4491 if (s
->aflag
== 2) {
4492 gen_op_movq_A0_reg(R_EDI
);
4496 gen_op_movl_A0_reg(R_EDI
);
4498 gen_op_andl_A0_ffff();
4500 gen_add_A0_ds_seg(s
);
4502 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4503 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4504 /* XXX: introduce a new table? */
4505 sse_fn_eppt
= (SSEFunc_0_eppt
)sse_fn_epp
;
4506 sse_fn_eppt(cpu_env
, cpu_ptr0
, cpu_ptr1
, cpu_A0
);
4509 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4510 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4511 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4514 if (b
== 0x2e || b
== 0x2f) {
4515 set_cc_op(s
, CC_OP_EFLAGS
);
4520 /* convert one instruction. s->is_jmp is set if the translation must
4521 be stopped. Return the next pc value */
4522 static target_ulong
disas_insn(CPUX86State
*env
, DisasContext
*s
,
4523 target_ulong pc_start
)
4525 int b
, prefixes
, aflag
, dflag
;
4527 int modrm
, reg
, rm
, mod
, reg_addr
, op
, opreg
, offset_addr
, val
;
4528 target_ulong next_eip
, tval
;
4531 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
4532 tcg_gen_debug_insn_start(pc_start
);
4541 #ifdef TARGET_X86_64
4546 s
->rip_offset
= 0; /* for relative ip address */
4550 b
= cpu_ldub_code(env
, s
->pc
);
4552 /* Collect prefixes. */
4555 prefixes
|= PREFIX_REPZ
;
4558 prefixes
|= PREFIX_REPNZ
;
4561 prefixes
|= PREFIX_LOCK
;
4582 prefixes
|= PREFIX_DATA
;
4585 prefixes
|= PREFIX_ADR
;
4587 #ifdef TARGET_X86_64
4591 rex_w
= (b
>> 3) & 1;
4592 rex_r
= (b
& 0x4) << 1;
4593 s
->rex_x
= (b
& 0x2) << 2;
4594 REX_B(s
) = (b
& 0x1) << 3;
4595 x86_64_hregs
= 1; /* select uniform byte register addressing */
4600 case 0xc5: /* 2-byte VEX */
4601 case 0xc4: /* 3-byte VEX */
4602 /* VEX prefixes cannot be used except in 32-bit mode.
4603 Otherwise the instruction is LES or LDS. */
4604 if (s
->code32
&& !s
->vm86
) {
4605 static const int pp_prefix
[4] = {
4606 0, PREFIX_DATA
, PREFIX_REPZ
, PREFIX_REPNZ
4608 int vex3
, vex2
= cpu_ldub_code(env
, s
->pc
);
4610 if (!CODE64(s
) && (vex2
& 0xc0) != 0xc0) {
4611 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4612 otherwise the instruction is LES or LDS. */
4617 /* 4.1.1-4.1.3: No preceeding lock, 66, f2, f3, or rex prefixes. */
4618 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
4619 | PREFIX_LOCK
| PREFIX_DATA
)) {
4622 #ifdef TARGET_X86_64
4627 rex_r
= (~vex2
>> 4) & 8;
4630 b
= cpu_ldub_code(env
, s
->pc
++);
4632 #ifdef TARGET_X86_64
4633 s
->rex_x
= (~vex2
>> 3) & 8;
4634 s
->rex_b
= (~vex2
>> 2) & 8;
4636 vex3
= cpu_ldub_code(env
, s
->pc
++);
4637 rex_w
= (vex3
>> 7) & 1;
4638 switch (vex2
& 0x1f) {
4639 case 0x01: /* Implied 0f leading opcode bytes. */
4640 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4642 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4645 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4648 default: /* Reserved for future use. */
4652 s
->vex_v
= (~vex3
>> 3) & 0xf;
4653 s
->vex_l
= (vex3
>> 2) & 1;
4654 prefixes
|= pp_prefix
[vex3
& 3] | PREFIX_VEX
;
4659 /* Post-process prefixes. */
4660 if (prefixes
& PREFIX_DATA
) {
4663 if (prefixes
& PREFIX_ADR
) {
4666 #ifdef TARGET_X86_64
4669 /* 0x66 is ignored if rex.w is set */
4672 if (!(prefixes
& PREFIX_ADR
)) {
4678 s
->prefix
= prefixes
;
4682 /* lock generation */
4683 if (prefixes
& PREFIX_LOCK
)
4686 /* now check op code */
4690 /**************************/
4691 /* extended op code */
4692 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4695 /**************************/
4713 ot
= dflag
+ OT_WORD
;
4716 case 0: /* OP Ev, Gv */
4717 modrm
= cpu_ldub_code(env
, s
->pc
++);
4718 reg
= ((modrm
>> 3) & 7) | rex_r
;
4719 mod
= (modrm
>> 6) & 3;
4720 rm
= (modrm
& 7) | REX_B(s
);
4722 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4724 } else if (op
== OP_XORL
&& rm
== reg
) {
4726 /* xor reg, reg optimisation */
4728 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4729 gen_op_mov_reg_T0(ot
, reg
);
4730 gen_op_update1_cc();
4735 gen_op_mov_TN_reg(ot
, 1, reg
);
4736 gen_op(s
, op
, ot
, opreg
);
4738 case 1: /* OP Gv, Ev */
4739 modrm
= cpu_ldub_code(env
, s
->pc
++);
4740 mod
= (modrm
>> 6) & 3;
4741 reg
= ((modrm
>> 3) & 7) | rex_r
;
4742 rm
= (modrm
& 7) | REX_B(s
);
4744 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4745 gen_op_ld_T1_A0(ot
+ s
->mem_index
);
4746 } else if (op
== OP_XORL
&& rm
== reg
) {
4749 gen_op_mov_TN_reg(ot
, 1, rm
);
4751 gen_op(s
, op
, ot
, reg
);
4753 case 2: /* OP A, Iv */
4754 val
= insn_get(env
, s
, ot
);
4755 gen_op_movl_T1_im(val
);
4756 gen_op(s
, op
, ot
, OR_EAX
);
4765 case 0x80: /* GRP1 */
4774 ot
= dflag
+ OT_WORD
;
4776 modrm
= cpu_ldub_code(env
, s
->pc
++);
4777 mod
= (modrm
>> 6) & 3;
4778 rm
= (modrm
& 7) | REX_B(s
);
4779 op
= (modrm
>> 3) & 7;
4785 s
->rip_offset
= insn_const_size(ot
);
4786 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4797 val
= insn_get(env
, s
, ot
);
4800 val
= (int8_t)insn_get(env
, s
, OT_BYTE
);
4803 gen_op_movl_T1_im(val
);
4804 gen_op(s
, op
, ot
, opreg
);
4808 /**************************/
4809 /* inc, dec, and other misc arith */
4810 case 0x40 ... 0x47: /* inc Gv */
4811 ot
= dflag
? OT_LONG
: OT_WORD
;
4812 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), 1);
4814 case 0x48 ... 0x4f: /* dec Gv */
4815 ot
= dflag
? OT_LONG
: OT_WORD
;
4816 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), -1);
4818 case 0xf6: /* GRP3 */
4823 ot
= dflag
+ OT_WORD
;
4825 modrm
= cpu_ldub_code(env
, s
->pc
++);
4826 mod
= (modrm
>> 6) & 3;
4827 rm
= (modrm
& 7) | REX_B(s
);
4828 op
= (modrm
>> 3) & 7;
4831 s
->rip_offset
= insn_const_size(ot
);
4832 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4833 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
4835 gen_op_mov_TN_reg(ot
, 0, rm
);
4840 val
= insn_get(env
, s
, ot
);
4841 gen_op_movl_T1_im(val
);
4842 gen_op_testl_T0_T1_cc();
4843 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4846 tcg_gen_not_tl(cpu_T
[0], cpu_T
[0]);
4848 gen_op_st_T0_A0(ot
+ s
->mem_index
);
4850 gen_op_mov_reg_T0(ot
, rm
);
4854 tcg_gen_neg_tl(cpu_T
[0], cpu_T
[0]);
4856 gen_op_st_T0_A0(ot
+ s
->mem_index
);
4858 gen_op_mov_reg_T0(ot
, rm
);
4860 gen_op_update_neg_cc();
4861 set_cc_op(s
, CC_OP_SUBB
+ ot
);
4866 gen_op_mov_TN_reg(OT_BYTE
, 1, R_EAX
);
4867 tcg_gen_ext8u_tl(cpu_T
[0], cpu_T
[0]);
4868 tcg_gen_ext8u_tl(cpu_T
[1], cpu_T
[1]);
4869 /* XXX: use 32 bit mul which could be faster */
4870 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4871 gen_op_mov_reg_T0(OT_WORD
, R_EAX
);
4872 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4873 tcg_gen_andi_tl(cpu_cc_src
, cpu_T
[0], 0xff00);
4874 set_cc_op(s
, CC_OP_MULB
);
4877 gen_op_mov_TN_reg(OT_WORD
, 1, R_EAX
);
4878 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
4879 tcg_gen_ext16u_tl(cpu_T
[1], cpu_T
[1]);
4880 /* XXX: use 32 bit mul which could be faster */
4881 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4882 gen_op_mov_reg_T0(OT_WORD
, R_EAX
);
4883 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4884 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], 16);
4885 gen_op_mov_reg_T0(OT_WORD
, R_EDX
);
4886 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
4887 set_cc_op(s
, CC_OP_MULW
);
4891 #ifdef TARGET_X86_64
4892 gen_op_mov_TN_reg(OT_LONG
, 1, R_EAX
);
4893 tcg_gen_ext32u_tl(cpu_T
[0], cpu_T
[0]);
4894 tcg_gen_ext32u_tl(cpu_T
[1], cpu_T
[1]);
4895 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4896 gen_op_mov_reg_T0(OT_LONG
, R_EAX
);
4897 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4898 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], 32);
4899 gen_op_mov_reg_T0(OT_LONG
, R_EDX
);
4900 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
4904 t0
= tcg_temp_new_i64();
4905 t1
= tcg_temp_new_i64();
4906 gen_op_mov_TN_reg(OT_LONG
, 1, R_EAX
);
4907 tcg_gen_extu_i32_i64(t0
, cpu_T
[0]);
4908 tcg_gen_extu_i32_i64(t1
, cpu_T
[1]);
4909 tcg_gen_mul_i64(t0
, t0
, t1
);
4910 tcg_gen_trunc_i64_i32(cpu_T
[0], t0
);
4911 gen_op_mov_reg_T0(OT_LONG
, R_EAX
);
4912 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4913 tcg_gen_shri_i64(t0
, t0
, 32);
4914 tcg_gen_trunc_i64_i32(cpu_T
[0], t0
);
4915 gen_op_mov_reg_T0(OT_LONG
, R_EDX
);
4916 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
4919 set_cc_op(s
, CC_OP_MULL
);
4921 #ifdef TARGET_X86_64
4923 gen_helper_mulq_EAX_T0(cpu_env
, cpu_T
[0]);
4924 set_cc_op(s
, CC_OP_MULQ
);
4932 gen_op_mov_TN_reg(OT_BYTE
, 1, R_EAX
);
4933 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
4934 tcg_gen_ext8s_tl(cpu_T
[1], cpu_T
[1]);
4935 /* XXX: use 32 bit mul which could be faster */
4936 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4937 gen_op_mov_reg_T0(OT_WORD
, R_EAX
);
4938 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4939 tcg_gen_ext8s_tl(cpu_tmp0
, cpu_T
[0]);
4940 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
4941 set_cc_op(s
, CC_OP_MULB
);
4944 gen_op_mov_TN_reg(OT_WORD
, 1, R_EAX
);
4945 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
4946 tcg_gen_ext16s_tl(cpu_T
[1], cpu_T
[1]);
4947 /* XXX: use 32 bit mul which could be faster */
4948 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4949 gen_op_mov_reg_T0(OT_WORD
, R_EAX
);
4950 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4951 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T
[0]);
4952 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
4953 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], 16);
4954 gen_op_mov_reg_T0(OT_WORD
, R_EDX
);
4955 set_cc_op(s
, CC_OP_MULW
);
4959 #ifdef TARGET_X86_64
4960 gen_op_mov_TN_reg(OT_LONG
, 1, R_EAX
);
4961 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
4962 tcg_gen_ext32s_tl(cpu_T
[1], cpu_T
[1]);
4963 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4964 gen_op_mov_reg_T0(OT_LONG
, R_EAX
);
4965 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4966 tcg_gen_ext32s_tl(cpu_tmp0
, cpu_T
[0]);
4967 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
4968 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], 32);
4969 gen_op_mov_reg_T0(OT_LONG
, R_EDX
);
4973 t0
= tcg_temp_new_i64();
4974 t1
= tcg_temp_new_i64();
4975 gen_op_mov_TN_reg(OT_LONG
, 1, R_EAX
);
4976 tcg_gen_ext_i32_i64(t0
, cpu_T
[0]);
4977 tcg_gen_ext_i32_i64(t1
, cpu_T
[1]);
4978 tcg_gen_mul_i64(t0
, t0
, t1
);
4979 tcg_gen_trunc_i64_i32(cpu_T
[0], t0
);
4980 gen_op_mov_reg_T0(OT_LONG
, R_EAX
);
4981 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4982 tcg_gen_sari_tl(cpu_tmp0
, cpu_T
[0], 31);
4983 tcg_gen_shri_i64(t0
, t0
, 32);
4984 tcg_gen_trunc_i64_i32(cpu_T
[0], t0
);
4985 gen_op_mov_reg_T0(OT_LONG
, R_EDX
);
4986 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
4989 set_cc_op(s
, CC_OP_MULL
);
4991 #ifdef TARGET_X86_64
4993 gen_helper_imulq_EAX_T0(cpu_env
, cpu_T
[0]);
4994 set_cc_op(s
, CC_OP_MULQ
);
5002 gen_jmp_im(pc_start
- s
->cs_base
);
5003 gen_helper_divb_AL(cpu_env
, cpu_T
[0]);
5006 gen_jmp_im(pc_start
- s
->cs_base
);
5007 gen_helper_divw_AX(cpu_env
, cpu_T
[0]);
5011 gen_jmp_im(pc_start
- s
->cs_base
);
5012 gen_helper_divl_EAX(cpu_env
, cpu_T
[0]);
5014 #ifdef TARGET_X86_64
5016 gen_jmp_im(pc_start
- s
->cs_base
);
5017 gen_helper_divq_EAX(cpu_env
, cpu_T
[0]);
5025 gen_jmp_im(pc_start
- s
->cs_base
);
5026 gen_helper_idivb_AL(cpu_env
, cpu_T
[0]);
5029 gen_jmp_im(pc_start
- s
->cs_base
);
5030 gen_helper_idivw_AX(cpu_env
, cpu_T
[0]);
5034 gen_jmp_im(pc_start
- s
->cs_base
);
5035 gen_helper_idivl_EAX(cpu_env
, cpu_T
[0]);
5037 #ifdef TARGET_X86_64
5039 gen_jmp_im(pc_start
- s
->cs_base
);
5040 gen_helper_idivq_EAX(cpu_env
, cpu_T
[0]);
5050 case 0xfe: /* GRP4 */
5051 case 0xff: /* GRP5 */
5055 ot
= dflag
+ OT_WORD
;
5057 modrm
= cpu_ldub_code(env
, s
->pc
++);
5058 mod
= (modrm
>> 6) & 3;
5059 rm
= (modrm
& 7) | REX_B(s
);
5060 op
= (modrm
>> 3) & 7;
5061 if (op
>= 2 && b
== 0xfe) {
5065 if (op
== 2 || op
== 4) {
5066 /* operand size for jumps is 64 bit */
5068 } else if (op
== 3 || op
== 5) {
5069 ot
= dflag
? OT_LONG
+ (rex_w
== 1) : OT_WORD
;
5070 } else if (op
== 6) {
5071 /* default push size is 64 bit */
5072 ot
= dflag
? OT_QUAD
: OT_WORD
;
5076 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5077 if (op
>= 2 && op
!= 3 && op
!= 5)
5078 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
5080 gen_op_mov_TN_reg(ot
, 0, rm
);
5084 case 0: /* inc Ev */
5089 gen_inc(s
, ot
, opreg
, 1);
5091 case 1: /* dec Ev */
5096 gen_inc(s
, ot
, opreg
, -1);
5098 case 2: /* call Ev */
5099 /* XXX: optimize if memory (no 'and' is necessary) */
5101 gen_op_andl_T0_ffff();
5102 next_eip
= s
->pc
- s
->cs_base
;
5103 gen_movtl_T1_im(next_eip
);
5108 case 3: /* lcall Ev */
5109 gen_op_ld_T1_A0(ot
+ s
->mem_index
);
5110 gen_add_A0_im(s
, 1 << (ot
- OT_WORD
+ 1));
5111 gen_op_ldu_T0_A0(OT_WORD
+ s
->mem_index
);
5113 if (s
->pe
&& !s
->vm86
) {
5114 gen_update_cc_op(s
);
5115 gen_jmp_im(pc_start
- s
->cs_base
);
5116 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5117 gen_helper_lcall_protected(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
5118 tcg_const_i32(dflag
),
5119 tcg_const_i32(s
->pc
- pc_start
));
5121 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5122 gen_helper_lcall_real(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
5123 tcg_const_i32(dflag
),
5124 tcg_const_i32(s
->pc
- s
->cs_base
));
5128 case 4: /* jmp Ev */
5130 gen_op_andl_T0_ffff();
5134 case 5: /* ljmp Ev */
5135 gen_op_ld_T1_A0(ot
+ s
->mem_index
);
5136 gen_add_A0_im(s
, 1 << (ot
- OT_WORD
+ 1));
5137 gen_op_ldu_T0_A0(OT_WORD
+ s
->mem_index
);
5139 if (s
->pe
&& !s
->vm86
) {
5140 gen_update_cc_op(s
);
5141 gen_jmp_im(pc_start
- s
->cs_base
);
5142 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5143 gen_helper_ljmp_protected(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
5144 tcg_const_i32(s
->pc
- pc_start
));
5146 gen_op_movl_seg_T0_vm(R_CS
);
5147 gen_op_movl_T0_T1();
5152 case 6: /* push Ev */
5160 case 0x84: /* test Ev, Gv */
5165 ot
= dflag
+ OT_WORD
;
5167 modrm
= cpu_ldub_code(env
, s
->pc
++);
5168 reg
= ((modrm
>> 3) & 7) | rex_r
;
5170 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5171 gen_op_mov_TN_reg(ot
, 1, reg
);
5172 gen_op_testl_T0_T1_cc();
5173 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5176 case 0xa8: /* test eAX, Iv */
5181 ot
= dflag
+ OT_WORD
;
5182 val
= insn_get(env
, s
, ot
);
5184 gen_op_mov_TN_reg(ot
, 0, OR_EAX
);
5185 gen_op_movl_T1_im(val
);
5186 gen_op_testl_T0_T1_cc();
5187 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5190 case 0x98: /* CWDE/CBW */
5191 #ifdef TARGET_X86_64
5193 gen_op_mov_TN_reg(OT_LONG
, 0, R_EAX
);
5194 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
5195 gen_op_mov_reg_T0(OT_QUAD
, R_EAX
);
5199 gen_op_mov_TN_reg(OT_WORD
, 0, R_EAX
);
5200 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5201 gen_op_mov_reg_T0(OT_LONG
, R_EAX
);
5203 gen_op_mov_TN_reg(OT_BYTE
, 0, R_EAX
);
5204 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
5205 gen_op_mov_reg_T0(OT_WORD
, R_EAX
);
5208 case 0x99: /* CDQ/CWD */
5209 #ifdef TARGET_X86_64
5211 gen_op_mov_TN_reg(OT_QUAD
, 0, R_EAX
);
5212 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 63);
5213 gen_op_mov_reg_T0(OT_QUAD
, R_EDX
);
5217 gen_op_mov_TN_reg(OT_LONG
, 0, R_EAX
);
5218 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
5219 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 31);
5220 gen_op_mov_reg_T0(OT_LONG
, R_EDX
);
5222 gen_op_mov_TN_reg(OT_WORD
, 0, R_EAX
);
5223 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5224 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 15);
5225 gen_op_mov_reg_T0(OT_WORD
, R_EDX
);
5228 case 0x1af: /* imul Gv, Ev */
5229 case 0x69: /* imul Gv, Ev, I */
5231 ot
= dflag
+ OT_WORD
;
5232 modrm
= cpu_ldub_code(env
, s
->pc
++);
5233 reg
= ((modrm
>> 3) & 7) | rex_r
;
5235 s
->rip_offset
= insn_const_size(ot
);
5238 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5240 val
= insn_get(env
, s
, ot
);
5241 gen_op_movl_T1_im(val
);
5242 } else if (b
== 0x6b) {
5243 val
= (int8_t)insn_get(env
, s
, OT_BYTE
);
5244 gen_op_movl_T1_im(val
);
5246 gen_op_mov_TN_reg(ot
, 1, reg
);
5249 #ifdef TARGET_X86_64
5250 if (ot
== OT_QUAD
) {
5251 gen_helper_imulq_T0_T1(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
5254 if (ot
== OT_LONG
) {
5255 #ifdef TARGET_X86_64
5256 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
5257 tcg_gen_ext32s_tl(cpu_T
[1], cpu_T
[1]);
5258 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5259 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5260 tcg_gen_ext32s_tl(cpu_tmp0
, cpu_T
[0]);
5261 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
5265 t0
= tcg_temp_new_i64();
5266 t1
= tcg_temp_new_i64();
5267 tcg_gen_ext_i32_i64(t0
, cpu_T
[0]);
5268 tcg_gen_ext_i32_i64(t1
, cpu_T
[1]);
5269 tcg_gen_mul_i64(t0
, t0
, t1
);
5270 tcg_gen_trunc_i64_i32(cpu_T
[0], t0
);
5271 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5272 tcg_gen_sari_tl(cpu_tmp0
, cpu_T
[0], 31);
5273 tcg_gen_shri_i64(t0
, t0
, 32);
5274 tcg_gen_trunc_i64_i32(cpu_T
[1], t0
);
5275 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[1], cpu_tmp0
);
5279 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5280 tcg_gen_ext16s_tl(cpu_T
[1], cpu_T
[1]);
5281 /* XXX: use 32 bit mul which could be faster */
5282 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5283 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5284 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T
[0]);
5285 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
5287 gen_op_mov_reg_T0(ot
, reg
);
5288 set_cc_op(s
, CC_OP_MULB
+ ot
);
5291 case 0x1c1: /* xadd Ev, Gv */
5295 ot
= dflag
+ OT_WORD
;
5296 modrm
= cpu_ldub_code(env
, s
->pc
++);
5297 reg
= ((modrm
>> 3) & 7) | rex_r
;
5298 mod
= (modrm
>> 6) & 3;
5300 rm
= (modrm
& 7) | REX_B(s
);
5301 gen_op_mov_TN_reg(ot
, 0, reg
);
5302 gen_op_mov_TN_reg(ot
, 1, rm
);
5303 gen_op_addl_T0_T1();
5304 gen_op_mov_reg_T1(ot
, reg
);
5305 gen_op_mov_reg_T0(ot
, rm
);
5307 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5308 gen_op_mov_TN_reg(ot
, 0, reg
);
5309 gen_op_ld_T1_A0(ot
+ s
->mem_index
);
5310 gen_op_addl_T0_T1();
5311 gen_op_st_T0_A0(ot
+ s
->mem_index
);
5312 gen_op_mov_reg_T1(ot
, reg
);
5314 gen_op_update2_cc();
5315 set_cc_op(s
, CC_OP_ADDB
+ ot
);
5318 case 0x1b1: /* cmpxchg Ev, Gv */
5321 TCGv t0
, t1
, t2
, a0
;
5326 ot
= dflag
+ OT_WORD
;
5327 modrm
= cpu_ldub_code(env
, s
->pc
++);
5328 reg
= ((modrm
>> 3) & 7) | rex_r
;
5329 mod
= (modrm
>> 6) & 3;
5330 t0
= tcg_temp_local_new();
5331 t1
= tcg_temp_local_new();
5332 t2
= tcg_temp_local_new();
5333 a0
= tcg_temp_local_new();
5334 gen_op_mov_v_reg(ot
, t1
, reg
);
5336 rm
= (modrm
& 7) | REX_B(s
);
5337 gen_op_mov_v_reg(ot
, t0
, rm
);
5339 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5340 tcg_gen_mov_tl(a0
, cpu_A0
);
5341 gen_op_ld_v(ot
+ s
->mem_index
, t0
, a0
);
5342 rm
= 0; /* avoid warning */
5344 label1
= gen_new_label();
5345 tcg_gen_mov_tl(t2
, cpu_regs
[R_EAX
]);
5348 tcg_gen_brcond_tl(TCG_COND_EQ
, t2
, t0
, label1
);
5349 label2
= gen_new_label();
5351 gen_op_mov_reg_v(ot
, R_EAX
, t0
);
5353 gen_set_label(label1
);
5354 gen_op_mov_reg_v(ot
, rm
, t1
);
5356 /* perform no-op store cycle like physical cpu; must be
5357 before changing accumulator to ensure idempotency if
5358 the store faults and the instruction is restarted */
5359 gen_op_st_v(ot
+ s
->mem_index
, t0
, a0
);
5360 gen_op_mov_reg_v(ot
, R_EAX
, t0
);
5362 gen_set_label(label1
);
5363 gen_op_st_v(ot
+ s
->mem_index
, t1
, a0
);
5365 gen_set_label(label2
);
5366 tcg_gen_mov_tl(cpu_cc_src
, t0
);
5367 tcg_gen_mov_tl(cpu_cc_srcT
, t2
);
5368 tcg_gen_sub_tl(cpu_cc_dst
, t2
, t0
);
5369 set_cc_op(s
, CC_OP_SUBB
+ ot
);
5376 case 0x1c7: /* cmpxchg8b */
5377 modrm
= cpu_ldub_code(env
, s
->pc
++);
5378 mod
= (modrm
>> 6) & 3;
5379 if ((mod
== 3) || ((modrm
& 0x38) != 0x8))
5381 #ifdef TARGET_X86_64
5383 if (!(s
->cpuid_ext_features
& CPUID_EXT_CX16
))
5385 gen_jmp_im(pc_start
- s
->cs_base
);
5386 gen_update_cc_op(s
);
5387 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5388 gen_helper_cmpxchg16b(cpu_env
, cpu_A0
);
5392 if (!(s
->cpuid_features
& CPUID_CX8
))
5394 gen_jmp_im(pc_start
- s
->cs_base
);
5395 gen_update_cc_op(s
);
5396 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5397 gen_helper_cmpxchg8b(cpu_env
, cpu_A0
);
5399 set_cc_op(s
, CC_OP_EFLAGS
);
5402 /**************************/
5404 case 0x50 ... 0x57: /* push */
5405 gen_op_mov_TN_reg(OT_LONG
, 0, (b
& 7) | REX_B(s
));
5408 case 0x58 ... 0x5f: /* pop */
5410 ot
= dflag
? OT_QUAD
: OT_WORD
;
5412 ot
= dflag
+ OT_WORD
;
5415 /* NOTE: order is important for pop %sp */
5417 gen_op_mov_reg_T0(ot
, (b
& 7) | REX_B(s
));
5419 case 0x60: /* pusha */
5424 case 0x61: /* popa */
5429 case 0x68: /* push Iv */
5432 ot
= dflag
? OT_QUAD
: OT_WORD
;
5434 ot
= dflag
+ OT_WORD
;
5437 val
= insn_get(env
, s
, ot
);
5439 val
= (int8_t)insn_get(env
, s
, OT_BYTE
);
5440 gen_op_movl_T0_im(val
);
5443 case 0x8f: /* pop Ev */
5445 ot
= dflag
? OT_QUAD
: OT_WORD
;
5447 ot
= dflag
+ OT_WORD
;
5449 modrm
= cpu_ldub_code(env
, s
->pc
++);
5450 mod
= (modrm
>> 6) & 3;
5453 /* NOTE: order is important for pop %sp */
5455 rm
= (modrm
& 7) | REX_B(s
);
5456 gen_op_mov_reg_T0(ot
, rm
);
5458 /* NOTE: order is important too for MMU exceptions */
5459 s
->popl_esp_hack
= 1 << ot
;
5460 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5461 s
->popl_esp_hack
= 0;
5465 case 0xc8: /* enter */
5468 val
= cpu_lduw_code(env
, s
->pc
);
5470 level
= cpu_ldub_code(env
, s
->pc
++);
5471 gen_enter(s
, val
, level
);
5474 case 0xc9: /* leave */
5475 /* XXX: exception not precise (ESP is updated before potential exception) */
5477 gen_op_mov_TN_reg(OT_QUAD
, 0, R_EBP
);
5478 gen_op_mov_reg_T0(OT_QUAD
, R_ESP
);
5479 } else if (s
->ss32
) {
5480 gen_op_mov_TN_reg(OT_LONG
, 0, R_EBP
);
5481 gen_op_mov_reg_T0(OT_LONG
, R_ESP
);
5483 gen_op_mov_TN_reg(OT_WORD
, 0, R_EBP
);
5484 gen_op_mov_reg_T0(OT_WORD
, R_ESP
);
5488 ot
= dflag
? OT_QUAD
: OT_WORD
;
5490 ot
= dflag
+ OT_WORD
;
5492 gen_op_mov_reg_T0(ot
, R_EBP
);
5495 case 0x06: /* push es */
5496 case 0x0e: /* push cs */
5497 case 0x16: /* push ss */
5498 case 0x1e: /* push ds */
5501 gen_op_movl_T0_seg(b
>> 3);
5504 case 0x1a0: /* push fs */
5505 case 0x1a8: /* push gs */
5506 gen_op_movl_T0_seg((b
>> 3) & 7);
5509 case 0x07: /* pop es */
5510 case 0x17: /* pop ss */
5511 case 0x1f: /* pop ds */
5516 gen_movl_seg_T0(s
, reg
, pc_start
- s
->cs_base
);
5519 /* if reg == SS, inhibit interrupts/trace. */
5520 /* If several instructions disable interrupts, only the
5522 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
5523 gen_helper_set_inhibit_irq(cpu_env
);
5527 gen_jmp_im(s
->pc
- s
->cs_base
);
5531 case 0x1a1: /* pop fs */
5532 case 0x1a9: /* pop gs */
5534 gen_movl_seg_T0(s
, (b
>> 3) & 7, pc_start
- s
->cs_base
);
5537 gen_jmp_im(s
->pc
- s
->cs_base
);
5542 /**************************/
5545 case 0x89: /* mov Gv, Ev */
5549 ot
= dflag
+ OT_WORD
;
5550 modrm
= cpu_ldub_code(env
, s
->pc
++);
5551 reg
= ((modrm
>> 3) & 7) | rex_r
;
5553 /* generate a generic store */
5554 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
5557 case 0xc7: /* mov Ev, Iv */
5561 ot
= dflag
+ OT_WORD
;
5562 modrm
= cpu_ldub_code(env
, s
->pc
++);
5563 mod
= (modrm
>> 6) & 3;
5565 s
->rip_offset
= insn_const_size(ot
);
5566 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5568 val
= insn_get(env
, s
, ot
);
5569 gen_op_movl_T0_im(val
);
5571 gen_op_st_T0_A0(ot
+ s
->mem_index
);
5573 gen_op_mov_reg_T0(ot
, (modrm
& 7) | REX_B(s
));
5576 case 0x8b: /* mov Ev, Gv */
5580 ot
= OT_WORD
+ dflag
;
5581 modrm
= cpu_ldub_code(env
, s
->pc
++);
5582 reg
= ((modrm
>> 3) & 7) | rex_r
;
5584 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5585 gen_op_mov_reg_T0(ot
, reg
);
5587 case 0x8e: /* mov seg, Gv */
5588 modrm
= cpu_ldub_code(env
, s
->pc
++);
5589 reg
= (modrm
>> 3) & 7;
5590 if (reg
>= 6 || reg
== R_CS
)
5592 gen_ldst_modrm(env
, s
, modrm
, OT_WORD
, OR_TMP0
, 0);
5593 gen_movl_seg_T0(s
, reg
, pc_start
- s
->cs_base
);
5595 /* if reg == SS, inhibit interrupts/trace */
5596 /* If several instructions disable interrupts, only the
5598 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
5599 gen_helper_set_inhibit_irq(cpu_env
);
5603 gen_jmp_im(s
->pc
- s
->cs_base
);
5607 case 0x8c: /* mov Gv, seg */
5608 modrm
= cpu_ldub_code(env
, s
->pc
++);
5609 reg
= (modrm
>> 3) & 7;
5610 mod
= (modrm
>> 6) & 3;
5613 gen_op_movl_T0_seg(reg
);
5615 ot
= OT_WORD
+ dflag
;
5618 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5621 case 0x1b6: /* movzbS Gv, Eb */
5622 case 0x1b7: /* movzwS Gv, Eb */
5623 case 0x1be: /* movsbS Gv, Eb */
5624 case 0x1bf: /* movswS Gv, Eb */
5627 /* d_ot is the size of destination */
5628 d_ot
= dflag
+ OT_WORD
;
5629 /* ot is the size of source */
5630 ot
= (b
& 1) + OT_BYTE
;
5631 modrm
= cpu_ldub_code(env
, s
->pc
++);
5632 reg
= ((modrm
>> 3) & 7) | rex_r
;
5633 mod
= (modrm
>> 6) & 3;
5634 rm
= (modrm
& 7) | REX_B(s
);
5637 gen_op_mov_TN_reg(ot
, 0, rm
);
5638 switch(ot
| (b
& 8)) {
5640 tcg_gen_ext8u_tl(cpu_T
[0], cpu_T
[0]);
5643 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
5646 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
5650 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5653 gen_op_mov_reg_T0(d_ot
, reg
);
5655 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5657 gen_op_lds_T0_A0(ot
+ s
->mem_index
);
5659 gen_op_ldu_T0_A0(ot
+ s
->mem_index
);
5661 gen_op_mov_reg_T0(d_ot
, reg
);
5666 case 0x8d: /* lea */
5667 ot
= dflag
+ OT_WORD
;
5668 modrm
= cpu_ldub_code(env
, s
->pc
++);
5669 mod
= (modrm
>> 6) & 3;
5672 reg
= ((modrm
>> 3) & 7) | rex_r
;
5673 /* we must ensure that no segment is added */
5677 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5679 gen_op_mov_reg_A0(ot
- OT_WORD
, reg
);
5682 case 0xa0: /* mov EAX, Ov */
5684 case 0xa2: /* mov Ov, EAX */
5687 target_ulong offset_addr
;
5692 ot
= dflag
+ OT_WORD
;
5693 #ifdef TARGET_X86_64
5694 if (s
->aflag
== 2) {
5695 offset_addr
= cpu_ldq_code(env
, s
->pc
);
5697 gen_op_movq_A0_im(offset_addr
);
5702 offset_addr
= insn_get(env
, s
, OT_LONG
);
5704 offset_addr
= insn_get(env
, s
, OT_WORD
);
5706 gen_op_movl_A0_im(offset_addr
);
5708 gen_add_A0_ds_seg(s
);
5710 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
5711 gen_op_mov_reg_T0(ot
, R_EAX
);
5713 gen_op_mov_TN_reg(ot
, 0, R_EAX
);
5714 gen_op_st_T0_A0(ot
+ s
->mem_index
);
5718 case 0xd7: /* xlat */
5719 #ifdef TARGET_X86_64
5720 if (s
->aflag
== 2) {
5721 gen_op_movq_A0_reg(R_EBX
);
5722 gen_op_mov_TN_reg(OT_QUAD
, 0, R_EAX
);
5723 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xff);
5724 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_T
[0]);
5728 gen_op_movl_A0_reg(R_EBX
);
5729 gen_op_mov_TN_reg(OT_LONG
, 0, R_EAX
);
5730 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xff);
5731 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_T
[0]);
5733 gen_op_andl_A0_ffff();
5735 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffffffff);
5737 gen_add_A0_ds_seg(s
);
5738 gen_op_ldu_T0_A0(OT_BYTE
+ s
->mem_index
);
5739 gen_op_mov_reg_T0(OT_BYTE
, R_EAX
);
5741 case 0xb0 ... 0xb7: /* mov R, Ib */
5742 val
= insn_get(env
, s
, OT_BYTE
);
5743 gen_op_movl_T0_im(val
);
5744 gen_op_mov_reg_T0(OT_BYTE
, (b
& 7) | REX_B(s
));
5746 case 0xb8 ... 0xbf: /* mov R, Iv */
5747 #ifdef TARGET_X86_64
5751 tmp
= cpu_ldq_code(env
, s
->pc
);
5753 reg
= (b
& 7) | REX_B(s
);
5754 gen_movtl_T0_im(tmp
);
5755 gen_op_mov_reg_T0(OT_QUAD
, reg
);
5759 ot
= dflag
? OT_LONG
: OT_WORD
;
5760 val
= insn_get(env
, s
, ot
);
5761 reg
= (b
& 7) | REX_B(s
);
5762 gen_op_movl_T0_im(val
);
5763 gen_op_mov_reg_T0(ot
, reg
);
5767 case 0x91 ... 0x97: /* xchg R, EAX */
5769 ot
= dflag
+ OT_WORD
;
5770 reg
= (b
& 7) | REX_B(s
);
5774 case 0x87: /* xchg Ev, Gv */
5778 ot
= dflag
+ OT_WORD
;
5779 modrm
= cpu_ldub_code(env
, s
->pc
++);
5780 reg
= ((modrm
>> 3) & 7) | rex_r
;
5781 mod
= (modrm
>> 6) & 3;
5783 rm
= (modrm
& 7) | REX_B(s
);
5785 gen_op_mov_TN_reg(ot
, 0, reg
);
5786 gen_op_mov_TN_reg(ot
, 1, rm
);
5787 gen_op_mov_reg_T0(ot
, rm
);
5788 gen_op_mov_reg_T1(ot
, reg
);
5790 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5791 gen_op_mov_TN_reg(ot
, 0, reg
);
5792 /* for xchg, lock is implicit */
5793 if (!(prefixes
& PREFIX_LOCK
))
5795 gen_op_ld_T1_A0(ot
+ s
->mem_index
);
5796 gen_op_st_T0_A0(ot
+ s
->mem_index
);
5797 if (!(prefixes
& PREFIX_LOCK
))
5798 gen_helper_unlock();
5799 gen_op_mov_reg_T1(ot
, reg
);
5802 case 0xc4: /* les Gv */
5803 /* In CODE64 this is VEX3; see above. */
5806 case 0xc5: /* lds Gv */
5807 /* In CODE64 this is VEX2; see above. */
5810 case 0x1b2: /* lss Gv */
5813 case 0x1b4: /* lfs Gv */
5816 case 0x1b5: /* lgs Gv */
5819 ot
= dflag
? OT_LONG
: OT_WORD
;
5820 modrm
= cpu_ldub_code(env
, s
->pc
++);
5821 reg
= ((modrm
>> 3) & 7) | rex_r
;
5822 mod
= (modrm
>> 6) & 3;
5825 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5826 gen_op_ld_T1_A0(ot
+ s
->mem_index
);
5827 gen_add_A0_im(s
, 1 << (ot
- OT_WORD
+ 1));
5828 /* load the segment first to handle exceptions properly */
5829 gen_op_ldu_T0_A0(OT_WORD
+ s
->mem_index
);
5830 gen_movl_seg_T0(s
, op
, pc_start
- s
->cs_base
);
5831 /* then put the data */
5832 gen_op_mov_reg_T1(ot
, reg
);
5834 gen_jmp_im(s
->pc
- s
->cs_base
);
5839 /************************/
5850 ot
= dflag
+ OT_WORD
;
5852 modrm
= cpu_ldub_code(env
, s
->pc
++);
5853 mod
= (modrm
>> 6) & 3;
5854 op
= (modrm
>> 3) & 7;
5860 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5863 opreg
= (modrm
& 7) | REX_B(s
);
5868 gen_shift(s
, op
, ot
, opreg
, OR_ECX
);
5871 shift
= cpu_ldub_code(env
, s
->pc
++);
5873 gen_shifti(s
, op
, ot
, opreg
, shift
);
5888 case 0x1a4: /* shld imm */
5892 case 0x1a5: /* shld cl */
5896 case 0x1ac: /* shrd imm */
5900 case 0x1ad: /* shrd cl */
5904 ot
= dflag
+ OT_WORD
;
5905 modrm
= cpu_ldub_code(env
, s
->pc
++);
5906 mod
= (modrm
>> 6) & 3;
5907 rm
= (modrm
& 7) | REX_B(s
);
5908 reg
= ((modrm
>> 3) & 7) | rex_r
;
5910 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5915 gen_op_mov_TN_reg(ot
, 1, reg
);
5918 TCGv imm
= tcg_const_tl(cpu_ldub_code(env
, s
->pc
++));
5919 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, imm
);
5922 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, cpu_regs
[R_ECX
]);
5926 /************************/
5929 if (s
->flags
& (HF_EM_MASK
| HF_TS_MASK
)) {
5930 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5931 /* XXX: what to do if illegal op ? */
5932 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
5935 modrm
= cpu_ldub_code(env
, s
->pc
++);
5936 mod
= (modrm
>> 6) & 3;
5938 op
= ((b
& 7) << 3) | ((modrm
>> 3) & 7);
5941 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5943 case 0x00 ... 0x07: /* fxxxs */
5944 case 0x10 ... 0x17: /* fixxxl */
5945 case 0x20 ... 0x27: /* fxxxl */
5946 case 0x30 ... 0x37: /* fixxx */
5953 gen_op_ld_T0_A0(OT_LONG
+ s
->mem_index
);
5954 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5955 gen_helper_flds_FT0(cpu_env
, cpu_tmp2_i32
);
5958 gen_op_ld_T0_A0(OT_LONG
+ s
->mem_index
);
5959 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5960 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
5963 tcg_gen_qemu_ld64(cpu_tmp1_i64
, cpu_A0
,
5964 (s
->mem_index
>> 2) - 1);
5965 gen_helper_fldl_FT0(cpu_env
, cpu_tmp1_i64
);
5969 gen_op_lds_T0_A0(OT_WORD
+ s
->mem_index
);
5970 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5971 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
5975 gen_helper_fp_arith_ST0_FT0(op1
);
5977 /* fcomp needs pop */
5978 gen_helper_fpop(cpu_env
);
5982 case 0x08: /* flds */
5983 case 0x0a: /* fsts */
5984 case 0x0b: /* fstps */
5985 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5986 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5987 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5992 gen_op_ld_T0_A0(OT_LONG
+ s
->mem_index
);
5993 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5994 gen_helper_flds_ST0(cpu_env
, cpu_tmp2_i32
);
5997 gen_op_ld_T0_A0(OT_LONG
+ s
->mem_index
);
5998 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5999 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
6002 tcg_gen_qemu_ld64(cpu_tmp1_i64
, cpu_A0
,
6003 (s
->mem_index
>> 2) - 1);
6004 gen_helper_fldl_ST0(cpu_env
, cpu_tmp1_i64
);
6008 gen_op_lds_T0_A0(OT_WORD
+ s
->mem_index
);
6009 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6010 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
6015 /* XXX: the corresponding CPUID bit must be tested ! */
6018 gen_helper_fisttl_ST0(cpu_tmp2_i32
, cpu_env
);
6019 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6020 gen_op_st_T0_A0(OT_LONG
+ s
->mem_index
);
6023 gen_helper_fisttll_ST0(cpu_tmp1_i64
, cpu_env
);
6024 tcg_gen_qemu_st64(cpu_tmp1_i64
, cpu_A0
,
6025 (s
->mem_index
>> 2) - 1);
6029 gen_helper_fistt_ST0(cpu_tmp2_i32
, cpu_env
);
6030 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6031 gen_op_st_T0_A0(OT_WORD
+ s
->mem_index
);
6034 gen_helper_fpop(cpu_env
);
6039 gen_helper_fsts_ST0(cpu_tmp2_i32
, cpu_env
);
6040 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6041 gen_op_st_T0_A0(OT_LONG
+ s
->mem_index
);
6044 gen_helper_fistl_ST0(cpu_tmp2_i32
, cpu_env
);
6045 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6046 gen_op_st_T0_A0(OT_LONG
+ s
->mem_index
);
6049 gen_helper_fstl_ST0(cpu_tmp1_i64
, cpu_env
);
6050 tcg_gen_qemu_st64(cpu_tmp1_i64
, cpu_A0
,
6051 (s
->mem_index
>> 2) - 1);
6055 gen_helper_fist_ST0(cpu_tmp2_i32
, cpu_env
);
6056 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6057 gen_op_st_T0_A0(OT_WORD
+ s
->mem_index
);
6061 gen_helper_fpop(cpu_env
);
6065 case 0x0c: /* fldenv mem */
6066 gen_update_cc_op(s
);
6067 gen_jmp_im(pc_start
- s
->cs_base
);
6068 gen_helper_fldenv(cpu_env
, cpu_A0
, tcg_const_i32(s
->dflag
));
6070 case 0x0d: /* fldcw mem */
6071 gen_op_ld_T0_A0(OT_WORD
+ s
->mem_index
);
6072 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6073 gen_helper_fldcw(cpu_env
, cpu_tmp2_i32
);
6075 case 0x0e: /* fnstenv mem */
6076 gen_update_cc_op(s
);
6077 gen_jmp_im(pc_start
- s
->cs_base
);
6078 gen_helper_fstenv(cpu_env
, cpu_A0
, tcg_const_i32(s
->dflag
));
6080 case 0x0f: /* fnstcw mem */
6081 gen_helper_fnstcw(cpu_tmp2_i32
, cpu_env
);
6082 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6083 gen_op_st_T0_A0(OT_WORD
+ s
->mem_index
);
6085 case 0x1d: /* fldt mem */
6086 gen_update_cc_op(s
);
6087 gen_jmp_im(pc_start
- s
->cs_base
);
6088 gen_helper_fldt_ST0(cpu_env
, cpu_A0
);
6090 case 0x1f: /* fstpt mem */
6091 gen_update_cc_op(s
);
6092 gen_jmp_im(pc_start
- s
->cs_base
);
6093 gen_helper_fstt_ST0(cpu_env
, cpu_A0
);
6094 gen_helper_fpop(cpu_env
);
6096 case 0x2c: /* frstor mem */
6097 gen_update_cc_op(s
);
6098 gen_jmp_im(pc_start
- s
->cs_base
);
6099 gen_helper_frstor(cpu_env
, cpu_A0
, tcg_const_i32(s
->dflag
));
6101 case 0x2e: /* fnsave mem */
6102 gen_update_cc_op(s
);
6103 gen_jmp_im(pc_start
- s
->cs_base
);
6104 gen_helper_fsave(cpu_env
, cpu_A0
, tcg_const_i32(s
->dflag
));
6106 case 0x2f: /* fnstsw mem */
6107 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
6108 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6109 gen_op_st_T0_A0(OT_WORD
+ s
->mem_index
);
6111 case 0x3c: /* fbld */
6112 gen_update_cc_op(s
);
6113 gen_jmp_im(pc_start
- s
->cs_base
);
6114 gen_helper_fbld_ST0(cpu_env
, cpu_A0
);
6116 case 0x3e: /* fbstp */
6117 gen_update_cc_op(s
);
6118 gen_jmp_im(pc_start
- s
->cs_base
);
6119 gen_helper_fbst_ST0(cpu_env
, cpu_A0
);
6120 gen_helper_fpop(cpu_env
);
6122 case 0x3d: /* fildll */
6123 tcg_gen_qemu_ld64(cpu_tmp1_i64
, cpu_A0
,
6124 (s
->mem_index
>> 2) - 1);
6125 gen_helper_fildll_ST0(cpu_env
, cpu_tmp1_i64
);
6127 case 0x3f: /* fistpll */
6128 gen_helper_fistll_ST0(cpu_tmp1_i64
, cpu_env
);
6129 tcg_gen_qemu_st64(cpu_tmp1_i64
, cpu_A0
,
6130 (s
->mem_index
>> 2) - 1);
6131 gen_helper_fpop(cpu_env
);
6137 /* register float ops */
6141 case 0x08: /* fld sti */
6142 gen_helper_fpush(cpu_env
);
6143 gen_helper_fmov_ST0_STN(cpu_env
,
6144 tcg_const_i32((opreg
+ 1) & 7));
6146 case 0x09: /* fxchg sti */
6147 case 0x29: /* fxchg4 sti, undocumented op */
6148 case 0x39: /* fxchg7 sti, undocumented op */
6149 gen_helper_fxchg_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6151 case 0x0a: /* grp d9/2 */
6154 /* check exceptions (FreeBSD FPU probe) */
6155 gen_update_cc_op(s
);
6156 gen_jmp_im(pc_start
- s
->cs_base
);
6157 gen_helper_fwait(cpu_env
);
6163 case 0x0c: /* grp d9/4 */
6166 gen_helper_fchs_ST0(cpu_env
);
6169 gen_helper_fabs_ST0(cpu_env
);
6172 gen_helper_fldz_FT0(cpu_env
);
6173 gen_helper_fcom_ST0_FT0(cpu_env
);
6176 gen_helper_fxam_ST0(cpu_env
);
6182 case 0x0d: /* grp d9/5 */
6186 gen_helper_fpush(cpu_env
);
6187 gen_helper_fld1_ST0(cpu_env
);
6190 gen_helper_fpush(cpu_env
);
6191 gen_helper_fldl2t_ST0(cpu_env
);
6194 gen_helper_fpush(cpu_env
);
6195 gen_helper_fldl2e_ST0(cpu_env
);
6198 gen_helper_fpush(cpu_env
);
6199 gen_helper_fldpi_ST0(cpu_env
);
6202 gen_helper_fpush(cpu_env
);
6203 gen_helper_fldlg2_ST0(cpu_env
);
6206 gen_helper_fpush(cpu_env
);
6207 gen_helper_fldln2_ST0(cpu_env
);
6210 gen_helper_fpush(cpu_env
);
6211 gen_helper_fldz_ST0(cpu_env
);
6218 case 0x0e: /* grp d9/6 */
6221 gen_helper_f2xm1(cpu_env
);
6224 gen_helper_fyl2x(cpu_env
);
6227 gen_helper_fptan(cpu_env
);
6229 case 3: /* fpatan */
6230 gen_helper_fpatan(cpu_env
);
6232 case 4: /* fxtract */
6233 gen_helper_fxtract(cpu_env
);
6235 case 5: /* fprem1 */
6236 gen_helper_fprem1(cpu_env
);
6238 case 6: /* fdecstp */
6239 gen_helper_fdecstp(cpu_env
);
6242 case 7: /* fincstp */
6243 gen_helper_fincstp(cpu_env
);
6247 case 0x0f: /* grp d9/7 */
6250 gen_helper_fprem(cpu_env
);
6252 case 1: /* fyl2xp1 */
6253 gen_helper_fyl2xp1(cpu_env
);
6256 gen_helper_fsqrt(cpu_env
);
6258 case 3: /* fsincos */
6259 gen_helper_fsincos(cpu_env
);
6261 case 5: /* fscale */
6262 gen_helper_fscale(cpu_env
);
6264 case 4: /* frndint */
6265 gen_helper_frndint(cpu_env
);
6268 gen_helper_fsin(cpu_env
);
6272 gen_helper_fcos(cpu_env
);
6276 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6277 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6278 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6284 gen_helper_fp_arith_STN_ST0(op1
, opreg
);
6286 gen_helper_fpop(cpu_env
);
6288 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6289 gen_helper_fp_arith_ST0_FT0(op1
);
6293 case 0x02: /* fcom */
6294 case 0x22: /* fcom2, undocumented op */
6295 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6296 gen_helper_fcom_ST0_FT0(cpu_env
);
6298 case 0x03: /* fcomp */
6299 case 0x23: /* fcomp3, undocumented op */
6300 case 0x32: /* fcomp5, undocumented op */
6301 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6302 gen_helper_fcom_ST0_FT0(cpu_env
);
6303 gen_helper_fpop(cpu_env
);
6305 case 0x15: /* da/5 */
6307 case 1: /* fucompp */
6308 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6309 gen_helper_fucom_ST0_FT0(cpu_env
);
6310 gen_helper_fpop(cpu_env
);
6311 gen_helper_fpop(cpu_env
);
6319 case 0: /* feni (287 only, just do nop here) */
6321 case 1: /* fdisi (287 only, just do nop here) */
6324 gen_helper_fclex(cpu_env
);
6326 case 3: /* fninit */
6327 gen_helper_fninit(cpu_env
);
6329 case 4: /* fsetpm (287 only, just do nop here) */
6335 case 0x1d: /* fucomi */
6336 gen_update_cc_op(s
);
6337 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6338 gen_helper_fucomi_ST0_FT0(cpu_env
);
6339 set_cc_op(s
, CC_OP_EFLAGS
);
6341 case 0x1e: /* fcomi */
6342 gen_update_cc_op(s
);
6343 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6344 gen_helper_fcomi_ST0_FT0(cpu_env
);
6345 set_cc_op(s
, CC_OP_EFLAGS
);
6347 case 0x28: /* ffree sti */
6348 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6350 case 0x2a: /* fst sti */
6351 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6353 case 0x2b: /* fstp sti */
6354 case 0x0b: /* fstp1 sti, undocumented op */
6355 case 0x3a: /* fstp8 sti, undocumented op */
6356 case 0x3b: /* fstp9 sti, undocumented op */
6357 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6358 gen_helper_fpop(cpu_env
);
6360 case 0x2c: /* fucom st(i) */
6361 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6362 gen_helper_fucom_ST0_FT0(cpu_env
);
6364 case 0x2d: /* fucomp st(i) */
6365 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6366 gen_helper_fucom_ST0_FT0(cpu_env
);
6367 gen_helper_fpop(cpu_env
);
6369 case 0x33: /* de/3 */
6371 case 1: /* fcompp */
6372 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6373 gen_helper_fcom_ST0_FT0(cpu_env
);
6374 gen_helper_fpop(cpu_env
);
6375 gen_helper_fpop(cpu_env
);
6381 case 0x38: /* ffreep sti, undocumented op */
6382 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6383 gen_helper_fpop(cpu_env
);
6385 case 0x3c: /* df/4 */
6388 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
6389 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6390 gen_op_mov_reg_T0(OT_WORD
, R_EAX
);
6396 case 0x3d: /* fucomip */
6397 gen_update_cc_op(s
);
6398 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6399 gen_helper_fucomi_ST0_FT0(cpu_env
);
6400 gen_helper_fpop(cpu_env
);
6401 set_cc_op(s
, CC_OP_EFLAGS
);
6403 case 0x3e: /* fcomip */
6404 gen_update_cc_op(s
);
6405 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6406 gen_helper_fcomi_ST0_FT0(cpu_env
);
6407 gen_helper_fpop(cpu_env
);
6408 set_cc_op(s
, CC_OP_EFLAGS
);
6410 case 0x10 ... 0x13: /* fcmovxx */
6414 static const uint8_t fcmov_cc
[8] = {
6420 op1
= fcmov_cc
[op
& 3] | (((op
>> 3) & 1) ^ 1);
6421 l1
= gen_new_label();
6422 gen_jcc1_noeob(s
, op1
, l1
);
6423 gen_helper_fmov_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6432 /************************/
6435 case 0xa4: /* movsS */
6440 ot
= dflag
+ OT_WORD
;
6442 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6443 gen_repz_movs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6449 case 0xaa: /* stosS */
6454 ot
= dflag
+ OT_WORD
;
6456 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6457 gen_repz_stos(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6462 case 0xac: /* lodsS */
6467 ot
= dflag
+ OT_WORD
;
6468 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6469 gen_repz_lods(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6474 case 0xae: /* scasS */
6479 ot
= dflag
+ OT_WORD
;
6480 if (prefixes
& PREFIX_REPNZ
) {
6481 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6482 } else if (prefixes
& PREFIX_REPZ
) {
6483 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6489 case 0xa6: /* cmpsS */
6494 ot
= dflag
+ OT_WORD
;
6495 if (prefixes
& PREFIX_REPNZ
) {
6496 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6497 } else if (prefixes
& PREFIX_REPZ
) {
6498 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6503 case 0x6c: /* insS */
6508 ot
= dflag
? OT_LONG
: OT_WORD
;
6509 gen_op_mov_TN_reg(OT_WORD
, 0, R_EDX
);
6510 gen_op_andl_T0_ffff();
6511 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6512 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
) | 4);
6513 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6514 gen_repz_ins(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6518 gen_jmp(s
, s
->pc
- s
->cs_base
);
6522 case 0x6e: /* outsS */
6527 ot
= dflag
? OT_LONG
: OT_WORD
;
6528 gen_op_mov_TN_reg(OT_WORD
, 0, R_EDX
);
6529 gen_op_andl_T0_ffff();
6530 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6531 svm_is_rep(prefixes
) | 4);
6532 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6533 gen_repz_outs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6537 gen_jmp(s
, s
->pc
- s
->cs_base
);
6542 /************************/
6550 ot
= dflag
? OT_LONG
: OT_WORD
;
6551 val
= cpu_ldub_code(env
, s
->pc
++);
6552 gen_op_movl_T0_im(val
);
6553 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6554 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6557 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6558 gen_helper_in_func(ot
, cpu_T
[1], cpu_tmp2_i32
);
6559 gen_op_mov_reg_T1(ot
, R_EAX
);
6562 gen_jmp(s
, s
->pc
- s
->cs_base
);
6570 ot
= dflag
? OT_LONG
: OT_WORD
;
6571 val
= cpu_ldub_code(env
, s
->pc
++);
6572 gen_op_movl_T0_im(val
);
6573 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6574 svm_is_rep(prefixes
));
6575 gen_op_mov_TN_reg(ot
, 1, R_EAX
);
6579 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6580 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
6581 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6584 gen_jmp(s
, s
->pc
- s
->cs_base
);
6592 ot
= dflag
? OT_LONG
: OT_WORD
;
6593 gen_op_mov_TN_reg(OT_WORD
, 0, R_EDX
);
6594 gen_op_andl_T0_ffff();
6595 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6596 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6599 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6600 gen_helper_in_func(ot
, cpu_T
[1], cpu_tmp2_i32
);
6601 gen_op_mov_reg_T1(ot
, R_EAX
);
6604 gen_jmp(s
, s
->pc
- s
->cs_base
);
6612 ot
= dflag
? OT_LONG
: OT_WORD
;
6613 gen_op_mov_TN_reg(OT_WORD
, 0, R_EDX
);
6614 gen_op_andl_T0_ffff();
6615 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6616 svm_is_rep(prefixes
));
6617 gen_op_mov_TN_reg(ot
, 1, R_EAX
);
6621 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6622 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
6623 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6626 gen_jmp(s
, s
->pc
- s
->cs_base
);
6630 /************************/
6632 case 0xc2: /* ret im */
6633 val
= cpu_ldsw_code(env
, s
->pc
);
6636 if (CODE64(s
) && s
->dflag
)
6638 gen_stack_update(s
, val
+ (2 << s
->dflag
));
6640 gen_op_andl_T0_ffff();
6644 case 0xc3: /* ret */
6648 gen_op_andl_T0_ffff();
6652 case 0xca: /* lret im */
6653 val
= cpu_ldsw_code(env
, s
->pc
);
6656 if (s
->pe
&& !s
->vm86
) {
6657 gen_update_cc_op(s
);
6658 gen_jmp_im(pc_start
- s
->cs_base
);
6659 gen_helper_lret_protected(cpu_env
, tcg_const_i32(s
->dflag
),
6660 tcg_const_i32(val
));
6664 gen_op_ld_T0_A0(1 + s
->dflag
+ s
->mem_index
);
6666 gen_op_andl_T0_ffff();
6667 /* NOTE: keeping EIP updated is not a problem in case of
6671 gen_op_addl_A0_im(2 << s
->dflag
);
6672 gen_op_ld_T0_A0(1 + s
->dflag
+ s
->mem_index
);
6673 gen_op_movl_seg_T0_vm(R_CS
);
6674 /* add stack offset */
6675 gen_stack_update(s
, val
+ (4 << s
->dflag
));
6679 case 0xcb: /* lret */
6682 case 0xcf: /* iret */
6683 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IRET
);
6686 gen_helper_iret_real(cpu_env
, tcg_const_i32(s
->dflag
));
6687 set_cc_op(s
, CC_OP_EFLAGS
);
6688 } else if (s
->vm86
) {
6690 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6692 gen_helper_iret_real(cpu_env
, tcg_const_i32(s
->dflag
));
6693 set_cc_op(s
, CC_OP_EFLAGS
);
6696 gen_update_cc_op(s
);
6697 gen_jmp_im(pc_start
- s
->cs_base
);
6698 gen_helper_iret_protected(cpu_env
, tcg_const_i32(s
->dflag
),
6699 tcg_const_i32(s
->pc
- s
->cs_base
));
6700 set_cc_op(s
, CC_OP_EFLAGS
);
6704 case 0xe8: /* call im */
6707 tval
= (int32_t)insn_get(env
, s
, OT_LONG
);
6709 tval
= (int16_t)insn_get(env
, s
, OT_WORD
);
6710 next_eip
= s
->pc
- s
->cs_base
;
6716 gen_movtl_T0_im(next_eip
);
6721 case 0x9a: /* lcall im */
6723 unsigned int selector
, offset
;
6727 ot
= dflag
? OT_LONG
: OT_WORD
;
6728 offset
= insn_get(env
, s
, ot
);
6729 selector
= insn_get(env
, s
, OT_WORD
);
6731 gen_op_movl_T0_im(selector
);
6732 gen_op_movl_T1_imu(offset
);
6735 case 0xe9: /* jmp im */
6737 tval
= (int32_t)insn_get(env
, s
, OT_LONG
);
6739 tval
= (int16_t)insn_get(env
, s
, OT_WORD
);
6740 tval
+= s
->pc
- s
->cs_base
;
6747 case 0xea: /* ljmp im */
6749 unsigned int selector
, offset
;
6753 ot
= dflag
? OT_LONG
: OT_WORD
;
6754 offset
= insn_get(env
, s
, ot
);
6755 selector
= insn_get(env
, s
, OT_WORD
);
6757 gen_op_movl_T0_im(selector
);
6758 gen_op_movl_T1_imu(offset
);
6761 case 0xeb: /* jmp Jb */
6762 tval
= (int8_t)insn_get(env
, s
, OT_BYTE
);
6763 tval
+= s
->pc
- s
->cs_base
;
6768 case 0x70 ... 0x7f: /* jcc Jb */
6769 tval
= (int8_t)insn_get(env
, s
, OT_BYTE
);
6771 case 0x180 ... 0x18f: /* jcc Jv */
6773 tval
= (int32_t)insn_get(env
, s
, OT_LONG
);
6775 tval
= (int16_t)insn_get(env
, s
, OT_WORD
);
6778 next_eip
= s
->pc
- s
->cs_base
;
6782 gen_jcc(s
, b
, tval
, next_eip
);
6785 case 0x190 ... 0x19f: /* setcc Gv */
6786 modrm
= cpu_ldub_code(env
, s
->pc
++);
6787 gen_setcc1(s
, b
, cpu_T
[0]);
6788 gen_ldst_modrm(env
, s
, modrm
, OT_BYTE
, OR_TMP0
, 1);
6790 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6791 ot
= dflag
+ OT_WORD
;
6792 modrm
= cpu_ldub_code(env
, s
->pc
++);
6793 reg
= ((modrm
>> 3) & 7) | rex_r
;
6794 gen_cmovcc1(env
, s
, ot
, b
, modrm
, reg
);
6797 /************************/
6799 case 0x9c: /* pushf */
6800 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_PUSHF
);
6801 if (s
->vm86
&& s
->iopl
!= 3) {
6802 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6804 gen_update_cc_op(s
);
6805 gen_helper_read_eflags(cpu_T
[0], cpu_env
);
6809 case 0x9d: /* popf */
6810 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_POPF
);
6811 if (s
->vm86
&& s
->iopl
!= 3) {
6812 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6817 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6818 tcg_const_i32((TF_MASK
| AC_MASK
|
6823 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6824 tcg_const_i32((TF_MASK
| AC_MASK
|
6826 IF_MASK
| IOPL_MASK
)
6830 if (s
->cpl
<= s
->iopl
) {
6832 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6833 tcg_const_i32((TF_MASK
|
6839 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6840 tcg_const_i32((TF_MASK
|
6849 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6850 tcg_const_i32((TF_MASK
| AC_MASK
|
6851 ID_MASK
| NT_MASK
)));
6853 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6854 tcg_const_i32((TF_MASK
| AC_MASK
|
6861 set_cc_op(s
, CC_OP_EFLAGS
);
6862 /* abort translation because TF/AC flag may change */
6863 gen_jmp_im(s
->pc
- s
->cs_base
);
6867 case 0x9e: /* sahf */
6868 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6870 gen_op_mov_TN_reg(OT_BYTE
, 0, R_AH
);
6871 gen_compute_eflags(s
);
6872 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, CC_O
);
6873 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], CC_S
| CC_Z
| CC_A
| CC_P
| CC_C
);
6874 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, cpu_T
[0]);
6876 case 0x9f: /* lahf */
6877 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
6879 gen_compute_eflags(s
);
6880 /* Note: gen_compute_eflags() only gives the condition codes */
6881 tcg_gen_ori_tl(cpu_T
[0], cpu_cc_src
, 0x02);
6882 gen_op_mov_reg_T0(OT_BYTE
, R_AH
);
6884 case 0xf5: /* cmc */
6885 gen_compute_eflags(s
);
6886 tcg_gen_xori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6888 case 0xf8: /* clc */
6889 gen_compute_eflags(s
);
6890 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_C
);
6892 case 0xf9: /* stc */
6893 gen_compute_eflags(s
);
6894 tcg_gen_ori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
6896 case 0xfc: /* cld */
6897 tcg_gen_movi_i32(cpu_tmp2_i32
, 1);
6898 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6900 case 0xfd: /* std */
6901 tcg_gen_movi_i32(cpu_tmp2_i32
, -1);
6902 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
6905 /************************/
6906 /* bit operations */
6907 case 0x1ba: /* bt/bts/btr/btc Gv, im */
6908 ot
= dflag
+ OT_WORD
;
6909 modrm
= cpu_ldub_code(env
, s
->pc
++);
6910 op
= (modrm
>> 3) & 7;
6911 mod
= (modrm
>> 6) & 3;
6912 rm
= (modrm
& 7) | REX_B(s
);
6915 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
6916 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
6918 gen_op_mov_TN_reg(ot
, 0, rm
);
6921 val
= cpu_ldub_code(env
, s
->pc
++);
6922 gen_op_movl_T1_im(val
);
6927 case 0x1a3: /* bt Gv, Ev */
6930 case 0x1ab: /* bts */
6933 case 0x1b3: /* btr */
6936 case 0x1bb: /* btc */
6939 ot
= dflag
+ OT_WORD
;
6940 modrm
= cpu_ldub_code(env
, s
->pc
++);
6941 reg
= ((modrm
>> 3) & 7) | rex_r
;
6942 mod
= (modrm
>> 6) & 3;
6943 rm
= (modrm
& 7) | REX_B(s
);
6944 gen_op_mov_TN_reg(OT_LONG
, 1, reg
);
6946 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
6947 /* specific case: we need to add a displacement */
6948 gen_exts(ot
, cpu_T
[1]);
6949 tcg_gen_sari_tl(cpu_tmp0
, cpu_T
[1], 3 + ot
);
6950 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, ot
);
6951 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
6952 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
6954 gen_op_mov_TN_reg(ot
, 0, rm
);
6957 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], (1 << (3 + ot
)) - 1);
6960 tcg_gen_shr_tl(cpu_cc_src
, cpu_T
[0], cpu_T
[1]);
6961 tcg_gen_movi_tl(cpu_cc_dst
, 0);
6964 tcg_gen_shr_tl(cpu_tmp4
, cpu_T
[0], cpu_T
[1]);
6965 tcg_gen_movi_tl(cpu_tmp0
, 1);
6966 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
6967 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
6970 tcg_gen_shr_tl(cpu_tmp4
, cpu_T
[0], cpu_T
[1]);
6971 tcg_gen_movi_tl(cpu_tmp0
, 1);
6972 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
6973 tcg_gen_not_tl(cpu_tmp0
, cpu_tmp0
);
6974 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
6978 tcg_gen_shr_tl(cpu_tmp4
, cpu_T
[0], cpu_T
[1]);
6979 tcg_gen_movi_tl(cpu_tmp0
, 1);
6980 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
6981 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
6984 set_cc_op(s
, CC_OP_SARB
+ ot
);
6987 gen_op_st_T0_A0(ot
+ s
->mem_index
);
6989 gen_op_mov_reg_T0(ot
, rm
);
6990 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
6991 tcg_gen_movi_tl(cpu_cc_dst
, 0);
6994 case 0x1bc: /* bsf */
6995 case 0x1bd: /* bsr */
7000 ot
= dflag
+ OT_WORD
;
7001 modrm
= cpu_ldub_code(env
, s
->pc
++);
7002 reg
= ((modrm
>> 3) & 7) | rex_r
;
7003 gen_ldst_modrm(env
, s
,modrm
, ot
, OR_TMP0
, 0);
7004 gen_extu(ot
, cpu_T
[0]);
7005 t0
= tcg_temp_local_new();
7006 tcg_gen_mov_tl(t0
, cpu_T
[0]);
7007 if ((b
& 1) && (prefixes
& PREFIX_REPZ
) &&
7008 (s
->cpuid_ext3_features
& CPUID_EXT3_ABM
)) {
7010 case OT_WORD
: gen_helper_lzcnt(cpu_T
[0], t0
,
7011 tcg_const_i32(16)); break;
7012 case OT_LONG
: gen_helper_lzcnt(cpu_T
[0], t0
,
7013 tcg_const_i32(32)); break;
7014 case OT_QUAD
: gen_helper_lzcnt(cpu_T
[0], t0
,
7015 tcg_const_i32(64)); break;
7017 gen_op_mov_reg_T0(ot
, reg
);
7019 label1
= gen_new_label();
7020 tcg_gen_movi_tl(cpu_cc_dst
, 0);
7021 tcg_gen_brcondi_tl(TCG_COND_EQ
, t0
, 0, label1
);
7023 gen_helper_bsr(cpu_T
[0], t0
);
7025 gen_helper_bsf(cpu_T
[0], t0
);
7027 gen_op_mov_reg_T0(ot
, reg
);
7028 tcg_gen_movi_tl(cpu_cc_dst
, 1);
7029 gen_set_label(label1
);
7030 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
7035 /************************/
7037 case 0x27: /* daa */
7040 gen_update_cc_op(s
);
7041 gen_helper_daa(cpu_env
);
7042 set_cc_op(s
, CC_OP_EFLAGS
);
7044 case 0x2f: /* das */
7047 gen_update_cc_op(s
);
7048 gen_helper_das(cpu_env
);
7049 set_cc_op(s
, CC_OP_EFLAGS
);
7051 case 0x37: /* aaa */
7054 gen_update_cc_op(s
);
7055 gen_helper_aaa(cpu_env
);
7056 set_cc_op(s
, CC_OP_EFLAGS
);
7058 case 0x3f: /* aas */
7061 gen_update_cc_op(s
);
7062 gen_helper_aas(cpu_env
);
7063 set_cc_op(s
, CC_OP_EFLAGS
);
7065 case 0xd4: /* aam */
7068 val
= cpu_ldub_code(env
, s
->pc
++);
7070 gen_exception(s
, EXCP00_DIVZ
, pc_start
- s
->cs_base
);
7072 gen_helper_aam(cpu_env
, tcg_const_i32(val
));
7073 set_cc_op(s
, CC_OP_LOGICB
);
7076 case 0xd5: /* aad */
7079 val
= cpu_ldub_code(env
, s
->pc
++);
7080 gen_helper_aad(cpu_env
, tcg_const_i32(val
));
7081 set_cc_op(s
, CC_OP_LOGICB
);
7083 /************************/
7085 case 0x90: /* nop */
7086 /* XXX: correct lock test for all insn */
7087 if (prefixes
& PREFIX_LOCK
) {
7090 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
7092 goto do_xchg_reg_eax
;
7094 if (prefixes
& PREFIX_REPZ
) {
7095 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_PAUSE
);
7098 case 0x9b: /* fwait */
7099 if ((s
->flags
& (HF_MP_MASK
| HF_TS_MASK
)) ==
7100 (HF_MP_MASK
| HF_TS_MASK
)) {
7101 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7103 gen_update_cc_op(s
);
7104 gen_jmp_im(pc_start
- s
->cs_base
);
7105 gen_helper_fwait(cpu_env
);
7108 case 0xcc: /* int3 */
7109 gen_interrupt(s
, EXCP03_INT3
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
7111 case 0xcd: /* int N */
7112 val
= cpu_ldub_code(env
, s
->pc
++);
7113 if (s
->vm86
&& s
->iopl
!= 3) {
7114 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7116 gen_interrupt(s
, val
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
7119 case 0xce: /* into */
7122 gen_update_cc_op(s
);
7123 gen_jmp_im(pc_start
- s
->cs_base
);
7124 gen_helper_into(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7127 case 0xf1: /* icebp (undocumented, exits to external debugger) */
7128 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_ICEBP
);
7130 gen_debug(s
, pc_start
- s
->cs_base
);
7134 qemu_set_log(CPU_LOG_INT
| CPU_LOG_TB_IN_ASM
);
7138 case 0xfa: /* cli */
7140 if (s
->cpl
<= s
->iopl
) {
7141 gen_helper_cli(cpu_env
);
7143 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7147 gen_helper_cli(cpu_env
);
7149 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7153 case 0xfb: /* sti */
7155 if (s
->cpl
<= s
->iopl
) {
7157 gen_helper_sti(cpu_env
);
7158 /* interruptions are enabled only the first insn after sti */
7159 /* If several instructions disable interrupts, only the
7161 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
7162 gen_helper_set_inhibit_irq(cpu_env
);
7163 /* give a chance to handle pending irqs */
7164 gen_jmp_im(s
->pc
- s
->cs_base
);
7167 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7173 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7177 case 0x62: /* bound */
7180 ot
= dflag
? OT_LONG
: OT_WORD
;
7181 modrm
= cpu_ldub_code(env
, s
->pc
++);
7182 reg
= (modrm
>> 3) & 7;
7183 mod
= (modrm
>> 6) & 3;
7186 gen_op_mov_TN_reg(ot
, 0, reg
);
7187 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7188 gen_jmp_im(pc_start
- s
->cs_base
);
7189 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
7190 if (ot
== OT_WORD
) {
7191 gen_helper_boundw(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
7193 gen_helper_boundl(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
7196 case 0x1c8 ... 0x1cf: /* bswap reg */
7197 reg
= (b
& 7) | REX_B(s
);
7198 #ifdef TARGET_X86_64
7200 gen_op_mov_TN_reg(OT_QUAD
, 0, reg
);
7201 tcg_gen_bswap64_i64(cpu_T
[0], cpu_T
[0]);
7202 gen_op_mov_reg_T0(OT_QUAD
, reg
);
7206 gen_op_mov_TN_reg(OT_LONG
, 0, reg
);
7207 tcg_gen_ext32u_tl(cpu_T
[0], cpu_T
[0]);
7208 tcg_gen_bswap32_tl(cpu_T
[0], cpu_T
[0]);
7209 gen_op_mov_reg_T0(OT_LONG
, reg
);
7212 case 0xd6: /* salc */
7215 gen_compute_eflags_c(s
, cpu_T
[0]);
7216 tcg_gen_neg_tl(cpu_T
[0], cpu_T
[0]);
7217 gen_op_mov_reg_T0(OT_BYTE
, R_EAX
);
7219 case 0xe0: /* loopnz */
7220 case 0xe1: /* loopz */
7221 case 0xe2: /* loop */
7222 case 0xe3: /* jecxz */
7226 tval
= (int8_t)insn_get(env
, s
, OT_BYTE
);
7227 next_eip
= s
->pc
- s
->cs_base
;
7232 l1
= gen_new_label();
7233 l2
= gen_new_label();
7234 l3
= gen_new_label();
7237 case 0: /* loopnz */
7239 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
7240 gen_op_jz_ecx(s
->aflag
, l3
);
7241 gen_jcc1(s
, (JCC_Z
<< 1) | (b
^ 1), l1
);
7244 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
7245 gen_op_jnz_ecx(s
->aflag
, l1
);
7249 gen_op_jz_ecx(s
->aflag
, l1
);
7254 gen_jmp_im(next_eip
);
7263 case 0x130: /* wrmsr */
7264 case 0x132: /* rdmsr */
7266 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7268 gen_update_cc_op(s
);
7269 gen_jmp_im(pc_start
- s
->cs_base
);
7271 gen_helper_rdmsr(cpu_env
);
7273 gen_helper_wrmsr(cpu_env
);
7277 case 0x131: /* rdtsc */
7278 gen_update_cc_op(s
);
7279 gen_jmp_im(pc_start
- s
->cs_base
);
7282 gen_helper_rdtsc(cpu_env
);
7285 gen_jmp(s
, s
->pc
- s
->cs_base
);
7288 case 0x133: /* rdpmc */
7289 gen_update_cc_op(s
);
7290 gen_jmp_im(pc_start
- s
->cs_base
);
7291 gen_helper_rdpmc(cpu_env
);
7293 case 0x134: /* sysenter */
7294 /* For Intel SYSENTER is valid on 64-bit */
7295 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7298 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7300 gen_update_cc_op(s
);
7301 gen_jmp_im(pc_start
- s
->cs_base
);
7302 gen_helper_sysenter(cpu_env
);
7306 case 0x135: /* sysexit */
7307 /* For Intel SYSEXIT is valid on 64-bit */
7308 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7311 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7313 gen_update_cc_op(s
);
7314 gen_jmp_im(pc_start
- s
->cs_base
);
7315 gen_helper_sysexit(cpu_env
, tcg_const_i32(dflag
));
7319 #ifdef TARGET_X86_64
7320 case 0x105: /* syscall */
7321 /* XXX: is it usable in real mode ? */
7322 gen_update_cc_op(s
);
7323 gen_jmp_im(pc_start
- s
->cs_base
);
7324 gen_helper_syscall(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7327 case 0x107: /* sysret */
7329 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7331 gen_update_cc_op(s
);
7332 gen_jmp_im(pc_start
- s
->cs_base
);
7333 gen_helper_sysret(cpu_env
, tcg_const_i32(s
->dflag
));
7334 /* condition codes are modified only in long mode */
7336 set_cc_op(s
, CC_OP_EFLAGS
);
7342 case 0x1a2: /* cpuid */
7343 gen_update_cc_op(s
);
7344 gen_jmp_im(pc_start
- s
->cs_base
);
7345 gen_helper_cpuid(cpu_env
);
7347 case 0xf4: /* hlt */
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
);
7353 gen_helper_hlt(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7354 s
->is_jmp
= DISAS_TB_JUMP
;
7358 modrm
= cpu_ldub_code(env
, s
->pc
++);
7359 mod
= (modrm
>> 6) & 3;
7360 op
= (modrm
>> 3) & 7;
7363 if (!s
->pe
|| s
->vm86
)
7365 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_READ
);
7366 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,ldt
.selector
));
7370 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7373 if (!s
->pe
|| s
->vm86
)
7376 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7378 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_WRITE
);
7379 gen_ldst_modrm(env
, s
, modrm
, OT_WORD
, OR_TMP0
, 0);
7380 gen_jmp_im(pc_start
- s
->cs_base
);
7381 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
7382 gen_helper_lldt(cpu_env
, cpu_tmp2_i32
);
7386 if (!s
->pe
|| s
->vm86
)
7388 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_READ
);
7389 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,tr
.selector
));
7393 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7396 if (!s
->pe
|| s
->vm86
)
7399 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7401 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_WRITE
);
7402 gen_ldst_modrm(env
, s
, modrm
, OT_WORD
, OR_TMP0
, 0);
7403 gen_jmp_im(pc_start
- s
->cs_base
);
7404 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
7405 gen_helper_ltr(cpu_env
, cpu_tmp2_i32
);
7410 if (!s
->pe
|| s
->vm86
)
7412 gen_ldst_modrm(env
, s
, modrm
, OT_WORD
, OR_TMP0
, 0);
7413 gen_update_cc_op(s
);
7415 gen_helper_verr(cpu_env
, cpu_T
[0]);
7417 gen_helper_verw(cpu_env
, cpu_T
[0]);
7419 set_cc_op(s
, CC_OP_EFLAGS
);
7426 modrm
= cpu_ldub_code(env
, s
->pc
++);
7427 mod
= (modrm
>> 6) & 3;
7428 op
= (modrm
>> 3) & 7;
7434 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_READ
);
7435 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7436 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7437 gen_op_st_T0_A0(OT_WORD
+ s
->mem_index
);
7438 gen_add_A0_im(s
, 2);
7439 tcg_gen_ld_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7441 gen_op_andl_T0_im(0xffffff);
7442 gen_op_st_T0_A0(CODE64(s
) + OT_LONG
+ s
->mem_index
);
7447 case 0: /* monitor */
7448 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) ||
7451 gen_update_cc_op(s
);
7452 gen_jmp_im(pc_start
- s
->cs_base
);
7453 #ifdef TARGET_X86_64
7454 if (s
->aflag
== 2) {
7455 gen_op_movq_A0_reg(R_EAX
);
7459 gen_op_movl_A0_reg(R_EAX
);
7461 gen_op_andl_A0_ffff();
7463 gen_add_A0_ds_seg(s
);
7464 gen_helper_monitor(cpu_env
, cpu_A0
);
7467 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) ||
7470 gen_update_cc_op(s
);
7471 gen_jmp_im(pc_start
- s
->cs_base
);
7472 gen_helper_mwait(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7476 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
) ||
7480 gen_helper_clac(cpu_env
);
7481 gen_jmp_im(s
->pc
- s
->cs_base
);
7485 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
) ||
7489 gen_helper_stac(cpu_env
);
7490 gen_jmp_im(s
->pc
- s
->cs_base
);
7497 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_READ
);
7498 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7499 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7500 gen_op_st_T0_A0(OT_WORD
+ s
->mem_index
);
7501 gen_add_A0_im(s
, 2);
7502 tcg_gen_ld_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, idt
.base
));
7504 gen_op_andl_T0_im(0xffffff);
7505 gen_op_st_T0_A0(CODE64(s
) + OT_LONG
+ s
->mem_index
);
7511 gen_update_cc_op(s
);
7512 gen_jmp_im(pc_start
- s
->cs_base
);
7515 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7518 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7521 gen_helper_vmrun(cpu_env
, tcg_const_i32(s
->aflag
),
7522 tcg_const_i32(s
->pc
- pc_start
));
7524 s
->is_jmp
= DISAS_TB_JUMP
;
7527 case 1: /* VMMCALL */
7528 if (!(s
->flags
& HF_SVME_MASK
))
7530 gen_helper_vmmcall(cpu_env
);
7532 case 2: /* VMLOAD */
7533 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7536 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7539 gen_helper_vmload(cpu_env
, tcg_const_i32(s
->aflag
));
7542 case 3: /* VMSAVE */
7543 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7546 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7549 gen_helper_vmsave(cpu_env
, tcg_const_i32(s
->aflag
));
7553 if ((!(s
->flags
& HF_SVME_MASK
) &&
7554 !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
)) ||
7558 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7561 gen_helper_stgi(cpu_env
);
7565 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7568 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7571 gen_helper_clgi(cpu_env
);
7574 case 6: /* SKINIT */
7575 if ((!(s
->flags
& HF_SVME_MASK
) &&
7576 !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
)) ||
7579 gen_helper_skinit(cpu_env
);
7581 case 7: /* INVLPGA */
7582 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7585 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7588 gen_helper_invlpga(cpu_env
, tcg_const_i32(s
->aflag
));
7594 } else if (s
->cpl
!= 0) {
7595 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7597 gen_svm_check_intercept(s
, pc_start
,
7598 op
==2 ? SVM_EXIT_GDTR_WRITE
: SVM_EXIT_IDTR_WRITE
);
7599 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7600 gen_op_ld_T1_A0(OT_WORD
+ s
->mem_index
);
7601 gen_add_A0_im(s
, 2);
7602 gen_op_ld_T0_A0(CODE64(s
) + OT_LONG
+ s
->mem_index
);
7604 gen_op_andl_T0_im(0xffffff);
7606 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,gdt
.base
));
7607 tcg_gen_st32_tl(cpu_T
[1], cpu_env
, offsetof(CPUX86State
,gdt
.limit
));
7609 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,idt
.base
));
7610 tcg_gen_st32_tl(cpu_T
[1], cpu_env
, offsetof(CPUX86State
,idt
.limit
));
7615 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_CR0
);
7616 #if defined TARGET_X86_64 && defined HOST_WORDS_BIGENDIAN
7617 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,cr
[0]) + 4);
7619 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,cr
[0]));
7621 gen_ldst_modrm(env
, s
, modrm
, OT_WORD
, OR_TMP0
, 1);
7625 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7627 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7628 gen_ldst_modrm(env
, s
, modrm
, OT_WORD
, OR_TMP0
, 0);
7629 gen_helper_lmsw(cpu_env
, cpu_T
[0]);
7630 gen_jmp_im(s
->pc
- s
->cs_base
);
7635 if (mod
!= 3) { /* invlpg */
7637 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7639 gen_update_cc_op(s
);
7640 gen_jmp_im(pc_start
- s
->cs_base
);
7641 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7642 gen_helper_invlpg(cpu_env
, cpu_A0
);
7643 gen_jmp_im(s
->pc
- s
->cs_base
);
7648 case 0: /* swapgs */
7649 #ifdef TARGET_X86_64
7652 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7654 tcg_gen_ld_tl(cpu_T
[0], cpu_env
,
7655 offsetof(CPUX86State
,segs
[R_GS
].base
));
7656 tcg_gen_ld_tl(cpu_T
[1], cpu_env
,
7657 offsetof(CPUX86State
,kernelgsbase
));
7658 tcg_gen_st_tl(cpu_T
[1], cpu_env
,
7659 offsetof(CPUX86State
,segs
[R_GS
].base
));
7660 tcg_gen_st_tl(cpu_T
[0], cpu_env
,
7661 offsetof(CPUX86State
,kernelgsbase
));
7669 case 1: /* rdtscp */
7670 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_RDTSCP
))
7672 gen_update_cc_op(s
);
7673 gen_jmp_im(pc_start
- s
->cs_base
);
7676 gen_helper_rdtscp(cpu_env
);
7679 gen_jmp(s
, s
->pc
- s
->cs_base
);
7691 case 0x108: /* invd */
7692 case 0x109: /* wbinvd */
7694 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7696 gen_svm_check_intercept(s
, pc_start
, (b
& 2) ? SVM_EXIT_INVD
: SVM_EXIT_WBINVD
);
7700 case 0x63: /* arpl or movslS (x86_64) */
7701 #ifdef TARGET_X86_64
7704 /* d_ot is the size of destination */
7705 d_ot
= dflag
+ OT_WORD
;
7707 modrm
= cpu_ldub_code(env
, s
->pc
++);
7708 reg
= ((modrm
>> 3) & 7) | rex_r
;
7709 mod
= (modrm
>> 6) & 3;
7710 rm
= (modrm
& 7) | REX_B(s
);
7713 gen_op_mov_TN_reg(OT_LONG
, 0, rm
);
7715 if (d_ot
== OT_QUAD
)
7716 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
7717 gen_op_mov_reg_T0(d_ot
, reg
);
7719 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7720 if (d_ot
== OT_QUAD
) {
7721 gen_op_lds_T0_A0(OT_LONG
+ s
->mem_index
);
7723 gen_op_ld_T0_A0(OT_LONG
+ s
->mem_index
);
7725 gen_op_mov_reg_T0(d_ot
, reg
);
7731 TCGv t0
, t1
, t2
, a0
;
7733 if (!s
->pe
|| s
->vm86
)
7735 t0
= tcg_temp_local_new();
7736 t1
= tcg_temp_local_new();
7737 t2
= tcg_temp_local_new();
7739 modrm
= cpu_ldub_code(env
, s
->pc
++);
7740 reg
= (modrm
>> 3) & 7;
7741 mod
= (modrm
>> 6) & 3;
7744 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7745 gen_op_ld_v(ot
+ s
->mem_index
, t0
, cpu_A0
);
7746 a0
= tcg_temp_local_new();
7747 tcg_gen_mov_tl(a0
, cpu_A0
);
7749 gen_op_mov_v_reg(ot
, t0
, rm
);
7752 gen_op_mov_v_reg(ot
, t1
, reg
);
7753 tcg_gen_andi_tl(cpu_tmp0
, t0
, 3);
7754 tcg_gen_andi_tl(t1
, t1
, 3);
7755 tcg_gen_movi_tl(t2
, 0);
7756 label1
= gen_new_label();
7757 tcg_gen_brcond_tl(TCG_COND_GE
, cpu_tmp0
, t1
, label1
);
7758 tcg_gen_andi_tl(t0
, t0
, ~3);
7759 tcg_gen_or_tl(t0
, t0
, t1
);
7760 tcg_gen_movi_tl(t2
, CC_Z
);
7761 gen_set_label(label1
);
7763 gen_op_st_v(ot
+ s
->mem_index
, t0
, a0
);
7766 gen_op_mov_reg_v(ot
, rm
, t0
);
7768 gen_compute_eflags(s
);
7769 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_Z
);
7770 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, t2
);
7776 case 0x102: /* lar */
7777 case 0x103: /* lsl */
7781 if (!s
->pe
|| s
->vm86
)
7783 ot
= dflag
? OT_LONG
: OT_WORD
;
7784 modrm
= cpu_ldub_code(env
, s
->pc
++);
7785 reg
= ((modrm
>> 3) & 7) | rex_r
;
7786 gen_ldst_modrm(env
, s
, modrm
, OT_WORD
, OR_TMP0
, 0);
7787 t0
= tcg_temp_local_new();
7788 gen_update_cc_op(s
);
7790 gen_helper_lar(t0
, cpu_env
, cpu_T
[0]);
7792 gen_helper_lsl(t0
, cpu_env
, cpu_T
[0]);
7794 tcg_gen_andi_tl(cpu_tmp0
, cpu_cc_src
, CC_Z
);
7795 label1
= gen_new_label();
7796 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
7797 gen_op_mov_reg_v(ot
, reg
, t0
);
7798 gen_set_label(label1
);
7799 set_cc_op(s
, CC_OP_EFLAGS
);
7804 modrm
= cpu_ldub_code(env
, s
->pc
++);
7805 mod
= (modrm
>> 6) & 3;
7806 op
= (modrm
>> 3) & 7;
7808 case 0: /* prefetchnta */
7809 case 1: /* prefetchnt0 */
7810 case 2: /* prefetchnt0 */
7811 case 3: /* prefetchnt0 */
7814 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7815 /* nothing more to do */
7817 default: /* nop (multi byte) */
7818 gen_nop_modrm(env
, s
, modrm
);
7822 case 0x119 ... 0x11f: /* nop (multi byte) */
7823 modrm
= cpu_ldub_code(env
, s
->pc
++);
7824 gen_nop_modrm(env
, s
, modrm
);
7826 case 0x120: /* mov reg, crN */
7827 case 0x122: /* mov crN, reg */
7829 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7831 modrm
= cpu_ldub_code(env
, s
->pc
++);
7832 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7833 * AMD documentation (24594.pdf) and testing of
7834 * intel 386 and 486 processors all show that the mod bits
7835 * are assumed to be 1's, regardless of actual values.
7837 rm
= (modrm
& 7) | REX_B(s
);
7838 reg
= ((modrm
>> 3) & 7) | rex_r
;
7843 if ((prefixes
& PREFIX_LOCK
) && (reg
== 0) &&
7844 (s
->cpuid_ext3_features
& CPUID_EXT3_CR8LEG
)) {
7853 gen_update_cc_op(s
);
7854 gen_jmp_im(pc_start
- s
->cs_base
);
7856 gen_op_mov_TN_reg(ot
, 0, rm
);
7857 gen_helper_write_crN(cpu_env
, tcg_const_i32(reg
),
7859 gen_jmp_im(s
->pc
- s
->cs_base
);
7862 gen_helper_read_crN(cpu_T
[0], cpu_env
, tcg_const_i32(reg
));
7863 gen_op_mov_reg_T0(ot
, rm
);
7871 case 0x121: /* mov reg, drN */
7872 case 0x123: /* mov drN, reg */
7874 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7876 modrm
= cpu_ldub_code(env
, s
->pc
++);
7877 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7878 * AMD documentation (24594.pdf) and testing of
7879 * intel 386 and 486 processors all show that the mod bits
7880 * are assumed to be 1's, regardless of actual values.
7882 rm
= (modrm
& 7) | REX_B(s
);
7883 reg
= ((modrm
>> 3) & 7) | rex_r
;
7888 /* XXX: do it dynamically with CR4.DE bit */
7889 if (reg
== 4 || reg
== 5 || reg
>= 8)
7892 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_DR0
+ reg
);
7893 gen_op_mov_TN_reg(ot
, 0, rm
);
7894 gen_helper_movl_drN_T0(cpu_env
, tcg_const_i32(reg
), cpu_T
[0]);
7895 gen_jmp_im(s
->pc
- s
->cs_base
);
7898 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_DR0
+ reg
);
7899 tcg_gen_ld_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,dr
[reg
]));
7900 gen_op_mov_reg_T0(ot
, rm
);
7904 case 0x106: /* clts */
7906 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7908 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7909 gen_helper_clts(cpu_env
);
7910 /* abort block because static cpu state changed */
7911 gen_jmp_im(s
->pc
- s
->cs_base
);
7915 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
7916 case 0x1c3: /* MOVNTI reg, mem */
7917 if (!(s
->cpuid_features
& CPUID_SSE2
))
7919 ot
= s
->dflag
== 2 ? OT_QUAD
: OT_LONG
;
7920 modrm
= cpu_ldub_code(env
, s
->pc
++);
7921 mod
= (modrm
>> 6) & 3;
7924 reg
= ((modrm
>> 3) & 7) | rex_r
;
7925 /* generate a generic store */
7926 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
7929 modrm
= cpu_ldub_code(env
, s
->pc
++);
7930 mod
= (modrm
>> 6) & 3;
7931 op
= (modrm
>> 3) & 7;
7933 case 0: /* fxsave */
7934 if (mod
== 3 || !(s
->cpuid_features
& CPUID_FXSR
) ||
7935 (s
->prefix
& PREFIX_LOCK
))
7937 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
7938 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7941 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7942 gen_update_cc_op(s
);
7943 gen_jmp_im(pc_start
- s
->cs_base
);
7944 gen_helper_fxsave(cpu_env
, cpu_A0
, tcg_const_i32((s
->dflag
== 2)));
7946 case 1: /* fxrstor */
7947 if (mod
== 3 || !(s
->cpuid_features
& CPUID_FXSR
) ||
7948 (s
->prefix
& PREFIX_LOCK
))
7950 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
7951 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7954 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7955 gen_update_cc_op(s
);
7956 gen_jmp_im(pc_start
- s
->cs_base
);
7957 gen_helper_fxrstor(cpu_env
, cpu_A0
,
7958 tcg_const_i32((s
->dflag
== 2)));
7960 case 2: /* ldmxcsr */
7961 case 3: /* stmxcsr */
7962 if (s
->flags
& HF_TS_MASK
) {
7963 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7966 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
) ||
7969 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7971 gen_op_ld_T0_A0(OT_LONG
+ s
->mem_index
);
7972 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
7973 gen_helper_ldmxcsr(cpu_env
, cpu_tmp2_i32
);
7975 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, mxcsr
));
7976 gen_op_st_T0_A0(OT_LONG
+ s
->mem_index
);
7979 case 5: /* lfence */
7980 case 6: /* mfence */
7981 if ((modrm
& 0xc7) != 0xc0 || !(s
->cpuid_features
& CPUID_SSE2
))
7984 case 7: /* sfence / clflush */
7985 if ((modrm
& 0xc7) == 0xc0) {
7987 /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX */
7988 if (!(s
->cpuid_features
& CPUID_SSE
))
7992 if (!(s
->cpuid_features
& CPUID_CLFLUSH
))
7994 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
8001 case 0x10d: /* 3DNow! prefetch(w) */
8002 modrm
= cpu_ldub_code(env
, s
->pc
++);
8003 mod
= (modrm
>> 6) & 3;
8006 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
8007 /* ignore for now */
8009 case 0x1aa: /* rsm */
8010 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_RSM
);
8011 if (!(s
->flags
& HF_SMM_MASK
))
8013 gen_update_cc_op(s
);
8014 gen_jmp_im(s
->pc
- s
->cs_base
);
8015 gen_helper_rsm(cpu_env
);
8018 case 0x1b8: /* SSE4.2 popcnt */
8019 if ((prefixes
& (PREFIX_REPZ
| PREFIX_LOCK
| PREFIX_REPNZ
)) !=
8022 if (!(s
->cpuid_ext_features
& CPUID_EXT_POPCNT
))
8025 modrm
= cpu_ldub_code(env
, s
->pc
++);
8026 reg
= ((modrm
>> 3) & 7) | rex_r
;
8028 if (s
->prefix
& PREFIX_DATA
)
8030 else if (s
->dflag
!= 2)
8035 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
8036 gen_helper_popcnt(cpu_T
[0], cpu_env
, cpu_T
[0], tcg_const_i32(ot
));
8037 gen_op_mov_reg_T0(ot
, reg
);
8039 set_cc_op(s
, CC_OP_EFLAGS
);
8041 case 0x10e ... 0x10f:
8042 /* 3DNow! instructions, ignore prefixes */
8043 s
->prefix
&= ~(PREFIX_REPZ
| PREFIX_REPNZ
| PREFIX_DATA
);
8044 case 0x110 ... 0x117:
8045 case 0x128 ... 0x12f:
8046 case 0x138 ... 0x13a:
8047 case 0x150 ... 0x179:
8048 case 0x17c ... 0x17f:
8050 case 0x1c4 ... 0x1c6:
8051 case 0x1d0 ... 0x1fe:
8052 gen_sse(env
, s
, b
, pc_start
, rex_r
);
8057 /* lock generation */
8058 if (s
->prefix
& PREFIX_LOCK
)
8059 gen_helper_unlock();
8062 if (s
->prefix
& PREFIX_LOCK
)
8063 gen_helper_unlock();
8064 /* XXX: ensure that no lock was generated */
8065 gen_exception(s
, EXCP06_ILLOP
, pc_start
- s
->cs_base
);
8069 void optimize_flags_init(void)
8071 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
8072 cpu_cc_op
= tcg_global_mem_new_i32(TCG_AREG0
,
8073 offsetof(CPUX86State
, cc_op
), "cc_op");
8074 cpu_cc_dst
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_dst
),
8076 cpu_cc_src
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_src
),
8078 cpu_cc_src2
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_src2
),
8081 #ifdef TARGET_X86_64
8082 cpu_regs
[R_EAX
] = tcg_global_mem_new_i64(TCG_AREG0
,
8083 offsetof(CPUX86State
, regs
[R_EAX
]), "rax");
8084 cpu_regs
[R_ECX
] = tcg_global_mem_new_i64(TCG_AREG0
,
8085 offsetof(CPUX86State
, regs
[R_ECX
]), "rcx");
8086 cpu_regs
[R_EDX
] = tcg_global_mem_new_i64(TCG_AREG0
,
8087 offsetof(CPUX86State
, regs
[R_EDX
]), "rdx");
8088 cpu_regs
[R_EBX
] = tcg_global_mem_new_i64(TCG_AREG0
,
8089 offsetof(CPUX86State
, regs
[R_EBX
]), "rbx");
8090 cpu_regs
[R_ESP
] = tcg_global_mem_new_i64(TCG_AREG0
,
8091 offsetof(CPUX86State
, regs
[R_ESP
]), "rsp");
8092 cpu_regs
[R_EBP
] = tcg_global_mem_new_i64(TCG_AREG0
,
8093 offsetof(CPUX86State
, regs
[R_EBP
]), "rbp");
8094 cpu_regs
[R_ESI
] = tcg_global_mem_new_i64(TCG_AREG0
,
8095 offsetof(CPUX86State
, regs
[R_ESI
]), "rsi");
8096 cpu_regs
[R_EDI
] = tcg_global_mem_new_i64(TCG_AREG0
,
8097 offsetof(CPUX86State
, regs
[R_EDI
]), "rdi");
8098 cpu_regs
[8] = tcg_global_mem_new_i64(TCG_AREG0
,
8099 offsetof(CPUX86State
, regs
[8]), "r8");
8100 cpu_regs
[9] = tcg_global_mem_new_i64(TCG_AREG0
,
8101 offsetof(CPUX86State
, regs
[9]), "r9");
8102 cpu_regs
[10] = tcg_global_mem_new_i64(TCG_AREG0
,
8103 offsetof(CPUX86State
, regs
[10]), "r10");
8104 cpu_regs
[11] = tcg_global_mem_new_i64(TCG_AREG0
,
8105 offsetof(CPUX86State
, regs
[11]), "r11");
8106 cpu_regs
[12] = tcg_global_mem_new_i64(TCG_AREG0
,
8107 offsetof(CPUX86State
, regs
[12]), "r12");
8108 cpu_regs
[13] = tcg_global_mem_new_i64(TCG_AREG0
,
8109 offsetof(CPUX86State
, regs
[13]), "r13");
8110 cpu_regs
[14] = tcg_global_mem_new_i64(TCG_AREG0
,
8111 offsetof(CPUX86State
, regs
[14]), "r14");
8112 cpu_regs
[15] = tcg_global_mem_new_i64(TCG_AREG0
,
8113 offsetof(CPUX86State
, regs
[15]), "r15");
8115 cpu_regs
[R_EAX
] = tcg_global_mem_new_i32(TCG_AREG0
,
8116 offsetof(CPUX86State
, regs
[R_EAX
]), "eax");
8117 cpu_regs
[R_ECX
] = tcg_global_mem_new_i32(TCG_AREG0
,
8118 offsetof(CPUX86State
, regs
[R_ECX
]), "ecx");
8119 cpu_regs
[R_EDX
] = tcg_global_mem_new_i32(TCG_AREG0
,
8120 offsetof(CPUX86State
, regs
[R_EDX
]), "edx");
8121 cpu_regs
[R_EBX
] = tcg_global_mem_new_i32(TCG_AREG0
,
8122 offsetof(CPUX86State
, regs
[R_EBX
]), "ebx");
8123 cpu_regs
[R_ESP
] = tcg_global_mem_new_i32(TCG_AREG0
,
8124 offsetof(CPUX86State
, regs
[R_ESP
]), "esp");
8125 cpu_regs
[R_EBP
] = tcg_global_mem_new_i32(TCG_AREG0
,
8126 offsetof(CPUX86State
, regs
[R_EBP
]), "ebp");
8127 cpu_regs
[R_ESI
] = tcg_global_mem_new_i32(TCG_AREG0
,
8128 offsetof(CPUX86State
, regs
[R_ESI
]), "esi");
8129 cpu_regs
[R_EDI
] = tcg_global_mem_new_i32(TCG_AREG0
,
8130 offsetof(CPUX86State
, regs
[R_EDI
]), "edi");
8133 /* register helpers */
8134 #define GEN_HELPER 2
8138 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
8139 basic block 'tb'. If search_pc is TRUE, also generate PC
8140 information for each intermediate instruction. */
8141 static inline void gen_intermediate_code_internal(CPUX86State
*env
,
8142 TranslationBlock
*tb
,
8145 DisasContext dc1
, *dc
= &dc1
;
8146 target_ulong pc_ptr
;
8147 uint16_t *gen_opc_end
;
8151 target_ulong pc_start
;
8152 target_ulong cs_base
;
8156 /* generate intermediate code */
8158 cs_base
= tb
->cs_base
;
8161 dc
->pe
= (flags
>> HF_PE_SHIFT
) & 1;
8162 dc
->code32
= (flags
>> HF_CS32_SHIFT
) & 1;
8163 dc
->ss32
= (flags
>> HF_SS32_SHIFT
) & 1;
8164 dc
->addseg
= (flags
>> HF_ADDSEG_SHIFT
) & 1;
8166 dc
->vm86
= (flags
>> VM_SHIFT
) & 1;
8167 dc
->cpl
= (flags
>> HF_CPL_SHIFT
) & 3;
8168 dc
->iopl
= (flags
>> IOPL_SHIFT
) & 3;
8169 dc
->tf
= (flags
>> TF_SHIFT
) & 1;
8170 dc
->singlestep_enabled
= env
->singlestep_enabled
;
8171 dc
->cc_op
= CC_OP_DYNAMIC
;
8172 dc
->cc_op_dirty
= false;
8173 dc
->cs_base
= cs_base
;
8175 dc
->popl_esp_hack
= 0;
8176 /* select memory access functions */
8178 if (flags
& HF_SOFTMMU_MASK
) {
8179 dc
->mem_index
= (cpu_mmu_index(env
) + 1) << 2;
8181 dc
->cpuid_features
= env
->cpuid_features
;
8182 dc
->cpuid_ext_features
= env
->cpuid_ext_features
;
8183 dc
->cpuid_ext2_features
= env
->cpuid_ext2_features
;
8184 dc
->cpuid_ext3_features
= env
->cpuid_ext3_features
;
8185 dc
->cpuid_7_0_ebx_features
= env
->cpuid_7_0_ebx_features
;
8186 #ifdef TARGET_X86_64
8187 dc
->lma
= (flags
>> HF_LMA_SHIFT
) & 1;
8188 dc
->code64
= (flags
>> HF_CS64_SHIFT
) & 1;
8191 dc
->jmp_opt
= !(dc
->tf
|| env
->singlestep_enabled
||
8192 (flags
& HF_INHIBIT_IRQ_MASK
)
8193 #ifndef CONFIG_SOFTMMU
8194 || (flags
& HF_SOFTMMU_MASK
)
8198 /* check addseg logic */
8199 if (!dc
->addseg
&& (dc
->vm86
|| !dc
->pe
|| !dc
->code32
))
8200 printf("ERROR addseg\n");
8203 cpu_T
[0] = tcg_temp_new();
8204 cpu_T
[1] = tcg_temp_new();
8205 cpu_A0
= tcg_temp_new();
8207 cpu_tmp0
= tcg_temp_new();
8208 cpu_tmp1_i64
= tcg_temp_new_i64();
8209 cpu_tmp2_i32
= tcg_temp_new_i32();
8210 cpu_tmp3_i32
= tcg_temp_new_i32();
8211 cpu_tmp4
= tcg_temp_new();
8212 cpu_tmp5
= tcg_temp_new();
8213 cpu_ptr0
= tcg_temp_new_ptr();
8214 cpu_ptr1
= tcg_temp_new_ptr();
8215 cpu_cc_srcT
= tcg_temp_local_new();
8217 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
8219 dc
->is_jmp
= DISAS_NEXT
;
8223 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
8225 max_insns
= CF_COUNT_MASK
;
8229 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
8230 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
8231 if (bp
->pc
== pc_ptr
&&
8232 !((bp
->flags
& BP_CPU
) && (tb
->flags
& HF_RF_MASK
))) {
8233 gen_debug(dc
, pc_ptr
- dc
->cs_base
);
8239 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
8243 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
8245 tcg_ctx
.gen_opc_pc
[lj
] = pc_ptr
;
8246 gen_opc_cc_op
[lj
] = dc
->cc_op
;
8247 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
8248 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
8250 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
8253 pc_ptr
= disas_insn(env
, dc
, pc_ptr
);
8255 /* stop translation if indicated */
8258 /* if single step mode, we generate only one instruction and
8259 generate an exception */
8260 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
8261 the flag and abort the translation to give the irqs a
8262 change to be happen */
8263 if (dc
->tf
|| dc
->singlestep_enabled
||
8264 (flags
& HF_INHIBIT_IRQ_MASK
)) {
8265 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8269 /* if too long translation, stop generation too */
8270 if (tcg_ctx
.gen_opc_ptr
>= gen_opc_end
||
8271 (pc_ptr
- pc_start
) >= (TARGET_PAGE_SIZE
- 32) ||
8272 num_insns
>= max_insns
) {
8273 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8278 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8283 if (tb
->cflags
& CF_LAST_IO
)
8285 gen_icount_end(tb
, num_insns
);
8286 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
8287 /* we don't forget to fill the last values */
8289 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
8292 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
8296 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
8298 qemu_log("----------------\n");
8299 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
8300 #ifdef TARGET_X86_64
8305 disas_flags
= !dc
->code32
;
8306 log_target_disas(env
, pc_start
, pc_ptr
- pc_start
, disas_flags
);
8312 tb
->size
= pc_ptr
- pc_start
;
8313 tb
->icount
= num_insns
;
8317 void gen_intermediate_code(CPUX86State
*env
, TranslationBlock
*tb
)
8319 gen_intermediate_code_internal(env
, tb
, 0);
8322 void gen_intermediate_code_pc(CPUX86State
*env
, TranslationBlock
*tb
)
8324 gen_intermediate_code_internal(env
, tb
, 1);
8327 void restore_state_to_opc(CPUX86State
*env
, TranslationBlock
*tb
, int pc_pos
)
8331 if (qemu_loglevel_mask(CPU_LOG_TB_OP
)) {
8333 qemu_log("RESTORE:\n");
8334 for(i
= 0;i
<= pc_pos
; i
++) {
8335 if (tcg_ctx
.gen_opc_instr_start
[i
]) {
8336 qemu_log("0x%04x: " TARGET_FMT_lx
"\n", i
,
8337 tcg_ctx
.gen_opc_pc
[i
]);
8340 qemu_log("pc_pos=0x%x eip=" TARGET_FMT_lx
" cs_base=%x\n",
8341 pc_pos
, tcg_ctx
.gen_opc_pc
[pc_pos
] - tb
->cs_base
,
8342 (uint32_t)tb
->cs_base
);
8345 env
->eip
= tcg_ctx
.gen_opc_pc
[pc_pos
] - tb
->cs_base
;
8346 cc_op
= gen_opc_cc_op
[pc_pos
];
8347 if (cc_op
!= CC_OP_DYNAMIC
)