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
,
213 [CC_OP_ADCX
] = USES_CC_DST
| USES_CC_SRC
,
214 [CC_OP_ADOX
] = USES_CC_SRC
| USES_CC_SRC2
,
215 [CC_OP_ADCOX
] = USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
,
219 static void set_cc_op(DisasContext
*s
, CCOp op
)
223 if (s
->cc_op
== op
) {
227 /* Discard CC computation that will no longer be used. */
228 dead
= cc_op_live
[s
->cc_op
] & ~cc_op_live
[op
];
229 if (dead
& USES_CC_DST
) {
230 tcg_gen_discard_tl(cpu_cc_dst
);
232 if (dead
& USES_CC_SRC
) {
233 tcg_gen_discard_tl(cpu_cc_src
);
235 if (dead
& USES_CC_SRC2
) {
236 tcg_gen_discard_tl(cpu_cc_src2
);
238 if (dead
& USES_CC_SRCT
) {
239 tcg_gen_discard_tl(cpu_cc_srcT
);
243 /* The DYNAMIC setting is translator only, and should never be
244 stored. Thus we always consider it clean. */
245 s
->cc_op_dirty
= (op
!= CC_OP_DYNAMIC
);
248 static void gen_update_cc_op(DisasContext
*s
)
250 if (s
->cc_op_dirty
) {
251 tcg_gen_movi_i32(cpu_cc_op
, s
->cc_op
);
252 s
->cc_op_dirty
= false;
256 static inline void gen_op_movl_T0_0(void)
258 tcg_gen_movi_tl(cpu_T
[0], 0);
261 static inline void gen_op_movl_T0_im(int32_t val
)
263 tcg_gen_movi_tl(cpu_T
[0], val
);
266 static inline void gen_op_movl_T0_imu(uint32_t val
)
268 tcg_gen_movi_tl(cpu_T
[0], val
);
271 static inline void gen_op_movl_T1_im(int32_t val
)
273 tcg_gen_movi_tl(cpu_T
[1], val
);
276 static inline void gen_op_movl_T1_imu(uint32_t val
)
278 tcg_gen_movi_tl(cpu_T
[1], val
);
281 static inline void gen_op_movl_A0_im(uint32_t val
)
283 tcg_gen_movi_tl(cpu_A0
, val
);
287 static inline void gen_op_movq_A0_im(int64_t val
)
289 tcg_gen_movi_tl(cpu_A0
, val
);
293 static inline void gen_movtl_T0_im(target_ulong val
)
295 tcg_gen_movi_tl(cpu_T
[0], val
);
298 static inline void gen_movtl_T1_im(target_ulong val
)
300 tcg_gen_movi_tl(cpu_T
[1], val
);
303 static inline void gen_op_andl_T0_ffff(void)
305 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffff);
308 static inline void gen_op_andl_T0_im(uint32_t val
)
310 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], val
);
313 static inline void gen_op_movl_T0_T1(void)
315 tcg_gen_mov_tl(cpu_T
[0], cpu_T
[1]);
318 static inline void gen_op_andl_A0_ffff(void)
320 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffff);
325 #define NB_OP_SIZES 4
327 #else /* !TARGET_X86_64 */
329 #define NB_OP_SIZES 3
331 #endif /* !TARGET_X86_64 */
333 #if defined(HOST_WORDS_BIGENDIAN)
334 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
335 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
336 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
337 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
338 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
340 #define REG_B_OFFSET 0
341 #define REG_H_OFFSET 1
342 #define REG_W_OFFSET 0
343 #define REG_L_OFFSET 0
344 #define REG_LH_OFFSET 4
347 /* In instruction encodings for byte register accesses the
348 * register number usually indicates "low 8 bits of register N";
349 * however there are some special cases where N 4..7 indicates
350 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
351 * true for this special case, false otherwise.
353 static inline bool byte_reg_is_xH(int reg
)
359 if (reg
>= 8 || x86_64_hregs
) {
366 static inline void gen_op_mov_reg_v(int ot
, int reg
, TCGv t0
)
370 if (!byte_reg_is_xH(reg
)) {
371 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 8);
373 tcg_gen_deposit_tl(cpu_regs
[reg
- 4], cpu_regs
[reg
- 4], t0
, 8, 8);
377 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 16);
379 default: /* XXX this shouldn't be reached; abort? */
381 /* For x86_64, this sets the higher half of register to zero.
382 For i386, this is equivalent to a mov. */
383 tcg_gen_ext32u_tl(cpu_regs
[reg
], t0
);
387 tcg_gen_mov_tl(cpu_regs
[reg
], t0
);
393 static inline void gen_op_mov_reg_T0(int ot
, int reg
)
395 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
398 static inline void gen_op_mov_reg_T1(int ot
, int reg
)
400 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
403 static inline void gen_op_mov_reg_A0(int size
, int reg
)
407 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], cpu_A0
, 0, 16);
409 default: /* XXX this shouldn't be reached; abort? */
411 /* For x86_64, this sets the higher half of register to zero.
412 For i386, this is equivalent to a mov. */
413 tcg_gen_ext32u_tl(cpu_regs
[reg
], cpu_A0
);
417 tcg_gen_mov_tl(cpu_regs
[reg
], cpu_A0
);
423 static inline void gen_op_mov_v_reg(int ot
, TCGv t0
, int reg
)
425 if (ot
== OT_BYTE
&& byte_reg_is_xH(reg
)) {
426 tcg_gen_shri_tl(t0
, cpu_regs
[reg
- 4], 8);
427 tcg_gen_ext8u_tl(t0
, t0
);
429 tcg_gen_mov_tl(t0
, cpu_regs
[reg
]);
433 static inline void gen_op_mov_TN_reg(int ot
, int t_index
, int reg
)
435 gen_op_mov_v_reg(ot
, cpu_T
[t_index
], reg
);
438 static inline void gen_op_movl_A0_reg(int reg
)
440 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[reg
]);
443 static inline void gen_op_addl_A0_im(int32_t val
)
445 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, val
);
447 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffffffff);
452 static inline void gen_op_addq_A0_im(int64_t val
)
454 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, val
);
458 static void gen_add_A0_im(DisasContext
*s
, int val
)
462 gen_op_addq_A0_im(val
);
465 gen_op_addl_A0_im(val
);
468 static inline void gen_op_addl_T0_T1(void)
470 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
473 static inline void gen_op_jmp_T0(void)
475 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, eip
));
478 static inline void gen_op_add_reg_im(int size
, int reg
, int32_t val
)
482 tcg_gen_addi_tl(cpu_tmp0
, cpu_regs
[reg
], val
);
483 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], cpu_tmp0
, 0, 16);
486 tcg_gen_addi_tl(cpu_tmp0
, cpu_regs
[reg
], val
);
487 /* For x86_64, this sets the higher half of register to zero.
488 For i386, this is equivalent to a nop. */
489 tcg_gen_ext32u_tl(cpu_tmp0
, cpu_tmp0
);
490 tcg_gen_mov_tl(cpu_regs
[reg
], cpu_tmp0
);
494 tcg_gen_addi_tl(cpu_regs
[reg
], cpu_regs
[reg
], val
);
500 static inline void gen_op_add_reg_T0(int size
, int reg
)
504 tcg_gen_add_tl(cpu_tmp0
, cpu_regs
[reg
], cpu_T
[0]);
505 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], cpu_tmp0
, 0, 16);
508 tcg_gen_add_tl(cpu_tmp0
, cpu_regs
[reg
], cpu_T
[0]);
509 /* For x86_64, this sets the higher half of register to zero.
510 For i386, this is equivalent to a nop. */
511 tcg_gen_ext32u_tl(cpu_tmp0
, cpu_tmp0
);
512 tcg_gen_mov_tl(cpu_regs
[reg
], cpu_tmp0
);
516 tcg_gen_add_tl(cpu_regs
[reg
], cpu_regs
[reg
], cpu_T
[0]);
522 static inline void gen_op_addl_A0_reg_sN(int shift
, int reg
)
524 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[reg
]);
526 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, shift
);
527 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
528 /* For x86_64, this sets the higher half of register to zero.
529 For i386, this is equivalent to a nop. */
530 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
533 static inline void gen_op_movl_A0_seg(int reg
)
535 tcg_gen_ld32u_tl(cpu_A0
, cpu_env
, offsetof(CPUX86State
, segs
[reg
].base
) + REG_L_OFFSET
);
538 static inline void gen_op_addl_A0_seg(DisasContext
*s
, int reg
)
540 tcg_gen_ld_tl(cpu_tmp0
, cpu_env
, offsetof(CPUX86State
, segs
[reg
].base
));
543 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffffffff);
544 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
546 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
547 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffffffff);
550 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
555 static inline void gen_op_movq_A0_seg(int reg
)
557 tcg_gen_ld_tl(cpu_A0
, cpu_env
, offsetof(CPUX86State
, segs
[reg
].base
));
560 static inline void gen_op_addq_A0_seg(int reg
)
562 tcg_gen_ld_tl(cpu_tmp0
, cpu_env
, offsetof(CPUX86State
, segs
[reg
].base
));
563 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
566 static inline void gen_op_movq_A0_reg(int reg
)
568 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[reg
]);
571 static inline void gen_op_addq_A0_reg_sN(int shift
, int reg
)
573 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[reg
]);
575 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, shift
);
576 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
580 static inline void gen_op_lds_T0_A0(int idx
)
582 int mem_index
= (idx
>> 2) - 1;
585 tcg_gen_qemu_ld8s(cpu_T
[0], cpu_A0
, mem_index
);
588 tcg_gen_qemu_ld16s(cpu_T
[0], cpu_A0
, mem_index
);
592 tcg_gen_qemu_ld32s(cpu_T
[0], cpu_A0
, mem_index
);
597 static inline void gen_op_ld_v(int idx
, TCGv t0
, TCGv a0
)
599 int mem_index
= (idx
>> 2) - 1;
602 tcg_gen_qemu_ld8u(t0
, a0
, mem_index
);
605 tcg_gen_qemu_ld16u(t0
, a0
, mem_index
);
608 tcg_gen_qemu_ld32u(t0
, a0
, mem_index
);
612 /* Should never happen on 32-bit targets. */
614 tcg_gen_qemu_ld64(t0
, a0
, mem_index
);
620 /* XXX: always use ldu or lds */
621 static inline void gen_op_ld_T0_A0(int idx
)
623 gen_op_ld_v(idx
, cpu_T
[0], cpu_A0
);
626 static inline void gen_op_ldu_T0_A0(int idx
)
628 gen_op_ld_v(idx
, cpu_T
[0], cpu_A0
);
631 static inline void gen_op_ld_T1_A0(int idx
)
633 gen_op_ld_v(idx
, cpu_T
[1], cpu_A0
);
636 static inline void gen_op_st_v(int idx
, TCGv t0
, TCGv a0
)
638 int mem_index
= (idx
>> 2) - 1;
641 tcg_gen_qemu_st8(t0
, a0
, mem_index
);
644 tcg_gen_qemu_st16(t0
, a0
, mem_index
);
647 tcg_gen_qemu_st32(t0
, a0
, mem_index
);
651 /* Should never happen on 32-bit targets. */
653 tcg_gen_qemu_st64(t0
, a0
, mem_index
);
659 static inline void gen_op_st_T0_A0(int idx
)
661 gen_op_st_v(idx
, cpu_T
[0], cpu_A0
);
664 static inline void gen_op_st_T1_A0(int idx
)
666 gen_op_st_v(idx
, cpu_T
[1], cpu_A0
);
669 static inline void gen_jmp_im(target_ulong pc
)
671 tcg_gen_movi_tl(cpu_tmp0
, pc
);
672 tcg_gen_st_tl(cpu_tmp0
, cpu_env
, offsetof(CPUX86State
, eip
));
675 static inline void gen_string_movl_A0_ESI(DisasContext
*s
)
679 override
= s
->override
;
683 gen_op_movq_A0_seg(override
);
684 gen_op_addq_A0_reg_sN(0, R_ESI
);
686 gen_op_movq_A0_reg(R_ESI
);
692 if (s
->addseg
&& override
< 0)
695 gen_op_movl_A0_seg(override
);
696 gen_op_addl_A0_reg_sN(0, R_ESI
);
698 gen_op_movl_A0_reg(R_ESI
);
701 /* 16 address, always override */
704 gen_op_movl_A0_reg(R_ESI
);
705 gen_op_andl_A0_ffff();
706 gen_op_addl_A0_seg(s
, override
);
710 static inline void gen_string_movl_A0_EDI(DisasContext
*s
)
714 gen_op_movq_A0_reg(R_EDI
);
719 gen_op_movl_A0_seg(R_ES
);
720 gen_op_addl_A0_reg_sN(0, R_EDI
);
722 gen_op_movl_A0_reg(R_EDI
);
725 gen_op_movl_A0_reg(R_EDI
);
726 gen_op_andl_A0_ffff();
727 gen_op_addl_A0_seg(s
, R_ES
);
731 static inline void gen_op_movl_T0_Dshift(int ot
)
733 tcg_gen_ld32s_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, df
));
734 tcg_gen_shli_tl(cpu_T
[0], cpu_T
[0], ot
);
737 static TCGv
gen_ext_tl(TCGv dst
, TCGv src
, int size
, bool sign
)
742 tcg_gen_ext8s_tl(dst
, src
);
744 tcg_gen_ext8u_tl(dst
, src
);
749 tcg_gen_ext16s_tl(dst
, src
);
751 tcg_gen_ext16u_tl(dst
, src
);
757 tcg_gen_ext32s_tl(dst
, src
);
759 tcg_gen_ext32u_tl(dst
, src
);
768 static void gen_extu(int ot
, TCGv reg
)
770 gen_ext_tl(reg
, reg
, ot
, false);
773 static void gen_exts(int ot
, TCGv reg
)
775 gen_ext_tl(reg
, reg
, ot
, true);
778 static inline void gen_op_jnz_ecx(int size
, int label1
)
780 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[R_ECX
]);
781 gen_extu(size
+ 1, cpu_tmp0
);
782 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_tmp0
, 0, label1
);
785 static inline void gen_op_jz_ecx(int size
, int label1
)
787 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[R_ECX
]);
788 gen_extu(size
+ 1, cpu_tmp0
);
789 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
792 static void gen_helper_in_func(int ot
, TCGv v
, TCGv_i32 n
)
796 gen_helper_inb(v
, n
);
799 gen_helper_inw(v
, n
);
802 gen_helper_inl(v
, n
);
807 static void gen_helper_out_func(int ot
, TCGv_i32 v
, TCGv_i32 n
)
811 gen_helper_outb(v
, n
);
814 gen_helper_outw(v
, n
);
817 gen_helper_outl(v
, n
);
822 static void gen_check_io(DisasContext
*s
, int ot
, target_ulong cur_eip
,
826 target_ulong next_eip
;
829 if (s
->pe
&& (s
->cpl
> s
->iopl
|| s
->vm86
)) {
833 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
836 gen_helper_check_iob(cpu_env
, cpu_tmp2_i32
);
839 gen_helper_check_iow(cpu_env
, cpu_tmp2_i32
);
842 gen_helper_check_iol(cpu_env
, cpu_tmp2_i32
);
846 if(s
->flags
& HF_SVMI_MASK
) {
851 svm_flags
|= (1 << (4 + ot
));
852 next_eip
= s
->pc
- s
->cs_base
;
853 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
854 gen_helper_svm_check_io(cpu_env
, cpu_tmp2_i32
,
855 tcg_const_i32(svm_flags
),
856 tcg_const_i32(next_eip
- cur_eip
));
860 static inline void gen_movs(DisasContext
*s
, int ot
)
862 gen_string_movl_A0_ESI(s
);
863 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
864 gen_string_movl_A0_EDI(s
);
865 gen_op_st_T0_A0(ot
+ s
->mem_index
);
866 gen_op_movl_T0_Dshift(ot
);
867 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
868 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
871 static void gen_op_update1_cc(void)
873 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
876 static void gen_op_update2_cc(void)
878 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
879 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
882 static void gen_op_update3_cc(TCGv reg
)
884 tcg_gen_mov_tl(cpu_cc_src2
, reg
);
885 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
886 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
889 static inline void gen_op_testl_T0_T1_cc(void)
891 tcg_gen_and_tl(cpu_cc_dst
, cpu_T
[0], cpu_T
[1]);
894 static void gen_op_update_neg_cc(void)
896 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
897 tcg_gen_neg_tl(cpu_cc_src
, cpu_T
[0]);
898 tcg_gen_movi_tl(cpu_cc_srcT
, 0);
901 /* compute all eflags to cc_src */
902 static void gen_compute_eflags(DisasContext
*s
)
904 TCGv zero
, dst
, src1
, src2
;
907 if (s
->cc_op
== CC_OP_EFLAGS
) {
910 if (s
->cc_op
== CC_OP_CLR
) {
911 tcg_gen_movi_tl(cpu_cc_src
, CC_Z
);
912 set_cc_op(s
, CC_OP_EFLAGS
);
921 /* Take care to not read values that are not live. */
922 live
= cc_op_live
[s
->cc_op
] & ~USES_CC_SRCT
;
923 dead
= live
^ (USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
);
925 zero
= tcg_const_tl(0);
926 if (dead
& USES_CC_DST
) {
929 if (dead
& USES_CC_SRC
) {
932 if (dead
& USES_CC_SRC2
) {
938 gen_helper_cc_compute_all(cpu_cc_src
, dst
, src1
, src2
, cpu_cc_op
);
939 set_cc_op(s
, CC_OP_EFLAGS
);
946 typedef struct CCPrepare
{
956 /* compute eflags.C to reg */
957 static CCPrepare
gen_prepare_eflags_c(DisasContext
*s
, TCGv reg
)
963 case CC_OP_SUBB
... CC_OP_SUBQ
:
964 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
965 size
= s
->cc_op
- CC_OP_SUBB
;
966 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
967 /* If no temporary was used, be careful not to alias t1 and t0. */
968 t0
= TCGV_EQUAL(t1
, cpu_cc_src
) ? cpu_tmp0
: reg
;
969 tcg_gen_mov_tl(t0
, cpu_cc_srcT
);
973 case CC_OP_ADDB
... CC_OP_ADDQ
:
974 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
975 size
= s
->cc_op
- CC_OP_ADDB
;
976 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
977 t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
979 return (CCPrepare
) { .cond
= TCG_COND_LTU
, .reg
= t0
,
980 .reg2
= t1
, .mask
= -1, .use_reg2
= true };
982 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
984 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
986 case CC_OP_INCB
... CC_OP_INCQ
:
987 case CC_OP_DECB
... CC_OP_DECQ
:
988 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
989 .mask
= -1, .no_setcond
= true };
991 case CC_OP_SHLB
... CC_OP_SHLQ
:
992 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
993 size
= s
->cc_op
- CC_OP_SHLB
;
994 shift
= (8 << size
) - 1;
995 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
996 .mask
= (target_ulong
)1 << shift
};
998 case CC_OP_MULB
... CC_OP_MULQ
:
999 return (CCPrepare
) { .cond
= TCG_COND_NE
,
1000 .reg
= cpu_cc_src
, .mask
= -1 };
1002 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
1003 size
= s
->cc_op
- CC_OP_BMILGB
;
1004 t0
= gen_ext_tl(reg
, cpu_cc_src
, size
, false);
1005 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
1009 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_dst
,
1010 .mask
= -1, .no_setcond
= true };
1013 case CC_OP_SARB
... CC_OP_SARQ
:
1015 return (CCPrepare
) { .cond
= TCG_COND_NE
,
1016 .reg
= cpu_cc_src
, .mask
= CC_C
};
1019 /* The need to compute only C from CC_OP_DYNAMIC is important
1020 in efficiently implementing e.g. INC at the start of a TB. */
1021 gen_update_cc_op(s
);
1022 gen_helper_cc_compute_c(reg
, cpu_cc_dst
, cpu_cc_src
,
1023 cpu_cc_src2
, cpu_cc_op
);
1024 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
1025 .mask
= -1, .no_setcond
= true };
1029 /* compute eflags.P to reg */
1030 static CCPrepare
gen_prepare_eflags_p(DisasContext
*s
, TCGv reg
)
1032 gen_compute_eflags(s
);
1033 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
1037 /* compute eflags.S to reg */
1038 static CCPrepare
gen_prepare_eflags_s(DisasContext
*s
, TCGv reg
)
1042 gen_compute_eflags(s
);
1048 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
1051 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
1054 int size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
1055 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, true);
1056 return (CCPrepare
) { .cond
= TCG_COND_LT
, .reg
= t0
, .mask
= -1 };
1061 /* compute eflags.O to reg */
1062 static CCPrepare
gen_prepare_eflags_o(DisasContext
*s
, TCGv reg
)
1067 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src2
,
1068 .mask
= -1, .no_setcond
= true };
1070 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
1072 gen_compute_eflags(s
);
1073 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
1078 /* compute eflags.Z to reg */
1079 static CCPrepare
gen_prepare_eflags_z(DisasContext
*s
, TCGv reg
)
1083 gen_compute_eflags(s
);
1089 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
1092 return (CCPrepare
) { .cond
= TCG_COND_ALWAYS
, .mask
= -1 };
1095 int size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
1096 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
1097 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
1102 /* perform a conditional store into register 'reg' according to jump opcode
1103 value 'b'. In the fast case, T0 is guaranted not to be used. */
1104 static CCPrepare
gen_prepare_cc(DisasContext
*s
, int b
, TCGv reg
)
1106 int inv
, jcc_op
, size
, cond
;
1111 jcc_op
= (b
>> 1) & 7;
1114 case CC_OP_SUBB
... CC_OP_SUBQ
:
1115 /* We optimize relational operators for the cmp/jcc case. */
1116 size
= s
->cc_op
- CC_OP_SUBB
;
1119 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
1120 gen_extu(size
, cpu_tmp4
);
1121 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
1122 cc
= (CCPrepare
) { .cond
= TCG_COND_LEU
, .reg
= cpu_tmp4
,
1123 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
1132 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
1133 gen_exts(size
, cpu_tmp4
);
1134 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, true);
1135 cc
= (CCPrepare
) { .cond
= cond
, .reg
= cpu_tmp4
,
1136 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
1146 /* This actually generates good code for JC, JZ and JS. */
1149 cc
= gen_prepare_eflags_o(s
, reg
);
1152 cc
= gen_prepare_eflags_c(s
, reg
);
1155 cc
= gen_prepare_eflags_z(s
, reg
);
1158 gen_compute_eflags(s
);
1159 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
1160 .mask
= CC_Z
| CC_C
};
1163 cc
= gen_prepare_eflags_s(s
, reg
);
1166 cc
= gen_prepare_eflags_p(s
, reg
);
1169 gen_compute_eflags(s
);
1170 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
1173 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
1174 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
1175 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
1180 gen_compute_eflags(s
);
1181 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
1184 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
1185 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
1186 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
1187 .mask
= CC_S
| CC_Z
};
1194 cc
.cond
= tcg_invert_cond(cc
.cond
);
1199 static void gen_setcc1(DisasContext
*s
, int b
, TCGv reg
)
1201 CCPrepare cc
= gen_prepare_cc(s
, b
, reg
);
1203 if (cc
.no_setcond
) {
1204 if (cc
.cond
== TCG_COND_EQ
) {
1205 tcg_gen_xori_tl(reg
, cc
.reg
, 1);
1207 tcg_gen_mov_tl(reg
, cc
.reg
);
1212 if (cc
.cond
== TCG_COND_NE
&& !cc
.use_reg2
&& cc
.imm
== 0 &&
1213 cc
.mask
!= 0 && (cc
.mask
& (cc
.mask
- 1)) == 0) {
1214 tcg_gen_shri_tl(reg
, cc
.reg
, ctztl(cc
.mask
));
1215 tcg_gen_andi_tl(reg
, reg
, 1);
1218 if (cc
.mask
!= -1) {
1219 tcg_gen_andi_tl(reg
, cc
.reg
, cc
.mask
);
1223 tcg_gen_setcond_tl(cc
.cond
, reg
, cc
.reg
, cc
.reg2
);
1225 tcg_gen_setcondi_tl(cc
.cond
, reg
, cc
.reg
, cc
.imm
);
1229 static inline void gen_compute_eflags_c(DisasContext
*s
, TCGv reg
)
1231 gen_setcc1(s
, JCC_B
<< 1, reg
);
1234 /* generate a conditional jump to label 'l1' according to jump opcode
1235 value 'b'. In the fast case, T0 is guaranted not to be used. */
1236 static inline void gen_jcc1_noeob(DisasContext
*s
, int b
, int l1
)
1238 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T
[0]);
1240 if (cc
.mask
!= -1) {
1241 tcg_gen_andi_tl(cpu_T
[0], cc
.reg
, cc
.mask
);
1245 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1247 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1251 /* Generate a conditional jump to label 'l1' according to jump opcode
1252 value 'b'. In the fast case, T0 is guaranted not to be used.
1253 A translation block must end soon. */
1254 static inline void gen_jcc1(DisasContext
*s
, int b
, int l1
)
1256 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T
[0]);
1258 gen_update_cc_op(s
);
1259 if (cc
.mask
!= -1) {
1260 tcg_gen_andi_tl(cpu_T
[0], cc
.reg
, cc
.mask
);
1263 set_cc_op(s
, CC_OP_DYNAMIC
);
1265 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1267 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1271 /* XXX: does not work with gdbstub "ice" single step - not a
1273 static int gen_jz_ecx_string(DisasContext
*s
, target_ulong next_eip
)
1277 l1
= gen_new_label();
1278 l2
= gen_new_label();
1279 gen_op_jnz_ecx(s
->aflag
, l1
);
1281 gen_jmp_tb(s
, next_eip
, 1);
1286 static inline void gen_stos(DisasContext
*s
, int ot
)
1288 gen_op_mov_TN_reg(OT_LONG
, 0, R_EAX
);
1289 gen_string_movl_A0_EDI(s
);
1290 gen_op_st_T0_A0(ot
+ s
->mem_index
);
1291 gen_op_movl_T0_Dshift(ot
);
1292 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1295 static inline void gen_lods(DisasContext
*s
, int ot
)
1297 gen_string_movl_A0_ESI(s
);
1298 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
1299 gen_op_mov_reg_T0(ot
, R_EAX
);
1300 gen_op_movl_T0_Dshift(ot
);
1301 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1304 static inline void gen_scas(DisasContext
*s
, int ot
)
1306 gen_string_movl_A0_EDI(s
);
1307 gen_op_ld_T1_A0(ot
+ s
->mem_index
);
1308 gen_op(s
, OP_CMPL
, ot
, R_EAX
);
1309 gen_op_movl_T0_Dshift(ot
);
1310 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1313 static inline void gen_cmps(DisasContext
*s
, int ot
)
1315 gen_string_movl_A0_EDI(s
);
1316 gen_op_ld_T1_A0(ot
+ s
->mem_index
);
1317 gen_string_movl_A0_ESI(s
);
1318 gen_op(s
, OP_CMPL
, ot
, OR_TMP0
);
1319 gen_op_movl_T0_Dshift(ot
);
1320 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1321 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1324 static inline void gen_ins(DisasContext
*s
, int ot
)
1328 gen_string_movl_A0_EDI(s
);
1329 /* Note: we must do this dummy write first to be restartable in
1330 case of page fault. */
1332 gen_op_st_T0_A0(ot
+ s
->mem_index
);
1333 gen_op_mov_TN_reg(OT_WORD
, 1, R_EDX
);
1334 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[1]);
1335 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1336 gen_helper_in_func(ot
, cpu_T
[0], cpu_tmp2_i32
);
1337 gen_op_st_T0_A0(ot
+ s
->mem_index
);
1338 gen_op_movl_T0_Dshift(ot
);
1339 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1344 static inline void gen_outs(DisasContext
*s
, int ot
)
1348 gen_string_movl_A0_ESI(s
);
1349 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
1351 gen_op_mov_TN_reg(OT_WORD
, 1, R_EDX
);
1352 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[1]);
1353 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1354 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[0]);
1355 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1357 gen_op_movl_T0_Dshift(ot
);
1358 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1363 /* same method as Valgrind : we generate jumps to current or next
1365 #define GEN_REPZ(op) \
1366 static inline void gen_repz_ ## op(DisasContext *s, int ot, \
1367 target_ulong cur_eip, target_ulong next_eip) \
1370 gen_update_cc_op(s); \
1371 l2 = gen_jz_ecx_string(s, next_eip); \
1372 gen_ ## op(s, ot); \
1373 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1374 /* a loop would cause two single step exceptions if ECX = 1 \
1375 before rep string_insn */ \
1377 gen_op_jz_ecx(s->aflag, l2); \
1378 gen_jmp(s, cur_eip); \
1381 #define GEN_REPZ2(op) \
1382 static inline void gen_repz_ ## op(DisasContext *s, int ot, \
1383 target_ulong cur_eip, \
1384 target_ulong next_eip, \
1388 gen_update_cc_op(s); \
1389 l2 = gen_jz_ecx_string(s, next_eip); \
1390 gen_ ## op(s, ot); \
1391 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1392 gen_update_cc_op(s); \
1393 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
1395 gen_op_jz_ecx(s->aflag, l2); \
1396 gen_jmp(s, cur_eip); \
1407 static void gen_helper_fp_arith_ST0_FT0(int op
)
1411 gen_helper_fadd_ST0_FT0(cpu_env
);
1414 gen_helper_fmul_ST0_FT0(cpu_env
);
1417 gen_helper_fcom_ST0_FT0(cpu_env
);
1420 gen_helper_fcom_ST0_FT0(cpu_env
);
1423 gen_helper_fsub_ST0_FT0(cpu_env
);
1426 gen_helper_fsubr_ST0_FT0(cpu_env
);
1429 gen_helper_fdiv_ST0_FT0(cpu_env
);
1432 gen_helper_fdivr_ST0_FT0(cpu_env
);
1437 /* NOTE the exception in "r" op ordering */
1438 static void gen_helper_fp_arith_STN_ST0(int op
, int opreg
)
1440 TCGv_i32 tmp
= tcg_const_i32(opreg
);
1443 gen_helper_fadd_STN_ST0(cpu_env
, tmp
);
1446 gen_helper_fmul_STN_ST0(cpu_env
, tmp
);
1449 gen_helper_fsubr_STN_ST0(cpu_env
, tmp
);
1452 gen_helper_fsub_STN_ST0(cpu_env
, tmp
);
1455 gen_helper_fdivr_STN_ST0(cpu_env
, tmp
);
1458 gen_helper_fdiv_STN_ST0(cpu_env
, tmp
);
1463 /* if d == OR_TMP0, it means memory operand (address in A0) */
1464 static void gen_op(DisasContext
*s1
, int op
, int ot
, int d
)
1467 gen_op_mov_TN_reg(ot
, 0, d
);
1469 gen_op_ld_T0_A0(ot
+ s1
->mem_index
);
1473 gen_compute_eflags_c(s1
, cpu_tmp4
);
1474 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1475 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_tmp4
);
1477 gen_op_mov_reg_T0(ot
, d
);
1479 gen_op_st_T0_A0(ot
+ s1
->mem_index
);
1480 gen_op_update3_cc(cpu_tmp4
);
1481 set_cc_op(s1
, CC_OP_ADCB
+ ot
);
1484 gen_compute_eflags_c(s1
, cpu_tmp4
);
1485 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1486 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_tmp4
);
1488 gen_op_mov_reg_T0(ot
, d
);
1490 gen_op_st_T0_A0(ot
+ s1
->mem_index
);
1491 gen_op_update3_cc(cpu_tmp4
);
1492 set_cc_op(s1
, CC_OP_SBBB
+ ot
);
1495 gen_op_addl_T0_T1();
1497 gen_op_mov_reg_T0(ot
, d
);
1499 gen_op_st_T0_A0(ot
+ s1
->mem_index
);
1500 gen_op_update2_cc();
1501 set_cc_op(s1
, CC_OP_ADDB
+ ot
);
1504 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T
[0]);
1505 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1507 gen_op_mov_reg_T0(ot
, d
);
1509 gen_op_st_T0_A0(ot
+ s1
->mem_index
);
1510 gen_op_update2_cc();
1511 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1515 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1517 gen_op_mov_reg_T0(ot
, d
);
1519 gen_op_st_T0_A0(ot
+ s1
->mem_index
);
1520 gen_op_update1_cc();
1521 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1524 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1526 gen_op_mov_reg_T0(ot
, d
);
1528 gen_op_st_T0_A0(ot
+ s1
->mem_index
);
1529 gen_op_update1_cc();
1530 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1533 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1535 gen_op_mov_reg_T0(ot
, d
);
1537 gen_op_st_T0_A0(ot
+ s1
->mem_index
);
1538 gen_op_update1_cc();
1539 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1542 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
1543 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T
[0]);
1544 tcg_gen_sub_tl(cpu_cc_dst
, cpu_T
[0], cpu_T
[1]);
1545 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1550 /* if d == OR_TMP0, it means memory operand (address in A0) */
1551 static void gen_inc(DisasContext
*s1
, int ot
, int d
, int c
)
1554 gen_op_mov_TN_reg(ot
, 0, d
);
1556 gen_op_ld_T0_A0(ot
+ s1
->mem_index
);
1557 gen_compute_eflags_c(s1
, cpu_cc_src
);
1559 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], 1);
1560 set_cc_op(s1
, CC_OP_INCB
+ ot
);
1562 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], -1);
1563 set_cc_op(s1
, CC_OP_DECB
+ ot
);
1566 gen_op_mov_reg_T0(ot
, d
);
1568 gen_op_st_T0_A0(ot
+ s1
->mem_index
);
1569 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
1572 static void gen_shift_rm_T1(DisasContext
*s
, int ot
, int op1
,
1573 int is_right
, int is_arith
)
1579 if (ot
== OT_QUAD
) {
1586 if (op1
== OR_TMP0
) {
1587 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
1589 gen_op_mov_TN_reg(ot
, 0, op1
);
1592 t0
= tcg_temp_local_new();
1593 t1
= tcg_temp_local_new();
1594 t2
= tcg_temp_local_new();
1596 tcg_gen_andi_tl(t2
, cpu_T
[1], mask
);
1600 gen_exts(ot
, cpu_T
[0]);
1601 tcg_gen_mov_tl(t0
, cpu_T
[0]);
1602 tcg_gen_sar_tl(cpu_T
[0], cpu_T
[0], t2
);
1604 gen_extu(ot
, cpu_T
[0]);
1605 tcg_gen_mov_tl(t0
, cpu_T
[0]);
1606 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], t2
);
1609 tcg_gen_mov_tl(t0
, cpu_T
[0]);
1610 tcg_gen_shl_tl(cpu_T
[0], cpu_T
[0], t2
);
1614 if (op1
== OR_TMP0
) {
1615 gen_op_st_T0_A0(ot
+ s
->mem_index
);
1617 gen_op_mov_reg_T0(ot
, op1
);
1620 /* Update eflags data because we cannot predict flags afterward. */
1621 gen_update_cc_op(s
);
1622 set_cc_op(s
, CC_OP_DYNAMIC
);
1624 tcg_gen_mov_tl(t1
, cpu_T
[0]);
1626 shift_label
= gen_new_label();
1627 tcg_gen_brcondi_tl(TCG_COND_EQ
, t2
, 0, shift_label
);
1629 tcg_gen_addi_tl(t2
, t2
, -1);
1630 tcg_gen_mov_tl(cpu_cc_dst
, t1
);
1634 tcg_gen_sar_tl(cpu_cc_src
, t0
, t2
);
1636 tcg_gen_shr_tl(cpu_cc_src
, t0
, t2
);
1639 tcg_gen_shl_tl(cpu_cc_src
, t0
, t2
);
1643 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_SARB
+ ot
);
1645 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_SHLB
+ ot
);
1648 gen_set_label(shift_label
);
1655 static void gen_shift_rm_im(DisasContext
*s
, int ot
, int op1
, int op2
,
1656 int is_right
, int is_arith
)
1667 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
1669 gen_op_mov_TN_reg(ot
, 0, op1
);
1675 gen_exts(ot
, cpu_T
[0]);
1676 tcg_gen_sari_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1677 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], op2
);
1679 gen_extu(ot
, cpu_T
[0]);
1680 tcg_gen_shri_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1681 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], op2
);
1684 tcg_gen_shli_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1685 tcg_gen_shli_tl(cpu_T
[0], cpu_T
[0], op2
);
1691 gen_op_st_T0_A0(ot
+ s
->mem_index
);
1693 gen_op_mov_reg_T0(ot
, op1
);
1695 /* update eflags if non zero shift */
1697 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
1698 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
1699 set_cc_op(s
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1703 static inline void tcg_gen_lshift(TCGv ret
, TCGv arg1
, target_long arg2
)
1706 tcg_gen_shli_tl(ret
, arg1
, arg2
);
1708 tcg_gen_shri_tl(ret
, arg1
, -arg2
);
1711 static void gen_rot_rm_T1(DisasContext
*s
, int ot
, int op1
,
1715 int label1
, label2
, data_bits
;
1716 TCGv t0
, t1
, t2
, a0
;
1718 /* XXX: inefficient, but we must use local temps */
1719 t0
= tcg_temp_local_new();
1720 t1
= tcg_temp_local_new();
1721 t2
= tcg_temp_local_new();
1722 a0
= tcg_temp_local_new();
1730 if (op1
== OR_TMP0
) {
1731 tcg_gen_mov_tl(a0
, cpu_A0
);
1732 gen_op_ld_v(ot
+ s
->mem_index
, t0
, a0
);
1734 gen_op_mov_v_reg(ot
, t0
, op1
);
1737 tcg_gen_mov_tl(t1
, cpu_T
[1]);
1739 tcg_gen_andi_tl(t1
, t1
, mask
);
1741 /* Must test zero case to avoid using undefined behaviour in TCG
1743 label1
= gen_new_label();
1744 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, label1
);
1747 tcg_gen_andi_tl(cpu_tmp0
, t1
, (1 << (3 + ot
)) - 1);
1749 tcg_gen_mov_tl(cpu_tmp0
, t1
);
1752 tcg_gen_mov_tl(t2
, t0
);
1754 data_bits
= 8 << ot
;
1755 /* XXX: rely on behaviour of shifts when operand 2 overflows (XXX:
1756 fix TCG definition) */
1758 tcg_gen_shr_tl(cpu_tmp4
, t0
, cpu_tmp0
);
1759 tcg_gen_subfi_tl(cpu_tmp0
, data_bits
, cpu_tmp0
);
1760 tcg_gen_shl_tl(t0
, t0
, cpu_tmp0
);
1762 tcg_gen_shl_tl(cpu_tmp4
, t0
, cpu_tmp0
);
1763 tcg_gen_subfi_tl(cpu_tmp0
, data_bits
, cpu_tmp0
);
1764 tcg_gen_shr_tl(t0
, t0
, cpu_tmp0
);
1766 tcg_gen_or_tl(t0
, t0
, cpu_tmp4
);
1768 gen_set_label(label1
);
1770 if (op1
== OR_TMP0
) {
1771 gen_op_st_v(ot
+ s
->mem_index
, t0
, a0
);
1773 gen_op_mov_reg_v(ot
, op1
, t0
);
1776 /* update eflags. It is needed anyway most of the time, do it always. */
1777 gen_compute_eflags(s
);
1778 assert(s
->cc_op
== CC_OP_EFLAGS
);
1780 label2
= gen_new_label();
1781 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, label2
);
1783 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~(CC_O
| CC_C
));
1784 tcg_gen_xor_tl(cpu_tmp0
, t2
, t0
);
1785 tcg_gen_lshift(cpu_tmp0
, cpu_tmp0
, 11 - (data_bits
- 1));
1786 tcg_gen_andi_tl(cpu_tmp0
, cpu_tmp0
, CC_O
);
1787 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, cpu_tmp0
);
1789 tcg_gen_shri_tl(t0
, t0
, data_bits
- 1);
1791 tcg_gen_andi_tl(t0
, t0
, CC_C
);
1792 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, t0
);
1794 gen_set_label(label2
);
1802 static void gen_rot_rm_im(DisasContext
*s
, int ot
, int op1
, int op2
,
1809 /* XXX: inefficient, but we must use local temps */
1810 t0
= tcg_temp_local_new();
1811 t1
= tcg_temp_local_new();
1812 a0
= tcg_temp_local_new();
1820 if (op1
== OR_TMP0
) {
1821 tcg_gen_mov_tl(a0
, cpu_A0
);
1822 gen_op_ld_v(ot
+ s
->mem_index
, t0
, a0
);
1824 gen_op_mov_v_reg(ot
, t0
, op1
);
1828 tcg_gen_mov_tl(t1
, t0
);
1831 data_bits
= 8 << ot
;
1833 int shift
= op2
& ((1 << (3 + ot
)) - 1);
1835 tcg_gen_shri_tl(cpu_tmp4
, t0
, shift
);
1836 tcg_gen_shli_tl(t0
, t0
, data_bits
- shift
);
1839 tcg_gen_shli_tl(cpu_tmp4
, t0
, shift
);
1840 tcg_gen_shri_tl(t0
, t0
, data_bits
- shift
);
1842 tcg_gen_or_tl(t0
, t0
, cpu_tmp4
);
1846 if (op1
== OR_TMP0
) {
1847 gen_op_st_v(ot
+ s
->mem_index
, t0
, a0
);
1849 gen_op_mov_reg_v(ot
, op1
, t0
);
1854 gen_compute_eflags(s
);
1855 assert(s
->cc_op
== CC_OP_EFLAGS
);
1857 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~(CC_O
| CC_C
));
1858 tcg_gen_xor_tl(cpu_tmp0
, t1
, t0
);
1859 tcg_gen_lshift(cpu_tmp0
, cpu_tmp0
, 11 - (data_bits
- 1));
1860 tcg_gen_andi_tl(cpu_tmp0
, cpu_tmp0
, CC_O
);
1861 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, cpu_tmp0
);
1863 tcg_gen_shri_tl(t0
, t0
, data_bits
- 1);
1865 tcg_gen_andi_tl(t0
, t0
, CC_C
);
1866 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, t0
);
1874 /* XXX: add faster immediate = 1 case */
1875 static void gen_rotc_rm_T1(DisasContext
*s
, int ot
, int op1
,
1878 gen_compute_eflags(s
);
1879 assert(s
->cc_op
== CC_OP_EFLAGS
);
1883 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
1885 gen_op_mov_TN_reg(ot
, 0, op1
);
1890 gen_helper_rcrb(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1893 gen_helper_rcrw(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1896 gen_helper_rcrl(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1898 #ifdef TARGET_X86_64
1900 gen_helper_rcrq(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1907 gen_helper_rclb(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1910 gen_helper_rclw(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1913 gen_helper_rcll(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1915 #ifdef TARGET_X86_64
1917 gen_helper_rclq(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1924 gen_op_st_T0_A0(ot
+ s
->mem_index
);
1926 gen_op_mov_reg_T0(ot
, op1
);
1929 /* XXX: add faster immediate case */
1930 static void gen_shiftd_rm_T1(DisasContext
*s
, int ot
, int op1
,
1931 int is_right
, TCGv count
)
1933 int label1
, label2
, data_bits
;
1935 TCGv t0
, t1
, t2
, a0
;
1937 t0
= tcg_temp_local_new();
1938 t1
= tcg_temp_local_new();
1939 t2
= tcg_temp_local_new();
1940 a0
= tcg_temp_local_new();
1948 if (op1
== OR_TMP0
) {
1949 tcg_gen_mov_tl(a0
, cpu_A0
);
1950 gen_op_ld_v(ot
+ s
->mem_index
, t0
, a0
);
1952 gen_op_mov_v_reg(ot
, t0
, op1
);
1955 tcg_gen_andi_tl(t2
, count
, mask
);
1956 tcg_gen_mov_tl(t1
, cpu_T
[1]);
1958 /* Must test zero case to avoid using undefined behaviour in TCG
1960 label1
= gen_new_label();
1961 tcg_gen_brcondi_tl(TCG_COND_EQ
, t2
, 0, label1
);
1963 tcg_gen_addi_tl(cpu_tmp5
, t2
, -1);
1964 if (ot
== OT_WORD
) {
1965 /* Note: we implement the Intel behaviour for shift count > 16 */
1967 tcg_gen_andi_tl(t0
, t0
, 0xffff);
1968 tcg_gen_shli_tl(cpu_tmp0
, t1
, 16);
1969 tcg_gen_or_tl(t0
, t0
, cpu_tmp0
);
1970 tcg_gen_ext32u_tl(t0
, t0
);
1972 tcg_gen_shr_tl(cpu_tmp4
, t0
, cpu_tmp5
);
1974 /* only needed if count > 16, but a test would complicate */
1975 tcg_gen_subfi_tl(cpu_tmp5
, 32, t2
);
1976 tcg_gen_shl_tl(cpu_tmp0
, t0
, cpu_tmp5
);
1978 tcg_gen_shr_tl(t0
, t0
, t2
);
1980 tcg_gen_or_tl(t0
, t0
, cpu_tmp0
);
1982 /* XXX: not optimal */
1983 tcg_gen_andi_tl(t0
, t0
, 0xffff);
1984 tcg_gen_shli_tl(t1
, t1
, 16);
1985 tcg_gen_or_tl(t1
, t1
, t0
);
1986 tcg_gen_ext32u_tl(t1
, t1
);
1988 tcg_gen_shl_tl(cpu_tmp4
, t0
, cpu_tmp5
);
1989 tcg_gen_subfi_tl(cpu_tmp0
, 32, cpu_tmp5
);
1990 tcg_gen_shr_tl(cpu_tmp5
, t1
, cpu_tmp0
);
1991 tcg_gen_or_tl(cpu_tmp4
, cpu_tmp4
, cpu_tmp5
);
1993 tcg_gen_shl_tl(t0
, t0
, t2
);
1994 tcg_gen_subfi_tl(cpu_tmp5
, 32, t2
);
1995 tcg_gen_shr_tl(t1
, t1
, cpu_tmp5
);
1996 tcg_gen_or_tl(t0
, t0
, t1
);
1999 data_bits
= 8 << ot
;
2002 tcg_gen_ext32u_tl(t0
, t0
);
2004 tcg_gen_shr_tl(cpu_tmp4
, t0
, cpu_tmp5
);
2006 tcg_gen_shr_tl(t0
, t0
, t2
);
2007 tcg_gen_subfi_tl(cpu_tmp5
, data_bits
, t2
);
2008 tcg_gen_shl_tl(t1
, t1
, cpu_tmp5
);
2009 tcg_gen_or_tl(t0
, t0
, t1
);
2013 tcg_gen_ext32u_tl(t1
, t1
);
2015 tcg_gen_shl_tl(cpu_tmp4
, t0
, cpu_tmp5
);
2017 tcg_gen_shl_tl(t0
, t0
, t2
);
2018 tcg_gen_subfi_tl(cpu_tmp5
, data_bits
, t2
);
2019 tcg_gen_shr_tl(t1
, t1
, cpu_tmp5
);
2020 tcg_gen_or_tl(t0
, t0
, t1
);
2023 tcg_gen_mov_tl(t1
, cpu_tmp4
);
2025 gen_set_label(label1
);
2027 if (op1
== OR_TMP0
) {
2028 gen_op_st_v(ot
+ s
->mem_index
, t0
, a0
);
2030 gen_op_mov_reg_v(ot
, op1
, t0
);
2033 /* Update eflags data because we cannot predict flags afterward. */
2034 gen_update_cc_op(s
);
2035 set_cc_op(s
, CC_OP_DYNAMIC
);
2037 label2
= gen_new_label();
2038 tcg_gen_brcondi_tl(TCG_COND_EQ
, t2
, 0, label2
);
2040 tcg_gen_mov_tl(cpu_cc_src
, t1
);
2041 tcg_gen_mov_tl(cpu_cc_dst
, t0
);
2043 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_SARB
+ ot
);
2045 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_SHLB
+ ot
);
2047 gen_set_label(label2
);
2055 static void gen_shift(DisasContext
*s1
, int op
, int ot
, int d
, int s
)
2058 gen_op_mov_TN_reg(ot
, 1, s
);
2061 gen_rot_rm_T1(s1
, ot
, d
, 0);
2064 gen_rot_rm_T1(s1
, ot
, d
, 1);
2068 gen_shift_rm_T1(s1
, ot
, d
, 0, 0);
2071 gen_shift_rm_T1(s1
, ot
, d
, 1, 0);
2074 gen_shift_rm_T1(s1
, ot
, d
, 1, 1);
2077 gen_rotc_rm_T1(s1
, ot
, d
, 0);
2080 gen_rotc_rm_T1(s1
, ot
, d
, 1);
2085 static void gen_shifti(DisasContext
*s1
, int op
, int ot
, int d
, int c
)
2089 gen_rot_rm_im(s1
, ot
, d
, c
, 0);
2092 gen_rot_rm_im(s1
, ot
, d
, c
, 1);
2096 gen_shift_rm_im(s1
, ot
, d
, c
, 0, 0);
2099 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 0);
2102 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 1);
2105 /* currently not optimized */
2106 gen_op_movl_T1_im(c
);
2107 gen_shift(s1
, op
, ot
, d
, OR_TMP1
);
2112 static void gen_lea_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2113 int *reg_ptr
, int *offset_ptr
)
2121 int mod
, rm
, code
, override
, must_add_seg
;
2123 override
= s
->override
;
2124 must_add_seg
= s
->addseg
;
2127 mod
= (modrm
>> 6) & 3;
2139 code
= cpu_ldub_code(env
, s
->pc
++);
2140 scale
= (code
>> 6) & 3;
2141 index
= ((code
>> 3) & 7) | REX_X(s
);
2148 if ((base
& 7) == 5) {
2150 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
2152 if (CODE64(s
) && !havesib
) {
2153 disp
+= s
->pc
+ s
->rip_offset
;
2160 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
2164 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
2170 /* for correct popl handling with esp */
2171 if (base
== 4 && s
->popl_esp_hack
)
2172 disp
+= s
->popl_esp_hack
;
2173 #ifdef TARGET_X86_64
2174 if (s
->aflag
== 2) {
2175 gen_op_movq_A0_reg(base
);
2177 gen_op_addq_A0_im(disp
);
2182 gen_op_movl_A0_reg(base
);
2184 gen_op_addl_A0_im(disp
);
2187 #ifdef TARGET_X86_64
2188 if (s
->aflag
== 2) {
2189 gen_op_movq_A0_im(disp
);
2193 gen_op_movl_A0_im(disp
);
2196 /* index == 4 means no index */
2197 if (havesib
&& (index
!= 4)) {
2198 #ifdef TARGET_X86_64
2199 if (s
->aflag
== 2) {
2200 gen_op_addq_A0_reg_sN(scale
, index
);
2204 gen_op_addl_A0_reg_sN(scale
, index
);
2209 if (base
== R_EBP
|| base
== R_ESP
)
2214 #ifdef TARGET_X86_64
2215 if (s
->aflag
== 2) {
2216 gen_op_addq_A0_seg(override
);
2220 gen_op_addl_A0_seg(s
, override
);
2227 disp
= cpu_lduw_code(env
, s
->pc
);
2229 gen_op_movl_A0_im(disp
);
2230 rm
= 0; /* avoid SS override */
2237 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
2241 disp
= cpu_lduw_code(env
, s
->pc
);
2247 gen_op_movl_A0_reg(R_EBX
);
2248 gen_op_addl_A0_reg_sN(0, R_ESI
);
2251 gen_op_movl_A0_reg(R_EBX
);
2252 gen_op_addl_A0_reg_sN(0, R_EDI
);
2255 gen_op_movl_A0_reg(R_EBP
);
2256 gen_op_addl_A0_reg_sN(0, R_ESI
);
2259 gen_op_movl_A0_reg(R_EBP
);
2260 gen_op_addl_A0_reg_sN(0, R_EDI
);
2263 gen_op_movl_A0_reg(R_ESI
);
2266 gen_op_movl_A0_reg(R_EDI
);
2269 gen_op_movl_A0_reg(R_EBP
);
2273 gen_op_movl_A0_reg(R_EBX
);
2277 gen_op_addl_A0_im(disp
);
2278 gen_op_andl_A0_ffff();
2282 if (rm
== 2 || rm
== 3 || rm
== 6)
2287 gen_op_addl_A0_seg(s
, override
);
2297 static void gen_nop_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2299 int mod
, rm
, base
, code
;
2301 mod
= (modrm
>> 6) & 3;
2311 code
= cpu_ldub_code(env
, s
->pc
++);
2347 /* used for LEA and MOV AX, mem */
2348 static void gen_add_A0_ds_seg(DisasContext
*s
)
2350 int override
, must_add_seg
;
2351 must_add_seg
= s
->addseg
;
2353 if (s
->override
>= 0) {
2354 override
= s
->override
;
2358 #ifdef TARGET_X86_64
2360 gen_op_addq_A0_seg(override
);
2364 gen_op_addl_A0_seg(s
, override
);
2369 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2371 static void gen_ldst_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2372 int ot
, int reg
, int is_store
)
2374 int mod
, rm
, opreg
, disp
;
2376 mod
= (modrm
>> 6) & 3;
2377 rm
= (modrm
& 7) | REX_B(s
);
2381 gen_op_mov_TN_reg(ot
, 0, reg
);
2382 gen_op_mov_reg_T0(ot
, rm
);
2384 gen_op_mov_TN_reg(ot
, 0, rm
);
2386 gen_op_mov_reg_T0(ot
, reg
);
2389 gen_lea_modrm(env
, s
, modrm
, &opreg
, &disp
);
2392 gen_op_mov_TN_reg(ot
, 0, reg
);
2393 gen_op_st_T0_A0(ot
+ s
->mem_index
);
2395 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
2397 gen_op_mov_reg_T0(ot
, reg
);
2402 static inline uint32_t insn_get(CPUX86State
*env
, DisasContext
*s
, int ot
)
2408 ret
= cpu_ldub_code(env
, s
->pc
);
2412 ret
= cpu_lduw_code(env
, s
->pc
);
2417 ret
= cpu_ldl_code(env
, s
->pc
);
2424 static inline int insn_const_size(unsigned int ot
)
2432 static inline void gen_goto_tb(DisasContext
*s
, int tb_num
, target_ulong eip
)
2434 TranslationBlock
*tb
;
2437 pc
= s
->cs_base
+ eip
;
2439 /* NOTE: we handle the case where the TB spans two pages here */
2440 if ((pc
& TARGET_PAGE_MASK
) == (tb
->pc
& TARGET_PAGE_MASK
) ||
2441 (pc
& TARGET_PAGE_MASK
) == ((s
->pc
- 1) & TARGET_PAGE_MASK
)) {
2442 /* jump to same page: we can use a direct jump */
2443 tcg_gen_goto_tb(tb_num
);
2445 tcg_gen_exit_tb((tcg_target_long
)tb
+ tb_num
);
2447 /* jump to another page: currently not optimized */
2453 static inline void gen_jcc(DisasContext
*s
, int b
,
2454 target_ulong val
, target_ulong next_eip
)
2459 l1
= gen_new_label();
2462 gen_goto_tb(s
, 0, next_eip
);
2465 gen_goto_tb(s
, 1, val
);
2466 s
->is_jmp
= DISAS_TB_JUMP
;
2468 l1
= gen_new_label();
2469 l2
= gen_new_label();
2472 gen_jmp_im(next_eip
);
2482 static void gen_cmovcc1(CPUX86State
*env
, DisasContext
*s
, int ot
, int b
,
2487 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
2489 cc
= gen_prepare_cc(s
, b
, cpu_T
[1]);
2490 if (cc
.mask
!= -1) {
2491 TCGv t0
= tcg_temp_new();
2492 tcg_gen_andi_tl(t0
, cc
.reg
, cc
.mask
);
2496 cc
.reg2
= tcg_const_tl(cc
.imm
);
2499 tcg_gen_movcond_tl(cc
.cond
, cpu_T
[0], cc
.reg
, cc
.reg2
,
2500 cpu_T
[0], cpu_regs
[reg
]);
2501 gen_op_mov_reg_T0(ot
, reg
);
2503 if (cc
.mask
!= -1) {
2504 tcg_temp_free(cc
.reg
);
2507 tcg_temp_free(cc
.reg2
);
2511 static inline void gen_op_movl_T0_seg(int seg_reg
)
2513 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
,
2514 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2517 static inline void gen_op_movl_seg_T0_vm(int seg_reg
)
2519 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffff);
2520 tcg_gen_st32_tl(cpu_T
[0], cpu_env
,
2521 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2522 tcg_gen_shli_tl(cpu_T
[0], cpu_T
[0], 4);
2523 tcg_gen_st_tl(cpu_T
[0], cpu_env
,
2524 offsetof(CPUX86State
,segs
[seg_reg
].base
));
2527 /* move T0 to seg_reg and compute if the CPU state may change. Never
2528 call this function with seg_reg == R_CS */
2529 static void gen_movl_seg_T0(DisasContext
*s
, int seg_reg
, target_ulong cur_eip
)
2531 if (s
->pe
&& !s
->vm86
) {
2532 /* XXX: optimize by finding processor state dynamically */
2533 gen_update_cc_op(s
);
2534 gen_jmp_im(cur_eip
);
2535 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
2536 gen_helper_load_seg(cpu_env
, tcg_const_i32(seg_reg
), cpu_tmp2_i32
);
2537 /* abort translation because the addseg value may change or
2538 because ss32 may change. For R_SS, translation must always
2539 stop as a special handling must be done to disable hardware
2540 interrupts for the next instruction */
2541 if (seg_reg
== R_SS
|| (s
->code32
&& seg_reg
< R_FS
))
2542 s
->is_jmp
= DISAS_TB_JUMP
;
2544 gen_op_movl_seg_T0_vm(seg_reg
);
2545 if (seg_reg
== R_SS
)
2546 s
->is_jmp
= DISAS_TB_JUMP
;
2550 static inline int svm_is_rep(int prefixes
)
2552 return ((prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) ? 8 : 0);
2556 gen_svm_check_intercept_param(DisasContext
*s
, target_ulong pc_start
,
2557 uint32_t type
, uint64_t param
)
2559 /* no SVM activated; fast case */
2560 if (likely(!(s
->flags
& HF_SVMI_MASK
)))
2562 gen_update_cc_op(s
);
2563 gen_jmp_im(pc_start
- s
->cs_base
);
2564 gen_helper_svm_check_intercept_param(cpu_env
, tcg_const_i32(type
),
2565 tcg_const_i64(param
));
2569 gen_svm_check_intercept(DisasContext
*s
, target_ulong pc_start
, uint64_t type
)
2571 gen_svm_check_intercept_param(s
, pc_start
, type
, 0);
2574 static inline void gen_stack_update(DisasContext
*s
, int addend
)
2576 #ifdef TARGET_X86_64
2578 gen_op_add_reg_im(2, R_ESP
, addend
);
2582 gen_op_add_reg_im(1, R_ESP
, addend
);
2584 gen_op_add_reg_im(0, R_ESP
, addend
);
2588 /* generate a push. It depends on ss32, addseg and dflag */
2589 static void gen_push_T0(DisasContext
*s
)
2591 #ifdef TARGET_X86_64
2593 gen_op_movq_A0_reg(R_ESP
);
2595 gen_op_addq_A0_im(-8);
2596 gen_op_st_T0_A0(OT_QUAD
+ s
->mem_index
);
2598 gen_op_addq_A0_im(-2);
2599 gen_op_st_T0_A0(OT_WORD
+ s
->mem_index
);
2601 gen_op_mov_reg_A0(2, R_ESP
);
2605 gen_op_movl_A0_reg(R_ESP
);
2607 gen_op_addl_A0_im(-2);
2609 gen_op_addl_A0_im(-4);
2612 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2613 gen_op_addl_A0_seg(s
, R_SS
);
2616 gen_op_andl_A0_ffff();
2617 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2618 gen_op_addl_A0_seg(s
, R_SS
);
2620 gen_op_st_T0_A0(s
->dflag
+ 1 + s
->mem_index
);
2621 if (s
->ss32
&& !s
->addseg
)
2622 gen_op_mov_reg_A0(1, R_ESP
);
2624 gen_op_mov_reg_T1(s
->ss32
+ 1, R_ESP
);
2628 /* generate a push. It depends on ss32, addseg and dflag */
2629 /* slower version for T1, only used for call Ev */
2630 static void gen_push_T1(DisasContext
*s
)
2632 #ifdef TARGET_X86_64
2634 gen_op_movq_A0_reg(R_ESP
);
2636 gen_op_addq_A0_im(-8);
2637 gen_op_st_T1_A0(OT_QUAD
+ s
->mem_index
);
2639 gen_op_addq_A0_im(-2);
2640 gen_op_st_T0_A0(OT_WORD
+ s
->mem_index
);
2642 gen_op_mov_reg_A0(2, R_ESP
);
2646 gen_op_movl_A0_reg(R_ESP
);
2648 gen_op_addl_A0_im(-2);
2650 gen_op_addl_A0_im(-4);
2653 gen_op_addl_A0_seg(s
, R_SS
);
2656 gen_op_andl_A0_ffff();
2657 gen_op_addl_A0_seg(s
, R_SS
);
2659 gen_op_st_T1_A0(s
->dflag
+ 1 + s
->mem_index
);
2661 if (s
->ss32
&& !s
->addseg
)
2662 gen_op_mov_reg_A0(1, R_ESP
);
2664 gen_stack_update(s
, (-2) << s
->dflag
);
2668 /* two step pop is necessary for precise exceptions */
2669 static void gen_pop_T0(DisasContext
*s
)
2671 #ifdef TARGET_X86_64
2673 gen_op_movq_A0_reg(R_ESP
);
2674 gen_op_ld_T0_A0((s
->dflag
? OT_QUAD
: OT_WORD
) + s
->mem_index
);
2678 gen_op_movl_A0_reg(R_ESP
);
2681 gen_op_addl_A0_seg(s
, R_SS
);
2683 gen_op_andl_A0_ffff();
2684 gen_op_addl_A0_seg(s
, R_SS
);
2686 gen_op_ld_T0_A0(s
->dflag
+ 1 + s
->mem_index
);
2690 static void gen_pop_update(DisasContext
*s
)
2692 #ifdef TARGET_X86_64
2693 if (CODE64(s
) && s
->dflag
) {
2694 gen_stack_update(s
, 8);
2698 gen_stack_update(s
, 2 << s
->dflag
);
2702 static void gen_stack_A0(DisasContext
*s
)
2704 gen_op_movl_A0_reg(R_ESP
);
2706 gen_op_andl_A0_ffff();
2707 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2709 gen_op_addl_A0_seg(s
, R_SS
);
2712 /* NOTE: wrap around in 16 bit not fully handled */
2713 static void gen_pusha(DisasContext
*s
)
2716 gen_op_movl_A0_reg(R_ESP
);
2717 gen_op_addl_A0_im(-16 << s
->dflag
);
2719 gen_op_andl_A0_ffff();
2720 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2722 gen_op_addl_A0_seg(s
, R_SS
);
2723 for(i
= 0;i
< 8; i
++) {
2724 gen_op_mov_TN_reg(OT_LONG
, 0, 7 - i
);
2725 gen_op_st_T0_A0(OT_WORD
+ s
->dflag
+ s
->mem_index
);
2726 gen_op_addl_A0_im(2 << s
->dflag
);
2728 gen_op_mov_reg_T1(OT_WORD
+ s
->ss32
, R_ESP
);
2731 /* NOTE: wrap around in 16 bit not fully handled */
2732 static void gen_popa(DisasContext
*s
)
2735 gen_op_movl_A0_reg(R_ESP
);
2737 gen_op_andl_A0_ffff();
2738 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2739 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], 16 << s
->dflag
);
2741 gen_op_addl_A0_seg(s
, R_SS
);
2742 for(i
= 0;i
< 8; i
++) {
2743 /* ESP is not reloaded */
2745 gen_op_ld_T0_A0(OT_WORD
+ s
->dflag
+ s
->mem_index
);
2746 gen_op_mov_reg_T0(OT_WORD
+ s
->dflag
, 7 - i
);
2748 gen_op_addl_A0_im(2 << s
->dflag
);
2750 gen_op_mov_reg_T1(OT_WORD
+ s
->ss32
, R_ESP
);
2753 static void gen_enter(DisasContext
*s
, int esp_addend
, int level
)
2758 #ifdef TARGET_X86_64
2760 ot
= s
->dflag
? OT_QUAD
: OT_WORD
;
2763 gen_op_movl_A0_reg(R_ESP
);
2764 gen_op_addq_A0_im(-opsize
);
2765 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2768 gen_op_mov_TN_reg(OT_LONG
, 0, R_EBP
);
2769 gen_op_st_T0_A0(ot
+ s
->mem_index
);
2771 /* XXX: must save state */
2772 gen_helper_enter64_level(cpu_env
, tcg_const_i32(level
),
2773 tcg_const_i32((ot
== OT_QUAD
)),
2776 gen_op_mov_reg_T1(ot
, R_EBP
);
2777 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], -esp_addend
+ (-opsize
* level
));
2778 gen_op_mov_reg_T1(OT_QUAD
, R_ESP
);
2782 ot
= s
->dflag
+ OT_WORD
;
2783 opsize
= 2 << s
->dflag
;
2785 gen_op_movl_A0_reg(R_ESP
);
2786 gen_op_addl_A0_im(-opsize
);
2788 gen_op_andl_A0_ffff();
2789 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2791 gen_op_addl_A0_seg(s
, R_SS
);
2793 gen_op_mov_TN_reg(OT_LONG
, 0, R_EBP
);
2794 gen_op_st_T0_A0(ot
+ s
->mem_index
);
2796 /* XXX: must save state */
2797 gen_helper_enter_level(cpu_env
, tcg_const_i32(level
),
2798 tcg_const_i32(s
->dflag
),
2801 gen_op_mov_reg_T1(ot
, R_EBP
);
2802 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], -esp_addend
+ (-opsize
* level
));
2803 gen_op_mov_reg_T1(OT_WORD
+ s
->ss32
, R_ESP
);
2807 static void gen_exception(DisasContext
*s
, int trapno
, target_ulong cur_eip
)
2809 gen_update_cc_op(s
);
2810 gen_jmp_im(cur_eip
);
2811 gen_helper_raise_exception(cpu_env
, tcg_const_i32(trapno
));
2812 s
->is_jmp
= DISAS_TB_JUMP
;
2815 /* an interrupt is different from an exception because of the
2817 static void gen_interrupt(DisasContext
*s
, int intno
,
2818 target_ulong cur_eip
, target_ulong next_eip
)
2820 gen_update_cc_op(s
);
2821 gen_jmp_im(cur_eip
);
2822 gen_helper_raise_interrupt(cpu_env
, tcg_const_i32(intno
),
2823 tcg_const_i32(next_eip
- cur_eip
));
2824 s
->is_jmp
= DISAS_TB_JUMP
;
2827 static void gen_debug(DisasContext
*s
, target_ulong cur_eip
)
2829 gen_update_cc_op(s
);
2830 gen_jmp_im(cur_eip
);
2831 gen_helper_debug(cpu_env
);
2832 s
->is_jmp
= DISAS_TB_JUMP
;
2835 /* generate a generic end of block. Trace exception is also generated
2837 static void gen_eob(DisasContext
*s
)
2839 gen_update_cc_op(s
);
2840 if (s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
) {
2841 gen_helper_reset_inhibit_irq(cpu_env
);
2843 if (s
->tb
->flags
& HF_RF_MASK
) {
2844 gen_helper_reset_rf(cpu_env
);
2846 if (s
->singlestep_enabled
) {
2847 gen_helper_debug(cpu_env
);
2849 gen_helper_single_step(cpu_env
);
2853 s
->is_jmp
= DISAS_TB_JUMP
;
2856 /* generate a jump to eip. No segment change must happen before as a
2857 direct call to the next block may occur */
2858 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
)
2860 gen_update_cc_op(s
);
2861 set_cc_op(s
, CC_OP_DYNAMIC
);
2863 gen_goto_tb(s
, tb_num
, eip
);
2864 s
->is_jmp
= DISAS_TB_JUMP
;
2871 static void gen_jmp(DisasContext
*s
, target_ulong eip
)
2873 gen_jmp_tb(s
, eip
, 0);
2876 static inline void gen_ldq_env_A0(int idx
, int offset
)
2878 int mem_index
= (idx
>> 2) - 1;
2879 tcg_gen_qemu_ld64(cpu_tmp1_i64
, cpu_A0
, mem_index
);
2880 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2883 static inline void gen_stq_env_A0(int idx
, int offset
)
2885 int mem_index
= (idx
>> 2) - 1;
2886 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2887 tcg_gen_qemu_st64(cpu_tmp1_i64
, cpu_A0
, mem_index
);
2890 static inline void gen_ldo_env_A0(int idx
, int offset
)
2892 int mem_index
= (idx
>> 2) - 1;
2893 tcg_gen_qemu_ld64(cpu_tmp1_i64
, cpu_A0
, mem_index
);
2894 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(0)));
2895 tcg_gen_addi_tl(cpu_tmp0
, cpu_A0
, 8);
2896 tcg_gen_qemu_ld64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
);
2897 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(1)));
2900 static inline void gen_sto_env_A0(int idx
, int offset
)
2902 int mem_index
= (idx
>> 2) - 1;
2903 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(0)));
2904 tcg_gen_qemu_st64(cpu_tmp1_i64
, cpu_A0
, mem_index
);
2905 tcg_gen_addi_tl(cpu_tmp0
, cpu_A0
, 8);
2906 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(1)));
2907 tcg_gen_qemu_st64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
);
2910 static inline void gen_op_movo(int d_offset
, int s_offset
)
2912 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
);
2913 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2914 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
+ 8);
2915 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
+ 8);
2918 static inline void gen_op_movq(int d_offset
, int s_offset
)
2920 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
);
2921 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2924 static inline void gen_op_movl(int d_offset
, int s_offset
)
2926 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
, s_offset
);
2927 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, d_offset
);
2930 static inline void gen_op_movq_env_0(int d_offset
)
2932 tcg_gen_movi_i64(cpu_tmp1_i64
, 0);
2933 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2936 typedef void (*SSEFunc_i_ep
)(TCGv_i32 val
, TCGv_ptr env
, TCGv_ptr reg
);
2937 typedef void (*SSEFunc_l_ep
)(TCGv_i64 val
, TCGv_ptr env
, TCGv_ptr reg
);
2938 typedef void (*SSEFunc_0_epi
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i32 val
);
2939 typedef void (*SSEFunc_0_epl
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i64 val
);
2940 typedef void (*SSEFunc_0_epp
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
);
2941 typedef void (*SSEFunc_0_eppi
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2943 typedef void (*SSEFunc_0_ppi
)(TCGv_ptr reg_a
, TCGv_ptr reg_b
, TCGv_i32 val
);
2944 typedef void (*SSEFunc_0_eppt
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2947 #define SSE_SPECIAL ((void *)1)
2948 #define SSE_DUMMY ((void *)2)
2950 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2951 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2952 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2954 static const SSEFunc_0_epp sse_op_table1
[256][4] = {
2955 /* 3DNow! extensions */
2956 [0x0e] = { SSE_DUMMY
}, /* femms */
2957 [0x0f] = { SSE_DUMMY
}, /* pf... */
2958 /* pure SSE operations */
2959 [0x10] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2960 [0x11] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2961 [0x12] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd, movsldup, movddup */
2962 [0x13] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd */
2963 [0x14] = { gen_helper_punpckldq_xmm
, gen_helper_punpcklqdq_xmm
},
2964 [0x15] = { gen_helper_punpckhdq_xmm
, gen_helper_punpckhqdq_xmm
},
2965 [0x16] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd, movshdup */
2966 [0x17] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd */
2968 [0x28] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2969 [0x29] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2970 [0x2a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2971 [0x2b] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movntps, movntpd, movntss, movntsd */
2972 [0x2c] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2973 [0x2d] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2974 [0x2e] = { gen_helper_ucomiss
, gen_helper_ucomisd
},
2975 [0x2f] = { gen_helper_comiss
, gen_helper_comisd
},
2976 [0x50] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movmskps, movmskpd */
2977 [0x51] = SSE_FOP(sqrt
),
2978 [0x52] = { gen_helper_rsqrtps
, NULL
, gen_helper_rsqrtss
, NULL
},
2979 [0x53] = { gen_helper_rcpps
, NULL
, gen_helper_rcpss
, NULL
},
2980 [0x54] = { gen_helper_pand_xmm
, gen_helper_pand_xmm
}, /* andps, andpd */
2981 [0x55] = { gen_helper_pandn_xmm
, gen_helper_pandn_xmm
}, /* andnps, andnpd */
2982 [0x56] = { gen_helper_por_xmm
, gen_helper_por_xmm
}, /* orps, orpd */
2983 [0x57] = { gen_helper_pxor_xmm
, gen_helper_pxor_xmm
}, /* xorps, xorpd */
2984 [0x58] = SSE_FOP(add
),
2985 [0x59] = SSE_FOP(mul
),
2986 [0x5a] = { gen_helper_cvtps2pd
, gen_helper_cvtpd2ps
,
2987 gen_helper_cvtss2sd
, gen_helper_cvtsd2ss
},
2988 [0x5b] = { gen_helper_cvtdq2ps
, gen_helper_cvtps2dq
, gen_helper_cvttps2dq
},
2989 [0x5c] = SSE_FOP(sub
),
2990 [0x5d] = SSE_FOP(min
),
2991 [0x5e] = SSE_FOP(div
),
2992 [0x5f] = SSE_FOP(max
),
2994 [0xc2] = SSE_FOP(cmpeq
),
2995 [0xc6] = { (SSEFunc_0_epp
)gen_helper_shufps
,
2996 (SSEFunc_0_epp
)gen_helper_shufpd
}, /* XXX: casts */
2998 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */
2999 [0x38] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
3000 [0x3a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
3002 /* MMX ops and their SSE extensions */
3003 [0x60] = MMX_OP2(punpcklbw
),
3004 [0x61] = MMX_OP2(punpcklwd
),
3005 [0x62] = MMX_OP2(punpckldq
),
3006 [0x63] = MMX_OP2(packsswb
),
3007 [0x64] = MMX_OP2(pcmpgtb
),
3008 [0x65] = MMX_OP2(pcmpgtw
),
3009 [0x66] = MMX_OP2(pcmpgtl
),
3010 [0x67] = MMX_OP2(packuswb
),
3011 [0x68] = MMX_OP2(punpckhbw
),
3012 [0x69] = MMX_OP2(punpckhwd
),
3013 [0x6a] = MMX_OP2(punpckhdq
),
3014 [0x6b] = MMX_OP2(packssdw
),
3015 [0x6c] = { NULL
, gen_helper_punpcklqdq_xmm
},
3016 [0x6d] = { NULL
, gen_helper_punpckhqdq_xmm
},
3017 [0x6e] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movd mm, ea */
3018 [0x6f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, , movqdu */
3019 [0x70] = { (SSEFunc_0_epp
)gen_helper_pshufw_mmx
,
3020 (SSEFunc_0_epp
)gen_helper_pshufd_xmm
,
3021 (SSEFunc_0_epp
)gen_helper_pshufhw_xmm
,
3022 (SSEFunc_0_epp
)gen_helper_pshuflw_xmm
}, /* XXX: casts */
3023 [0x71] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftw */
3024 [0x72] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftd */
3025 [0x73] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftq */
3026 [0x74] = MMX_OP2(pcmpeqb
),
3027 [0x75] = MMX_OP2(pcmpeqw
),
3028 [0x76] = MMX_OP2(pcmpeql
),
3029 [0x77] = { SSE_DUMMY
}, /* emms */
3030 [0x78] = { NULL
, SSE_SPECIAL
, NULL
, SSE_SPECIAL
}, /* extrq_i, insertq_i */
3031 [0x79] = { NULL
, gen_helper_extrq_r
, NULL
, gen_helper_insertq_r
},
3032 [0x7c] = { NULL
, gen_helper_haddpd
, NULL
, gen_helper_haddps
},
3033 [0x7d] = { NULL
, gen_helper_hsubpd
, NULL
, gen_helper_hsubps
},
3034 [0x7e] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movd, movd, , movq */
3035 [0x7f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, movdqu */
3036 [0xc4] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pinsrw */
3037 [0xc5] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pextrw */
3038 [0xd0] = { NULL
, gen_helper_addsubpd
, NULL
, gen_helper_addsubps
},
3039 [0xd1] = MMX_OP2(psrlw
),
3040 [0xd2] = MMX_OP2(psrld
),
3041 [0xd3] = MMX_OP2(psrlq
),
3042 [0xd4] = MMX_OP2(paddq
),
3043 [0xd5] = MMX_OP2(pmullw
),
3044 [0xd6] = { NULL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
3045 [0xd7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pmovmskb */
3046 [0xd8] = MMX_OP2(psubusb
),
3047 [0xd9] = MMX_OP2(psubusw
),
3048 [0xda] = MMX_OP2(pminub
),
3049 [0xdb] = MMX_OP2(pand
),
3050 [0xdc] = MMX_OP2(paddusb
),
3051 [0xdd] = MMX_OP2(paddusw
),
3052 [0xde] = MMX_OP2(pmaxub
),
3053 [0xdf] = MMX_OP2(pandn
),
3054 [0xe0] = MMX_OP2(pavgb
),
3055 [0xe1] = MMX_OP2(psraw
),
3056 [0xe2] = MMX_OP2(psrad
),
3057 [0xe3] = MMX_OP2(pavgw
),
3058 [0xe4] = MMX_OP2(pmulhuw
),
3059 [0xe5] = MMX_OP2(pmulhw
),
3060 [0xe6] = { NULL
, gen_helper_cvttpd2dq
, gen_helper_cvtdq2pd
, gen_helper_cvtpd2dq
},
3061 [0xe7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movntq, movntq */
3062 [0xe8] = MMX_OP2(psubsb
),
3063 [0xe9] = MMX_OP2(psubsw
),
3064 [0xea] = MMX_OP2(pminsw
),
3065 [0xeb] = MMX_OP2(por
),
3066 [0xec] = MMX_OP2(paddsb
),
3067 [0xed] = MMX_OP2(paddsw
),
3068 [0xee] = MMX_OP2(pmaxsw
),
3069 [0xef] = MMX_OP2(pxor
),
3070 [0xf0] = { NULL
, NULL
, NULL
, SSE_SPECIAL
}, /* lddqu */
3071 [0xf1] = MMX_OP2(psllw
),
3072 [0xf2] = MMX_OP2(pslld
),
3073 [0xf3] = MMX_OP2(psllq
),
3074 [0xf4] = MMX_OP2(pmuludq
),
3075 [0xf5] = MMX_OP2(pmaddwd
),
3076 [0xf6] = MMX_OP2(psadbw
),
3077 [0xf7] = { (SSEFunc_0_epp
)gen_helper_maskmov_mmx
,
3078 (SSEFunc_0_epp
)gen_helper_maskmov_xmm
}, /* XXX: casts */
3079 [0xf8] = MMX_OP2(psubb
),
3080 [0xf9] = MMX_OP2(psubw
),
3081 [0xfa] = MMX_OP2(psubl
),
3082 [0xfb] = MMX_OP2(psubq
),
3083 [0xfc] = MMX_OP2(paddb
),
3084 [0xfd] = MMX_OP2(paddw
),
3085 [0xfe] = MMX_OP2(paddl
),
3088 static const SSEFunc_0_epp sse_op_table2
[3 * 8][2] = {
3089 [0 + 2] = MMX_OP2(psrlw
),
3090 [0 + 4] = MMX_OP2(psraw
),
3091 [0 + 6] = MMX_OP2(psllw
),
3092 [8 + 2] = MMX_OP2(psrld
),
3093 [8 + 4] = MMX_OP2(psrad
),
3094 [8 + 6] = MMX_OP2(pslld
),
3095 [16 + 2] = MMX_OP2(psrlq
),
3096 [16 + 3] = { NULL
, gen_helper_psrldq_xmm
},
3097 [16 + 6] = MMX_OP2(psllq
),
3098 [16 + 7] = { NULL
, gen_helper_pslldq_xmm
},
3101 static const SSEFunc_0_epi sse_op_table3ai
[] = {
3102 gen_helper_cvtsi2ss
,
3106 #ifdef TARGET_X86_64
3107 static const SSEFunc_0_epl sse_op_table3aq
[] = {
3108 gen_helper_cvtsq2ss
,
3113 static const SSEFunc_i_ep sse_op_table3bi
[] = {
3114 gen_helper_cvttss2si
,
3115 gen_helper_cvtss2si
,
3116 gen_helper_cvttsd2si
,
3120 #ifdef TARGET_X86_64
3121 static const SSEFunc_l_ep sse_op_table3bq
[] = {
3122 gen_helper_cvttss2sq
,
3123 gen_helper_cvtss2sq
,
3124 gen_helper_cvttsd2sq
,
3129 static const SSEFunc_0_epp sse_op_table4
[8][4] = {
3140 static const SSEFunc_0_epp sse_op_table5
[256] = {
3141 [0x0c] = gen_helper_pi2fw
,
3142 [0x0d] = gen_helper_pi2fd
,
3143 [0x1c] = gen_helper_pf2iw
,
3144 [0x1d] = gen_helper_pf2id
,
3145 [0x8a] = gen_helper_pfnacc
,
3146 [0x8e] = gen_helper_pfpnacc
,
3147 [0x90] = gen_helper_pfcmpge
,
3148 [0x94] = gen_helper_pfmin
,
3149 [0x96] = gen_helper_pfrcp
,
3150 [0x97] = gen_helper_pfrsqrt
,
3151 [0x9a] = gen_helper_pfsub
,
3152 [0x9e] = gen_helper_pfadd
,
3153 [0xa0] = gen_helper_pfcmpgt
,
3154 [0xa4] = gen_helper_pfmax
,
3155 [0xa6] = gen_helper_movq
, /* pfrcpit1; no need to actually increase precision */
3156 [0xa7] = gen_helper_movq
, /* pfrsqit1 */
3157 [0xaa] = gen_helper_pfsubr
,
3158 [0xae] = gen_helper_pfacc
,
3159 [0xb0] = gen_helper_pfcmpeq
,
3160 [0xb4] = gen_helper_pfmul
,
3161 [0xb6] = gen_helper_movq
, /* pfrcpit2 */
3162 [0xb7] = gen_helper_pmulhrw_mmx
,
3163 [0xbb] = gen_helper_pswapd
,
3164 [0xbf] = gen_helper_pavgb_mmx
/* pavgusb */
3167 struct SSEOpHelper_epp
{
3168 SSEFunc_0_epp op
[2];
3172 struct SSEOpHelper_eppi
{
3173 SSEFunc_0_eppi op
[2];
3177 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
3178 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
3179 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
3180 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
3182 static const struct SSEOpHelper_epp sse_op_table6
[256] = {
3183 [0x00] = SSSE3_OP(pshufb
),
3184 [0x01] = SSSE3_OP(phaddw
),
3185 [0x02] = SSSE3_OP(phaddd
),
3186 [0x03] = SSSE3_OP(phaddsw
),
3187 [0x04] = SSSE3_OP(pmaddubsw
),
3188 [0x05] = SSSE3_OP(phsubw
),
3189 [0x06] = SSSE3_OP(phsubd
),
3190 [0x07] = SSSE3_OP(phsubsw
),
3191 [0x08] = SSSE3_OP(psignb
),
3192 [0x09] = SSSE3_OP(psignw
),
3193 [0x0a] = SSSE3_OP(psignd
),
3194 [0x0b] = SSSE3_OP(pmulhrsw
),
3195 [0x10] = SSE41_OP(pblendvb
),
3196 [0x14] = SSE41_OP(blendvps
),
3197 [0x15] = SSE41_OP(blendvpd
),
3198 [0x17] = SSE41_OP(ptest
),
3199 [0x1c] = SSSE3_OP(pabsb
),
3200 [0x1d] = SSSE3_OP(pabsw
),
3201 [0x1e] = SSSE3_OP(pabsd
),
3202 [0x20] = SSE41_OP(pmovsxbw
),
3203 [0x21] = SSE41_OP(pmovsxbd
),
3204 [0x22] = SSE41_OP(pmovsxbq
),
3205 [0x23] = SSE41_OP(pmovsxwd
),
3206 [0x24] = SSE41_OP(pmovsxwq
),
3207 [0x25] = SSE41_OP(pmovsxdq
),
3208 [0x28] = SSE41_OP(pmuldq
),
3209 [0x29] = SSE41_OP(pcmpeqq
),
3210 [0x2a] = SSE41_SPECIAL
, /* movntqda */
3211 [0x2b] = SSE41_OP(packusdw
),
3212 [0x30] = SSE41_OP(pmovzxbw
),
3213 [0x31] = SSE41_OP(pmovzxbd
),
3214 [0x32] = SSE41_OP(pmovzxbq
),
3215 [0x33] = SSE41_OP(pmovzxwd
),
3216 [0x34] = SSE41_OP(pmovzxwq
),
3217 [0x35] = SSE41_OP(pmovzxdq
),
3218 [0x37] = SSE42_OP(pcmpgtq
),
3219 [0x38] = SSE41_OP(pminsb
),
3220 [0x39] = SSE41_OP(pminsd
),
3221 [0x3a] = SSE41_OP(pminuw
),
3222 [0x3b] = SSE41_OP(pminud
),
3223 [0x3c] = SSE41_OP(pmaxsb
),
3224 [0x3d] = SSE41_OP(pmaxsd
),
3225 [0x3e] = SSE41_OP(pmaxuw
),
3226 [0x3f] = SSE41_OP(pmaxud
),
3227 [0x40] = SSE41_OP(pmulld
),
3228 [0x41] = SSE41_OP(phminposuw
),
3231 static const struct SSEOpHelper_eppi sse_op_table7
[256] = {
3232 [0x08] = SSE41_OP(roundps
),
3233 [0x09] = SSE41_OP(roundpd
),
3234 [0x0a] = SSE41_OP(roundss
),
3235 [0x0b] = SSE41_OP(roundsd
),
3236 [0x0c] = SSE41_OP(blendps
),
3237 [0x0d] = SSE41_OP(blendpd
),
3238 [0x0e] = SSE41_OP(pblendw
),
3239 [0x0f] = SSSE3_OP(palignr
),
3240 [0x14] = SSE41_SPECIAL
, /* pextrb */
3241 [0x15] = SSE41_SPECIAL
, /* pextrw */
3242 [0x16] = SSE41_SPECIAL
, /* pextrd/pextrq */
3243 [0x17] = SSE41_SPECIAL
, /* extractps */
3244 [0x20] = SSE41_SPECIAL
, /* pinsrb */
3245 [0x21] = SSE41_SPECIAL
, /* insertps */
3246 [0x22] = SSE41_SPECIAL
, /* pinsrd/pinsrq */
3247 [0x40] = SSE41_OP(dpps
),
3248 [0x41] = SSE41_OP(dppd
),
3249 [0x42] = SSE41_OP(mpsadbw
),
3250 [0x60] = SSE42_OP(pcmpestrm
),
3251 [0x61] = SSE42_OP(pcmpestri
),
3252 [0x62] = SSE42_OP(pcmpistrm
),
3253 [0x63] = SSE42_OP(pcmpistri
),
3256 static void gen_sse(CPUX86State
*env
, DisasContext
*s
, int b
,
3257 target_ulong pc_start
, int rex_r
)
3259 int b1
, op1_offset
, op2_offset
, is_xmm
, val
, ot
;
3260 int modrm
, mod
, rm
, reg
, reg_addr
, offset_addr
;
3261 SSEFunc_0_epp sse_fn_epp
;
3262 SSEFunc_0_eppi sse_fn_eppi
;
3263 SSEFunc_0_ppi sse_fn_ppi
;
3264 SSEFunc_0_eppt sse_fn_eppt
;
3267 if (s
->prefix
& PREFIX_DATA
)
3269 else if (s
->prefix
& PREFIX_REPZ
)
3271 else if (s
->prefix
& PREFIX_REPNZ
)
3275 sse_fn_epp
= sse_op_table1
[b
][b1
];
3279 if ((b
<= 0x5f && b
>= 0x10) || b
== 0xc6 || b
== 0xc2) {
3289 /* simple MMX/SSE operation */
3290 if (s
->flags
& HF_TS_MASK
) {
3291 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
3294 if (s
->flags
& HF_EM_MASK
) {
3296 gen_exception(s
, EXCP06_ILLOP
, pc_start
- s
->cs_base
);
3299 if (is_xmm
&& !(s
->flags
& HF_OSFXSR_MASK
))
3300 if ((b
!= 0x38 && b
!= 0x3a) || (s
->prefix
& PREFIX_DATA
))
3303 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
))
3306 gen_helper_emms(cpu_env
);
3311 gen_helper_emms(cpu_env
);
3314 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3315 the static cpu state) */
3317 gen_helper_enter_mmx(cpu_env
);
3320 modrm
= cpu_ldub_code(env
, s
->pc
++);
3321 reg
= ((modrm
>> 3) & 7);
3324 mod
= (modrm
>> 6) & 3;
3325 if (sse_fn_epp
== SSE_SPECIAL
) {
3328 case 0x0e7: /* movntq */
3331 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3332 gen_stq_env_A0(s
->mem_index
, offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3334 case 0x1e7: /* movntdq */
3335 case 0x02b: /* movntps */
3336 case 0x12b: /* movntps */
3339 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3340 gen_sto_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
]));
3342 case 0x3f0: /* lddqu */
3345 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3346 gen_ldo_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
]));
3348 case 0x22b: /* movntss */
3349 case 0x32b: /* movntsd */
3352 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3354 gen_stq_env_A0(s
->mem_index
, offsetof(CPUX86State
,
3357 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
3358 xmm_regs
[reg
].XMM_L(0)));
3359 gen_op_st_T0_A0(OT_LONG
+ s
->mem_index
);
3362 case 0x6e: /* movd mm, ea */
3363 #ifdef TARGET_X86_64
3364 if (s
->dflag
== 2) {
3365 gen_ldst_modrm(env
, s
, modrm
, OT_QUAD
, OR_TMP0
, 0);
3366 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3370 gen_ldst_modrm(env
, s
, modrm
, OT_LONG
, OR_TMP0
, 0);
3371 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3372 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3373 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3374 gen_helper_movl_mm_T0_mmx(cpu_ptr0
, cpu_tmp2_i32
);
3377 case 0x16e: /* movd xmm, ea */
3378 #ifdef TARGET_X86_64
3379 if (s
->dflag
== 2) {
3380 gen_ldst_modrm(env
, s
, modrm
, OT_QUAD
, OR_TMP0
, 0);
3381 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3382 offsetof(CPUX86State
,xmm_regs
[reg
]));
3383 gen_helper_movq_mm_T0_xmm(cpu_ptr0
, cpu_T
[0]);
3387 gen_ldst_modrm(env
, s
, modrm
, OT_LONG
, OR_TMP0
, 0);
3388 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3389 offsetof(CPUX86State
,xmm_regs
[reg
]));
3390 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3391 gen_helper_movl_mm_T0_xmm(cpu_ptr0
, cpu_tmp2_i32
);
3394 case 0x6f: /* movq mm, ea */
3396 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3397 gen_ldq_env_A0(s
->mem_index
, offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3400 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
3401 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3402 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
3403 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3406 case 0x010: /* movups */
3407 case 0x110: /* movupd */
3408 case 0x028: /* movaps */
3409 case 0x128: /* movapd */
3410 case 0x16f: /* movdqa xmm, ea */
3411 case 0x26f: /* movdqu xmm, ea */
3413 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3414 gen_ldo_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
]));
3416 rm
= (modrm
& 7) | REX_B(s
);
3417 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[reg
]),
3418 offsetof(CPUX86State
,xmm_regs
[rm
]));
3421 case 0x210: /* movss xmm, ea */
3423 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3424 gen_op_ld_T0_A0(OT_LONG
+ s
->mem_index
);
3425 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3427 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(1)));
3428 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)));
3429 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)));
3431 rm
= (modrm
& 7) | REX_B(s
);
3432 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)),
3433 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(0)));
3436 case 0x310: /* movsd xmm, ea */
3438 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3439 gen_ldq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3441 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)));
3442 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)));
3444 rm
= (modrm
& 7) | REX_B(s
);
3445 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3446 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3449 case 0x012: /* movlps */
3450 case 0x112: /* movlpd */
3452 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3453 gen_ldq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3456 rm
= (modrm
& 7) | REX_B(s
);
3457 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3458 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(1)));
3461 case 0x212: /* movsldup */
3463 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3464 gen_ldo_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
]));
3466 rm
= (modrm
& 7) | REX_B(s
);
3467 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)),
3468 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(0)));
3469 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)),
3470 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(2)));
3472 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(1)),
3473 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3474 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)),
3475 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)));
3477 case 0x312: /* movddup */
3479 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3480 gen_ldq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3482 rm
= (modrm
& 7) | REX_B(s
);
3483 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3484 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3486 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)),
3487 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3489 case 0x016: /* movhps */
3490 case 0x116: /* movhpd */
3492 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3493 gen_ldq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)));
3496 rm
= (modrm
& 7) | REX_B(s
);
3497 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)),
3498 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3501 case 0x216: /* movshdup */
3503 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3504 gen_ldo_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
]));
3506 rm
= (modrm
& 7) | REX_B(s
);
3507 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(1)),
3508 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(1)));
3509 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)),
3510 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(3)));
3512 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)),
3513 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(1)));
3514 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)),
3515 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)));
3520 int bit_index
, field_length
;
3522 if (b1
== 1 && reg
!= 0)
3524 field_length
= cpu_ldub_code(env
, s
->pc
++) & 0x3F;
3525 bit_index
= cpu_ldub_code(env
, s
->pc
++) & 0x3F;
3526 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3527 offsetof(CPUX86State
,xmm_regs
[reg
]));
3529 gen_helper_extrq_i(cpu_env
, cpu_ptr0
,
3530 tcg_const_i32(bit_index
),
3531 tcg_const_i32(field_length
));
3533 gen_helper_insertq_i(cpu_env
, cpu_ptr0
,
3534 tcg_const_i32(bit_index
),
3535 tcg_const_i32(field_length
));
3538 case 0x7e: /* movd ea, mm */
3539 #ifdef TARGET_X86_64
3540 if (s
->dflag
== 2) {
3541 tcg_gen_ld_i64(cpu_T
[0], cpu_env
,
3542 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3543 gen_ldst_modrm(env
, s
, modrm
, OT_QUAD
, OR_TMP0
, 1);
3547 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
,
3548 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_L(0)));
3549 gen_ldst_modrm(env
, s
, modrm
, OT_LONG
, OR_TMP0
, 1);
3552 case 0x17e: /* movd ea, xmm */
3553 #ifdef TARGET_X86_64
3554 if (s
->dflag
== 2) {
3555 tcg_gen_ld_i64(cpu_T
[0], cpu_env
,
3556 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3557 gen_ldst_modrm(env
, s
, modrm
, OT_QUAD
, OR_TMP0
, 1);
3561 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
,
3562 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3563 gen_ldst_modrm(env
, s
, modrm
, OT_LONG
, OR_TMP0
, 1);
3566 case 0x27e: /* movq xmm, ea */
3568 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3569 gen_ldq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3571 rm
= (modrm
& 7) | REX_B(s
);
3572 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3573 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3575 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)));
3577 case 0x7f: /* movq ea, mm */
3579 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3580 gen_stq_env_A0(s
->mem_index
, offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3583 gen_op_movq(offsetof(CPUX86State
,fpregs
[rm
].mmx
),
3584 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3587 case 0x011: /* movups */
3588 case 0x111: /* movupd */
3589 case 0x029: /* movaps */
3590 case 0x129: /* movapd */
3591 case 0x17f: /* movdqa ea, xmm */
3592 case 0x27f: /* movdqu ea, xmm */
3594 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3595 gen_sto_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
]));
3597 rm
= (modrm
& 7) | REX_B(s
);
3598 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[rm
]),
3599 offsetof(CPUX86State
,xmm_regs
[reg
]));
3602 case 0x211: /* movss ea, xmm */
3604 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3605 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3606 gen_op_st_T0_A0(OT_LONG
+ s
->mem_index
);
3608 rm
= (modrm
& 7) | REX_B(s
);
3609 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(0)),
3610 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3613 case 0x311: /* movsd ea, xmm */
3615 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3616 gen_stq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3618 rm
= (modrm
& 7) | REX_B(s
);
3619 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)),
3620 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3623 case 0x013: /* movlps */
3624 case 0x113: /* movlpd */
3626 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3627 gen_stq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3632 case 0x017: /* movhps */
3633 case 0x117: /* movhpd */
3635 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3636 gen_stq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)));
3641 case 0x71: /* shift mm, im */
3644 case 0x171: /* shift xmm, im */
3650 val
= cpu_ldub_code(env
, s
->pc
++);
3652 gen_op_movl_T0_im(val
);
3653 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.XMM_L(0)));
3655 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.XMM_L(1)));
3656 op1_offset
= offsetof(CPUX86State
,xmm_t0
);
3658 gen_op_movl_T0_im(val
);
3659 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,mmx_t0
.MMX_L(0)));
3661 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,mmx_t0
.MMX_L(1)));
3662 op1_offset
= offsetof(CPUX86State
,mmx_t0
);
3664 sse_fn_epp
= sse_op_table2
[((b
- 1) & 3) * 8 +
3665 (((modrm
>> 3)) & 7)][b1
];
3670 rm
= (modrm
& 7) | REX_B(s
);
3671 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3674 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3676 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3677 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op1_offset
);
3678 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3680 case 0x050: /* movmskps */
3681 rm
= (modrm
& 7) | REX_B(s
);
3682 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3683 offsetof(CPUX86State
,xmm_regs
[rm
]));
3684 gen_helper_movmskps(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3685 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
3686 gen_op_mov_reg_T0(OT_LONG
, reg
);
3688 case 0x150: /* movmskpd */
3689 rm
= (modrm
& 7) | REX_B(s
);
3690 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3691 offsetof(CPUX86State
,xmm_regs
[rm
]));
3692 gen_helper_movmskpd(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3693 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
3694 gen_op_mov_reg_T0(OT_LONG
, reg
);
3696 case 0x02a: /* cvtpi2ps */
3697 case 0x12a: /* cvtpi2pd */
3698 gen_helper_enter_mmx(cpu_env
);
3700 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3701 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3702 gen_ldq_env_A0(s
->mem_index
, op2_offset
);
3705 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3707 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3708 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3709 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3712 gen_helper_cvtpi2ps(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3716 gen_helper_cvtpi2pd(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3720 case 0x22a: /* cvtsi2ss */
3721 case 0x32a: /* cvtsi2sd */
3722 ot
= (s
->dflag
== 2) ? OT_QUAD
: OT_LONG
;
3723 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3724 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3725 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3726 if (ot
== OT_LONG
) {
3727 SSEFunc_0_epi sse_fn_epi
= sse_op_table3ai
[(b
>> 8) & 1];
3728 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3729 sse_fn_epi(cpu_env
, cpu_ptr0
, cpu_tmp2_i32
);
3731 #ifdef TARGET_X86_64
3732 SSEFunc_0_epl sse_fn_epl
= sse_op_table3aq
[(b
>> 8) & 1];
3733 sse_fn_epl(cpu_env
, cpu_ptr0
, cpu_T
[0]);
3739 case 0x02c: /* cvttps2pi */
3740 case 0x12c: /* cvttpd2pi */
3741 case 0x02d: /* cvtps2pi */
3742 case 0x12d: /* cvtpd2pi */
3743 gen_helper_enter_mmx(cpu_env
);
3745 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3746 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3747 gen_ldo_env_A0(s
->mem_index
, op2_offset
);
3749 rm
= (modrm
& 7) | REX_B(s
);
3750 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3752 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
);
3753 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3754 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3757 gen_helper_cvttps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3760 gen_helper_cvttpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3763 gen_helper_cvtps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3766 gen_helper_cvtpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3770 case 0x22c: /* cvttss2si */
3771 case 0x32c: /* cvttsd2si */
3772 case 0x22d: /* cvtss2si */
3773 case 0x32d: /* cvtsd2si */
3774 ot
= (s
->dflag
== 2) ? OT_QUAD
: OT_LONG
;
3776 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3778 gen_ldq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_t0
.XMM_Q(0)));
3780 gen_op_ld_T0_A0(OT_LONG
+ s
->mem_index
);
3781 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.XMM_L(0)));
3783 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3785 rm
= (modrm
& 7) | REX_B(s
);
3786 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3788 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3789 if (ot
== OT_LONG
) {
3790 SSEFunc_i_ep sse_fn_i_ep
=
3791 sse_op_table3bi
[((b
>> 7) & 2) | (b
& 1)];
3792 sse_fn_i_ep(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3793 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
3795 #ifdef TARGET_X86_64
3796 SSEFunc_l_ep sse_fn_l_ep
=
3797 sse_op_table3bq
[((b
>> 7) & 2) | (b
& 1)];
3798 sse_fn_l_ep(cpu_T
[0], cpu_env
, cpu_ptr0
);
3803 gen_op_mov_reg_T0(ot
, reg
);
3805 case 0xc4: /* pinsrw */
3808 gen_ldst_modrm(env
, s
, modrm
, OT_WORD
, OR_TMP0
, 0);
3809 val
= cpu_ldub_code(env
, s
->pc
++);
3812 tcg_gen_st16_tl(cpu_T
[0], cpu_env
,
3813 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_W(val
)));
3816 tcg_gen_st16_tl(cpu_T
[0], cpu_env
,
3817 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_W(val
)));
3820 case 0xc5: /* pextrw */
3824 ot
= (s
->dflag
== 2) ? OT_QUAD
: OT_LONG
;
3825 val
= cpu_ldub_code(env
, s
->pc
++);
3828 rm
= (modrm
& 7) | REX_B(s
);
3829 tcg_gen_ld16u_tl(cpu_T
[0], cpu_env
,
3830 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_W(val
)));
3834 tcg_gen_ld16u_tl(cpu_T
[0], cpu_env
,
3835 offsetof(CPUX86State
,fpregs
[rm
].mmx
.MMX_W(val
)));
3837 reg
= ((modrm
>> 3) & 7) | rex_r
;
3838 gen_op_mov_reg_T0(ot
, reg
);
3840 case 0x1d6: /* movq ea, xmm */
3842 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3843 gen_stq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3845 rm
= (modrm
& 7) | REX_B(s
);
3846 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)),
3847 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3848 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(1)));
3851 case 0x2d6: /* movq2dq */
3852 gen_helper_enter_mmx(cpu_env
);
3854 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3855 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3856 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)));
3858 case 0x3d6: /* movdq2q */
3859 gen_helper_enter_mmx(cpu_env
);
3860 rm
= (modrm
& 7) | REX_B(s
);
3861 gen_op_movq(offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
),
3862 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3864 case 0xd7: /* pmovmskb */
3869 rm
= (modrm
& 7) | REX_B(s
);
3870 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[rm
]));
3871 gen_helper_pmovmskb_xmm(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3874 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3875 gen_helper_pmovmskb_mmx(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3877 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
3878 reg
= ((modrm
>> 3) & 7) | rex_r
;
3879 gen_op_mov_reg_T0(OT_LONG
, reg
);
3885 if ((b
& 0xf0) == 0xf0) {
3888 modrm
= cpu_ldub_code(env
, s
->pc
++);
3890 reg
= ((modrm
>> 3) & 7) | rex_r
;
3891 mod
= (modrm
>> 6) & 3;
3896 sse_fn_epp
= sse_op_table6
[b
].op
[b1
];
3900 if (!(s
->cpuid_ext_features
& sse_op_table6
[b
].ext_mask
))
3904 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3906 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
3908 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3909 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3911 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3912 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3913 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3914 gen_ldq_env_A0(s
->mem_index
, op2_offset
+
3915 offsetof(XMMReg
, XMM_Q(0)));
3917 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3918 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3919 tcg_gen_qemu_ld32u(cpu_tmp0
, cpu_A0
,
3920 (s
->mem_index
>> 2) - 1);
3921 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_tmp0
);
3922 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, op2_offset
+
3923 offsetof(XMMReg
, XMM_L(0)));
3925 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3926 tcg_gen_qemu_ld16u(cpu_tmp0
, cpu_A0
,
3927 (s
->mem_index
>> 2) - 1);
3928 tcg_gen_st16_tl(cpu_tmp0
, cpu_env
, op2_offset
+
3929 offsetof(XMMReg
, XMM_W(0)));
3931 case 0x2a: /* movntqda */
3932 gen_ldo_env_A0(s
->mem_index
, op1_offset
);
3935 gen_ldo_env_A0(s
->mem_index
, op2_offset
);
3939 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
3941 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3943 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3944 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3945 gen_ldq_env_A0(s
->mem_index
, op2_offset
);
3948 if (sse_fn_epp
== SSE_SPECIAL
) {
3952 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3953 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3954 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3957 set_cc_op(s
, CC_OP_EFLAGS
);
3964 /* Various integer extensions at 0f 38 f[0-f]. */
3965 b
= modrm
| (b1
<< 8);
3966 modrm
= cpu_ldub_code(env
, s
->pc
++);
3967 reg
= ((modrm
>> 3) & 7) | rex_r
;
3970 case 0x3f0: /* crc32 Gd,Eb */
3971 case 0x3f1: /* crc32 Gd,Ey */
3973 if (!(s
->cpuid_ext_features
& CPUID_EXT_SSE42
)) {
3976 if ((b
& 0xff) == 0xf0) {
3978 } else if (s
->dflag
!= 2) {
3979 ot
= (s
->prefix
& PREFIX_DATA
? OT_WORD
: OT_LONG
);
3984 gen_op_mov_TN_reg(OT_LONG
, 0, reg
);
3985 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3986 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3987 gen_helper_crc32(cpu_T
[0], cpu_tmp2_i32
,
3988 cpu_T
[0], tcg_const_i32(8 << ot
));
3990 ot
= (s
->dflag
== 2) ? OT_QUAD
: OT_LONG
;
3991 gen_op_mov_reg_T0(ot
, reg
);
3994 case 0x1f0: /* crc32 or movbe */
3996 /* For these insns, the f3 prefix is supposed to have priority
3997 over the 66 prefix, but that's not what we implement above
3999 if (s
->prefix
& PREFIX_REPNZ
) {
4003 case 0x0f0: /* movbe Gy,My */
4004 case 0x0f1: /* movbe My,Gy */
4005 if (!(s
->cpuid_ext_features
& CPUID_EXT_MOVBE
)) {
4008 if (s
->dflag
!= 2) {
4009 ot
= (s
->prefix
& PREFIX_DATA
? OT_WORD
: OT_LONG
);
4014 /* Load the data incoming to the bswap. Note that the TCG
4015 implementation of bswap requires the input be zero
4016 extended. In the case of the loads, we simply know that
4017 gen_op_ld_v via gen_ldst_modrm does that already. */
4019 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4023 tcg_gen_ext16u_tl(cpu_T
[0], cpu_regs
[reg
]);
4026 tcg_gen_ext32u_tl(cpu_T
[0], cpu_regs
[reg
]);
4029 tcg_gen_mov_tl(cpu_T
[0], cpu_regs
[reg
]);
4036 tcg_gen_bswap16_tl(cpu_T
[0], cpu_T
[0]);
4039 tcg_gen_bswap32_tl(cpu_T
[0], cpu_T
[0]);
4041 #ifdef TARGET_X86_64
4043 tcg_gen_bswap64_tl(cpu_T
[0], cpu_T
[0]);
4049 gen_op_mov_reg_T0(ot
, reg
);
4051 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
4055 case 0x0f2: /* andn Gy, By, Ey */
4056 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
4057 || !(s
->prefix
& PREFIX_VEX
)
4061 ot
= s
->dflag
== 2 ? OT_QUAD
: OT_LONG
;
4062 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4063 tcg_gen_andc_tl(cpu_T
[0], cpu_regs
[s
->vex_v
], cpu_T
[0]);
4064 gen_op_mov_reg_T0(ot
, reg
);
4065 gen_op_update1_cc();
4066 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4069 case 0x0f7: /* bextr Gy, Ey, By */
4070 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
4071 || !(s
->prefix
& PREFIX_VEX
)
4075 ot
= s
->dflag
== 2 ? OT_QUAD
: OT_LONG
;
4079 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4080 /* Extract START, and shift the operand.
4081 Shifts larger than operand size get zeros. */
4082 tcg_gen_ext8u_tl(cpu_A0
, cpu_regs
[s
->vex_v
]);
4083 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], cpu_A0
);
4085 bound
= tcg_const_tl(ot
== OT_QUAD
? 63 : 31);
4086 zero
= tcg_const_tl(0);
4087 tcg_gen_movcond_tl(TCG_COND_LEU
, cpu_T
[0], cpu_A0
, bound
,
4089 tcg_temp_free(zero
);
4091 /* Extract the LEN into a mask. Lengths larger than
4092 operand size get all ones. */
4093 tcg_gen_shri_tl(cpu_A0
, cpu_regs
[s
->vex_v
], 8);
4094 tcg_gen_ext8u_tl(cpu_A0
, cpu_A0
);
4095 tcg_gen_movcond_tl(TCG_COND_LEU
, cpu_A0
, cpu_A0
, bound
,
4097 tcg_temp_free(bound
);
4098 tcg_gen_movi_tl(cpu_T
[1], 1);
4099 tcg_gen_shl_tl(cpu_T
[1], cpu_T
[1], cpu_A0
);
4100 tcg_gen_subi_tl(cpu_T
[1], cpu_T
[1], 1);
4101 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4103 gen_op_mov_reg_T0(ot
, reg
);
4104 gen_op_update1_cc();
4105 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4109 case 0x0f5: /* bzhi Gy, Ey, By */
4110 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4111 || !(s
->prefix
& PREFIX_VEX
)
4115 ot
= s
->dflag
== 2 ? OT_QUAD
: OT_LONG
;
4116 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4117 tcg_gen_ext8u_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
4119 TCGv bound
= tcg_const_tl(ot
== OT_QUAD
? 63 : 31);
4120 /* Note that since we're using BMILG (in order to get O
4121 cleared) we need to store the inverse into C. */
4122 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_cc_src
,
4124 tcg_gen_movcond_tl(TCG_COND_GT
, cpu_T
[1], cpu_T
[1],
4125 bound
, bound
, cpu_T
[1]);
4126 tcg_temp_free(bound
);
4128 tcg_gen_movi_tl(cpu_A0
, -1);
4129 tcg_gen_shl_tl(cpu_A0
, cpu_A0
, cpu_T
[1]);
4130 tcg_gen_andc_tl(cpu_T
[0], cpu_T
[0], cpu_A0
);
4131 gen_op_mov_reg_T0(ot
, reg
);
4132 gen_op_update1_cc();
4133 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4136 case 0x3f6: /* mulx By, Gy, rdx, Ey */
4137 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4138 || !(s
->prefix
& PREFIX_VEX
)
4142 ot
= s
->dflag
== 2 ? OT_QUAD
: OT_LONG
;
4143 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4147 t0
= tcg_temp_new_i64();
4148 t1
= tcg_temp_new_i64();
4149 #ifdef TARGET_X86_64
4150 tcg_gen_ext32u_i64(t0
, cpu_T
[0]);
4151 tcg_gen_ext32u_i64(t1
, cpu_regs
[R_EDX
]);
4153 tcg_gen_extu_i32_i64(t0
, cpu_T
[0]);
4154 tcg_gen_extu_i32_i64(t0
, cpu_regs
[R_EDX
]);
4156 tcg_gen_mul_i64(t0
, t0
, t1
);
4157 tcg_gen_trunc_i64_tl(cpu_T
[0], t0
);
4158 tcg_gen_shri_i64(t0
, t0
, 32);
4159 tcg_gen_trunc_i64_tl(cpu_T
[1], t0
);
4160 tcg_temp_free_i64(t0
);
4161 tcg_temp_free_i64(t1
);
4162 gen_op_mov_reg_T0(OT_LONG
, s
->vex_v
);
4163 gen_op_mov_reg_T1(OT_LONG
, reg
);
4165 #ifdef TARGET_X86_64
4167 tcg_gen_mov_tl(cpu_T
[1], cpu_regs
[R_EDX
]);
4168 tcg_gen_mul_tl(cpu_regs
[s
->vex_v
], cpu_T
[0], cpu_T
[1]);
4169 gen_helper_umulh(cpu_regs
[reg
], cpu_T
[0], cpu_T
[1]);
4175 case 0x3f5: /* pdep Gy, By, Ey */
4176 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4177 || !(s
->prefix
& PREFIX_VEX
)
4181 ot
= s
->dflag
== 2 ? OT_QUAD
: OT_LONG
;
4182 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4183 /* Note that by zero-extending the mask operand, we
4184 automatically handle zero-extending the result. */
4185 if (s
->dflag
== 2) {
4186 tcg_gen_mov_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
4188 tcg_gen_ext32u_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
4190 gen_helper_pdep(cpu_regs
[reg
], cpu_T
[0], cpu_T
[1]);
4193 case 0x2f5: /* pext Gy, By, Ey */
4194 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4195 || !(s
->prefix
& PREFIX_VEX
)
4199 ot
= s
->dflag
== 2 ? OT_QUAD
: OT_LONG
;
4200 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4201 /* Note that by zero-extending the mask operand, we
4202 automatically handle zero-extending the result. */
4203 if (s
->dflag
== 2) {
4204 tcg_gen_mov_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
4206 tcg_gen_ext32u_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
4208 gen_helper_pext(cpu_regs
[reg
], cpu_T
[0], cpu_T
[1]);
4211 case 0x1f6: /* adcx Gy, Ey */
4212 case 0x2f6: /* adox Gy, Ey */
4213 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_ADX
)) {
4216 TCGv carry_in
, carry_out
;
4219 ot
= (s
->dflag
== 2 ? OT_QUAD
: OT_LONG
);
4220 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4222 /* Re-use the carry-out from a previous round. */
4223 TCGV_UNUSED(carry_in
);
4224 carry_out
= (b
== 0x1f6 ? cpu_cc_dst
: cpu_cc_src2
);
4228 carry_in
= cpu_cc_dst
;
4229 end_op
= CC_OP_ADCX
;
4231 end_op
= CC_OP_ADCOX
;
4236 end_op
= CC_OP_ADCOX
;
4238 carry_in
= cpu_cc_src2
;
4239 end_op
= CC_OP_ADOX
;
4243 end_op
= CC_OP_ADCOX
;
4244 carry_in
= carry_out
;
4247 end_op
= (b
== 0x1f6 ? CC_OP_ADCX
: CC_OP_ADCOX
);
4250 /* If we can't reuse carry-out, get it out of EFLAGS. */
4251 if (TCGV_IS_UNUSED(carry_in
)) {
4252 if (s
->cc_op
!= CC_OP_ADCX
&& s
->cc_op
!= CC_OP_ADOX
) {
4253 gen_compute_eflags(s
);
4255 carry_in
= cpu_tmp0
;
4256 tcg_gen_shri_tl(carry_in
, cpu_cc_src
,
4257 ctz32(b
== 0x1f6 ? CC_C
: CC_O
));
4258 tcg_gen_andi_tl(carry_in
, carry_in
, 1);
4262 #ifdef TARGET_X86_64
4264 /* If we know TL is 64-bit, and we want a 32-bit
4265 result, just do everything in 64-bit arithmetic. */
4266 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_regs
[reg
]);
4267 tcg_gen_ext32u_i64(cpu_T
[0], cpu_T
[0]);
4268 tcg_gen_add_i64(cpu_T
[0], cpu_T
[0], cpu_regs
[reg
]);
4269 tcg_gen_add_i64(cpu_T
[0], cpu_T
[0], carry_in
);
4270 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_T
[0]);
4271 tcg_gen_shri_i64(carry_out
, cpu_T
[0], 32);
4275 /* Otherwise compute the carry-out in two steps. */
4276 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_regs
[reg
]);
4277 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_tmp4
,
4278 cpu_T
[0], cpu_regs
[reg
]);
4279 tcg_gen_add_tl(cpu_regs
[reg
], cpu_T
[0], carry_in
);
4280 tcg_gen_setcond_tl(TCG_COND_LTU
, carry_out
,
4281 cpu_regs
[reg
], cpu_T
[0]);
4282 tcg_gen_or_tl(carry_out
, carry_out
, cpu_tmp4
);
4285 /* We began with all flags computed to CC_SRC, and we
4286 have now placed the carry-out in CC_DST. All that
4287 is left is to record the CC_OP. */
4288 set_cc_op(s
, end_op
);
4292 case 0x1f7: /* shlx Gy, Ey, By */
4293 case 0x2f7: /* sarx Gy, Ey, By */
4294 case 0x3f7: /* shrx Gy, Ey, By */
4295 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4296 || !(s
->prefix
& PREFIX_VEX
)
4300 ot
= (s
->dflag
== 2 ? OT_QUAD
: OT_LONG
);
4301 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4302 if (ot
== OT_QUAD
) {
4303 tcg_gen_andi_tl(cpu_T
[1], cpu_regs
[s
->vex_v
], 63);
4305 tcg_gen_andi_tl(cpu_T
[1], cpu_regs
[s
->vex_v
], 31);
4308 tcg_gen_shl_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4309 } else if (b
== 0x2f7) {
4310 if (ot
!= OT_QUAD
) {
4311 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
4313 tcg_gen_sar_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4315 if (ot
!= OT_QUAD
) {
4316 tcg_gen_ext32u_tl(cpu_T
[0], cpu_T
[0]);
4318 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4320 gen_op_mov_reg_T0(ot
, reg
);
4326 case 0x3f3: /* Group 17 */
4327 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
4328 || !(s
->prefix
& PREFIX_VEX
)
4332 ot
= s
->dflag
== 2 ? OT_QUAD
: OT_LONG
;
4333 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4336 case 1: /* blsr By,Ey */
4337 tcg_gen_neg_tl(cpu_T
[1], cpu_T
[0]);
4338 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4339 gen_op_mov_reg_T0(ot
, s
->vex_v
);
4340 gen_op_update2_cc();
4341 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4344 case 2: /* blsmsk By,Ey */
4345 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
4346 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], 1);
4347 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_cc_src
);
4348 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4349 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4352 case 3: /* blsi By, Ey */
4353 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
4354 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], 1);
4355 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_cc_src
);
4356 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4357 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4373 modrm
= cpu_ldub_code(env
, s
->pc
++);
4375 reg
= ((modrm
>> 3) & 7) | rex_r
;
4376 mod
= (modrm
>> 6) & 3;
4381 sse_fn_eppi
= sse_op_table7
[b
].op
[b1
];
4385 if (!(s
->cpuid_ext_features
& sse_op_table7
[b
].ext_mask
))
4388 if (sse_fn_eppi
== SSE_SPECIAL
) {
4389 ot
= (s
->dflag
== 2) ? OT_QUAD
: OT_LONG
;
4390 rm
= (modrm
& 7) | REX_B(s
);
4392 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4393 reg
= ((modrm
>> 3) & 7) | rex_r
;
4394 val
= cpu_ldub_code(env
, s
->pc
++);
4396 case 0x14: /* pextrb */
4397 tcg_gen_ld8u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4398 xmm_regs
[reg
].XMM_B(val
& 15)));
4400 gen_op_mov_reg_T0(ot
, rm
);
4402 tcg_gen_qemu_st8(cpu_T
[0], cpu_A0
,
4403 (s
->mem_index
>> 2) - 1);
4405 case 0x15: /* pextrw */
4406 tcg_gen_ld16u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4407 xmm_regs
[reg
].XMM_W(val
& 7)));
4409 gen_op_mov_reg_T0(ot
, rm
);
4411 tcg_gen_qemu_st16(cpu_T
[0], cpu_A0
,
4412 (s
->mem_index
>> 2) - 1);
4415 if (ot
== OT_LONG
) { /* pextrd */
4416 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4417 offsetof(CPUX86State
,
4418 xmm_regs
[reg
].XMM_L(val
& 3)));
4419 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
4421 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4423 tcg_gen_qemu_st32(cpu_T
[0], cpu_A0
,
4424 (s
->mem_index
>> 2) - 1);
4425 } else { /* pextrq */
4426 #ifdef TARGET_X86_64
4427 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
4428 offsetof(CPUX86State
,
4429 xmm_regs
[reg
].XMM_Q(val
& 1)));
4431 gen_op_mov_reg_v(ot
, rm
, cpu_tmp1_i64
);
4433 tcg_gen_qemu_st64(cpu_tmp1_i64
, cpu_A0
,
4434 (s
->mem_index
>> 2) - 1);
4440 case 0x17: /* extractps */
4441 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4442 xmm_regs
[reg
].XMM_L(val
& 3)));
4444 gen_op_mov_reg_T0(ot
, rm
);
4446 tcg_gen_qemu_st32(cpu_T
[0], cpu_A0
,
4447 (s
->mem_index
>> 2) - 1);
4449 case 0x20: /* pinsrb */
4451 gen_op_mov_TN_reg(OT_LONG
, 0, rm
);
4453 tcg_gen_qemu_ld8u(cpu_tmp0
, cpu_A0
,
4454 (s
->mem_index
>> 2) - 1);
4455 tcg_gen_st8_tl(cpu_tmp0
, cpu_env
, offsetof(CPUX86State
,
4456 xmm_regs
[reg
].XMM_B(val
& 15)));
4458 case 0x21: /* insertps */
4460 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4461 offsetof(CPUX86State
,xmm_regs
[rm
]
4462 .XMM_L((val
>> 6) & 3)));
4464 tcg_gen_qemu_ld32u(cpu_tmp0
, cpu_A0
,
4465 (s
->mem_index
>> 2) - 1);
4466 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_tmp0
);
4468 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4469 offsetof(CPUX86State
,xmm_regs
[reg
]
4470 .XMM_L((val
>> 4) & 3)));
4472 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4473 cpu_env
, offsetof(CPUX86State
,
4474 xmm_regs
[reg
].XMM_L(0)));
4476 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4477 cpu_env
, offsetof(CPUX86State
,
4478 xmm_regs
[reg
].XMM_L(1)));
4480 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4481 cpu_env
, offsetof(CPUX86State
,
4482 xmm_regs
[reg
].XMM_L(2)));
4484 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4485 cpu_env
, offsetof(CPUX86State
,
4486 xmm_regs
[reg
].XMM_L(3)));
4489 if (ot
== OT_LONG
) { /* pinsrd */
4491 gen_op_mov_v_reg(ot
, cpu_tmp0
, rm
);
4493 tcg_gen_qemu_ld32u(cpu_tmp0
, cpu_A0
,
4494 (s
->mem_index
>> 2) - 1);
4495 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_tmp0
);
4496 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4497 offsetof(CPUX86State
,
4498 xmm_regs
[reg
].XMM_L(val
& 3)));
4499 } else { /* pinsrq */
4500 #ifdef TARGET_X86_64
4502 gen_op_mov_v_reg(ot
, cpu_tmp1_i64
, rm
);
4504 tcg_gen_qemu_ld64(cpu_tmp1_i64
, cpu_A0
,
4505 (s
->mem_index
>> 2) - 1);
4506 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
4507 offsetof(CPUX86State
,
4508 xmm_regs
[reg
].XMM_Q(val
& 1)));
4519 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4521 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
4523 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4524 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4525 gen_ldo_env_A0(s
->mem_index
, op2_offset
);
4528 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4530 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4532 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4533 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4534 gen_ldq_env_A0(s
->mem_index
, op2_offset
);
4537 val
= cpu_ldub_code(env
, s
->pc
++);
4539 if ((b
& 0xfc) == 0x60) { /* pcmpXstrX */
4540 set_cc_op(s
, CC_OP_EFLAGS
);
4543 /* The helper must use entire 64-bit gp registers */
4547 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4548 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4549 sse_fn_eppi(cpu_env
, cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4553 /* Various integer extensions at 0f 3a f[0-f]. */
4554 b
= modrm
| (b1
<< 8);
4555 modrm
= cpu_ldub_code(env
, s
->pc
++);
4556 reg
= ((modrm
>> 3) & 7) | rex_r
;
4559 case 0x3f0: /* rorx Gy,Ey, Ib */
4560 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4561 || !(s
->prefix
& PREFIX_VEX
)
4565 ot
= s
->dflag
== 2 ? OT_QUAD
: OT_LONG
;
4566 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4567 b
= cpu_ldub_code(env
, s
->pc
++);
4568 if (ot
== OT_QUAD
) {
4569 tcg_gen_rotri_tl(cpu_T
[0], cpu_T
[0], b
& 63);
4571 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4572 tcg_gen_rotri_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, b
& 31);
4573 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
4575 gen_op_mov_reg_T0(ot
, reg
);
4587 /* generic MMX or SSE operation */
4589 case 0x70: /* pshufx insn */
4590 case 0xc6: /* pshufx insn */
4591 case 0xc2: /* compare insns */
4598 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4600 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4601 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4602 if (b1
>= 2 && ((b
>= 0x50 && b
<= 0x5f && b
!= 0x5b) ||
4604 /* specific case for SSE single instructions */
4607 gen_op_ld_T0_A0(OT_LONG
+ s
->mem_index
);
4608 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.XMM_L(0)));
4611 gen_ldq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_t0
.XMM_D(0)));
4614 gen_ldo_env_A0(s
->mem_index
, op2_offset
);
4617 rm
= (modrm
& 7) | REX_B(s
);
4618 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
4621 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4623 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4624 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4625 gen_ldq_env_A0(s
->mem_index
, op2_offset
);
4628 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4632 case 0x0f: /* 3DNow! data insns */
4633 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
))
4635 val
= cpu_ldub_code(env
, s
->pc
++);
4636 sse_fn_epp
= sse_op_table5
[val
];
4640 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4641 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4642 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4644 case 0x70: /* pshufx insn */
4645 case 0xc6: /* pshufx insn */
4646 val
= cpu_ldub_code(env
, s
->pc
++);
4647 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4648 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4649 /* XXX: introduce a new table? */
4650 sse_fn_ppi
= (SSEFunc_0_ppi
)sse_fn_epp
;
4651 sse_fn_ppi(cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4655 val
= cpu_ldub_code(env
, s
->pc
++);
4658 sse_fn_epp
= sse_op_table4
[val
][b1
];
4660 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4661 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4662 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4665 /* maskmov : we must prepare A0 */
4668 #ifdef TARGET_X86_64
4669 if (s
->aflag
== 2) {
4670 gen_op_movq_A0_reg(R_EDI
);
4674 gen_op_movl_A0_reg(R_EDI
);
4676 gen_op_andl_A0_ffff();
4678 gen_add_A0_ds_seg(s
);
4680 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4681 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4682 /* XXX: introduce a new table? */
4683 sse_fn_eppt
= (SSEFunc_0_eppt
)sse_fn_epp
;
4684 sse_fn_eppt(cpu_env
, cpu_ptr0
, cpu_ptr1
, cpu_A0
);
4687 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4688 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4689 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4692 if (b
== 0x2e || b
== 0x2f) {
4693 set_cc_op(s
, CC_OP_EFLAGS
);
4698 /* convert one instruction. s->is_jmp is set if the translation must
4699 be stopped. Return the next pc value */
4700 static target_ulong
disas_insn(CPUX86State
*env
, DisasContext
*s
,
4701 target_ulong pc_start
)
4703 int b
, prefixes
, aflag
, dflag
;
4705 int modrm
, reg
, rm
, mod
, reg_addr
, op
, opreg
, offset_addr
, val
;
4706 target_ulong next_eip
, tval
;
4709 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
4710 tcg_gen_debug_insn_start(pc_start
);
4719 #ifdef TARGET_X86_64
4724 s
->rip_offset
= 0; /* for relative ip address */
4728 b
= cpu_ldub_code(env
, s
->pc
);
4730 /* Collect prefixes. */
4733 prefixes
|= PREFIX_REPZ
;
4736 prefixes
|= PREFIX_REPNZ
;
4739 prefixes
|= PREFIX_LOCK
;
4760 prefixes
|= PREFIX_DATA
;
4763 prefixes
|= PREFIX_ADR
;
4765 #ifdef TARGET_X86_64
4769 rex_w
= (b
>> 3) & 1;
4770 rex_r
= (b
& 0x4) << 1;
4771 s
->rex_x
= (b
& 0x2) << 2;
4772 REX_B(s
) = (b
& 0x1) << 3;
4773 x86_64_hregs
= 1; /* select uniform byte register addressing */
4778 case 0xc5: /* 2-byte VEX */
4779 case 0xc4: /* 3-byte VEX */
4780 /* VEX prefixes cannot be used except in 32-bit mode.
4781 Otherwise the instruction is LES or LDS. */
4782 if (s
->code32
&& !s
->vm86
) {
4783 static const int pp_prefix
[4] = {
4784 0, PREFIX_DATA
, PREFIX_REPZ
, PREFIX_REPNZ
4786 int vex3
, vex2
= cpu_ldub_code(env
, s
->pc
);
4788 if (!CODE64(s
) && (vex2
& 0xc0) != 0xc0) {
4789 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4790 otherwise the instruction is LES or LDS. */
4795 /* 4.1.1-4.1.3: No preceeding lock, 66, f2, f3, or rex prefixes. */
4796 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
4797 | PREFIX_LOCK
| PREFIX_DATA
)) {
4800 #ifdef TARGET_X86_64
4805 rex_r
= (~vex2
>> 4) & 8;
4808 b
= cpu_ldub_code(env
, s
->pc
++);
4810 #ifdef TARGET_X86_64
4811 s
->rex_x
= (~vex2
>> 3) & 8;
4812 s
->rex_b
= (~vex2
>> 2) & 8;
4814 vex3
= cpu_ldub_code(env
, s
->pc
++);
4815 rex_w
= (vex3
>> 7) & 1;
4816 switch (vex2
& 0x1f) {
4817 case 0x01: /* Implied 0f leading opcode bytes. */
4818 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4820 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4823 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4826 default: /* Reserved for future use. */
4830 s
->vex_v
= (~vex3
>> 3) & 0xf;
4831 s
->vex_l
= (vex3
>> 2) & 1;
4832 prefixes
|= pp_prefix
[vex3
& 3] | PREFIX_VEX
;
4837 /* Post-process prefixes. */
4838 if (prefixes
& PREFIX_DATA
) {
4841 if (prefixes
& PREFIX_ADR
) {
4844 #ifdef TARGET_X86_64
4847 /* 0x66 is ignored if rex.w is set */
4850 if (!(prefixes
& PREFIX_ADR
)) {
4856 s
->prefix
= prefixes
;
4860 /* lock generation */
4861 if (prefixes
& PREFIX_LOCK
)
4864 /* now check op code */
4868 /**************************/
4869 /* extended op code */
4870 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4873 /**************************/
4891 ot
= dflag
+ OT_WORD
;
4894 case 0: /* OP Ev, Gv */
4895 modrm
= cpu_ldub_code(env
, s
->pc
++);
4896 reg
= ((modrm
>> 3) & 7) | rex_r
;
4897 mod
= (modrm
>> 6) & 3;
4898 rm
= (modrm
& 7) | REX_B(s
);
4900 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4902 } else if (op
== OP_XORL
&& rm
== reg
) {
4904 /* xor reg, reg optimisation */
4905 set_cc_op(s
, CC_OP_CLR
);
4907 gen_op_mov_reg_T0(ot
, reg
);
4912 gen_op_mov_TN_reg(ot
, 1, reg
);
4913 gen_op(s
, op
, ot
, opreg
);
4915 case 1: /* OP Gv, Ev */
4916 modrm
= cpu_ldub_code(env
, s
->pc
++);
4917 mod
= (modrm
>> 6) & 3;
4918 reg
= ((modrm
>> 3) & 7) | rex_r
;
4919 rm
= (modrm
& 7) | REX_B(s
);
4921 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4922 gen_op_ld_T1_A0(ot
+ s
->mem_index
);
4923 } else if (op
== OP_XORL
&& rm
== reg
) {
4926 gen_op_mov_TN_reg(ot
, 1, rm
);
4928 gen_op(s
, op
, ot
, reg
);
4930 case 2: /* OP A, Iv */
4931 val
= insn_get(env
, s
, ot
);
4932 gen_op_movl_T1_im(val
);
4933 gen_op(s
, op
, ot
, OR_EAX
);
4942 case 0x80: /* GRP1 */
4951 ot
= dflag
+ OT_WORD
;
4953 modrm
= cpu_ldub_code(env
, s
->pc
++);
4954 mod
= (modrm
>> 6) & 3;
4955 rm
= (modrm
& 7) | REX_B(s
);
4956 op
= (modrm
>> 3) & 7;
4962 s
->rip_offset
= insn_const_size(ot
);
4963 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4974 val
= insn_get(env
, s
, ot
);
4977 val
= (int8_t)insn_get(env
, s
, OT_BYTE
);
4980 gen_op_movl_T1_im(val
);
4981 gen_op(s
, op
, ot
, opreg
);
4985 /**************************/
4986 /* inc, dec, and other misc arith */
4987 case 0x40 ... 0x47: /* inc Gv */
4988 ot
= dflag
? OT_LONG
: OT_WORD
;
4989 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), 1);
4991 case 0x48 ... 0x4f: /* dec Gv */
4992 ot
= dflag
? OT_LONG
: OT_WORD
;
4993 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), -1);
4995 case 0xf6: /* GRP3 */
5000 ot
= dflag
+ OT_WORD
;
5002 modrm
= cpu_ldub_code(env
, s
->pc
++);
5003 mod
= (modrm
>> 6) & 3;
5004 rm
= (modrm
& 7) | REX_B(s
);
5005 op
= (modrm
>> 3) & 7;
5008 s
->rip_offset
= insn_const_size(ot
);
5009 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5010 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
5012 gen_op_mov_TN_reg(ot
, 0, rm
);
5017 val
= insn_get(env
, s
, ot
);
5018 gen_op_movl_T1_im(val
);
5019 gen_op_testl_T0_T1_cc();
5020 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5023 tcg_gen_not_tl(cpu_T
[0], cpu_T
[0]);
5025 gen_op_st_T0_A0(ot
+ s
->mem_index
);
5027 gen_op_mov_reg_T0(ot
, rm
);
5031 tcg_gen_neg_tl(cpu_T
[0], cpu_T
[0]);
5033 gen_op_st_T0_A0(ot
+ s
->mem_index
);
5035 gen_op_mov_reg_T0(ot
, rm
);
5037 gen_op_update_neg_cc();
5038 set_cc_op(s
, CC_OP_SUBB
+ ot
);
5043 gen_op_mov_TN_reg(OT_BYTE
, 1, R_EAX
);
5044 tcg_gen_ext8u_tl(cpu_T
[0], cpu_T
[0]);
5045 tcg_gen_ext8u_tl(cpu_T
[1], cpu_T
[1]);
5046 /* XXX: use 32 bit mul which could be faster */
5047 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5048 gen_op_mov_reg_T0(OT_WORD
, R_EAX
);
5049 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5050 tcg_gen_andi_tl(cpu_cc_src
, cpu_T
[0], 0xff00);
5051 set_cc_op(s
, CC_OP_MULB
);
5054 gen_op_mov_TN_reg(OT_WORD
, 1, R_EAX
);
5055 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
5056 tcg_gen_ext16u_tl(cpu_T
[1], cpu_T
[1]);
5057 /* XXX: use 32 bit mul which could be faster */
5058 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5059 gen_op_mov_reg_T0(OT_WORD
, R_EAX
);
5060 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5061 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], 16);
5062 gen_op_mov_reg_T0(OT_WORD
, R_EDX
);
5063 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
5064 set_cc_op(s
, CC_OP_MULW
);
5068 #ifdef TARGET_X86_64
5069 gen_op_mov_TN_reg(OT_LONG
, 1, R_EAX
);
5070 tcg_gen_ext32u_tl(cpu_T
[0], cpu_T
[0]);
5071 tcg_gen_ext32u_tl(cpu_T
[1], cpu_T
[1]);
5072 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5073 gen_op_mov_reg_T0(OT_LONG
, R_EAX
);
5074 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5075 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], 32);
5076 gen_op_mov_reg_T0(OT_LONG
, R_EDX
);
5077 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
5081 t0
= tcg_temp_new_i64();
5082 t1
= tcg_temp_new_i64();
5083 gen_op_mov_TN_reg(OT_LONG
, 1, R_EAX
);
5084 tcg_gen_extu_i32_i64(t0
, cpu_T
[0]);
5085 tcg_gen_extu_i32_i64(t1
, cpu_T
[1]);
5086 tcg_gen_mul_i64(t0
, t0
, t1
);
5087 tcg_gen_trunc_i64_i32(cpu_T
[0], t0
);
5088 gen_op_mov_reg_T0(OT_LONG
, R_EAX
);
5089 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5090 tcg_gen_shri_i64(t0
, t0
, 32);
5091 tcg_gen_trunc_i64_i32(cpu_T
[0], t0
);
5092 gen_op_mov_reg_T0(OT_LONG
, R_EDX
);
5093 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
5096 set_cc_op(s
, CC_OP_MULL
);
5098 #ifdef TARGET_X86_64
5100 gen_helper_mulq_EAX_T0(cpu_env
, cpu_T
[0]);
5101 set_cc_op(s
, CC_OP_MULQ
);
5109 gen_op_mov_TN_reg(OT_BYTE
, 1, R_EAX
);
5110 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
5111 tcg_gen_ext8s_tl(cpu_T
[1], cpu_T
[1]);
5112 /* XXX: use 32 bit mul which could be faster */
5113 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5114 gen_op_mov_reg_T0(OT_WORD
, R_EAX
);
5115 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5116 tcg_gen_ext8s_tl(cpu_tmp0
, cpu_T
[0]);
5117 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
5118 set_cc_op(s
, CC_OP_MULB
);
5121 gen_op_mov_TN_reg(OT_WORD
, 1, R_EAX
);
5122 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5123 tcg_gen_ext16s_tl(cpu_T
[1], cpu_T
[1]);
5124 /* XXX: use 32 bit mul which could be faster */
5125 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5126 gen_op_mov_reg_T0(OT_WORD
, R_EAX
);
5127 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5128 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T
[0]);
5129 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
5130 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], 16);
5131 gen_op_mov_reg_T0(OT_WORD
, R_EDX
);
5132 set_cc_op(s
, CC_OP_MULW
);
5136 #ifdef TARGET_X86_64
5137 gen_op_mov_TN_reg(OT_LONG
, 1, R_EAX
);
5138 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
5139 tcg_gen_ext32s_tl(cpu_T
[1], cpu_T
[1]);
5140 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5141 gen_op_mov_reg_T0(OT_LONG
, R_EAX
);
5142 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5143 tcg_gen_ext32s_tl(cpu_tmp0
, cpu_T
[0]);
5144 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
5145 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], 32);
5146 gen_op_mov_reg_T0(OT_LONG
, R_EDX
);
5150 t0
= tcg_temp_new_i64();
5151 t1
= tcg_temp_new_i64();
5152 gen_op_mov_TN_reg(OT_LONG
, 1, R_EAX
);
5153 tcg_gen_ext_i32_i64(t0
, cpu_T
[0]);
5154 tcg_gen_ext_i32_i64(t1
, cpu_T
[1]);
5155 tcg_gen_mul_i64(t0
, t0
, t1
);
5156 tcg_gen_trunc_i64_i32(cpu_T
[0], t0
);
5157 gen_op_mov_reg_T0(OT_LONG
, R_EAX
);
5158 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5159 tcg_gen_sari_tl(cpu_tmp0
, cpu_T
[0], 31);
5160 tcg_gen_shri_i64(t0
, t0
, 32);
5161 tcg_gen_trunc_i64_i32(cpu_T
[0], t0
);
5162 gen_op_mov_reg_T0(OT_LONG
, R_EDX
);
5163 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
5166 set_cc_op(s
, CC_OP_MULL
);
5168 #ifdef TARGET_X86_64
5170 gen_helper_imulq_EAX_T0(cpu_env
, cpu_T
[0]);
5171 set_cc_op(s
, CC_OP_MULQ
);
5179 gen_jmp_im(pc_start
- s
->cs_base
);
5180 gen_helper_divb_AL(cpu_env
, cpu_T
[0]);
5183 gen_jmp_im(pc_start
- s
->cs_base
);
5184 gen_helper_divw_AX(cpu_env
, cpu_T
[0]);
5188 gen_jmp_im(pc_start
- s
->cs_base
);
5189 gen_helper_divl_EAX(cpu_env
, cpu_T
[0]);
5191 #ifdef TARGET_X86_64
5193 gen_jmp_im(pc_start
- s
->cs_base
);
5194 gen_helper_divq_EAX(cpu_env
, cpu_T
[0]);
5202 gen_jmp_im(pc_start
- s
->cs_base
);
5203 gen_helper_idivb_AL(cpu_env
, cpu_T
[0]);
5206 gen_jmp_im(pc_start
- s
->cs_base
);
5207 gen_helper_idivw_AX(cpu_env
, cpu_T
[0]);
5211 gen_jmp_im(pc_start
- s
->cs_base
);
5212 gen_helper_idivl_EAX(cpu_env
, cpu_T
[0]);
5214 #ifdef TARGET_X86_64
5216 gen_jmp_im(pc_start
- s
->cs_base
);
5217 gen_helper_idivq_EAX(cpu_env
, cpu_T
[0]);
5227 case 0xfe: /* GRP4 */
5228 case 0xff: /* GRP5 */
5232 ot
= dflag
+ OT_WORD
;
5234 modrm
= cpu_ldub_code(env
, s
->pc
++);
5235 mod
= (modrm
>> 6) & 3;
5236 rm
= (modrm
& 7) | REX_B(s
);
5237 op
= (modrm
>> 3) & 7;
5238 if (op
>= 2 && b
== 0xfe) {
5242 if (op
== 2 || op
== 4) {
5243 /* operand size for jumps is 64 bit */
5245 } else if (op
== 3 || op
== 5) {
5246 ot
= dflag
? OT_LONG
+ (rex_w
== 1) : OT_WORD
;
5247 } else if (op
== 6) {
5248 /* default push size is 64 bit */
5249 ot
= dflag
? OT_QUAD
: OT_WORD
;
5253 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5254 if (op
>= 2 && op
!= 3 && op
!= 5)
5255 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
5257 gen_op_mov_TN_reg(ot
, 0, rm
);
5261 case 0: /* inc Ev */
5266 gen_inc(s
, ot
, opreg
, 1);
5268 case 1: /* dec Ev */
5273 gen_inc(s
, ot
, opreg
, -1);
5275 case 2: /* call Ev */
5276 /* XXX: optimize if memory (no 'and' is necessary) */
5278 gen_op_andl_T0_ffff();
5279 next_eip
= s
->pc
- s
->cs_base
;
5280 gen_movtl_T1_im(next_eip
);
5285 case 3: /* lcall Ev */
5286 gen_op_ld_T1_A0(ot
+ s
->mem_index
);
5287 gen_add_A0_im(s
, 1 << (ot
- OT_WORD
+ 1));
5288 gen_op_ldu_T0_A0(OT_WORD
+ s
->mem_index
);
5290 if (s
->pe
&& !s
->vm86
) {
5291 gen_update_cc_op(s
);
5292 gen_jmp_im(pc_start
- s
->cs_base
);
5293 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5294 gen_helper_lcall_protected(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
5295 tcg_const_i32(dflag
),
5296 tcg_const_i32(s
->pc
- pc_start
));
5298 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5299 gen_helper_lcall_real(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
5300 tcg_const_i32(dflag
),
5301 tcg_const_i32(s
->pc
- s
->cs_base
));
5305 case 4: /* jmp Ev */
5307 gen_op_andl_T0_ffff();
5311 case 5: /* ljmp Ev */
5312 gen_op_ld_T1_A0(ot
+ s
->mem_index
);
5313 gen_add_A0_im(s
, 1 << (ot
- OT_WORD
+ 1));
5314 gen_op_ldu_T0_A0(OT_WORD
+ s
->mem_index
);
5316 if (s
->pe
&& !s
->vm86
) {
5317 gen_update_cc_op(s
);
5318 gen_jmp_im(pc_start
- s
->cs_base
);
5319 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5320 gen_helper_ljmp_protected(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
5321 tcg_const_i32(s
->pc
- pc_start
));
5323 gen_op_movl_seg_T0_vm(R_CS
);
5324 gen_op_movl_T0_T1();
5329 case 6: /* push Ev */
5337 case 0x84: /* test Ev, Gv */
5342 ot
= dflag
+ OT_WORD
;
5344 modrm
= cpu_ldub_code(env
, s
->pc
++);
5345 reg
= ((modrm
>> 3) & 7) | rex_r
;
5347 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5348 gen_op_mov_TN_reg(ot
, 1, reg
);
5349 gen_op_testl_T0_T1_cc();
5350 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5353 case 0xa8: /* test eAX, Iv */
5358 ot
= dflag
+ OT_WORD
;
5359 val
= insn_get(env
, s
, ot
);
5361 gen_op_mov_TN_reg(ot
, 0, OR_EAX
);
5362 gen_op_movl_T1_im(val
);
5363 gen_op_testl_T0_T1_cc();
5364 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5367 case 0x98: /* CWDE/CBW */
5368 #ifdef TARGET_X86_64
5370 gen_op_mov_TN_reg(OT_LONG
, 0, R_EAX
);
5371 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
5372 gen_op_mov_reg_T0(OT_QUAD
, R_EAX
);
5376 gen_op_mov_TN_reg(OT_WORD
, 0, R_EAX
);
5377 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5378 gen_op_mov_reg_T0(OT_LONG
, R_EAX
);
5380 gen_op_mov_TN_reg(OT_BYTE
, 0, R_EAX
);
5381 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
5382 gen_op_mov_reg_T0(OT_WORD
, R_EAX
);
5385 case 0x99: /* CDQ/CWD */
5386 #ifdef TARGET_X86_64
5388 gen_op_mov_TN_reg(OT_QUAD
, 0, R_EAX
);
5389 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 63);
5390 gen_op_mov_reg_T0(OT_QUAD
, R_EDX
);
5394 gen_op_mov_TN_reg(OT_LONG
, 0, R_EAX
);
5395 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
5396 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 31);
5397 gen_op_mov_reg_T0(OT_LONG
, R_EDX
);
5399 gen_op_mov_TN_reg(OT_WORD
, 0, R_EAX
);
5400 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5401 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 15);
5402 gen_op_mov_reg_T0(OT_WORD
, R_EDX
);
5405 case 0x1af: /* imul Gv, Ev */
5406 case 0x69: /* imul Gv, Ev, I */
5408 ot
= dflag
+ OT_WORD
;
5409 modrm
= cpu_ldub_code(env
, s
->pc
++);
5410 reg
= ((modrm
>> 3) & 7) | rex_r
;
5412 s
->rip_offset
= insn_const_size(ot
);
5415 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5417 val
= insn_get(env
, s
, ot
);
5418 gen_op_movl_T1_im(val
);
5419 } else if (b
== 0x6b) {
5420 val
= (int8_t)insn_get(env
, s
, OT_BYTE
);
5421 gen_op_movl_T1_im(val
);
5423 gen_op_mov_TN_reg(ot
, 1, reg
);
5426 #ifdef TARGET_X86_64
5427 if (ot
== OT_QUAD
) {
5428 gen_helper_imulq_T0_T1(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
5431 if (ot
== OT_LONG
) {
5432 #ifdef TARGET_X86_64
5433 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
5434 tcg_gen_ext32s_tl(cpu_T
[1], cpu_T
[1]);
5435 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5436 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5437 tcg_gen_ext32s_tl(cpu_tmp0
, cpu_T
[0]);
5438 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
5442 t0
= tcg_temp_new_i64();
5443 t1
= tcg_temp_new_i64();
5444 tcg_gen_ext_i32_i64(t0
, cpu_T
[0]);
5445 tcg_gen_ext_i32_i64(t1
, cpu_T
[1]);
5446 tcg_gen_mul_i64(t0
, t0
, t1
);
5447 tcg_gen_trunc_i64_i32(cpu_T
[0], t0
);
5448 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5449 tcg_gen_sari_tl(cpu_tmp0
, cpu_T
[0], 31);
5450 tcg_gen_shri_i64(t0
, t0
, 32);
5451 tcg_gen_trunc_i64_i32(cpu_T
[1], t0
);
5452 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[1], cpu_tmp0
);
5456 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5457 tcg_gen_ext16s_tl(cpu_T
[1], cpu_T
[1]);
5458 /* XXX: use 32 bit mul which could be faster */
5459 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5460 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5461 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T
[0]);
5462 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
5464 gen_op_mov_reg_T0(ot
, reg
);
5465 set_cc_op(s
, CC_OP_MULB
+ ot
);
5468 case 0x1c1: /* xadd Ev, Gv */
5472 ot
= dflag
+ OT_WORD
;
5473 modrm
= cpu_ldub_code(env
, s
->pc
++);
5474 reg
= ((modrm
>> 3) & 7) | rex_r
;
5475 mod
= (modrm
>> 6) & 3;
5477 rm
= (modrm
& 7) | REX_B(s
);
5478 gen_op_mov_TN_reg(ot
, 0, reg
);
5479 gen_op_mov_TN_reg(ot
, 1, rm
);
5480 gen_op_addl_T0_T1();
5481 gen_op_mov_reg_T1(ot
, reg
);
5482 gen_op_mov_reg_T0(ot
, rm
);
5484 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5485 gen_op_mov_TN_reg(ot
, 0, reg
);
5486 gen_op_ld_T1_A0(ot
+ s
->mem_index
);
5487 gen_op_addl_T0_T1();
5488 gen_op_st_T0_A0(ot
+ s
->mem_index
);
5489 gen_op_mov_reg_T1(ot
, reg
);
5491 gen_op_update2_cc();
5492 set_cc_op(s
, CC_OP_ADDB
+ ot
);
5495 case 0x1b1: /* cmpxchg Ev, Gv */
5498 TCGv t0
, t1
, t2
, a0
;
5503 ot
= dflag
+ OT_WORD
;
5504 modrm
= cpu_ldub_code(env
, s
->pc
++);
5505 reg
= ((modrm
>> 3) & 7) | rex_r
;
5506 mod
= (modrm
>> 6) & 3;
5507 t0
= tcg_temp_local_new();
5508 t1
= tcg_temp_local_new();
5509 t2
= tcg_temp_local_new();
5510 a0
= tcg_temp_local_new();
5511 gen_op_mov_v_reg(ot
, t1
, reg
);
5513 rm
= (modrm
& 7) | REX_B(s
);
5514 gen_op_mov_v_reg(ot
, t0
, rm
);
5516 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5517 tcg_gen_mov_tl(a0
, cpu_A0
);
5518 gen_op_ld_v(ot
+ s
->mem_index
, t0
, a0
);
5519 rm
= 0; /* avoid warning */
5521 label1
= gen_new_label();
5522 tcg_gen_mov_tl(t2
, cpu_regs
[R_EAX
]);
5525 tcg_gen_brcond_tl(TCG_COND_EQ
, t2
, t0
, label1
);
5526 label2
= gen_new_label();
5528 gen_op_mov_reg_v(ot
, R_EAX
, t0
);
5530 gen_set_label(label1
);
5531 gen_op_mov_reg_v(ot
, rm
, t1
);
5533 /* perform no-op store cycle like physical cpu; must be
5534 before changing accumulator to ensure idempotency if
5535 the store faults and the instruction is restarted */
5536 gen_op_st_v(ot
+ s
->mem_index
, t0
, a0
);
5537 gen_op_mov_reg_v(ot
, R_EAX
, t0
);
5539 gen_set_label(label1
);
5540 gen_op_st_v(ot
+ s
->mem_index
, t1
, a0
);
5542 gen_set_label(label2
);
5543 tcg_gen_mov_tl(cpu_cc_src
, t0
);
5544 tcg_gen_mov_tl(cpu_cc_srcT
, t2
);
5545 tcg_gen_sub_tl(cpu_cc_dst
, t2
, t0
);
5546 set_cc_op(s
, CC_OP_SUBB
+ ot
);
5553 case 0x1c7: /* cmpxchg8b */
5554 modrm
= cpu_ldub_code(env
, s
->pc
++);
5555 mod
= (modrm
>> 6) & 3;
5556 if ((mod
== 3) || ((modrm
& 0x38) != 0x8))
5558 #ifdef TARGET_X86_64
5560 if (!(s
->cpuid_ext_features
& CPUID_EXT_CX16
))
5562 gen_jmp_im(pc_start
- s
->cs_base
);
5563 gen_update_cc_op(s
);
5564 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5565 gen_helper_cmpxchg16b(cpu_env
, cpu_A0
);
5569 if (!(s
->cpuid_features
& CPUID_CX8
))
5571 gen_jmp_im(pc_start
- s
->cs_base
);
5572 gen_update_cc_op(s
);
5573 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5574 gen_helper_cmpxchg8b(cpu_env
, cpu_A0
);
5576 set_cc_op(s
, CC_OP_EFLAGS
);
5579 /**************************/
5581 case 0x50 ... 0x57: /* push */
5582 gen_op_mov_TN_reg(OT_LONG
, 0, (b
& 7) | REX_B(s
));
5585 case 0x58 ... 0x5f: /* pop */
5587 ot
= dflag
? OT_QUAD
: OT_WORD
;
5589 ot
= dflag
+ OT_WORD
;
5592 /* NOTE: order is important for pop %sp */
5594 gen_op_mov_reg_T0(ot
, (b
& 7) | REX_B(s
));
5596 case 0x60: /* pusha */
5601 case 0x61: /* popa */
5606 case 0x68: /* push Iv */
5609 ot
= dflag
? OT_QUAD
: OT_WORD
;
5611 ot
= dflag
+ OT_WORD
;
5614 val
= insn_get(env
, s
, ot
);
5616 val
= (int8_t)insn_get(env
, s
, OT_BYTE
);
5617 gen_op_movl_T0_im(val
);
5620 case 0x8f: /* pop Ev */
5622 ot
= dflag
? OT_QUAD
: OT_WORD
;
5624 ot
= dflag
+ OT_WORD
;
5626 modrm
= cpu_ldub_code(env
, s
->pc
++);
5627 mod
= (modrm
>> 6) & 3;
5630 /* NOTE: order is important for pop %sp */
5632 rm
= (modrm
& 7) | REX_B(s
);
5633 gen_op_mov_reg_T0(ot
, rm
);
5635 /* NOTE: order is important too for MMU exceptions */
5636 s
->popl_esp_hack
= 1 << ot
;
5637 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5638 s
->popl_esp_hack
= 0;
5642 case 0xc8: /* enter */
5645 val
= cpu_lduw_code(env
, s
->pc
);
5647 level
= cpu_ldub_code(env
, s
->pc
++);
5648 gen_enter(s
, val
, level
);
5651 case 0xc9: /* leave */
5652 /* XXX: exception not precise (ESP is updated before potential exception) */
5654 gen_op_mov_TN_reg(OT_QUAD
, 0, R_EBP
);
5655 gen_op_mov_reg_T0(OT_QUAD
, R_ESP
);
5656 } else if (s
->ss32
) {
5657 gen_op_mov_TN_reg(OT_LONG
, 0, R_EBP
);
5658 gen_op_mov_reg_T0(OT_LONG
, R_ESP
);
5660 gen_op_mov_TN_reg(OT_WORD
, 0, R_EBP
);
5661 gen_op_mov_reg_T0(OT_WORD
, R_ESP
);
5665 ot
= dflag
? OT_QUAD
: OT_WORD
;
5667 ot
= dflag
+ OT_WORD
;
5669 gen_op_mov_reg_T0(ot
, R_EBP
);
5672 case 0x06: /* push es */
5673 case 0x0e: /* push cs */
5674 case 0x16: /* push ss */
5675 case 0x1e: /* push ds */
5678 gen_op_movl_T0_seg(b
>> 3);
5681 case 0x1a0: /* push fs */
5682 case 0x1a8: /* push gs */
5683 gen_op_movl_T0_seg((b
>> 3) & 7);
5686 case 0x07: /* pop es */
5687 case 0x17: /* pop ss */
5688 case 0x1f: /* pop ds */
5693 gen_movl_seg_T0(s
, reg
, pc_start
- s
->cs_base
);
5696 /* if reg == SS, inhibit interrupts/trace. */
5697 /* If several instructions disable interrupts, only the
5699 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
5700 gen_helper_set_inhibit_irq(cpu_env
);
5704 gen_jmp_im(s
->pc
- s
->cs_base
);
5708 case 0x1a1: /* pop fs */
5709 case 0x1a9: /* pop gs */
5711 gen_movl_seg_T0(s
, (b
>> 3) & 7, pc_start
- s
->cs_base
);
5714 gen_jmp_im(s
->pc
- s
->cs_base
);
5719 /**************************/
5722 case 0x89: /* mov Gv, Ev */
5726 ot
= dflag
+ OT_WORD
;
5727 modrm
= cpu_ldub_code(env
, s
->pc
++);
5728 reg
= ((modrm
>> 3) & 7) | rex_r
;
5730 /* generate a generic store */
5731 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
5734 case 0xc7: /* mov Ev, Iv */
5738 ot
= dflag
+ OT_WORD
;
5739 modrm
= cpu_ldub_code(env
, s
->pc
++);
5740 mod
= (modrm
>> 6) & 3;
5742 s
->rip_offset
= insn_const_size(ot
);
5743 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5745 val
= insn_get(env
, s
, ot
);
5746 gen_op_movl_T0_im(val
);
5748 gen_op_st_T0_A0(ot
+ s
->mem_index
);
5750 gen_op_mov_reg_T0(ot
, (modrm
& 7) | REX_B(s
));
5753 case 0x8b: /* mov Ev, Gv */
5757 ot
= OT_WORD
+ dflag
;
5758 modrm
= cpu_ldub_code(env
, s
->pc
++);
5759 reg
= ((modrm
>> 3) & 7) | rex_r
;
5761 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5762 gen_op_mov_reg_T0(ot
, reg
);
5764 case 0x8e: /* mov seg, Gv */
5765 modrm
= cpu_ldub_code(env
, s
->pc
++);
5766 reg
= (modrm
>> 3) & 7;
5767 if (reg
>= 6 || reg
== R_CS
)
5769 gen_ldst_modrm(env
, s
, modrm
, OT_WORD
, OR_TMP0
, 0);
5770 gen_movl_seg_T0(s
, reg
, pc_start
- s
->cs_base
);
5772 /* if reg == SS, inhibit interrupts/trace */
5773 /* If several instructions disable interrupts, only the
5775 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
5776 gen_helper_set_inhibit_irq(cpu_env
);
5780 gen_jmp_im(s
->pc
- s
->cs_base
);
5784 case 0x8c: /* mov Gv, seg */
5785 modrm
= cpu_ldub_code(env
, s
->pc
++);
5786 reg
= (modrm
>> 3) & 7;
5787 mod
= (modrm
>> 6) & 3;
5790 gen_op_movl_T0_seg(reg
);
5792 ot
= OT_WORD
+ dflag
;
5795 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5798 case 0x1b6: /* movzbS Gv, Eb */
5799 case 0x1b7: /* movzwS Gv, Eb */
5800 case 0x1be: /* movsbS Gv, Eb */
5801 case 0x1bf: /* movswS Gv, Eb */
5804 /* d_ot is the size of destination */
5805 d_ot
= dflag
+ OT_WORD
;
5806 /* ot is the size of source */
5807 ot
= (b
& 1) + OT_BYTE
;
5808 modrm
= cpu_ldub_code(env
, s
->pc
++);
5809 reg
= ((modrm
>> 3) & 7) | rex_r
;
5810 mod
= (modrm
>> 6) & 3;
5811 rm
= (modrm
& 7) | REX_B(s
);
5814 gen_op_mov_TN_reg(ot
, 0, rm
);
5815 switch(ot
| (b
& 8)) {
5817 tcg_gen_ext8u_tl(cpu_T
[0], cpu_T
[0]);
5820 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
5823 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
5827 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5830 gen_op_mov_reg_T0(d_ot
, reg
);
5832 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5834 gen_op_lds_T0_A0(ot
+ s
->mem_index
);
5836 gen_op_ldu_T0_A0(ot
+ s
->mem_index
);
5838 gen_op_mov_reg_T0(d_ot
, reg
);
5843 case 0x8d: /* lea */
5844 ot
= dflag
+ OT_WORD
;
5845 modrm
= cpu_ldub_code(env
, s
->pc
++);
5846 mod
= (modrm
>> 6) & 3;
5849 reg
= ((modrm
>> 3) & 7) | rex_r
;
5850 /* we must ensure that no segment is added */
5854 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5856 gen_op_mov_reg_A0(ot
- OT_WORD
, reg
);
5859 case 0xa0: /* mov EAX, Ov */
5861 case 0xa2: /* mov Ov, EAX */
5864 target_ulong offset_addr
;
5869 ot
= dflag
+ OT_WORD
;
5870 #ifdef TARGET_X86_64
5871 if (s
->aflag
== 2) {
5872 offset_addr
= cpu_ldq_code(env
, s
->pc
);
5874 gen_op_movq_A0_im(offset_addr
);
5879 offset_addr
= insn_get(env
, s
, OT_LONG
);
5881 offset_addr
= insn_get(env
, s
, OT_WORD
);
5883 gen_op_movl_A0_im(offset_addr
);
5885 gen_add_A0_ds_seg(s
);
5887 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
5888 gen_op_mov_reg_T0(ot
, R_EAX
);
5890 gen_op_mov_TN_reg(ot
, 0, R_EAX
);
5891 gen_op_st_T0_A0(ot
+ s
->mem_index
);
5895 case 0xd7: /* xlat */
5896 #ifdef TARGET_X86_64
5897 if (s
->aflag
== 2) {
5898 gen_op_movq_A0_reg(R_EBX
);
5899 gen_op_mov_TN_reg(OT_QUAD
, 0, R_EAX
);
5900 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xff);
5901 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_T
[0]);
5905 gen_op_movl_A0_reg(R_EBX
);
5906 gen_op_mov_TN_reg(OT_LONG
, 0, R_EAX
);
5907 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xff);
5908 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_T
[0]);
5910 gen_op_andl_A0_ffff();
5912 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffffffff);
5914 gen_add_A0_ds_seg(s
);
5915 gen_op_ldu_T0_A0(OT_BYTE
+ s
->mem_index
);
5916 gen_op_mov_reg_T0(OT_BYTE
, R_EAX
);
5918 case 0xb0 ... 0xb7: /* mov R, Ib */
5919 val
= insn_get(env
, s
, OT_BYTE
);
5920 gen_op_movl_T0_im(val
);
5921 gen_op_mov_reg_T0(OT_BYTE
, (b
& 7) | REX_B(s
));
5923 case 0xb8 ... 0xbf: /* mov R, Iv */
5924 #ifdef TARGET_X86_64
5928 tmp
= cpu_ldq_code(env
, s
->pc
);
5930 reg
= (b
& 7) | REX_B(s
);
5931 gen_movtl_T0_im(tmp
);
5932 gen_op_mov_reg_T0(OT_QUAD
, reg
);
5936 ot
= dflag
? OT_LONG
: OT_WORD
;
5937 val
= insn_get(env
, s
, ot
);
5938 reg
= (b
& 7) | REX_B(s
);
5939 gen_op_movl_T0_im(val
);
5940 gen_op_mov_reg_T0(ot
, reg
);
5944 case 0x91 ... 0x97: /* xchg R, EAX */
5946 ot
= dflag
+ OT_WORD
;
5947 reg
= (b
& 7) | REX_B(s
);
5951 case 0x87: /* xchg Ev, Gv */
5955 ot
= dflag
+ OT_WORD
;
5956 modrm
= cpu_ldub_code(env
, s
->pc
++);
5957 reg
= ((modrm
>> 3) & 7) | rex_r
;
5958 mod
= (modrm
>> 6) & 3;
5960 rm
= (modrm
& 7) | REX_B(s
);
5962 gen_op_mov_TN_reg(ot
, 0, reg
);
5963 gen_op_mov_TN_reg(ot
, 1, rm
);
5964 gen_op_mov_reg_T0(ot
, rm
);
5965 gen_op_mov_reg_T1(ot
, reg
);
5967 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5968 gen_op_mov_TN_reg(ot
, 0, reg
);
5969 /* for xchg, lock is implicit */
5970 if (!(prefixes
& PREFIX_LOCK
))
5972 gen_op_ld_T1_A0(ot
+ s
->mem_index
);
5973 gen_op_st_T0_A0(ot
+ s
->mem_index
);
5974 if (!(prefixes
& PREFIX_LOCK
))
5975 gen_helper_unlock();
5976 gen_op_mov_reg_T1(ot
, reg
);
5979 case 0xc4: /* les Gv */
5980 /* In CODE64 this is VEX3; see above. */
5983 case 0xc5: /* lds Gv */
5984 /* In CODE64 this is VEX2; see above. */
5987 case 0x1b2: /* lss Gv */
5990 case 0x1b4: /* lfs Gv */
5993 case 0x1b5: /* lgs Gv */
5996 ot
= dflag
? OT_LONG
: OT_WORD
;
5997 modrm
= cpu_ldub_code(env
, s
->pc
++);
5998 reg
= ((modrm
>> 3) & 7) | rex_r
;
5999 mod
= (modrm
>> 6) & 3;
6002 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
6003 gen_op_ld_T1_A0(ot
+ s
->mem_index
);
6004 gen_add_A0_im(s
, 1 << (ot
- OT_WORD
+ 1));
6005 /* load the segment first to handle exceptions properly */
6006 gen_op_ldu_T0_A0(OT_WORD
+ s
->mem_index
);
6007 gen_movl_seg_T0(s
, op
, pc_start
- s
->cs_base
);
6008 /* then put the data */
6009 gen_op_mov_reg_T1(ot
, reg
);
6011 gen_jmp_im(s
->pc
- s
->cs_base
);
6016 /************************/
6027 ot
= dflag
+ OT_WORD
;
6029 modrm
= cpu_ldub_code(env
, s
->pc
++);
6030 mod
= (modrm
>> 6) & 3;
6031 op
= (modrm
>> 3) & 7;
6037 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
6040 opreg
= (modrm
& 7) | REX_B(s
);
6045 gen_shift(s
, op
, ot
, opreg
, OR_ECX
);
6048 shift
= cpu_ldub_code(env
, s
->pc
++);
6050 gen_shifti(s
, op
, ot
, opreg
, shift
);
6065 case 0x1a4: /* shld imm */
6069 case 0x1a5: /* shld cl */
6073 case 0x1ac: /* shrd imm */
6077 case 0x1ad: /* shrd cl */
6081 ot
= dflag
+ OT_WORD
;
6082 modrm
= cpu_ldub_code(env
, s
->pc
++);
6083 mod
= (modrm
>> 6) & 3;
6084 rm
= (modrm
& 7) | REX_B(s
);
6085 reg
= ((modrm
>> 3) & 7) | rex_r
;
6087 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
6092 gen_op_mov_TN_reg(ot
, 1, reg
);
6095 TCGv imm
= tcg_const_tl(cpu_ldub_code(env
, s
->pc
++));
6096 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, imm
);
6099 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, cpu_regs
[R_ECX
]);
6103 /************************/
6106 if (s
->flags
& (HF_EM_MASK
| HF_TS_MASK
)) {
6107 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
6108 /* XXX: what to do if illegal op ? */
6109 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
6112 modrm
= cpu_ldub_code(env
, s
->pc
++);
6113 mod
= (modrm
>> 6) & 3;
6115 op
= ((b
& 7) << 3) | ((modrm
>> 3) & 7);
6118 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
6120 case 0x00 ... 0x07: /* fxxxs */
6121 case 0x10 ... 0x17: /* fixxxl */
6122 case 0x20 ... 0x27: /* fxxxl */
6123 case 0x30 ... 0x37: /* fixxx */
6130 gen_op_ld_T0_A0(OT_LONG
+ s
->mem_index
);
6131 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6132 gen_helper_flds_FT0(cpu_env
, cpu_tmp2_i32
);
6135 gen_op_ld_T0_A0(OT_LONG
+ s
->mem_index
);
6136 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6137 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
6140 tcg_gen_qemu_ld64(cpu_tmp1_i64
, cpu_A0
,
6141 (s
->mem_index
>> 2) - 1);
6142 gen_helper_fldl_FT0(cpu_env
, cpu_tmp1_i64
);
6146 gen_op_lds_T0_A0(OT_WORD
+ s
->mem_index
);
6147 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6148 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
6152 gen_helper_fp_arith_ST0_FT0(op1
);
6154 /* fcomp needs pop */
6155 gen_helper_fpop(cpu_env
);
6159 case 0x08: /* flds */
6160 case 0x0a: /* fsts */
6161 case 0x0b: /* fstps */
6162 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
6163 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
6164 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
6169 gen_op_ld_T0_A0(OT_LONG
+ s
->mem_index
);
6170 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6171 gen_helper_flds_ST0(cpu_env
, cpu_tmp2_i32
);
6174 gen_op_ld_T0_A0(OT_LONG
+ s
->mem_index
);
6175 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6176 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
6179 tcg_gen_qemu_ld64(cpu_tmp1_i64
, cpu_A0
,
6180 (s
->mem_index
>> 2) - 1);
6181 gen_helper_fldl_ST0(cpu_env
, cpu_tmp1_i64
);
6185 gen_op_lds_T0_A0(OT_WORD
+ s
->mem_index
);
6186 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6187 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
6192 /* XXX: the corresponding CPUID bit must be tested ! */
6195 gen_helper_fisttl_ST0(cpu_tmp2_i32
, cpu_env
);
6196 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6197 gen_op_st_T0_A0(OT_LONG
+ s
->mem_index
);
6200 gen_helper_fisttll_ST0(cpu_tmp1_i64
, cpu_env
);
6201 tcg_gen_qemu_st64(cpu_tmp1_i64
, cpu_A0
,
6202 (s
->mem_index
>> 2) - 1);
6206 gen_helper_fistt_ST0(cpu_tmp2_i32
, cpu_env
);
6207 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6208 gen_op_st_T0_A0(OT_WORD
+ s
->mem_index
);
6211 gen_helper_fpop(cpu_env
);
6216 gen_helper_fsts_ST0(cpu_tmp2_i32
, cpu_env
);
6217 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6218 gen_op_st_T0_A0(OT_LONG
+ s
->mem_index
);
6221 gen_helper_fistl_ST0(cpu_tmp2_i32
, cpu_env
);
6222 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6223 gen_op_st_T0_A0(OT_LONG
+ s
->mem_index
);
6226 gen_helper_fstl_ST0(cpu_tmp1_i64
, cpu_env
);
6227 tcg_gen_qemu_st64(cpu_tmp1_i64
, cpu_A0
,
6228 (s
->mem_index
>> 2) - 1);
6232 gen_helper_fist_ST0(cpu_tmp2_i32
, cpu_env
);
6233 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6234 gen_op_st_T0_A0(OT_WORD
+ s
->mem_index
);
6238 gen_helper_fpop(cpu_env
);
6242 case 0x0c: /* fldenv mem */
6243 gen_update_cc_op(s
);
6244 gen_jmp_im(pc_start
- s
->cs_base
);
6245 gen_helper_fldenv(cpu_env
, cpu_A0
, tcg_const_i32(s
->dflag
));
6247 case 0x0d: /* fldcw mem */
6248 gen_op_ld_T0_A0(OT_WORD
+ s
->mem_index
);
6249 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6250 gen_helper_fldcw(cpu_env
, cpu_tmp2_i32
);
6252 case 0x0e: /* fnstenv mem */
6253 gen_update_cc_op(s
);
6254 gen_jmp_im(pc_start
- s
->cs_base
);
6255 gen_helper_fstenv(cpu_env
, cpu_A0
, tcg_const_i32(s
->dflag
));
6257 case 0x0f: /* fnstcw mem */
6258 gen_helper_fnstcw(cpu_tmp2_i32
, cpu_env
);
6259 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6260 gen_op_st_T0_A0(OT_WORD
+ s
->mem_index
);
6262 case 0x1d: /* fldt mem */
6263 gen_update_cc_op(s
);
6264 gen_jmp_im(pc_start
- s
->cs_base
);
6265 gen_helper_fldt_ST0(cpu_env
, cpu_A0
);
6267 case 0x1f: /* fstpt mem */
6268 gen_update_cc_op(s
);
6269 gen_jmp_im(pc_start
- s
->cs_base
);
6270 gen_helper_fstt_ST0(cpu_env
, cpu_A0
);
6271 gen_helper_fpop(cpu_env
);
6273 case 0x2c: /* frstor mem */
6274 gen_update_cc_op(s
);
6275 gen_jmp_im(pc_start
- s
->cs_base
);
6276 gen_helper_frstor(cpu_env
, cpu_A0
, tcg_const_i32(s
->dflag
));
6278 case 0x2e: /* fnsave mem */
6279 gen_update_cc_op(s
);
6280 gen_jmp_im(pc_start
- s
->cs_base
);
6281 gen_helper_fsave(cpu_env
, cpu_A0
, tcg_const_i32(s
->dflag
));
6283 case 0x2f: /* fnstsw mem */
6284 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
6285 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6286 gen_op_st_T0_A0(OT_WORD
+ s
->mem_index
);
6288 case 0x3c: /* fbld */
6289 gen_update_cc_op(s
);
6290 gen_jmp_im(pc_start
- s
->cs_base
);
6291 gen_helper_fbld_ST0(cpu_env
, cpu_A0
);
6293 case 0x3e: /* fbstp */
6294 gen_update_cc_op(s
);
6295 gen_jmp_im(pc_start
- s
->cs_base
);
6296 gen_helper_fbst_ST0(cpu_env
, cpu_A0
);
6297 gen_helper_fpop(cpu_env
);
6299 case 0x3d: /* fildll */
6300 tcg_gen_qemu_ld64(cpu_tmp1_i64
, cpu_A0
,
6301 (s
->mem_index
>> 2) - 1);
6302 gen_helper_fildll_ST0(cpu_env
, cpu_tmp1_i64
);
6304 case 0x3f: /* fistpll */
6305 gen_helper_fistll_ST0(cpu_tmp1_i64
, cpu_env
);
6306 tcg_gen_qemu_st64(cpu_tmp1_i64
, cpu_A0
,
6307 (s
->mem_index
>> 2) - 1);
6308 gen_helper_fpop(cpu_env
);
6314 /* register float ops */
6318 case 0x08: /* fld sti */
6319 gen_helper_fpush(cpu_env
);
6320 gen_helper_fmov_ST0_STN(cpu_env
,
6321 tcg_const_i32((opreg
+ 1) & 7));
6323 case 0x09: /* fxchg sti */
6324 case 0x29: /* fxchg4 sti, undocumented op */
6325 case 0x39: /* fxchg7 sti, undocumented op */
6326 gen_helper_fxchg_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6328 case 0x0a: /* grp d9/2 */
6331 /* check exceptions (FreeBSD FPU probe) */
6332 gen_update_cc_op(s
);
6333 gen_jmp_im(pc_start
- s
->cs_base
);
6334 gen_helper_fwait(cpu_env
);
6340 case 0x0c: /* grp d9/4 */
6343 gen_helper_fchs_ST0(cpu_env
);
6346 gen_helper_fabs_ST0(cpu_env
);
6349 gen_helper_fldz_FT0(cpu_env
);
6350 gen_helper_fcom_ST0_FT0(cpu_env
);
6353 gen_helper_fxam_ST0(cpu_env
);
6359 case 0x0d: /* grp d9/5 */
6363 gen_helper_fpush(cpu_env
);
6364 gen_helper_fld1_ST0(cpu_env
);
6367 gen_helper_fpush(cpu_env
);
6368 gen_helper_fldl2t_ST0(cpu_env
);
6371 gen_helper_fpush(cpu_env
);
6372 gen_helper_fldl2e_ST0(cpu_env
);
6375 gen_helper_fpush(cpu_env
);
6376 gen_helper_fldpi_ST0(cpu_env
);
6379 gen_helper_fpush(cpu_env
);
6380 gen_helper_fldlg2_ST0(cpu_env
);
6383 gen_helper_fpush(cpu_env
);
6384 gen_helper_fldln2_ST0(cpu_env
);
6387 gen_helper_fpush(cpu_env
);
6388 gen_helper_fldz_ST0(cpu_env
);
6395 case 0x0e: /* grp d9/6 */
6398 gen_helper_f2xm1(cpu_env
);
6401 gen_helper_fyl2x(cpu_env
);
6404 gen_helper_fptan(cpu_env
);
6406 case 3: /* fpatan */
6407 gen_helper_fpatan(cpu_env
);
6409 case 4: /* fxtract */
6410 gen_helper_fxtract(cpu_env
);
6412 case 5: /* fprem1 */
6413 gen_helper_fprem1(cpu_env
);
6415 case 6: /* fdecstp */
6416 gen_helper_fdecstp(cpu_env
);
6419 case 7: /* fincstp */
6420 gen_helper_fincstp(cpu_env
);
6424 case 0x0f: /* grp d9/7 */
6427 gen_helper_fprem(cpu_env
);
6429 case 1: /* fyl2xp1 */
6430 gen_helper_fyl2xp1(cpu_env
);
6433 gen_helper_fsqrt(cpu_env
);
6435 case 3: /* fsincos */
6436 gen_helper_fsincos(cpu_env
);
6438 case 5: /* fscale */
6439 gen_helper_fscale(cpu_env
);
6441 case 4: /* frndint */
6442 gen_helper_frndint(cpu_env
);
6445 gen_helper_fsin(cpu_env
);
6449 gen_helper_fcos(cpu_env
);
6453 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6454 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6455 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6461 gen_helper_fp_arith_STN_ST0(op1
, opreg
);
6463 gen_helper_fpop(cpu_env
);
6465 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6466 gen_helper_fp_arith_ST0_FT0(op1
);
6470 case 0x02: /* fcom */
6471 case 0x22: /* fcom2, undocumented op */
6472 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6473 gen_helper_fcom_ST0_FT0(cpu_env
);
6475 case 0x03: /* fcomp */
6476 case 0x23: /* fcomp3, undocumented op */
6477 case 0x32: /* fcomp5, undocumented op */
6478 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6479 gen_helper_fcom_ST0_FT0(cpu_env
);
6480 gen_helper_fpop(cpu_env
);
6482 case 0x15: /* da/5 */
6484 case 1: /* fucompp */
6485 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6486 gen_helper_fucom_ST0_FT0(cpu_env
);
6487 gen_helper_fpop(cpu_env
);
6488 gen_helper_fpop(cpu_env
);
6496 case 0: /* feni (287 only, just do nop here) */
6498 case 1: /* fdisi (287 only, just do nop here) */
6501 gen_helper_fclex(cpu_env
);
6503 case 3: /* fninit */
6504 gen_helper_fninit(cpu_env
);
6506 case 4: /* fsetpm (287 only, just do nop here) */
6512 case 0x1d: /* fucomi */
6513 gen_update_cc_op(s
);
6514 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6515 gen_helper_fucomi_ST0_FT0(cpu_env
);
6516 set_cc_op(s
, CC_OP_EFLAGS
);
6518 case 0x1e: /* fcomi */
6519 gen_update_cc_op(s
);
6520 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6521 gen_helper_fcomi_ST0_FT0(cpu_env
);
6522 set_cc_op(s
, CC_OP_EFLAGS
);
6524 case 0x28: /* ffree sti */
6525 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6527 case 0x2a: /* fst sti */
6528 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6530 case 0x2b: /* fstp sti */
6531 case 0x0b: /* fstp1 sti, undocumented op */
6532 case 0x3a: /* fstp8 sti, undocumented op */
6533 case 0x3b: /* fstp9 sti, undocumented op */
6534 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6535 gen_helper_fpop(cpu_env
);
6537 case 0x2c: /* fucom st(i) */
6538 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6539 gen_helper_fucom_ST0_FT0(cpu_env
);
6541 case 0x2d: /* fucomp st(i) */
6542 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6543 gen_helper_fucom_ST0_FT0(cpu_env
);
6544 gen_helper_fpop(cpu_env
);
6546 case 0x33: /* de/3 */
6548 case 1: /* fcompp */
6549 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6550 gen_helper_fcom_ST0_FT0(cpu_env
);
6551 gen_helper_fpop(cpu_env
);
6552 gen_helper_fpop(cpu_env
);
6558 case 0x38: /* ffreep sti, undocumented op */
6559 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6560 gen_helper_fpop(cpu_env
);
6562 case 0x3c: /* df/4 */
6565 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
6566 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6567 gen_op_mov_reg_T0(OT_WORD
, R_EAX
);
6573 case 0x3d: /* fucomip */
6574 gen_update_cc_op(s
);
6575 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6576 gen_helper_fucomi_ST0_FT0(cpu_env
);
6577 gen_helper_fpop(cpu_env
);
6578 set_cc_op(s
, CC_OP_EFLAGS
);
6580 case 0x3e: /* fcomip */
6581 gen_update_cc_op(s
);
6582 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6583 gen_helper_fcomi_ST0_FT0(cpu_env
);
6584 gen_helper_fpop(cpu_env
);
6585 set_cc_op(s
, CC_OP_EFLAGS
);
6587 case 0x10 ... 0x13: /* fcmovxx */
6591 static const uint8_t fcmov_cc
[8] = {
6597 op1
= fcmov_cc
[op
& 3] | (((op
>> 3) & 1) ^ 1);
6598 l1
= gen_new_label();
6599 gen_jcc1_noeob(s
, op1
, l1
);
6600 gen_helper_fmov_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6609 /************************/
6612 case 0xa4: /* movsS */
6617 ot
= dflag
+ OT_WORD
;
6619 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6620 gen_repz_movs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6626 case 0xaa: /* stosS */
6631 ot
= dflag
+ OT_WORD
;
6633 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6634 gen_repz_stos(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6639 case 0xac: /* lodsS */
6644 ot
= dflag
+ OT_WORD
;
6645 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6646 gen_repz_lods(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6651 case 0xae: /* scasS */
6656 ot
= dflag
+ OT_WORD
;
6657 if (prefixes
& PREFIX_REPNZ
) {
6658 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6659 } else if (prefixes
& PREFIX_REPZ
) {
6660 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6666 case 0xa6: /* cmpsS */
6671 ot
= dflag
+ OT_WORD
;
6672 if (prefixes
& PREFIX_REPNZ
) {
6673 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6674 } else if (prefixes
& PREFIX_REPZ
) {
6675 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6680 case 0x6c: /* insS */
6685 ot
= dflag
? OT_LONG
: OT_WORD
;
6686 gen_op_mov_TN_reg(OT_WORD
, 0, R_EDX
);
6687 gen_op_andl_T0_ffff();
6688 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6689 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
) | 4);
6690 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6691 gen_repz_ins(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6695 gen_jmp(s
, s
->pc
- s
->cs_base
);
6699 case 0x6e: /* outsS */
6704 ot
= dflag
? OT_LONG
: OT_WORD
;
6705 gen_op_mov_TN_reg(OT_WORD
, 0, R_EDX
);
6706 gen_op_andl_T0_ffff();
6707 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6708 svm_is_rep(prefixes
) | 4);
6709 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6710 gen_repz_outs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6714 gen_jmp(s
, s
->pc
- s
->cs_base
);
6719 /************************/
6727 ot
= dflag
? OT_LONG
: OT_WORD
;
6728 val
= cpu_ldub_code(env
, s
->pc
++);
6729 gen_op_movl_T0_im(val
);
6730 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6731 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6734 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6735 gen_helper_in_func(ot
, cpu_T
[1], cpu_tmp2_i32
);
6736 gen_op_mov_reg_T1(ot
, R_EAX
);
6739 gen_jmp(s
, s
->pc
- s
->cs_base
);
6747 ot
= dflag
? OT_LONG
: OT_WORD
;
6748 val
= cpu_ldub_code(env
, s
->pc
++);
6749 gen_op_movl_T0_im(val
);
6750 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6751 svm_is_rep(prefixes
));
6752 gen_op_mov_TN_reg(ot
, 1, R_EAX
);
6756 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6757 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
6758 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6761 gen_jmp(s
, s
->pc
- s
->cs_base
);
6769 ot
= dflag
? OT_LONG
: OT_WORD
;
6770 gen_op_mov_TN_reg(OT_WORD
, 0, R_EDX
);
6771 gen_op_andl_T0_ffff();
6772 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6773 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6776 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6777 gen_helper_in_func(ot
, cpu_T
[1], cpu_tmp2_i32
);
6778 gen_op_mov_reg_T1(ot
, R_EAX
);
6781 gen_jmp(s
, s
->pc
- s
->cs_base
);
6789 ot
= dflag
? OT_LONG
: OT_WORD
;
6790 gen_op_mov_TN_reg(OT_WORD
, 0, R_EDX
);
6791 gen_op_andl_T0_ffff();
6792 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6793 svm_is_rep(prefixes
));
6794 gen_op_mov_TN_reg(ot
, 1, R_EAX
);
6798 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6799 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
6800 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6803 gen_jmp(s
, s
->pc
- s
->cs_base
);
6807 /************************/
6809 case 0xc2: /* ret im */
6810 val
= cpu_ldsw_code(env
, s
->pc
);
6813 if (CODE64(s
) && s
->dflag
)
6815 gen_stack_update(s
, val
+ (2 << s
->dflag
));
6817 gen_op_andl_T0_ffff();
6821 case 0xc3: /* ret */
6825 gen_op_andl_T0_ffff();
6829 case 0xca: /* lret im */
6830 val
= cpu_ldsw_code(env
, s
->pc
);
6833 if (s
->pe
&& !s
->vm86
) {
6834 gen_update_cc_op(s
);
6835 gen_jmp_im(pc_start
- s
->cs_base
);
6836 gen_helper_lret_protected(cpu_env
, tcg_const_i32(s
->dflag
),
6837 tcg_const_i32(val
));
6841 gen_op_ld_T0_A0(1 + s
->dflag
+ s
->mem_index
);
6843 gen_op_andl_T0_ffff();
6844 /* NOTE: keeping EIP updated is not a problem in case of
6848 gen_op_addl_A0_im(2 << s
->dflag
);
6849 gen_op_ld_T0_A0(1 + s
->dflag
+ s
->mem_index
);
6850 gen_op_movl_seg_T0_vm(R_CS
);
6851 /* add stack offset */
6852 gen_stack_update(s
, val
+ (4 << s
->dflag
));
6856 case 0xcb: /* lret */
6859 case 0xcf: /* iret */
6860 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IRET
);
6863 gen_helper_iret_real(cpu_env
, tcg_const_i32(s
->dflag
));
6864 set_cc_op(s
, CC_OP_EFLAGS
);
6865 } else if (s
->vm86
) {
6867 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6869 gen_helper_iret_real(cpu_env
, tcg_const_i32(s
->dflag
));
6870 set_cc_op(s
, CC_OP_EFLAGS
);
6873 gen_update_cc_op(s
);
6874 gen_jmp_im(pc_start
- s
->cs_base
);
6875 gen_helper_iret_protected(cpu_env
, tcg_const_i32(s
->dflag
),
6876 tcg_const_i32(s
->pc
- s
->cs_base
));
6877 set_cc_op(s
, CC_OP_EFLAGS
);
6881 case 0xe8: /* call im */
6884 tval
= (int32_t)insn_get(env
, s
, OT_LONG
);
6886 tval
= (int16_t)insn_get(env
, s
, OT_WORD
);
6887 next_eip
= s
->pc
- s
->cs_base
;
6893 gen_movtl_T0_im(next_eip
);
6898 case 0x9a: /* lcall im */
6900 unsigned int selector
, offset
;
6904 ot
= dflag
? OT_LONG
: OT_WORD
;
6905 offset
= insn_get(env
, s
, ot
);
6906 selector
= insn_get(env
, s
, OT_WORD
);
6908 gen_op_movl_T0_im(selector
);
6909 gen_op_movl_T1_imu(offset
);
6912 case 0xe9: /* jmp im */
6914 tval
= (int32_t)insn_get(env
, s
, OT_LONG
);
6916 tval
= (int16_t)insn_get(env
, s
, OT_WORD
);
6917 tval
+= s
->pc
- s
->cs_base
;
6924 case 0xea: /* ljmp im */
6926 unsigned int selector
, offset
;
6930 ot
= dflag
? OT_LONG
: OT_WORD
;
6931 offset
= insn_get(env
, s
, ot
);
6932 selector
= insn_get(env
, s
, OT_WORD
);
6934 gen_op_movl_T0_im(selector
);
6935 gen_op_movl_T1_imu(offset
);
6938 case 0xeb: /* jmp Jb */
6939 tval
= (int8_t)insn_get(env
, s
, OT_BYTE
);
6940 tval
+= s
->pc
- s
->cs_base
;
6945 case 0x70 ... 0x7f: /* jcc Jb */
6946 tval
= (int8_t)insn_get(env
, s
, OT_BYTE
);
6948 case 0x180 ... 0x18f: /* jcc Jv */
6950 tval
= (int32_t)insn_get(env
, s
, OT_LONG
);
6952 tval
= (int16_t)insn_get(env
, s
, OT_WORD
);
6955 next_eip
= s
->pc
- s
->cs_base
;
6959 gen_jcc(s
, b
, tval
, next_eip
);
6962 case 0x190 ... 0x19f: /* setcc Gv */
6963 modrm
= cpu_ldub_code(env
, s
->pc
++);
6964 gen_setcc1(s
, b
, cpu_T
[0]);
6965 gen_ldst_modrm(env
, s
, modrm
, OT_BYTE
, OR_TMP0
, 1);
6967 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6968 ot
= dflag
+ OT_WORD
;
6969 modrm
= cpu_ldub_code(env
, s
->pc
++);
6970 reg
= ((modrm
>> 3) & 7) | rex_r
;
6971 gen_cmovcc1(env
, s
, ot
, b
, modrm
, reg
);
6974 /************************/
6976 case 0x9c: /* pushf */
6977 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_PUSHF
);
6978 if (s
->vm86
&& s
->iopl
!= 3) {
6979 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6981 gen_update_cc_op(s
);
6982 gen_helper_read_eflags(cpu_T
[0], cpu_env
);
6986 case 0x9d: /* popf */
6987 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_POPF
);
6988 if (s
->vm86
&& s
->iopl
!= 3) {
6989 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6994 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6995 tcg_const_i32((TF_MASK
| AC_MASK
|
7000 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
7001 tcg_const_i32((TF_MASK
| AC_MASK
|
7003 IF_MASK
| IOPL_MASK
)
7007 if (s
->cpl
<= s
->iopl
) {
7009 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
7010 tcg_const_i32((TF_MASK
|
7016 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
7017 tcg_const_i32((TF_MASK
|
7026 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
7027 tcg_const_i32((TF_MASK
| AC_MASK
|
7028 ID_MASK
| NT_MASK
)));
7030 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
7031 tcg_const_i32((TF_MASK
| AC_MASK
|
7038 set_cc_op(s
, CC_OP_EFLAGS
);
7039 /* abort translation because TF/AC flag may change */
7040 gen_jmp_im(s
->pc
- s
->cs_base
);
7044 case 0x9e: /* sahf */
7045 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
7047 gen_op_mov_TN_reg(OT_BYTE
, 0, R_AH
);
7048 gen_compute_eflags(s
);
7049 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, CC_O
);
7050 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], CC_S
| CC_Z
| CC_A
| CC_P
| CC_C
);
7051 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, cpu_T
[0]);
7053 case 0x9f: /* lahf */
7054 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
7056 gen_compute_eflags(s
);
7057 /* Note: gen_compute_eflags() only gives the condition codes */
7058 tcg_gen_ori_tl(cpu_T
[0], cpu_cc_src
, 0x02);
7059 gen_op_mov_reg_T0(OT_BYTE
, R_AH
);
7061 case 0xf5: /* cmc */
7062 gen_compute_eflags(s
);
7063 tcg_gen_xori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
7065 case 0xf8: /* clc */
7066 gen_compute_eflags(s
);
7067 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_C
);
7069 case 0xf9: /* stc */
7070 gen_compute_eflags(s
);
7071 tcg_gen_ori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
7073 case 0xfc: /* cld */
7074 tcg_gen_movi_i32(cpu_tmp2_i32
, 1);
7075 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
7077 case 0xfd: /* std */
7078 tcg_gen_movi_i32(cpu_tmp2_i32
, -1);
7079 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
7082 /************************/
7083 /* bit operations */
7084 case 0x1ba: /* bt/bts/btr/btc Gv, im */
7085 ot
= dflag
+ OT_WORD
;
7086 modrm
= cpu_ldub_code(env
, s
->pc
++);
7087 op
= (modrm
>> 3) & 7;
7088 mod
= (modrm
>> 6) & 3;
7089 rm
= (modrm
& 7) | REX_B(s
);
7092 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7093 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
7095 gen_op_mov_TN_reg(ot
, 0, rm
);
7098 val
= cpu_ldub_code(env
, s
->pc
++);
7099 gen_op_movl_T1_im(val
);
7104 case 0x1a3: /* bt Gv, Ev */
7107 case 0x1ab: /* bts */
7110 case 0x1b3: /* btr */
7113 case 0x1bb: /* btc */
7116 ot
= dflag
+ OT_WORD
;
7117 modrm
= cpu_ldub_code(env
, s
->pc
++);
7118 reg
= ((modrm
>> 3) & 7) | rex_r
;
7119 mod
= (modrm
>> 6) & 3;
7120 rm
= (modrm
& 7) | REX_B(s
);
7121 gen_op_mov_TN_reg(OT_LONG
, 1, reg
);
7123 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7124 /* specific case: we need to add a displacement */
7125 gen_exts(ot
, cpu_T
[1]);
7126 tcg_gen_sari_tl(cpu_tmp0
, cpu_T
[1], 3 + ot
);
7127 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, ot
);
7128 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
7129 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
7131 gen_op_mov_TN_reg(ot
, 0, rm
);
7134 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], (1 << (3 + ot
)) - 1);
7137 tcg_gen_shr_tl(cpu_cc_src
, cpu_T
[0], cpu_T
[1]);
7138 tcg_gen_movi_tl(cpu_cc_dst
, 0);
7141 tcg_gen_shr_tl(cpu_tmp4
, cpu_T
[0], cpu_T
[1]);
7142 tcg_gen_movi_tl(cpu_tmp0
, 1);
7143 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
7144 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
7147 tcg_gen_shr_tl(cpu_tmp4
, cpu_T
[0], cpu_T
[1]);
7148 tcg_gen_movi_tl(cpu_tmp0
, 1);
7149 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
7150 tcg_gen_not_tl(cpu_tmp0
, cpu_tmp0
);
7151 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
7155 tcg_gen_shr_tl(cpu_tmp4
, cpu_T
[0], cpu_T
[1]);
7156 tcg_gen_movi_tl(cpu_tmp0
, 1);
7157 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
7158 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
7161 set_cc_op(s
, CC_OP_SARB
+ ot
);
7164 gen_op_st_T0_A0(ot
+ s
->mem_index
);
7166 gen_op_mov_reg_T0(ot
, rm
);
7167 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
7168 tcg_gen_movi_tl(cpu_cc_dst
, 0);
7171 case 0x1bc: /* bsf / tzcnt */
7172 case 0x1bd: /* bsr / lzcnt */
7173 ot
= dflag
+ OT_WORD
;
7174 modrm
= cpu_ldub_code(env
, s
->pc
++);
7175 reg
= ((modrm
>> 3) & 7) | rex_r
;
7176 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
7177 gen_extu(ot
, cpu_T
[0]);
7179 /* Note that lzcnt and tzcnt are in different extensions. */
7180 if ((prefixes
& PREFIX_REPZ
)
7182 ? s
->cpuid_ext3_features
& CPUID_EXT3_ABM
7183 : s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)) {
7185 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
7187 /* For lzcnt, reduce the target_ulong result by the
7188 number of zeros that we expect to find at the top. */
7189 gen_helper_clz(cpu_T
[0], cpu_T
[0]);
7190 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], TARGET_LONG_BITS
- size
);
7192 /* For tzcnt, a zero input must return the operand size:
7193 force all bits outside the operand size to 1. */
7194 target_ulong mask
= (target_ulong
)-2 << (size
- 1);
7195 tcg_gen_ori_tl(cpu_T
[0], cpu_T
[0], mask
);
7196 gen_helper_ctz(cpu_T
[0], cpu_T
[0]);
7198 /* For lzcnt/tzcnt, C and Z bits are defined and are
7199 related to the result. */
7200 gen_op_update1_cc();
7201 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
7203 /* For bsr/bsf, only the Z bit is defined and it is related
7204 to the input and not the result. */
7205 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
7206 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
7208 /* For bsr, return the bit index of the first 1 bit,
7209 not the count of leading zeros. */
7210 gen_helper_clz(cpu_T
[0], cpu_T
[0]);
7211 tcg_gen_xori_tl(cpu_T
[0], cpu_T
[0], TARGET_LONG_BITS
- 1);
7213 gen_helper_ctz(cpu_T
[0], cpu_T
[0]);
7215 /* ??? The manual says that the output is undefined when the
7216 input is zero, but real hardware leaves it unchanged, and
7217 real programs appear to depend on that. */
7218 tcg_gen_movi_tl(cpu_tmp0
, 0);
7219 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_T
[0], cpu_cc_dst
, cpu_tmp0
,
7220 cpu_regs
[reg
], cpu_T
[0]);
7222 gen_op_mov_reg_T0(ot
, reg
);
7224 /************************/
7226 case 0x27: /* daa */
7229 gen_update_cc_op(s
);
7230 gen_helper_daa(cpu_env
);
7231 set_cc_op(s
, CC_OP_EFLAGS
);
7233 case 0x2f: /* das */
7236 gen_update_cc_op(s
);
7237 gen_helper_das(cpu_env
);
7238 set_cc_op(s
, CC_OP_EFLAGS
);
7240 case 0x37: /* aaa */
7243 gen_update_cc_op(s
);
7244 gen_helper_aaa(cpu_env
);
7245 set_cc_op(s
, CC_OP_EFLAGS
);
7247 case 0x3f: /* aas */
7250 gen_update_cc_op(s
);
7251 gen_helper_aas(cpu_env
);
7252 set_cc_op(s
, CC_OP_EFLAGS
);
7254 case 0xd4: /* aam */
7257 val
= cpu_ldub_code(env
, s
->pc
++);
7259 gen_exception(s
, EXCP00_DIVZ
, pc_start
- s
->cs_base
);
7261 gen_helper_aam(cpu_env
, tcg_const_i32(val
));
7262 set_cc_op(s
, CC_OP_LOGICB
);
7265 case 0xd5: /* aad */
7268 val
= cpu_ldub_code(env
, s
->pc
++);
7269 gen_helper_aad(cpu_env
, tcg_const_i32(val
));
7270 set_cc_op(s
, CC_OP_LOGICB
);
7272 /************************/
7274 case 0x90: /* nop */
7275 /* XXX: correct lock test for all insn */
7276 if (prefixes
& PREFIX_LOCK
) {
7279 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
7281 goto do_xchg_reg_eax
;
7283 if (prefixes
& PREFIX_REPZ
) {
7284 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_PAUSE
);
7287 case 0x9b: /* fwait */
7288 if ((s
->flags
& (HF_MP_MASK
| HF_TS_MASK
)) ==
7289 (HF_MP_MASK
| HF_TS_MASK
)) {
7290 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7292 gen_update_cc_op(s
);
7293 gen_jmp_im(pc_start
- s
->cs_base
);
7294 gen_helper_fwait(cpu_env
);
7297 case 0xcc: /* int3 */
7298 gen_interrupt(s
, EXCP03_INT3
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
7300 case 0xcd: /* int N */
7301 val
= cpu_ldub_code(env
, s
->pc
++);
7302 if (s
->vm86
&& s
->iopl
!= 3) {
7303 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7305 gen_interrupt(s
, val
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
7308 case 0xce: /* into */
7311 gen_update_cc_op(s
);
7312 gen_jmp_im(pc_start
- s
->cs_base
);
7313 gen_helper_into(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7316 case 0xf1: /* icebp (undocumented, exits to external debugger) */
7317 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_ICEBP
);
7319 gen_debug(s
, pc_start
- s
->cs_base
);
7323 qemu_set_log(CPU_LOG_INT
| CPU_LOG_TB_IN_ASM
);
7327 case 0xfa: /* cli */
7329 if (s
->cpl
<= s
->iopl
) {
7330 gen_helper_cli(cpu_env
);
7332 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7336 gen_helper_cli(cpu_env
);
7338 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7342 case 0xfb: /* sti */
7344 if (s
->cpl
<= s
->iopl
) {
7346 gen_helper_sti(cpu_env
);
7347 /* interruptions are enabled only the first insn after sti */
7348 /* If several instructions disable interrupts, only the
7350 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
7351 gen_helper_set_inhibit_irq(cpu_env
);
7352 /* give a chance to handle pending irqs */
7353 gen_jmp_im(s
->pc
- s
->cs_base
);
7356 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7362 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7366 case 0x62: /* bound */
7369 ot
= dflag
? OT_LONG
: OT_WORD
;
7370 modrm
= cpu_ldub_code(env
, s
->pc
++);
7371 reg
= (modrm
>> 3) & 7;
7372 mod
= (modrm
>> 6) & 3;
7375 gen_op_mov_TN_reg(ot
, 0, reg
);
7376 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7377 gen_jmp_im(pc_start
- s
->cs_base
);
7378 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
7379 if (ot
== OT_WORD
) {
7380 gen_helper_boundw(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
7382 gen_helper_boundl(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
7385 case 0x1c8 ... 0x1cf: /* bswap reg */
7386 reg
= (b
& 7) | REX_B(s
);
7387 #ifdef TARGET_X86_64
7389 gen_op_mov_TN_reg(OT_QUAD
, 0, reg
);
7390 tcg_gen_bswap64_i64(cpu_T
[0], cpu_T
[0]);
7391 gen_op_mov_reg_T0(OT_QUAD
, reg
);
7395 gen_op_mov_TN_reg(OT_LONG
, 0, reg
);
7396 tcg_gen_ext32u_tl(cpu_T
[0], cpu_T
[0]);
7397 tcg_gen_bswap32_tl(cpu_T
[0], cpu_T
[0]);
7398 gen_op_mov_reg_T0(OT_LONG
, reg
);
7401 case 0xd6: /* salc */
7404 gen_compute_eflags_c(s
, cpu_T
[0]);
7405 tcg_gen_neg_tl(cpu_T
[0], cpu_T
[0]);
7406 gen_op_mov_reg_T0(OT_BYTE
, R_EAX
);
7408 case 0xe0: /* loopnz */
7409 case 0xe1: /* loopz */
7410 case 0xe2: /* loop */
7411 case 0xe3: /* jecxz */
7415 tval
= (int8_t)insn_get(env
, s
, OT_BYTE
);
7416 next_eip
= s
->pc
- s
->cs_base
;
7421 l1
= gen_new_label();
7422 l2
= gen_new_label();
7423 l3
= gen_new_label();
7426 case 0: /* loopnz */
7428 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
7429 gen_op_jz_ecx(s
->aflag
, l3
);
7430 gen_jcc1(s
, (JCC_Z
<< 1) | (b
^ 1), l1
);
7433 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
7434 gen_op_jnz_ecx(s
->aflag
, l1
);
7438 gen_op_jz_ecx(s
->aflag
, l1
);
7443 gen_jmp_im(next_eip
);
7452 case 0x130: /* wrmsr */
7453 case 0x132: /* rdmsr */
7455 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7457 gen_update_cc_op(s
);
7458 gen_jmp_im(pc_start
- s
->cs_base
);
7460 gen_helper_rdmsr(cpu_env
);
7462 gen_helper_wrmsr(cpu_env
);
7466 case 0x131: /* rdtsc */
7467 gen_update_cc_op(s
);
7468 gen_jmp_im(pc_start
- s
->cs_base
);
7471 gen_helper_rdtsc(cpu_env
);
7474 gen_jmp(s
, s
->pc
- s
->cs_base
);
7477 case 0x133: /* rdpmc */
7478 gen_update_cc_op(s
);
7479 gen_jmp_im(pc_start
- s
->cs_base
);
7480 gen_helper_rdpmc(cpu_env
);
7482 case 0x134: /* sysenter */
7483 /* For Intel SYSENTER is valid on 64-bit */
7484 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7487 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7489 gen_update_cc_op(s
);
7490 gen_jmp_im(pc_start
- s
->cs_base
);
7491 gen_helper_sysenter(cpu_env
);
7495 case 0x135: /* sysexit */
7496 /* For Intel SYSEXIT is valid on 64-bit */
7497 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7500 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7502 gen_update_cc_op(s
);
7503 gen_jmp_im(pc_start
- s
->cs_base
);
7504 gen_helper_sysexit(cpu_env
, tcg_const_i32(dflag
));
7508 #ifdef TARGET_X86_64
7509 case 0x105: /* syscall */
7510 /* XXX: is it usable in real mode ? */
7511 gen_update_cc_op(s
);
7512 gen_jmp_im(pc_start
- s
->cs_base
);
7513 gen_helper_syscall(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7516 case 0x107: /* sysret */
7518 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7520 gen_update_cc_op(s
);
7521 gen_jmp_im(pc_start
- s
->cs_base
);
7522 gen_helper_sysret(cpu_env
, tcg_const_i32(s
->dflag
));
7523 /* condition codes are modified only in long mode */
7525 set_cc_op(s
, CC_OP_EFLAGS
);
7531 case 0x1a2: /* cpuid */
7532 gen_update_cc_op(s
);
7533 gen_jmp_im(pc_start
- s
->cs_base
);
7534 gen_helper_cpuid(cpu_env
);
7536 case 0xf4: /* hlt */
7538 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7540 gen_update_cc_op(s
);
7541 gen_jmp_im(pc_start
- s
->cs_base
);
7542 gen_helper_hlt(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7543 s
->is_jmp
= DISAS_TB_JUMP
;
7547 modrm
= cpu_ldub_code(env
, s
->pc
++);
7548 mod
= (modrm
>> 6) & 3;
7549 op
= (modrm
>> 3) & 7;
7552 if (!s
->pe
|| s
->vm86
)
7554 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_READ
);
7555 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,ldt
.selector
));
7559 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7562 if (!s
->pe
|| s
->vm86
)
7565 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7567 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_WRITE
);
7568 gen_ldst_modrm(env
, s
, modrm
, OT_WORD
, OR_TMP0
, 0);
7569 gen_jmp_im(pc_start
- s
->cs_base
);
7570 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
7571 gen_helper_lldt(cpu_env
, cpu_tmp2_i32
);
7575 if (!s
->pe
|| s
->vm86
)
7577 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_READ
);
7578 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,tr
.selector
));
7582 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7585 if (!s
->pe
|| s
->vm86
)
7588 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7590 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_WRITE
);
7591 gen_ldst_modrm(env
, s
, modrm
, OT_WORD
, OR_TMP0
, 0);
7592 gen_jmp_im(pc_start
- s
->cs_base
);
7593 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
7594 gen_helper_ltr(cpu_env
, cpu_tmp2_i32
);
7599 if (!s
->pe
|| s
->vm86
)
7601 gen_ldst_modrm(env
, s
, modrm
, OT_WORD
, OR_TMP0
, 0);
7602 gen_update_cc_op(s
);
7604 gen_helper_verr(cpu_env
, cpu_T
[0]);
7606 gen_helper_verw(cpu_env
, cpu_T
[0]);
7608 set_cc_op(s
, CC_OP_EFLAGS
);
7615 modrm
= cpu_ldub_code(env
, s
->pc
++);
7616 mod
= (modrm
>> 6) & 3;
7617 op
= (modrm
>> 3) & 7;
7623 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_READ
);
7624 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7625 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7626 gen_op_st_T0_A0(OT_WORD
+ s
->mem_index
);
7627 gen_add_A0_im(s
, 2);
7628 tcg_gen_ld_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7630 gen_op_andl_T0_im(0xffffff);
7631 gen_op_st_T0_A0(CODE64(s
) + OT_LONG
+ s
->mem_index
);
7636 case 0: /* monitor */
7637 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) ||
7640 gen_update_cc_op(s
);
7641 gen_jmp_im(pc_start
- s
->cs_base
);
7642 #ifdef TARGET_X86_64
7643 if (s
->aflag
== 2) {
7644 gen_op_movq_A0_reg(R_EAX
);
7648 gen_op_movl_A0_reg(R_EAX
);
7650 gen_op_andl_A0_ffff();
7652 gen_add_A0_ds_seg(s
);
7653 gen_helper_monitor(cpu_env
, cpu_A0
);
7656 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) ||
7659 gen_update_cc_op(s
);
7660 gen_jmp_im(pc_start
- s
->cs_base
);
7661 gen_helper_mwait(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7665 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
) ||
7669 gen_helper_clac(cpu_env
);
7670 gen_jmp_im(s
->pc
- s
->cs_base
);
7674 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
) ||
7678 gen_helper_stac(cpu_env
);
7679 gen_jmp_im(s
->pc
- s
->cs_base
);
7686 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_READ
);
7687 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7688 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7689 gen_op_st_T0_A0(OT_WORD
+ s
->mem_index
);
7690 gen_add_A0_im(s
, 2);
7691 tcg_gen_ld_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, idt
.base
));
7693 gen_op_andl_T0_im(0xffffff);
7694 gen_op_st_T0_A0(CODE64(s
) + OT_LONG
+ s
->mem_index
);
7700 gen_update_cc_op(s
);
7701 gen_jmp_im(pc_start
- s
->cs_base
);
7704 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7707 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7710 gen_helper_vmrun(cpu_env
, tcg_const_i32(s
->aflag
),
7711 tcg_const_i32(s
->pc
- pc_start
));
7713 s
->is_jmp
= DISAS_TB_JUMP
;
7716 case 1: /* VMMCALL */
7717 if (!(s
->flags
& HF_SVME_MASK
))
7719 gen_helper_vmmcall(cpu_env
);
7721 case 2: /* VMLOAD */
7722 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7725 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7728 gen_helper_vmload(cpu_env
, tcg_const_i32(s
->aflag
));
7731 case 3: /* VMSAVE */
7732 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7735 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7738 gen_helper_vmsave(cpu_env
, tcg_const_i32(s
->aflag
));
7742 if ((!(s
->flags
& HF_SVME_MASK
) &&
7743 !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
)) ||
7747 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7750 gen_helper_stgi(cpu_env
);
7754 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7757 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7760 gen_helper_clgi(cpu_env
);
7763 case 6: /* SKINIT */
7764 if ((!(s
->flags
& HF_SVME_MASK
) &&
7765 !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
)) ||
7768 gen_helper_skinit(cpu_env
);
7770 case 7: /* INVLPGA */
7771 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7774 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7777 gen_helper_invlpga(cpu_env
, tcg_const_i32(s
->aflag
));
7783 } else if (s
->cpl
!= 0) {
7784 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7786 gen_svm_check_intercept(s
, pc_start
,
7787 op
==2 ? SVM_EXIT_GDTR_WRITE
: SVM_EXIT_IDTR_WRITE
);
7788 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7789 gen_op_ld_T1_A0(OT_WORD
+ s
->mem_index
);
7790 gen_add_A0_im(s
, 2);
7791 gen_op_ld_T0_A0(CODE64(s
) + OT_LONG
+ s
->mem_index
);
7793 gen_op_andl_T0_im(0xffffff);
7795 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,gdt
.base
));
7796 tcg_gen_st32_tl(cpu_T
[1], cpu_env
, offsetof(CPUX86State
,gdt
.limit
));
7798 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,idt
.base
));
7799 tcg_gen_st32_tl(cpu_T
[1], cpu_env
, offsetof(CPUX86State
,idt
.limit
));
7804 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_CR0
);
7805 #if defined TARGET_X86_64 && defined HOST_WORDS_BIGENDIAN
7806 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,cr
[0]) + 4);
7808 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,cr
[0]));
7810 gen_ldst_modrm(env
, s
, modrm
, OT_WORD
, OR_TMP0
, 1);
7814 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7816 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7817 gen_ldst_modrm(env
, s
, modrm
, OT_WORD
, OR_TMP0
, 0);
7818 gen_helper_lmsw(cpu_env
, cpu_T
[0]);
7819 gen_jmp_im(s
->pc
- s
->cs_base
);
7824 if (mod
!= 3) { /* invlpg */
7826 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7828 gen_update_cc_op(s
);
7829 gen_jmp_im(pc_start
- s
->cs_base
);
7830 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7831 gen_helper_invlpg(cpu_env
, cpu_A0
);
7832 gen_jmp_im(s
->pc
- s
->cs_base
);
7837 case 0: /* swapgs */
7838 #ifdef TARGET_X86_64
7841 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7843 tcg_gen_ld_tl(cpu_T
[0], cpu_env
,
7844 offsetof(CPUX86State
,segs
[R_GS
].base
));
7845 tcg_gen_ld_tl(cpu_T
[1], cpu_env
,
7846 offsetof(CPUX86State
,kernelgsbase
));
7847 tcg_gen_st_tl(cpu_T
[1], cpu_env
,
7848 offsetof(CPUX86State
,segs
[R_GS
].base
));
7849 tcg_gen_st_tl(cpu_T
[0], cpu_env
,
7850 offsetof(CPUX86State
,kernelgsbase
));
7858 case 1: /* rdtscp */
7859 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_RDTSCP
))
7861 gen_update_cc_op(s
);
7862 gen_jmp_im(pc_start
- s
->cs_base
);
7865 gen_helper_rdtscp(cpu_env
);
7868 gen_jmp(s
, s
->pc
- s
->cs_base
);
7880 case 0x108: /* invd */
7881 case 0x109: /* wbinvd */
7883 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7885 gen_svm_check_intercept(s
, pc_start
, (b
& 2) ? SVM_EXIT_INVD
: SVM_EXIT_WBINVD
);
7889 case 0x63: /* arpl or movslS (x86_64) */
7890 #ifdef TARGET_X86_64
7893 /* d_ot is the size of destination */
7894 d_ot
= dflag
+ OT_WORD
;
7896 modrm
= cpu_ldub_code(env
, s
->pc
++);
7897 reg
= ((modrm
>> 3) & 7) | rex_r
;
7898 mod
= (modrm
>> 6) & 3;
7899 rm
= (modrm
& 7) | REX_B(s
);
7902 gen_op_mov_TN_reg(OT_LONG
, 0, rm
);
7904 if (d_ot
== OT_QUAD
)
7905 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
7906 gen_op_mov_reg_T0(d_ot
, reg
);
7908 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7909 if (d_ot
== OT_QUAD
) {
7910 gen_op_lds_T0_A0(OT_LONG
+ s
->mem_index
);
7912 gen_op_ld_T0_A0(OT_LONG
+ s
->mem_index
);
7914 gen_op_mov_reg_T0(d_ot
, reg
);
7920 TCGv t0
, t1
, t2
, a0
;
7922 if (!s
->pe
|| s
->vm86
)
7924 t0
= tcg_temp_local_new();
7925 t1
= tcg_temp_local_new();
7926 t2
= tcg_temp_local_new();
7928 modrm
= cpu_ldub_code(env
, s
->pc
++);
7929 reg
= (modrm
>> 3) & 7;
7930 mod
= (modrm
>> 6) & 3;
7933 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7934 gen_op_ld_v(ot
+ s
->mem_index
, t0
, cpu_A0
);
7935 a0
= tcg_temp_local_new();
7936 tcg_gen_mov_tl(a0
, cpu_A0
);
7938 gen_op_mov_v_reg(ot
, t0
, rm
);
7941 gen_op_mov_v_reg(ot
, t1
, reg
);
7942 tcg_gen_andi_tl(cpu_tmp0
, t0
, 3);
7943 tcg_gen_andi_tl(t1
, t1
, 3);
7944 tcg_gen_movi_tl(t2
, 0);
7945 label1
= gen_new_label();
7946 tcg_gen_brcond_tl(TCG_COND_GE
, cpu_tmp0
, t1
, label1
);
7947 tcg_gen_andi_tl(t0
, t0
, ~3);
7948 tcg_gen_or_tl(t0
, t0
, t1
);
7949 tcg_gen_movi_tl(t2
, CC_Z
);
7950 gen_set_label(label1
);
7952 gen_op_st_v(ot
+ s
->mem_index
, t0
, a0
);
7955 gen_op_mov_reg_v(ot
, rm
, t0
);
7957 gen_compute_eflags(s
);
7958 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_Z
);
7959 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, t2
);
7965 case 0x102: /* lar */
7966 case 0x103: /* lsl */
7970 if (!s
->pe
|| s
->vm86
)
7972 ot
= dflag
? OT_LONG
: OT_WORD
;
7973 modrm
= cpu_ldub_code(env
, s
->pc
++);
7974 reg
= ((modrm
>> 3) & 7) | rex_r
;
7975 gen_ldst_modrm(env
, s
, modrm
, OT_WORD
, OR_TMP0
, 0);
7976 t0
= tcg_temp_local_new();
7977 gen_update_cc_op(s
);
7979 gen_helper_lar(t0
, cpu_env
, cpu_T
[0]);
7981 gen_helper_lsl(t0
, cpu_env
, cpu_T
[0]);
7983 tcg_gen_andi_tl(cpu_tmp0
, cpu_cc_src
, CC_Z
);
7984 label1
= gen_new_label();
7985 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
7986 gen_op_mov_reg_v(ot
, reg
, t0
);
7987 gen_set_label(label1
);
7988 set_cc_op(s
, CC_OP_EFLAGS
);
7993 modrm
= cpu_ldub_code(env
, s
->pc
++);
7994 mod
= (modrm
>> 6) & 3;
7995 op
= (modrm
>> 3) & 7;
7997 case 0: /* prefetchnta */
7998 case 1: /* prefetchnt0 */
7999 case 2: /* prefetchnt0 */
8000 case 3: /* prefetchnt0 */
8003 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
8004 /* nothing more to do */
8006 default: /* nop (multi byte) */
8007 gen_nop_modrm(env
, s
, modrm
);
8011 case 0x119 ... 0x11f: /* nop (multi byte) */
8012 modrm
= cpu_ldub_code(env
, s
->pc
++);
8013 gen_nop_modrm(env
, s
, modrm
);
8015 case 0x120: /* mov reg, crN */
8016 case 0x122: /* mov crN, reg */
8018 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
8020 modrm
= cpu_ldub_code(env
, s
->pc
++);
8021 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
8022 * AMD documentation (24594.pdf) and testing of
8023 * intel 386 and 486 processors all show that the mod bits
8024 * are assumed to be 1's, regardless of actual values.
8026 rm
= (modrm
& 7) | REX_B(s
);
8027 reg
= ((modrm
>> 3) & 7) | rex_r
;
8032 if ((prefixes
& PREFIX_LOCK
) && (reg
== 0) &&
8033 (s
->cpuid_ext3_features
& CPUID_EXT3_CR8LEG
)) {
8042 gen_update_cc_op(s
);
8043 gen_jmp_im(pc_start
- s
->cs_base
);
8045 gen_op_mov_TN_reg(ot
, 0, rm
);
8046 gen_helper_write_crN(cpu_env
, tcg_const_i32(reg
),
8048 gen_jmp_im(s
->pc
- s
->cs_base
);
8051 gen_helper_read_crN(cpu_T
[0], cpu_env
, tcg_const_i32(reg
));
8052 gen_op_mov_reg_T0(ot
, rm
);
8060 case 0x121: /* mov reg, drN */
8061 case 0x123: /* mov drN, reg */
8063 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
8065 modrm
= cpu_ldub_code(env
, s
->pc
++);
8066 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
8067 * AMD documentation (24594.pdf) and testing of
8068 * intel 386 and 486 processors all show that the mod bits
8069 * are assumed to be 1's, regardless of actual values.
8071 rm
= (modrm
& 7) | REX_B(s
);
8072 reg
= ((modrm
>> 3) & 7) | rex_r
;
8077 /* XXX: do it dynamically with CR4.DE bit */
8078 if (reg
== 4 || reg
== 5 || reg
>= 8)
8081 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_DR0
+ reg
);
8082 gen_op_mov_TN_reg(ot
, 0, rm
);
8083 gen_helper_movl_drN_T0(cpu_env
, tcg_const_i32(reg
), cpu_T
[0]);
8084 gen_jmp_im(s
->pc
- s
->cs_base
);
8087 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_DR0
+ reg
);
8088 tcg_gen_ld_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,dr
[reg
]));
8089 gen_op_mov_reg_T0(ot
, rm
);
8093 case 0x106: /* clts */
8095 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
8097 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
8098 gen_helper_clts(cpu_env
);
8099 /* abort block because static cpu state changed */
8100 gen_jmp_im(s
->pc
- s
->cs_base
);
8104 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
8105 case 0x1c3: /* MOVNTI reg, mem */
8106 if (!(s
->cpuid_features
& CPUID_SSE2
))
8108 ot
= s
->dflag
== 2 ? OT_QUAD
: OT_LONG
;
8109 modrm
= cpu_ldub_code(env
, s
->pc
++);
8110 mod
= (modrm
>> 6) & 3;
8113 reg
= ((modrm
>> 3) & 7) | rex_r
;
8114 /* generate a generic store */
8115 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
8118 modrm
= cpu_ldub_code(env
, s
->pc
++);
8119 mod
= (modrm
>> 6) & 3;
8120 op
= (modrm
>> 3) & 7;
8122 case 0: /* fxsave */
8123 if (mod
== 3 || !(s
->cpuid_features
& CPUID_FXSR
) ||
8124 (s
->prefix
& PREFIX_LOCK
))
8126 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
8127 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8130 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
8131 gen_update_cc_op(s
);
8132 gen_jmp_im(pc_start
- s
->cs_base
);
8133 gen_helper_fxsave(cpu_env
, cpu_A0
, tcg_const_i32((s
->dflag
== 2)));
8135 case 1: /* fxrstor */
8136 if (mod
== 3 || !(s
->cpuid_features
& CPUID_FXSR
) ||
8137 (s
->prefix
& PREFIX_LOCK
))
8139 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
8140 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8143 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
8144 gen_update_cc_op(s
);
8145 gen_jmp_im(pc_start
- s
->cs_base
);
8146 gen_helper_fxrstor(cpu_env
, cpu_A0
,
8147 tcg_const_i32((s
->dflag
== 2)));
8149 case 2: /* ldmxcsr */
8150 case 3: /* stmxcsr */
8151 if (s
->flags
& HF_TS_MASK
) {
8152 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8155 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
) ||
8158 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
8160 gen_op_ld_T0_A0(OT_LONG
+ s
->mem_index
);
8161 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
8162 gen_helper_ldmxcsr(cpu_env
, cpu_tmp2_i32
);
8164 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, mxcsr
));
8165 gen_op_st_T0_A0(OT_LONG
+ s
->mem_index
);
8168 case 5: /* lfence */
8169 case 6: /* mfence */
8170 if ((modrm
& 0xc7) != 0xc0 || !(s
->cpuid_features
& CPUID_SSE2
))
8173 case 7: /* sfence / clflush */
8174 if ((modrm
& 0xc7) == 0xc0) {
8176 /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX */
8177 if (!(s
->cpuid_features
& CPUID_SSE
))
8181 if (!(s
->cpuid_features
& CPUID_CLFLUSH
))
8183 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
8190 case 0x10d: /* 3DNow! prefetch(w) */
8191 modrm
= cpu_ldub_code(env
, s
->pc
++);
8192 mod
= (modrm
>> 6) & 3;
8195 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
8196 /* ignore for now */
8198 case 0x1aa: /* rsm */
8199 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_RSM
);
8200 if (!(s
->flags
& HF_SMM_MASK
))
8202 gen_update_cc_op(s
);
8203 gen_jmp_im(s
->pc
- s
->cs_base
);
8204 gen_helper_rsm(cpu_env
);
8207 case 0x1b8: /* SSE4.2 popcnt */
8208 if ((prefixes
& (PREFIX_REPZ
| PREFIX_LOCK
| PREFIX_REPNZ
)) !=
8211 if (!(s
->cpuid_ext_features
& CPUID_EXT_POPCNT
))
8214 modrm
= cpu_ldub_code(env
, s
->pc
++);
8215 reg
= ((modrm
>> 3) & 7) | rex_r
;
8217 if (s
->prefix
& PREFIX_DATA
)
8219 else if (s
->dflag
!= 2)
8224 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
8225 gen_helper_popcnt(cpu_T
[0], cpu_env
, cpu_T
[0], tcg_const_i32(ot
));
8226 gen_op_mov_reg_T0(ot
, reg
);
8228 set_cc_op(s
, CC_OP_EFLAGS
);
8230 case 0x10e ... 0x10f:
8231 /* 3DNow! instructions, ignore prefixes */
8232 s
->prefix
&= ~(PREFIX_REPZ
| PREFIX_REPNZ
| PREFIX_DATA
);
8233 case 0x110 ... 0x117:
8234 case 0x128 ... 0x12f:
8235 case 0x138 ... 0x13a:
8236 case 0x150 ... 0x179:
8237 case 0x17c ... 0x17f:
8239 case 0x1c4 ... 0x1c6:
8240 case 0x1d0 ... 0x1fe:
8241 gen_sse(env
, s
, b
, pc_start
, rex_r
);
8246 /* lock generation */
8247 if (s
->prefix
& PREFIX_LOCK
)
8248 gen_helper_unlock();
8251 if (s
->prefix
& PREFIX_LOCK
)
8252 gen_helper_unlock();
8253 /* XXX: ensure that no lock was generated */
8254 gen_exception(s
, EXCP06_ILLOP
, pc_start
- s
->cs_base
);
8258 void optimize_flags_init(void)
8260 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
8261 cpu_cc_op
= tcg_global_mem_new_i32(TCG_AREG0
,
8262 offsetof(CPUX86State
, cc_op
), "cc_op");
8263 cpu_cc_dst
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_dst
),
8265 cpu_cc_src
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_src
),
8267 cpu_cc_src2
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_src2
),
8270 #ifdef TARGET_X86_64
8271 cpu_regs
[R_EAX
] = tcg_global_mem_new_i64(TCG_AREG0
,
8272 offsetof(CPUX86State
, regs
[R_EAX
]), "rax");
8273 cpu_regs
[R_ECX
] = tcg_global_mem_new_i64(TCG_AREG0
,
8274 offsetof(CPUX86State
, regs
[R_ECX
]), "rcx");
8275 cpu_regs
[R_EDX
] = tcg_global_mem_new_i64(TCG_AREG0
,
8276 offsetof(CPUX86State
, regs
[R_EDX
]), "rdx");
8277 cpu_regs
[R_EBX
] = tcg_global_mem_new_i64(TCG_AREG0
,
8278 offsetof(CPUX86State
, regs
[R_EBX
]), "rbx");
8279 cpu_regs
[R_ESP
] = tcg_global_mem_new_i64(TCG_AREG0
,
8280 offsetof(CPUX86State
, regs
[R_ESP
]), "rsp");
8281 cpu_regs
[R_EBP
] = tcg_global_mem_new_i64(TCG_AREG0
,
8282 offsetof(CPUX86State
, regs
[R_EBP
]), "rbp");
8283 cpu_regs
[R_ESI
] = tcg_global_mem_new_i64(TCG_AREG0
,
8284 offsetof(CPUX86State
, regs
[R_ESI
]), "rsi");
8285 cpu_regs
[R_EDI
] = tcg_global_mem_new_i64(TCG_AREG0
,
8286 offsetof(CPUX86State
, regs
[R_EDI
]), "rdi");
8287 cpu_regs
[8] = tcg_global_mem_new_i64(TCG_AREG0
,
8288 offsetof(CPUX86State
, regs
[8]), "r8");
8289 cpu_regs
[9] = tcg_global_mem_new_i64(TCG_AREG0
,
8290 offsetof(CPUX86State
, regs
[9]), "r9");
8291 cpu_regs
[10] = tcg_global_mem_new_i64(TCG_AREG0
,
8292 offsetof(CPUX86State
, regs
[10]), "r10");
8293 cpu_regs
[11] = tcg_global_mem_new_i64(TCG_AREG0
,
8294 offsetof(CPUX86State
, regs
[11]), "r11");
8295 cpu_regs
[12] = tcg_global_mem_new_i64(TCG_AREG0
,
8296 offsetof(CPUX86State
, regs
[12]), "r12");
8297 cpu_regs
[13] = tcg_global_mem_new_i64(TCG_AREG0
,
8298 offsetof(CPUX86State
, regs
[13]), "r13");
8299 cpu_regs
[14] = tcg_global_mem_new_i64(TCG_AREG0
,
8300 offsetof(CPUX86State
, regs
[14]), "r14");
8301 cpu_regs
[15] = tcg_global_mem_new_i64(TCG_AREG0
,
8302 offsetof(CPUX86State
, regs
[15]), "r15");
8304 cpu_regs
[R_EAX
] = tcg_global_mem_new_i32(TCG_AREG0
,
8305 offsetof(CPUX86State
, regs
[R_EAX
]), "eax");
8306 cpu_regs
[R_ECX
] = tcg_global_mem_new_i32(TCG_AREG0
,
8307 offsetof(CPUX86State
, regs
[R_ECX
]), "ecx");
8308 cpu_regs
[R_EDX
] = tcg_global_mem_new_i32(TCG_AREG0
,
8309 offsetof(CPUX86State
, regs
[R_EDX
]), "edx");
8310 cpu_regs
[R_EBX
] = tcg_global_mem_new_i32(TCG_AREG0
,
8311 offsetof(CPUX86State
, regs
[R_EBX
]), "ebx");
8312 cpu_regs
[R_ESP
] = tcg_global_mem_new_i32(TCG_AREG0
,
8313 offsetof(CPUX86State
, regs
[R_ESP
]), "esp");
8314 cpu_regs
[R_EBP
] = tcg_global_mem_new_i32(TCG_AREG0
,
8315 offsetof(CPUX86State
, regs
[R_EBP
]), "ebp");
8316 cpu_regs
[R_ESI
] = tcg_global_mem_new_i32(TCG_AREG0
,
8317 offsetof(CPUX86State
, regs
[R_ESI
]), "esi");
8318 cpu_regs
[R_EDI
] = tcg_global_mem_new_i32(TCG_AREG0
,
8319 offsetof(CPUX86State
, regs
[R_EDI
]), "edi");
8322 /* register helpers */
8323 #define GEN_HELPER 2
8327 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
8328 basic block 'tb'. If search_pc is TRUE, also generate PC
8329 information for each intermediate instruction. */
8330 static inline void gen_intermediate_code_internal(CPUX86State
*env
,
8331 TranslationBlock
*tb
,
8334 DisasContext dc1
, *dc
= &dc1
;
8335 target_ulong pc_ptr
;
8336 uint16_t *gen_opc_end
;
8340 target_ulong pc_start
;
8341 target_ulong cs_base
;
8345 /* generate intermediate code */
8347 cs_base
= tb
->cs_base
;
8350 dc
->pe
= (flags
>> HF_PE_SHIFT
) & 1;
8351 dc
->code32
= (flags
>> HF_CS32_SHIFT
) & 1;
8352 dc
->ss32
= (flags
>> HF_SS32_SHIFT
) & 1;
8353 dc
->addseg
= (flags
>> HF_ADDSEG_SHIFT
) & 1;
8355 dc
->vm86
= (flags
>> VM_SHIFT
) & 1;
8356 dc
->cpl
= (flags
>> HF_CPL_SHIFT
) & 3;
8357 dc
->iopl
= (flags
>> IOPL_SHIFT
) & 3;
8358 dc
->tf
= (flags
>> TF_SHIFT
) & 1;
8359 dc
->singlestep_enabled
= env
->singlestep_enabled
;
8360 dc
->cc_op
= CC_OP_DYNAMIC
;
8361 dc
->cc_op_dirty
= false;
8362 dc
->cs_base
= cs_base
;
8364 dc
->popl_esp_hack
= 0;
8365 /* select memory access functions */
8367 if (flags
& HF_SOFTMMU_MASK
) {
8368 dc
->mem_index
= (cpu_mmu_index(env
) + 1) << 2;
8370 dc
->cpuid_features
= env
->cpuid_features
;
8371 dc
->cpuid_ext_features
= env
->cpuid_ext_features
;
8372 dc
->cpuid_ext2_features
= env
->cpuid_ext2_features
;
8373 dc
->cpuid_ext3_features
= env
->cpuid_ext3_features
;
8374 dc
->cpuid_7_0_ebx_features
= env
->cpuid_7_0_ebx_features
;
8375 #ifdef TARGET_X86_64
8376 dc
->lma
= (flags
>> HF_LMA_SHIFT
) & 1;
8377 dc
->code64
= (flags
>> HF_CS64_SHIFT
) & 1;
8380 dc
->jmp_opt
= !(dc
->tf
|| env
->singlestep_enabled
||
8381 (flags
& HF_INHIBIT_IRQ_MASK
)
8382 #ifndef CONFIG_SOFTMMU
8383 || (flags
& HF_SOFTMMU_MASK
)
8387 /* check addseg logic */
8388 if (!dc
->addseg
&& (dc
->vm86
|| !dc
->pe
|| !dc
->code32
))
8389 printf("ERROR addseg\n");
8392 cpu_T
[0] = tcg_temp_new();
8393 cpu_T
[1] = tcg_temp_new();
8394 cpu_A0
= tcg_temp_new();
8396 cpu_tmp0
= tcg_temp_new();
8397 cpu_tmp1_i64
= tcg_temp_new_i64();
8398 cpu_tmp2_i32
= tcg_temp_new_i32();
8399 cpu_tmp3_i32
= tcg_temp_new_i32();
8400 cpu_tmp4
= tcg_temp_new();
8401 cpu_tmp5
= tcg_temp_new();
8402 cpu_ptr0
= tcg_temp_new_ptr();
8403 cpu_ptr1
= tcg_temp_new_ptr();
8404 cpu_cc_srcT
= tcg_temp_local_new();
8406 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
8408 dc
->is_jmp
= DISAS_NEXT
;
8412 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
8414 max_insns
= CF_COUNT_MASK
;
8418 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
8419 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
8420 if (bp
->pc
== pc_ptr
&&
8421 !((bp
->flags
& BP_CPU
) && (tb
->flags
& HF_RF_MASK
))) {
8422 gen_debug(dc
, pc_ptr
- dc
->cs_base
);
8428 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
8432 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
8434 tcg_ctx
.gen_opc_pc
[lj
] = pc_ptr
;
8435 gen_opc_cc_op
[lj
] = dc
->cc_op
;
8436 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
8437 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
8439 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
8442 pc_ptr
= disas_insn(env
, dc
, pc_ptr
);
8444 /* stop translation if indicated */
8447 /* if single step mode, we generate only one instruction and
8448 generate an exception */
8449 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
8450 the flag and abort the translation to give the irqs a
8451 change to be happen */
8452 if (dc
->tf
|| dc
->singlestep_enabled
||
8453 (flags
& HF_INHIBIT_IRQ_MASK
)) {
8454 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8458 /* if too long translation, stop generation too */
8459 if (tcg_ctx
.gen_opc_ptr
>= gen_opc_end
||
8460 (pc_ptr
- pc_start
) >= (TARGET_PAGE_SIZE
- 32) ||
8461 num_insns
>= max_insns
) {
8462 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8467 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8472 if (tb
->cflags
& CF_LAST_IO
)
8474 gen_icount_end(tb
, num_insns
);
8475 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
8476 /* we don't forget to fill the last values */
8478 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
8481 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
8485 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
8487 qemu_log("----------------\n");
8488 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
8489 #ifdef TARGET_X86_64
8494 disas_flags
= !dc
->code32
;
8495 log_target_disas(env
, pc_start
, pc_ptr
- pc_start
, disas_flags
);
8501 tb
->size
= pc_ptr
- pc_start
;
8502 tb
->icount
= num_insns
;
8506 void gen_intermediate_code(CPUX86State
*env
, TranslationBlock
*tb
)
8508 gen_intermediate_code_internal(env
, tb
, 0);
8511 void gen_intermediate_code_pc(CPUX86State
*env
, TranslationBlock
*tb
)
8513 gen_intermediate_code_internal(env
, tb
, 1);
8516 void restore_state_to_opc(CPUX86State
*env
, TranslationBlock
*tb
, int pc_pos
)
8520 if (qemu_loglevel_mask(CPU_LOG_TB_OP
)) {
8522 qemu_log("RESTORE:\n");
8523 for(i
= 0;i
<= pc_pos
; i
++) {
8524 if (tcg_ctx
.gen_opc_instr_start
[i
]) {
8525 qemu_log("0x%04x: " TARGET_FMT_lx
"\n", i
,
8526 tcg_ctx
.gen_opc_pc
[i
]);
8529 qemu_log("pc_pos=0x%x eip=" TARGET_FMT_lx
" cs_base=%x\n",
8530 pc_pos
, tcg_ctx
.gen_opc_pc
[pc_pos
] - tb
->cs_base
,
8531 (uint32_t)tb
->cs_base
);
8534 env
->eip
= tcg_ctx
.gen_opc_pc
[pc_pos
] - tb
->cs_base
;
8535 cc_op
= gen_opc_cc_op
[pc_pos
];
8536 if (cc_op
!= CC_OP_DYNAMIC
)