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
,
218 static void set_cc_op(DisasContext
*s
, CCOp op
)
222 if (s
->cc_op
== op
) {
226 /* Discard CC computation that will no longer be used. */
227 dead
= cc_op_live
[s
->cc_op
] & ~cc_op_live
[op
];
228 if (dead
& USES_CC_DST
) {
229 tcg_gen_discard_tl(cpu_cc_dst
);
231 if (dead
& USES_CC_SRC
) {
232 tcg_gen_discard_tl(cpu_cc_src
);
234 if (dead
& USES_CC_SRC2
) {
235 tcg_gen_discard_tl(cpu_cc_src2
);
237 if (dead
& USES_CC_SRCT
) {
238 tcg_gen_discard_tl(cpu_cc_srcT
);
242 /* The DYNAMIC setting is translator only, and should never be
243 stored. Thus we always consider it clean. */
244 s
->cc_op_dirty
= (op
!= CC_OP_DYNAMIC
);
247 static void gen_update_cc_op(DisasContext
*s
)
249 if (s
->cc_op_dirty
) {
250 tcg_gen_movi_i32(cpu_cc_op
, s
->cc_op
);
251 s
->cc_op_dirty
= false;
255 static inline void gen_op_movl_T0_0(void)
257 tcg_gen_movi_tl(cpu_T
[0], 0);
260 static inline void gen_op_movl_T0_im(int32_t val
)
262 tcg_gen_movi_tl(cpu_T
[0], val
);
265 static inline void gen_op_movl_T0_imu(uint32_t val
)
267 tcg_gen_movi_tl(cpu_T
[0], val
);
270 static inline void gen_op_movl_T1_im(int32_t val
)
272 tcg_gen_movi_tl(cpu_T
[1], val
);
275 static inline void gen_op_movl_T1_imu(uint32_t val
)
277 tcg_gen_movi_tl(cpu_T
[1], val
);
280 static inline void gen_op_movl_A0_im(uint32_t val
)
282 tcg_gen_movi_tl(cpu_A0
, val
);
286 static inline void gen_op_movq_A0_im(int64_t val
)
288 tcg_gen_movi_tl(cpu_A0
, val
);
292 static inline void gen_movtl_T0_im(target_ulong val
)
294 tcg_gen_movi_tl(cpu_T
[0], val
);
297 static inline void gen_movtl_T1_im(target_ulong val
)
299 tcg_gen_movi_tl(cpu_T
[1], val
);
302 static inline void gen_op_andl_T0_ffff(void)
304 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffff);
307 static inline void gen_op_andl_T0_im(uint32_t val
)
309 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], val
);
312 static inline void gen_op_movl_T0_T1(void)
314 tcg_gen_mov_tl(cpu_T
[0], cpu_T
[1]);
317 static inline void gen_op_andl_A0_ffff(void)
319 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffff);
324 #define NB_OP_SIZES 4
326 #else /* !TARGET_X86_64 */
328 #define NB_OP_SIZES 3
330 #endif /* !TARGET_X86_64 */
332 #if defined(HOST_WORDS_BIGENDIAN)
333 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
334 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
335 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
336 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
337 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
339 #define REG_B_OFFSET 0
340 #define REG_H_OFFSET 1
341 #define REG_W_OFFSET 0
342 #define REG_L_OFFSET 0
343 #define REG_LH_OFFSET 4
346 /* In instruction encodings for byte register accesses the
347 * register number usually indicates "low 8 bits of register N";
348 * however there are some special cases where N 4..7 indicates
349 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
350 * true for this special case, false otherwise.
352 static inline bool byte_reg_is_xH(int reg
)
358 if (reg
>= 8 || x86_64_hregs
) {
365 static inline void gen_op_mov_reg_v(int ot
, int reg
, TCGv t0
)
369 if (!byte_reg_is_xH(reg
)) {
370 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 8);
372 tcg_gen_deposit_tl(cpu_regs
[reg
- 4], cpu_regs
[reg
- 4], t0
, 8, 8);
376 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], t0
, 0, 16);
378 default: /* XXX this shouldn't be reached; abort? */
380 /* For x86_64, this sets the higher half of register to zero.
381 For i386, this is equivalent to a mov. */
382 tcg_gen_ext32u_tl(cpu_regs
[reg
], t0
);
386 tcg_gen_mov_tl(cpu_regs
[reg
], t0
);
392 static inline void gen_op_mov_reg_T0(int ot
, int reg
)
394 gen_op_mov_reg_v(ot
, reg
, cpu_T
[0]);
397 static inline void gen_op_mov_reg_T1(int ot
, int reg
)
399 gen_op_mov_reg_v(ot
, reg
, cpu_T
[1]);
402 static inline void gen_op_mov_reg_A0(int size
, int reg
)
406 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], cpu_A0
, 0, 16);
408 default: /* XXX this shouldn't be reached; abort? */
410 /* For x86_64, this sets the higher half of register to zero.
411 For i386, this is equivalent to a mov. */
412 tcg_gen_ext32u_tl(cpu_regs
[reg
], cpu_A0
);
416 tcg_gen_mov_tl(cpu_regs
[reg
], cpu_A0
);
422 static inline void gen_op_mov_v_reg(int ot
, TCGv t0
, int reg
)
424 if (ot
== OT_BYTE
&& byte_reg_is_xH(reg
)) {
425 tcg_gen_shri_tl(t0
, cpu_regs
[reg
- 4], 8);
426 tcg_gen_ext8u_tl(t0
, t0
);
428 tcg_gen_mov_tl(t0
, cpu_regs
[reg
]);
432 static inline void gen_op_mov_TN_reg(int ot
, int t_index
, int reg
)
434 gen_op_mov_v_reg(ot
, cpu_T
[t_index
], reg
);
437 static inline void gen_op_movl_A0_reg(int reg
)
439 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[reg
]);
442 static inline void gen_op_addl_A0_im(int32_t val
)
444 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, val
);
446 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffffffff);
451 static inline void gen_op_addq_A0_im(int64_t val
)
453 tcg_gen_addi_tl(cpu_A0
, cpu_A0
, val
);
457 static void gen_add_A0_im(DisasContext
*s
, int val
)
461 gen_op_addq_A0_im(val
);
464 gen_op_addl_A0_im(val
);
467 static inline void gen_op_addl_T0_T1(void)
469 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
472 static inline void gen_op_jmp_T0(void)
474 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, eip
));
477 static inline void gen_op_add_reg_im(int size
, int reg
, int32_t val
)
481 tcg_gen_addi_tl(cpu_tmp0
, cpu_regs
[reg
], val
);
482 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], cpu_tmp0
, 0, 16);
485 tcg_gen_addi_tl(cpu_tmp0
, cpu_regs
[reg
], val
);
486 /* For x86_64, this sets the higher half of register to zero.
487 For i386, this is equivalent to a nop. */
488 tcg_gen_ext32u_tl(cpu_tmp0
, cpu_tmp0
);
489 tcg_gen_mov_tl(cpu_regs
[reg
], cpu_tmp0
);
493 tcg_gen_addi_tl(cpu_regs
[reg
], cpu_regs
[reg
], val
);
499 static inline void gen_op_add_reg_T0(int size
, int reg
)
503 tcg_gen_add_tl(cpu_tmp0
, cpu_regs
[reg
], cpu_T
[0]);
504 tcg_gen_deposit_tl(cpu_regs
[reg
], cpu_regs
[reg
], cpu_tmp0
, 0, 16);
507 tcg_gen_add_tl(cpu_tmp0
, cpu_regs
[reg
], cpu_T
[0]);
508 /* For x86_64, this sets the higher half of register to zero.
509 For i386, this is equivalent to a nop. */
510 tcg_gen_ext32u_tl(cpu_tmp0
, cpu_tmp0
);
511 tcg_gen_mov_tl(cpu_regs
[reg
], cpu_tmp0
);
515 tcg_gen_add_tl(cpu_regs
[reg
], cpu_regs
[reg
], cpu_T
[0]);
521 static inline void gen_op_addl_A0_reg_sN(int shift
, int reg
)
523 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[reg
]);
525 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, shift
);
526 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
527 /* For x86_64, this sets the higher half of register to zero.
528 For i386, this is equivalent to a nop. */
529 tcg_gen_ext32u_tl(cpu_A0
, cpu_A0
);
532 static inline void gen_op_movl_A0_seg(int reg
)
534 tcg_gen_ld32u_tl(cpu_A0
, cpu_env
, offsetof(CPUX86State
, segs
[reg
].base
) + REG_L_OFFSET
);
537 static inline void gen_op_addl_A0_seg(DisasContext
*s
, int reg
)
539 tcg_gen_ld_tl(cpu_tmp0
, cpu_env
, offsetof(CPUX86State
, segs
[reg
].base
));
542 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffffffff);
543 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
545 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
546 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffffffff);
549 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
554 static inline void gen_op_movq_A0_seg(int reg
)
556 tcg_gen_ld_tl(cpu_A0
, cpu_env
, offsetof(CPUX86State
, segs
[reg
].base
));
559 static inline void gen_op_addq_A0_seg(int reg
)
561 tcg_gen_ld_tl(cpu_tmp0
, cpu_env
, offsetof(CPUX86State
, segs
[reg
].base
));
562 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
565 static inline void gen_op_movq_A0_reg(int reg
)
567 tcg_gen_mov_tl(cpu_A0
, cpu_regs
[reg
]);
570 static inline void gen_op_addq_A0_reg_sN(int shift
, int reg
)
572 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[reg
]);
574 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, shift
);
575 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
579 static inline void gen_op_lds_T0_A0(int idx
)
581 int mem_index
= (idx
>> 2) - 1;
584 tcg_gen_qemu_ld8s(cpu_T
[0], cpu_A0
, mem_index
);
587 tcg_gen_qemu_ld16s(cpu_T
[0], cpu_A0
, mem_index
);
591 tcg_gen_qemu_ld32s(cpu_T
[0], cpu_A0
, mem_index
);
596 static inline void gen_op_ld_v(int idx
, TCGv t0
, TCGv a0
)
598 int mem_index
= (idx
>> 2) - 1;
601 tcg_gen_qemu_ld8u(t0
, a0
, mem_index
);
604 tcg_gen_qemu_ld16u(t0
, a0
, mem_index
);
607 tcg_gen_qemu_ld32u(t0
, a0
, mem_index
);
611 /* Should never happen on 32-bit targets. */
613 tcg_gen_qemu_ld64(t0
, a0
, mem_index
);
619 /* XXX: always use ldu or lds */
620 static inline void gen_op_ld_T0_A0(int idx
)
622 gen_op_ld_v(idx
, cpu_T
[0], cpu_A0
);
625 static inline void gen_op_ldu_T0_A0(int idx
)
627 gen_op_ld_v(idx
, cpu_T
[0], cpu_A0
);
630 static inline void gen_op_ld_T1_A0(int idx
)
632 gen_op_ld_v(idx
, cpu_T
[1], cpu_A0
);
635 static inline void gen_op_st_v(int idx
, TCGv t0
, TCGv a0
)
637 int mem_index
= (idx
>> 2) - 1;
640 tcg_gen_qemu_st8(t0
, a0
, mem_index
);
643 tcg_gen_qemu_st16(t0
, a0
, mem_index
);
646 tcg_gen_qemu_st32(t0
, a0
, mem_index
);
650 /* Should never happen on 32-bit targets. */
652 tcg_gen_qemu_st64(t0
, a0
, mem_index
);
658 static inline void gen_op_st_T0_A0(int idx
)
660 gen_op_st_v(idx
, cpu_T
[0], cpu_A0
);
663 static inline void gen_op_st_T1_A0(int idx
)
665 gen_op_st_v(idx
, cpu_T
[1], cpu_A0
);
668 static inline void gen_jmp_im(target_ulong pc
)
670 tcg_gen_movi_tl(cpu_tmp0
, pc
);
671 tcg_gen_st_tl(cpu_tmp0
, cpu_env
, offsetof(CPUX86State
, eip
));
674 static inline void gen_string_movl_A0_ESI(DisasContext
*s
)
678 override
= s
->override
;
682 gen_op_movq_A0_seg(override
);
683 gen_op_addq_A0_reg_sN(0, R_ESI
);
685 gen_op_movq_A0_reg(R_ESI
);
691 if (s
->addseg
&& override
< 0)
694 gen_op_movl_A0_seg(override
);
695 gen_op_addl_A0_reg_sN(0, R_ESI
);
697 gen_op_movl_A0_reg(R_ESI
);
700 /* 16 address, always override */
703 gen_op_movl_A0_reg(R_ESI
);
704 gen_op_andl_A0_ffff();
705 gen_op_addl_A0_seg(s
, override
);
709 static inline void gen_string_movl_A0_EDI(DisasContext
*s
)
713 gen_op_movq_A0_reg(R_EDI
);
718 gen_op_movl_A0_seg(R_ES
);
719 gen_op_addl_A0_reg_sN(0, R_EDI
);
721 gen_op_movl_A0_reg(R_EDI
);
724 gen_op_movl_A0_reg(R_EDI
);
725 gen_op_andl_A0_ffff();
726 gen_op_addl_A0_seg(s
, R_ES
);
730 static inline void gen_op_movl_T0_Dshift(int ot
)
732 tcg_gen_ld32s_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, df
));
733 tcg_gen_shli_tl(cpu_T
[0], cpu_T
[0], ot
);
736 static TCGv
gen_ext_tl(TCGv dst
, TCGv src
, int size
, bool sign
)
741 tcg_gen_ext8s_tl(dst
, src
);
743 tcg_gen_ext8u_tl(dst
, src
);
748 tcg_gen_ext16s_tl(dst
, src
);
750 tcg_gen_ext16u_tl(dst
, src
);
756 tcg_gen_ext32s_tl(dst
, src
);
758 tcg_gen_ext32u_tl(dst
, src
);
767 static void gen_extu(int ot
, TCGv reg
)
769 gen_ext_tl(reg
, reg
, ot
, false);
772 static void gen_exts(int ot
, TCGv reg
)
774 gen_ext_tl(reg
, reg
, ot
, true);
777 static inline void gen_op_jnz_ecx(int size
, int label1
)
779 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[R_ECX
]);
780 gen_extu(size
+ 1, cpu_tmp0
);
781 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_tmp0
, 0, label1
);
784 static inline void gen_op_jz_ecx(int size
, int label1
)
786 tcg_gen_mov_tl(cpu_tmp0
, cpu_regs
[R_ECX
]);
787 gen_extu(size
+ 1, cpu_tmp0
);
788 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
791 static void gen_helper_in_func(int ot
, TCGv v
, TCGv_i32 n
)
795 gen_helper_inb(v
, n
);
798 gen_helper_inw(v
, n
);
801 gen_helper_inl(v
, n
);
806 static void gen_helper_out_func(int ot
, TCGv_i32 v
, TCGv_i32 n
)
810 gen_helper_outb(v
, n
);
813 gen_helper_outw(v
, n
);
816 gen_helper_outl(v
, n
);
821 static void gen_check_io(DisasContext
*s
, int ot
, target_ulong cur_eip
,
825 target_ulong next_eip
;
828 if (s
->pe
&& (s
->cpl
> s
->iopl
|| s
->vm86
)) {
832 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
835 gen_helper_check_iob(cpu_env
, cpu_tmp2_i32
);
838 gen_helper_check_iow(cpu_env
, cpu_tmp2_i32
);
841 gen_helper_check_iol(cpu_env
, cpu_tmp2_i32
);
845 if(s
->flags
& HF_SVMI_MASK
) {
850 svm_flags
|= (1 << (4 + ot
));
851 next_eip
= s
->pc
- s
->cs_base
;
852 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
853 gen_helper_svm_check_io(cpu_env
, cpu_tmp2_i32
,
854 tcg_const_i32(svm_flags
),
855 tcg_const_i32(next_eip
- cur_eip
));
859 static inline void gen_movs(DisasContext
*s
, int ot
)
861 gen_string_movl_A0_ESI(s
);
862 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
863 gen_string_movl_A0_EDI(s
);
864 gen_op_st_T0_A0(ot
+ s
->mem_index
);
865 gen_op_movl_T0_Dshift(ot
);
866 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
867 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
870 static void gen_op_update1_cc(void)
872 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
875 static void gen_op_update2_cc(void)
877 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
878 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
881 static void gen_op_update3_cc(TCGv reg
)
883 tcg_gen_mov_tl(cpu_cc_src2
, reg
);
884 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
885 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
888 static inline void gen_op_testl_T0_T1_cc(void)
890 tcg_gen_and_tl(cpu_cc_dst
, cpu_T
[0], cpu_T
[1]);
893 static void gen_op_update_neg_cc(void)
895 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
896 tcg_gen_neg_tl(cpu_cc_src
, cpu_T
[0]);
897 tcg_gen_movi_tl(cpu_cc_srcT
, 0);
900 /* compute all eflags to cc_src */
901 static void gen_compute_eflags(DisasContext
*s
)
903 TCGv zero
, dst
, src1
, src2
;
906 if (s
->cc_op
== CC_OP_EFLAGS
) {
915 /* Take care to not read values that are not live. */
916 live
= cc_op_live
[s
->cc_op
] & ~USES_CC_SRCT
;
917 dead
= live
^ (USES_CC_DST
| USES_CC_SRC
| USES_CC_SRC2
);
919 zero
= tcg_const_tl(0);
920 if (dead
& USES_CC_DST
) {
923 if (dead
& USES_CC_SRC
) {
926 if (dead
& USES_CC_SRC2
) {
932 gen_helper_cc_compute_all(cpu_cc_src
, dst
, src1
, src2
, cpu_cc_op
);
933 set_cc_op(s
, CC_OP_EFLAGS
);
940 typedef struct CCPrepare
{
950 /* compute eflags.C to reg */
951 static CCPrepare
gen_prepare_eflags_c(DisasContext
*s
, TCGv reg
)
957 case CC_OP_SUBB
... CC_OP_SUBQ
:
958 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
959 size
= s
->cc_op
- CC_OP_SUBB
;
960 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
961 /* If no temporary was used, be careful not to alias t1 and t0. */
962 t0
= TCGV_EQUAL(t1
, cpu_cc_src
) ? cpu_tmp0
: reg
;
963 tcg_gen_mov_tl(t0
, cpu_cc_srcT
);
967 case CC_OP_ADDB
... CC_OP_ADDQ
:
968 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
969 size
= s
->cc_op
- CC_OP_ADDB
;
970 t1
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
971 t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
973 return (CCPrepare
) { .cond
= TCG_COND_LTU
, .reg
= t0
,
974 .reg2
= t1
, .mask
= -1, .use_reg2
= true };
976 case CC_OP_LOGICB
... CC_OP_LOGICQ
:
977 return (CCPrepare
) { .cond
= TCG_COND_NEVER
, .mask
= -1 };
979 case CC_OP_INCB
... CC_OP_INCQ
:
980 case CC_OP_DECB
... CC_OP_DECQ
:
981 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
982 .mask
= -1, .no_setcond
= true };
984 case CC_OP_SHLB
... CC_OP_SHLQ
:
985 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
986 size
= s
->cc_op
- CC_OP_SHLB
;
987 shift
= (8 << size
) - 1;
988 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
989 .mask
= (target_ulong
)1 << shift
};
991 case CC_OP_MULB
... CC_OP_MULQ
:
992 return (CCPrepare
) { .cond
= TCG_COND_NE
,
993 .reg
= cpu_cc_src
, .mask
= -1 };
995 case CC_OP_BMILGB
... CC_OP_BMILGQ
:
996 size
= s
->cc_op
- CC_OP_BMILGB
;
997 t0
= gen_ext_tl(reg
, cpu_cc_src
, size
, false);
998 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
1002 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_dst
,
1003 .mask
= -1, .no_setcond
= true };
1006 case CC_OP_SARB
... CC_OP_SARQ
:
1008 return (CCPrepare
) { .cond
= TCG_COND_NE
,
1009 .reg
= cpu_cc_src
, .mask
= CC_C
};
1012 /* The need to compute only C from CC_OP_DYNAMIC is important
1013 in efficiently implementing e.g. INC at the start of a TB. */
1014 gen_update_cc_op(s
);
1015 gen_helper_cc_compute_c(reg
, cpu_cc_dst
, cpu_cc_src
,
1016 cpu_cc_src2
, cpu_cc_op
);
1017 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
1018 .mask
= -1, .no_setcond
= true };
1022 /* compute eflags.P to reg */
1023 static CCPrepare
gen_prepare_eflags_p(DisasContext
*s
, TCGv reg
)
1025 gen_compute_eflags(s
);
1026 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
1030 /* compute eflags.S to reg */
1031 static CCPrepare
gen_prepare_eflags_s(DisasContext
*s
, TCGv reg
)
1035 gen_compute_eflags(s
);
1041 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
1045 int size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
1046 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, true);
1047 return (CCPrepare
) { .cond
= TCG_COND_LT
, .reg
= t0
, .mask
= -1 };
1052 /* compute eflags.O to reg */
1053 static CCPrepare
gen_prepare_eflags_o(DisasContext
*s
, TCGv reg
)
1058 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src2
,
1059 .mask
= -1, .no_setcond
= true };
1062 gen_compute_eflags(s
);
1063 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
1068 /* compute eflags.Z to reg */
1069 static CCPrepare
gen_prepare_eflags_z(DisasContext
*s
, TCGv reg
)
1073 gen_compute_eflags(s
);
1079 return (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
1083 int size
= (s
->cc_op
- CC_OP_ADDB
) & 3;
1084 TCGv t0
= gen_ext_tl(reg
, cpu_cc_dst
, size
, false);
1085 return (CCPrepare
) { .cond
= TCG_COND_EQ
, .reg
= t0
, .mask
= -1 };
1090 /* perform a conditional store into register 'reg' according to jump opcode
1091 value 'b'. In the fast case, T0 is guaranted not to be used. */
1092 static CCPrepare
gen_prepare_cc(DisasContext
*s
, int b
, TCGv reg
)
1094 int inv
, jcc_op
, size
, cond
;
1099 jcc_op
= (b
>> 1) & 7;
1102 case CC_OP_SUBB
... CC_OP_SUBQ
:
1103 /* We optimize relational operators for the cmp/jcc case. */
1104 size
= s
->cc_op
- CC_OP_SUBB
;
1107 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
1108 gen_extu(size
, cpu_tmp4
);
1109 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, false);
1110 cc
= (CCPrepare
) { .cond
= TCG_COND_LEU
, .reg
= cpu_tmp4
,
1111 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
1120 tcg_gen_mov_tl(cpu_tmp4
, cpu_cc_srcT
);
1121 gen_exts(size
, cpu_tmp4
);
1122 t0
= gen_ext_tl(cpu_tmp0
, cpu_cc_src
, size
, true);
1123 cc
= (CCPrepare
) { .cond
= cond
, .reg
= cpu_tmp4
,
1124 .reg2
= t0
, .mask
= -1, .use_reg2
= true };
1134 /* This actually generates good code for JC, JZ and JS. */
1137 cc
= gen_prepare_eflags_o(s
, reg
);
1140 cc
= gen_prepare_eflags_c(s
, reg
);
1143 cc
= gen_prepare_eflags_z(s
, reg
);
1146 gen_compute_eflags(s
);
1147 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= cpu_cc_src
,
1148 .mask
= CC_Z
| CC_C
};
1151 cc
= gen_prepare_eflags_s(s
, reg
);
1154 cc
= gen_prepare_eflags_p(s
, reg
);
1157 gen_compute_eflags(s
);
1158 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
1161 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
1162 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
1163 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
1168 gen_compute_eflags(s
);
1169 if (TCGV_EQUAL(reg
, cpu_cc_src
)) {
1172 tcg_gen_shri_tl(reg
, cpu_cc_src
, 4); /* CC_O -> CC_S */
1173 tcg_gen_xor_tl(reg
, reg
, cpu_cc_src
);
1174 cc
= (CCPrepare
) { .cond
= TCG_COND_NE
, .reg
= reg
,
1175 .mask
= CC_S
| CC_Z
};
1182 cc
.cond
= tcg_invert_cond(cc
.cond
);
1187 static void gen_setcc1(DisasContext
*s
, int b
, TCGv reg
)
1189 CCPrepare cc
= gen_prepare_cc(s
, b
, reg
);
1191 if (cc
.no_setcond
) {
1192 if (cc
.cond
== TCG_COND_EQ
) {
1193 tcg_gen_xori_tl(reg
, cc
.reg
, 1);
1195 tcg_gen_mov_tl(reg
, cc
.reg
);
1200 if (cc
.cond
== TCG_COND_NE
&& !cc
.use_reg2
&& cc
.imm
== 0 &&
1201 cc
.mask
!= 0 && (cc
.mask
& (cc
.mask
- 1)) == 0) {
1202 tcg_gen_shri_tl(reg
, cc
.reg
, ctztl(cc
.mask
));
1203 tcg_gen_andi_tl(reg
, reg
, 1);
1206 if (cc
.mask
!= -1) {
1207 tcg_gen_andi_tl(reg
, cc
.reg
, cc
.mask
);
1211 tcg_gen_setcond_tl(cc
.cond
, reg
, cc
.reg
, cc
.reg2
);
1213 tcg_gen_setcondi_tl(cc
.cond
, reg
, cc
.reg
, cc
.imm
);
1217 static inline void gen_compute_eflags_c(DisasContext
*s
, TCGv reg
)
1219 gen_setcc1(s
, JCC_B
<< 1, reg
);
1222 /* generate a conditional jump to label 'l1' according to jump opcode
1223 value 'b'. In the fast case, T0 is guaranted not to be used. */
1224 static inline void gen_jcc1_noeob(DisasContext
*s
, int b
, int l1
)
1226 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T
[0]);
1228 if (cc
.mask
!= -1) {
1229 tcg_gen_andi_tl(cpu_T
[0], cc
.reg
, cc
.mask
);
1233 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1235 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1239 /* Generate a conditional jump to label 'l1' according to jump opcode
1240 value 'b'. In the fast case, T0 is guaranted not to be used.
1241 A translation block must end soon. */
1242 static inline void gen_jcc1(DisasContext
*s
, int b
, int l1
)
1244 CCPrepare cc
= gen_prepare_cc(s
, b
, cpu_T
[0]);
1246 gen_update_cc_op(s
);
1247 if (cc
.mask
!= -1) {
1248 tcg_gen_andi_tl(cpu_T
[0], cc
.reg
, cc
.mask
);
1251 set_cc_op(s
, CC_OP_DYNAMIC
);
1253 tcg_gen_brcond_tl(cc
.cond
, cc
.reg
, cc
.reg2
, l1
);
1255 tcg_gen_brcondi_tl(cc
.cond
, cc
.reg
, cc
.imm
, l1
);
1259 /* XXX: does not work with gdbstub "ice" single step - not a
1261 static int gen_jz_ecx_string(DisasContext
*s
, target_ulong next_eip
)
1265 l1
= gen_new_label();
1266 l2
= gen_new_label();
1267 gen_op_jnz_ecx(s
->aflag
, l1
);
1269 gen_jmp_tb(s
, next_eip
, 1);
1274 static inline void gen_stos(DisasContext
*s
, int ot
)
1276 gen_op_mov_TN_reg(OT_LONG
, 0, R_EAX
);
1277 gen_string_movl_A0_EDI(s
);
1278 gen_op_st_T0_A0(ot
+ s
->mem_index
);
1279 gen_op_movl_T0_Dshift(ot
);
1280 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1283 static inline void gen_lods(DisasContext
*s
, int ot
)
1285 gen_string_movl_A0_ESI(s
);
1286 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
1287 gen_op_mov_reg_T0(ot
, R_EAX
);
1288 gen_op_movl_T0_Dshift(ot
);
1289 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1292 static inline void gen_scas(DisasContext
*s
, int ot
)
1294 gen_string_movl_A0_EDI(s
);
1295 gen_op_ld_T1_A0(ot
+ s
->mem_index
);
1296 gen_op(s
, OP_CMPL
, ot
, R_EAX
);
1297 gen_op_movl_T0_Dshift(ot
);
1298 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1301 static inline void gen_cmps(DisasContext
*s
, int ot
)
1303 gen_string_movl_A0_EDI(s
);
1304 gen_op_ld_T1_A0(ot
+ s
->mem_index
);
1305 gen_string_movl_A0_ESI(s
);
1306 gen_op(s
, OP_CMPL
, ot
, OR_TMP0
);
1307 gen_op_movl_T0_Dshift(ot
);
1308 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1309 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1312 static inline void gen_ins(DisasContext
*s
, int ot
)
1316 gen_string_movl_A0_EDI(s
);
1317 /* Note: we must do this dummy write first to be restartable in
1318 case of page fault. */
1320 gen_op_st_T0_A0(ot
+ s
->mem_index
);
1321 gen_op_mov_TN_reg(OT_WORD
, 1, R_EDX
);
1322 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[1]);
1323 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1324 gen_helper_in_func(ot
, cpu_T
[0], cpu_tmp2_i32
);
1325 gen_op_st_T0_A0(ot
+ s
->mem_index
);
1326 gen_op_movl_T0_Dshift(ot
);
1327 gen_op_add_reg_T0(s
->aflag
, R_EDI
);
1332 static inline void gen_outs(DisasContext
*s
, int ot
)
1336 gen_string_movl_A0_ESI(s
);
1337 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
1339 gen_op_mov_TN_reg(OT_WORD
, 1, R_EDX
);
1340 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[1]);
1341 tcg_gen_andi_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, 0xffff);
1342 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[0]);
1343 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
1345 gen_op_movl_T0_Dshift(ot
);
1346 gen_op_add_reg_T0(s
->aflag
, R_ESI
);
1351 /* same method as Valgrind : we generate jumps to current or next
1353 #define GEN_REPZ(op) \
1354 static inline void gen_repz_ ## op(DisasContext *s, int ot, \
1355 target_ulong cur_eip, target_ulong next_eip) \
1358 gen_update_cc_op(s); \
1359 l2 = gen_jz_ecx_string(s, next_eip); \
1360 gen_ ## op(s, ot); \
1361 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1362 /* a loop would cause two single step exceptions if ECX = 1 \
1363 before rep string_insn */ \
1365 gen_op_jz_ecx(s->aflag, l2); \
1366 gen_jmp(s, cur_eip); \
1369 #define GEN_REPZ2(op) \
1370 static inline void gen_repz_ ## op(DisasContext *s, int ot, \
1371 target_ulong cur_eip, \
1372 target_ulong next_eip, \
1376 gen_update_cc_op(s); \
1377 l2 = gen_jz_ecx_string(s, next_eip); \
1378 gen_ ## op(s, ot); \
1379 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1380 gen_update_cc_op(s); \
1381 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
1383 gen_op_jz_ecx(s->aflag, l2); \
1384 gen_jmp(s, cur_eip); \
1395 static void gen_helper_fp_arith_ST0_FT0(int op
)
1399 gen_helper_fadd_ST0_FT0(cpu_env
);
1402 gen_helper_fmul_ST0_FT0(cpu_env
);
1405 gen_helper_fcom_ST0_FT0(cpu_env
);
1408 gen_helper_fcom_ST0_FT0(cpu_env
);
1411 gen_helper_fsub_ST0_FT0(cpu_env
);
1414 gen_helper_fsubr_ST0_FT0(cpu_env
);
1417 gen_helper_fdiv_ST0_FT0(cpu_env
);
1420 gen_helper_fdivr_ST0_FT0(cpu_env
);
1425 /* NOTE the exception in "r" op ordering */
1426 static void gen_helper_fp_arith_STN_ST0(int op
, int opreg
)
1428 TCGv_i32 tmp
= tcg_const_i32(opreg
);
1431 gen_helper_fadd_STN_ST0(cpu_env
, tmp
);
1434 gen_helper_fmul_STN_ST0(cpu_env
, tmp
);
1437 gen_helper_fsubr_STN_ST0(cpu_env
, tmp
);
1440 gen_helper_fsub_STN_ST0(cpu_env
, tmp
);
1443 gen_helper_fdivr_STN_ST0(cpu_env
, tmp
);
1446 gen_helper_fdiv_STN_ST0(cpu_env
, tmp
);
1451 /* if d == OR_TMP0, it means memory operand (address in A0) */
1452 static void gen_op(DisasContext
*s1
, int op
, int ot
, int d
)
1455 gen_op_mov_TN_reg(ot
, 0, d
);
1457 gen_op_ld_T0_A0(ot
+ s1
->mem_index
);
1461 gen_compute_eflags_c(s1
, cpu_tmp4
);
1462 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1463 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_tmp4
);
1465 gen_op_mov_reg_T0(ot
, d
);
1467 gen_op_st_T0_A0(ot
+ s1
->mem_index
);
1468 gen_op_update3_cc(cpu_tmp4
);
1469 set_cc_op(s1
, CC_OP_ADCB
+ ot
);
1472 gen_compute_eflags_c(s1
, cpu_tmp4
);
1473 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1474 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_tmp4
);
1476 gen_op_mov_reg_T0(ot
, d
);
1478 gen_op_st_T0_A0(ot
+ s1
->mem_index
);
1479 gen_op_update3_cc(cpu_tmp4
);
1480 set_cc_op(s1
, CC_OP_SBBB
+ ot
);
1483 gen_op_addl_T0_T1();
1485 gen_op_mov_reg_T0(ot
, d
);
1487 gen_op_st_T0_A0(ot
+ s1
->mem_index
);
1488 gen_op_update2_cc();
1489 set_cc_op(s1
, CC_OP_ADDB
+ ot
);
1492 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T
[0]);
1493 tcg_gen_sub_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1495 gen_op_mov_reg_T0(ot
, d
);
1497 gen_op_st_T0_A0(ot
+ s1
->mem_index
);
1498 gen_op_update2_cc();
1499 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1503 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1505 gen_op_mov_reg_T0(ot
, d
);
1507 gen_op_st_T0_A0(ot
+ s1
->mem_index
);
1508 gen_op_update1_cc();
1509 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1512 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1514 gen_op_mov_reg_T0(ot
, d
);
1516 gen_op_st_T0_A0(ot
+ s1
->mem_index
);
1517 gen_op_update1_cc();
1518 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1521 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
1523 gen_op_mov_reg_T0(ot
, d
);
1525 gen_op_st_T0_A0(ot
+ s1
->mem_index
);
1526 gen_op_update1_cc();
1527 set_cc_op(s1
, CC_OP_LOGICB
+ ot
);
1530 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[1]);
1531 tcg_gen_mov_tl(cpu_cc_srcT
, cpu_T
[0]);
1532 tcg_gen_sub_tl(cpu_cc_dst
, cpu_T
[0], cpu_T
[1]);
1533 set_cc_op(s1
, CC_OP_SUBB
+ ot
);
1538 /* if d == OR_TMP0, it means memory operand (address in A0) */
1539 static void gen_inc(DisasContext
*s1
, int ot
, int d
, int c
)
1542 gen_op_mov_TN_reg(ot
, 0, d
);
1544 gen_op_ld_T0_A0(ot
+ s1
->mem_index
);
1545 gen_compute_eflags_c(s1
, cpu_cc_src
);
1547 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], 1);
1548 set_cc_op(s1
, CC_OP_INCB
+ ot
);
1550 tcg_gen_addi_tl(cpu_T
[0], cpu_T
[0], -1);
1551 set_cc_op(s1
, CC_OP_DECB
+ ot
);
1554 gen_op_mov_reg_T0(ot
, d
);
1556 gen_op_st_T0_A0(ot
+ s1
->mem_index
);
1557 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
1560 static void gen_shift_rm_T1(DisasContext
*s
, int ot
, int op1
,
1561 int is_right
, int is_arith
)
1567 if (ot
== OT_QUAD
) {
1574 if (op1
== OR_TMP0
) {
1575 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
1577 gen_op_mov_TN_reg(ot
, 0, op1
);
1580 t0
= tcg_temp_local_new();
1581 t1
= tcg_temp_local_new();
1582 t2
= tcg_temp_local_new();
1584 tcg_gen_andi_tl(t2
, cpu_T
[1], mask
);
1588 gen_exts(ot
, cpu_T
[0]);
1589 tcg_gen_mov_tl(t0
, cpu_T
[0]);
1590 tcg_gen_sar_tl(cpu_T
[0], cpu_T
[0], t2
);
1592 gen_extu(ot
, cpu_T
[0]);
1593 tcg_gen_mov_tl(t0
, cpu_T
[0]);
1594 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], t2
);
1597 tcg_gen_mov_tl(t0
, cpu_T
[0]);
1598 tcg_gen_shl_tl(cpu_T
[0], cpu_T
[0], t2
);
1602 if (op1
== OR_TMP0
) {
1603 gen_op_st_T0_A0(ot
+ s
->mem_index
);
1605 gen_op_mov_reg_T0(ot
, op1
);
1608 /* Update eflags data because we cannot predict flags afterward. */
1609 gen_update_cc_op(s
);
1610 set_cc_op(s
, CC_OP_DYNAMIC
);
1612 tcg_gen_mov_tl(t1
, cpu_T
[0]);
1614 shift_label
= gen_new_label();
1615 tcg_gen_brcondi_tl(TCG_COND_EQ
, t2
, 0, shift_label
);
1617 tcg_gen_addi_tl(t2
, t2
, -1);
1618 tcg_gen_mov_tl(cpu_cc_dst
, t1
);
1622 tcg_gen_sar_tl(cpu_cc_src
, t0
, t2
);
1624 tcg_gen_shr_tl(cpu_cc_src
, t0
, t2
);
1627 tcg_gen_shl_tl(cpu_cc_src
, t0
, t2
);
1631 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_SARB
+ ot
);
1633 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_SHLB
+ ot
);
1636 gen_set_label(shift_label
);
1643 static void gen_shift_rm_im(DisasContext
*s
, int ot
, int op1
, int op2
,
1644 int is_right
, int is_arith
)
1655 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
1657 gen_op_mov_TN_reg(ot
, 0, op1
);
1663 gen_exts(ot
, cpu_T
[0]);
1664 tcg_gen_sari_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1665 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], op2
);
1667 gen_extu(ot
, cpu_T
[0]);
1668 tcg_gen_shri_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1669 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], op2
);
1672 tcg_gen_shli_tl(cpu_tmp4
, cpu_T
[0], op2
- 1);
1673 tcg_gen_shli_tl(cpu_T
[0], cpu_T
[0], op2
);
1679 gen_op_st_T0_A0(ot
+ s
->mem_index
);
1681 gen_op_mov_reg_T0(ot
, op1
);
1683 /* update eflags if non zero shift */
1685 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
1686 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
1687 set_cc_op(s
, (is_right
? CC_OP_SARB
: CC_OP_SHLB
) + ot
);
1691 static inline void tcg_gen_lshift(TCGv ret
, TCGv arg1
, target_long arg2
)
1694 tcg_gen_shli_tl(ret
, arg1
, arg2
);
1696 tcg_gen_shri_tl(ret
, arg1
, -arg2
);
1699 static void gen_rot_rm_T1(DisasContext
*s
, int ot
, int op1
,
1703 int label1
, label2
, data_bits
;
1704 TCGv t0
, t1
, t2
, a0
;
1706 /* XXX: inefficient, but we must use local temps */
1707 t0
= tcg_temp_local_new();
1708 t1
= tcg_temp_local_new();
1709 t2
= tcg_temp_local_new();
1710 a0
= tcg_temp_local_new();
1718 if (op1
== OR_TMP0
) {
1719 tcg_gen_mov_tl(a0
, cpu_A0
);
1720 gen_op_ld_v(ot
+ s
->mem_index
, t0
, a0
);
1722 gen_op_mov_v_reg(ot
, t0
, op1
);
1725 tcg_gen_mov_tl(t1
, cpu_T
[1]);
1727 tcg_gen_andi_tl(t1
, t1
, mask
);
1729 /* Must test zero case to avoid using undefined behaviour in TCG
1731 label1
= gen_new_label();
1732 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, label1
);
1735 tcg_gen_andi_tl(cpu_tmp0
, t1
, (1 << (3 + ot
)) - 1);
1737 tcg_gen_mov_tl(cpu_tmp0
, t1
);
1740 tcg_gen_mov_tl(t2
, t0
);
1742 data_bits
= 8 << ot
;
1743 /* XXX: rely on behaviour of shifts when operand 2 overflows (XXX:
1744 fix TCG definition) */
1746 tcg_gen_shr_tl(cpu_tmp4
, t0
, cpu_tmp0
);
1747 tcg_gen_subfi_tl(cpu_tmp0
, data_bits
, cpu_tmp0
);
1748 tcg_gen_shl_tl(t0
, t0
, cpu_tmp0
);
1750 tcg_gen_shl_tl(cpu_tmp4
, t0
, cpu_tmp0
);
1751 tcg_gen_subfi_tl(cpu_tmp0
, data_bits
, cpu_tmp0
);
1752 tcg_gen_shr_tl(t0
, t0
, cpu_tmp0
);
1754 tcg_gen_or_tl(t0
, t0
, cpu_tmp4
);
1756 gen_set_label(label1
);
1758 if (op1
== OR_TMP0
) {
1759 gen_op_st_v(ot
+ s
->mem_index
, t0
, a0
);
1761 gen_op_mov_reg_v(ot
, op1
, t0
);
1764 /* update eflags. It is needed anyway most of the time, do it always. */
1765 gen_compute_eflags(s
);
1766 assert(s
->cc_op
== CC_OP_EFLAGS
);
1768 label2
= gen_new_label();
1769 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, label2
);
1771 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~(CC_O
| CC_C
));
1772 tcg_gen_xor_tl(cpu_tmp0
, t2
, t0
);
1773 tcg_gen_lshift(cpu_tmp0
, cpu_tmp0
, 11 - (data_bits
- 1));
1774 tcg_gen_andi_tl(cpu_tmp0
, cpu_tmp0
, CC_O
);
1775 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, cpu_tmp0
);
1777 tcg_gen_shri_tl(t0
, t0
, data_bits
- 1);
1779 tcg_gen_andi_tl(t0
, t0
, CC_C
);
1780 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, t0
);
1782 gen_set_label(label2
);
1790 static void gen_rot_rm_im(DisasContext
*s
, int ot
, int op1
, int op2
,
1797 /* XXX: inefficient, but we must use local temps */
1798 t0
= tcg_temp_local_new();
1799 t1
= tcg_temp_local_new();
1800 a0
= tcg_temp_local_new();
1808 if (op1
== OR_TMP0
) {
1809 tcg_gen_mov_tl(a0
, cpu_A0
);
1810 gen_op_ld_v(ot
+ s
->mem_index
, t0
, a0
);
1812 gen_op_mov_v_reg(ot
, t0
, op1
);
1816 tcg_gen_mov_tl(t1
, t0
);
1819 data_bits
= 8 << ot
;
1821 int shift
= op2
& ((1 << (3 + ot
)) - 1);
1823 tcg_gen_shri_tl(cpu_tmp4
, t0
, shift
);
1824 tcg_gen_shli_tl(t0
, t0
, data_bits
- shift
);
1827 tcg_gen_shli_tl(cpu_tmp4
, t0
, shift
);
1828 tcg_gen_shri_tl(t0
, t0
, data_bits
- shift
);
1830 tcg_gen_or_tl(t0
, t0
, cpu_tmp4
);
1834 if (op1
== OR_TMP0
) {
1835 gen_op_st_v(ot
+ s
->mem_index
, t0
, a0
);
1837 gen_op_mov_reg_v(ot
, op1
, t0
);
1842 gen_compute_eflags(s
);
1843 assert(s
->cc_op
== CC_OP_EFLAGS
);
1845 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~(CC_O
| CC_C
));
1846 tcg_gen_xor_tl(cpu_tmp0
, t1
, t0
);
1847 tcg_gen_lshift(cpu_tmp0
, cpu_tmp0
, 11 - (data_bits
- 1));
1848 tcg_gen_andi_tl(cpu_tmp0
, cpu_tmp0
, CC_O
);
1849 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, cpu_tmp0
);
1851 tcg_gen_shri_tl(t0
, t0
, data_bits
- 1);
1853 tcg_gen_andi_tl(t0
, t0
, CC_C
);
1854 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, t0
);
1862 /* XXX: add faster immediate = 1 case */
1863 static void gen_rotc_rm_T1(DisasContext
*s
, int ot
, int op1
,
1866 gen_compute_eflags(s
);
1867 assert(s
->cc_op
== CC_OP_EFLAGS
);
1871 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
1873 gen_op_mov_TN_reg(ot
, 0, op1
);
1878 gen_helper_rcrb(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1881 gen_helper_rcrw(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1884 gen_helper_rcrl(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1886 #ifdef TARGET_X86_64
1888 gen_helper_rcrq(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1895 gen_helper_rclb(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1898 gen_helper_rclw(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1901 gen_helper_rcll(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1903 #ifdef TARGET_X86_64
1905 gen_helper_rclq(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
1912 gen_op_st_T0_A0(ot
+ s
->mem_index
);
1914 gen_op_mov_reg_T0(ot
, op1
);
1917 /* XXX: add faster immediate case */
1918 static void gen_shiftd_rm_T1(DisasContext
*s
, int ot
, int op1
,
1919 int is_right
, TCGv count
)
1921 int label1
, label2
, data_bits
;
1923 TCGv t0
, t1
, t2
, a0
;
1925 t0
= tcg_temp_local_new();
1926 t1
= tcg_temp_local_new();
1927 t2
= tcg_temp_local_new();
1928 a0
= tcg_temp_local_new();
1936 if (op1
== OR_TMP0
) {
1937 tcg_gen_mov_tl(a0
, cpu_A0
);
1938 gen_op_ld_v(ot
+ s
->mem_index
, t0
, a0
);
1940 gen_op_mov_v_reg(ot
, t0
, op1
);
1943 tcg_gen_andi_tl(t2
, count
, mask
);
1944 tcg_gen_mov_tl(t1
, cpu_T
[1]);
1946 /* Must test zero case to avoid using undefined behaviour in TCG
1948 label1
= gen_new_label();
1949 tcg_gen_brcondi_tl(TCG_COND_EQ
, t2
, 0, label1
);
1951 tcg_gen_addi_tl(cpu_tmp5
, t2
, -1);
1952 if (ot
== OT_WORD
) {
1953 /* Note: we implement the Intel behaviour for shift count > 16 */
1955 tcg_gen_andi_tl(t0
, t0
, 0xffff);
1956 tcg_gen_shli_tl(cpu_tmp0
, t1
, 16);
1957 tcg_gen_or_tl(t0
, t0
, cpu_tmp0
);
1958 tcg_gen_ext32u_tl(t0
, t0
);
1960 tcg_gen_shr_tl(cpu_tmp4
, t0
, cpu_tmp5
);
1962 /* only needed if count > 16, but a test would complicate */
1963 tcg_gen_subfi_tl(cpu_tmp5
, 32, t2
);
1964 tcg_gen_shl_tl(cpu_tmp0
, t0
, cpu_tmp5
);
1966 tcg_gen_shr_tl(t0
, t0
, t2
);
1968 tcg_gen_or_tl(t0
, t0
, cpu_tmp0
);
1970 /* XXX: not optimal */
1971 tcg_gen_andi_tl(t0
, t0
, 0xffff);
1972 tcg_gen_shli_tl(t1
, t1
, 16);
1973 tcg_gen_or_tl(t1
, t1
, t0
);
1974 tcg_gen_ext32u_tl(t1
, t1
);
1976 tcg_gen_shl_tl(cpu_tmp4
, t0
, cpu_tmp5
);
1977 tcg_gen_subfi_tl(cpu_tmp0
, 32, cpu_tmp5
);
1978 tcg_gen_shr_tl(cpu_tmp5
, t1
, cpu_tmp0
);
1979 tcg_gen_or_tl(cpu_tmp4
, cpu_tmp4
, cpu_tmp5
);
1981 tcg_gen_shl_tl(t0
, t0
, t2
);
1982 tcg_gen_subfi_tl(cpu_tmp5
, 32, t2
);
1983 tcg_gen_shr_tl(t1
, t1
, cpu_tmp5
);
1984 tcg_gen_or_tl(t0
, t0
, t1
);
1987 data_bits
= 8 << ot
;
1990 tcg_gen_ext32u_tl(t0
, t0
);
1992 tcg_gen_shr_tl(cpu_tmp4
, t0
, cpu_tmp5
);
1994 tcg_gen_shr_tl(t0
, t0
, t2
);
1995 tcg_gen_subfi_tl(cpu_tmp5
, data_bits
, t2
);
1996 tcg_gen_shl_tl(t1
, t1
, cpu_tmp5
);
1997 tcg_gen_or_tl(t0
, t0
, t1
);
2001 tcg_gen_ext32u_tl(t1
, t1
);
2003 tcg_gen_shl_tl(cpu_tmp4
, t0
, cpu_tmp5
);
2005 tcg_gen_shl_tl(t0
, t0
, t2
);
2006 tcg_gen_subfi_tl(cpu_tmp5
, data_bits
, t2
);
2007 tcg_gen_shr_tl(t1
, t1
, cpu_tmp5
);
2008 tcg_gen_or_tl(t0
, t0
, t1
);
2011 tcg_gen_mov_tl(t1
, cpu_tmp4
);
2013 gen_set_label(label1
);
2015 if (op1
== OR_TMP0
) {
2016 gen_op_st_v(ot
+ s
->mem_index
, t0
, a0
);
2018 gen_op_mov_reg_v(ot
, op1
, t0
);
2021 /* Update eflags data because we cannot predict flags afterward. */
2022 gen_update_cc_op(s
);
2023 set_cc_op(s
, CC_OP_DYNAMIC
);
2025 label2
= gen_new_label();
2026 tcg_gen_brcondi_tl(TCG_COND_EQ
, t2
, 0, label2
);
2028 tcg_gen_mov_tl(cpu_cc_src
, t1
);
2029 tcg_gen_mov_tl(cpu_cc_dst
, t0
);
2031 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_SARB
+ ot
);
2033 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_SHLB
+ ot
);
2035 gen_set_label(label2
);
2043 static void gen_shift(DisasContext
*s1
, int op
, int ot
, int d
, int s
)
2046 gen_op_mov_TN_reg(ot
, 1, s
);
2049 gen_rot_rm_T1(s1
, ot
, d
, 0);
2052 gen_rot_rm_T1(s1
, ot
, d
, 1);
2056 gen_shift_rm_T1(s1
, ot
, d
, 0, 0);
2059 gen_shift_rm_T1(s1
, ot
, d
, 1, 0);
2062 gen_shift_rm_T1(s1
, ot
, d
, 1, 1);
2065 gen_rotc_rm_T1(s1
, ot
, d
, 0);
2068 gen_rotc_rm_T1(s1
, ot
, d
, 1);
2073 static void gen_shifti(DisasContext
*s1
, int op
, int ot
, int d
, int c
)
2077 gen_rot_rm_im(s1
, ot
, d
, c
, 0);
2080 gen_rot_rm_im(s1
, ot
, d
, c
, 1);
2084 gen_shift_rm_im(s1
, ot
, d
, c
, 0, 0);
2087 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 0);
2090 gen_shift_rm_im(s1
, ot
, d
, c
, 1, 1);
2093 /* currently not optimized */
2094 gen_op_movl_T1_im(c
);
2095 gen_shift(s1
, op
, ot
, d
, OR_TMP1
);
2100 static void gen_lea_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2101 int *reg_ptr
, int *offset_ptr
)
2109 int mod
, rm
, code
, override
, must_add_seg
;
2111 override
= s
->override
;
2112 must_add_seg
= s
->addseg
;
2115 mod
= (modrm
>> 6) & 3;
2127 code
= cpu_ldub_code(env
, s
->pc
++);
2128 scale
= (code
>> 6) & 3;
2129 index
= ((code
>> 3) & 7) | REX_X(s
);
2136 if ((base
& 7) == 5) {
2138 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
2140 if (CODE64(s
) && !havesib
) {
2141 disp
+= s
->pc
+ s
->rip_offset
;
2148 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
2152 disp
= (int32_t)cpu_ldl_code(env
, s
->pc
);
2158 /* for correct popl handling with esp */
2159 if (base
== 4 && s
->popl_esp_hack
)
2160 disp
+= s
->popl_esp_hack
;
2161 #ifdef TARGET_X86_64
2162 if (s
->aflag
== 2) {
2163 gen_op_movq_A0_reg(base
);
2165 gen_op_addq_A0_im(disp
);
2170 gen_op_movl_A0_reg(base
);
2172 gen_op_addl_A0_im(disp
);
2175 #ifdef TARGET_X86_64
2176 if (s
->aflag
== 2) {
2177 gen_op_movq_A0_im(disp
);
2181 gen_op_movl_A0_im(disp
);
2184 /* index == 4 means no index */
2185 if (havesib
&& (index
!= 4)) {
2186 #ifdef TARGET_X86_64
2187 if (s
->aflag
== 2) {
2188 gen_op_addq_A0_reg_sN(scale
, index
);
2192 gen_op_addl_A0_reg_sN(scale
, index
);
2197 if (base
== R_EBP
|| base
== R_ESP
)
2202 #ifdef TARGET_X86_64
2203 if (s
->aflag
== 2) {
2204 gen_op_addq_A0_seg(override
);
2208 gen_op_addl_A0_seg(s
, override
);
2215 disp
= cpu_lduw_code(env
, s
->pc
);
2217 gen_op_movl_A0_im(disp
);
2218 rm
= 0; /* avoid SS override */
2225 disp
= (int8_t)cpu_ldub_code(env
, s
->pc
++);
2229 disp
= cpu_lduw_code(env
, s
->pc
);
2235 gen_op_movl_A0_reg(R_EBX
);
2236 gen_op_addl_A0_reg_sN(0, R_ESI
);
2239 gen_op_movl_A0_reg(R_EBX
);
2240 gen_op_addl_A0_reg_sN(0, R_EDI
);
2243 gen_op_movl_A0_reg(R_EBP
);
2244 gen_op_addl_A0_reg_sN(0, R_ESI
);
2247 gen_op_movl_A0_reg(R_EBP
);
2248 gen_op_addl_A0_reg_sN(0, R_EDI
);
2251 gen_op_movl_A0_reg(R_ESI
);
2254 gen_op_movl_A0_reg(R_EDI
);
2257 gen_op_movl_A0_reg(R_EBP
);
2261 gen_op_movl_A0_reg(R_EBX
);
2265 gen_op_addl_A0_im(disp
);
2266 gen_op_andl_A0_ffff();
2270 if (rm
== 2 || rm
== 3 || rm
== 6)
2275 gen_op_addl_A0_seg(s
, override
);
2285 static void gen_nop_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
)
2287 int mod
, rm
, base
, code
;
2289 mod
= (modrm
>> 6) & 3;
2299 code
= cpu_ldub_code(env
, s
->pc
++);
2335 /* used for LEA and MOV AX, mem */
2336 static void gen_add_A0_ds_seg(DisasContext
*s
)
2338 int override
, must_add_seg
;
2339 must_add_seg
= s
->addseg
;
2341 if (s
->override
>= 0) {
2342 override
= s
->override
;
2346 #ifdef TARGET_X86_64
2348 gen_op_addq_A0_seg(override
);
2352 gen_op_addl_A0_seg(s
, override
);
2357 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2359 static void gen_ldst_modrm(CPUX86State
*env
, DisasContext
*s
, int modrm
,
2360 int ot
, int reg
, int is_store
)
2362 int mod
, rm
, opreg
, disp
;
2364 mod
= (modrm
>> 6) & 3;
2365 rm
= (modrm
& 7) | REX_B(s
);
2369 gen_op_mov_TN_reg(ot
, 0, reg
);
2370 gen_op_mov_reg_T0(ot
, rm
);
2372 gen_op_mov_TN_reg(ot
, 0, rm
);
2374 gen_op_mov_reg_T0(ot
, reg
);
2377 gen_lea_modrm(env
, s
, modrm
, &opreg
, &disp
);
2380 gen_op_mov_TN_reg(ot
, 0, reg
);
2381 gen_op_st_T0_A0(ot
+ s
->mem_index
);
2383 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
2385 gen_op_mov_reg_T0(ot
, reg
);
2390 static inline uint32_t insn_get(CPUX86State
*env
, DisasContext
*s
, int ot
)
2396 ret
= cpu_ldub_code(env
, s
->pc
);
2400 ret
= cpu_lduw_code(env
, s
->pc
);
2405 ret
= cpu_ldl_code(env
, s
->pc
);
2412 static inline int insn_const_size(unsigned int ot
)
2420 static inline void gen_goto_tb(DisasContext
*s
, int tb_num
, target_ulong eip
)
2422 TranslationBlock
*tb
;
2425 pc
= s
->cs_base
+ eip
;
2427 /* NOTE: we handle the case where the TB spans two pages here */
2428 if ((pc
& TARGET_PAGE_MASK
) == (tb
->pc
& TARGET_PAGE_MASK
) ||
2429 (pc
& TARGET_PAGE_MASK
) == ((s
->pc
- 1) & TARGET_PAGE_MASK
)) {
2430 /* jump to same page: we can use a direct jump */
2431 tcg_gen_goto_tb(tb_num
);
2433 tcg_gen_exit_tb((tcg_target_long
)tb
+ tb_num
);
2435 /* jump to another page: currently not optimized */
2441 static inline void gen_jcc(DisasContext
*s
, int b
,
2442 target_ulong val
, target_ulong next_eip
)
2447 l1
= gen_new_label();
2450 gen_goto_tb(s
, 0, next_eip
);
2453 gen_goto_tb(s
, 1, val
);
2454 s
->is_jmp
= DISAS_TB_JUMP
;
2456 l1
= gen_new_label();
2457 l2
= gen_new_label();
2460 gen_jmp_im(next_eip
);
2470 static void gen_cmovcc1(CPUX86State
*env
, DisasContext
*s
, int ot
, int b
,
2475 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
2477 cc
= gen_prepare_cc(s
, b
, cpu_T
[1]);
2478 if (cc
.mask
!= -1) {
2479 TCGv t0
= tcg_temp_new();
2480 tcg_gen_andi_tl(t0
, cc
.reg
, cc
.mask
);
2484 cc
.reg2
= tcg_const_tl(cc
.imm
);
2487 tcg_gen_movcond_tl(cc
.cond
, cpu_T
[0], cc
.reg
, cc
.reg2
,
2488 cpu_T
[0], cpu_regs
[reg
]);
2489 gen_op_mov_reg_T0(ot
, reg
);
2491 if (cc
.mask
!= -1) {
2492 tcg_temp_free(cc
.reg
);
2495 tcg_temp_free(cc
.reg2
);
2499 static inline void gen_op_movl_T0_seg(int seg_reg
)
2501 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
,
2502 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2505 static inline void gen_op_movl_seg_T0_vm(int seg_reg
)
2507 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xffff);
2508 tcg_gen_st32_tl(cpu_T
[0], cpu_env
,
2509 offsetof(CPUX86State
,segs
[seg_reg
].selector
));
2510 tcg_gen_shli_tl(cpu_T
[0], cpu_T
[0], 4);
2511 tcg_gen_st_tl(cpu_T
[0], cpu_env
,
2512 offsetof(CPUX86State
,segs
[seg_reg
].base
));
2515 /* move T0 to seg_reg and compute if the CPU state may change. Never
2516 call this function with seg_reg == R_CS */
2517 static void gen_movl_seg_T0(DisasContext
*s
, int seg_reg
, target_ulong cur_eip
)
2519 if (s
->pe
&& !s
->vm86
) {
2520 /* XXX: optimize by finding processor state dynamically */
2521 gen_update_cc_op(s
);
2522 gen_jmp_im(cur_eip
);
2523 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
2524 gen_helper_load_seg(cpu_env
, tcg_const_i32(seg_reg
), cpu_tmp2_i32
);
2525 /* abort translation because the addseg value may change or
2526 because ss32 may change. For R_SS, translation must always
2527 stop as a special handling must be done to disable hardware
2528 interrupts for the next instruction */
2529 if (seg_reg
== R_SS
|| (s
->code32
&& seg_reg
< R_FS
))
2530 s
->is_jmp
= DISAS_TB_JUMP
;
2532 gen_op_movl_seg_T0_vm(seg_reg
);
2533 if (seg_reg
== R_SS
)
2534 s
->is_jmp
= DISAS_TB_JUMP
;
2538 static inline int svm_is_rep(int prefixes
)
2540 return ((prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) ? 8 : 0);
2544 gen_svm_check_intercept_param(DisasContext
*s
, target_ulong pc_start
,
2545 uint32_t type
, uint64_t param
)
2547 /* no SVM activated; fast case */
2548 if (likely(!(s
->flags
& HF_SVMI_MASK
)))
2550 gen_update_cc_op(s
);
2551 gen_jmp_im(pc_start
- s
->cs_base
);
2552 gen_helper_svm_check_intercept_param(cpu_env
, tcg_const_i32(type
),
2553 tcg_const_i64(param
));
2557 gen_svm_check_intercept(DisasContext
*s
, target_ulong pc_start
, uint64_t type
)
2559 gen_svm_check_intercept_param(s
, pc_start
, type
, 0);
2562 static inline void gen_stack_update(DisasContext
*s
, int addend
)
2564 #ifdef TARGET_X86_64
2566 gen_op_add_reg_im(2, R_ESP
, addend
);
2570 gen_op_add_reg_im(1, R_ESP
, addend
);
2572 gen_op_add_reg_im(0, R_ESP
, addend
);
2576 /* generate a push. It depends on ss32, addseg and dflag */
2577 static void gen_push_T0(DisasContext
*s
)
2579 #ifdef TARGET_X86_64
2581 gen_op_movq_A0_reg(R_ESP
);
2583 gen_op_addq_A0_im(-8);
2584 gen_op_st_T0_A0(OT_QUAD
+ s
->mem_index
);
2586 gen_op_addq_A0_im(-2);
2587 gen_op_st_T0_A0(OT_WORD
+ s
->mem_index
);
2589 gen_op_mov_reg_A0(2, R_ESP
);
2593 gen_op_movl_A0_reg(R_ESP
);
2595 gen_op_addl_A0_im(-2);
2597 gen_op_addl_A0_im(-4);
2600 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2601 gen_op_addl_A0_seg(s
, R_SS
);
2604 gen_op_andl_A0_ffff();
2605 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2606 gen_op_addl_A0_seg(s
, R_SS
);
2608 gen_op_st_T0_A0(s
->dflag
+ 1 + s
->mem_index
);
2609 if (s
->ss32
&& !s
->addseg
)
2610 gen_op_mov_reg_A0(1, R_ESP
);
2612 gen_op_mov_reg_T1(s
->ss32
+ 1, R_ESP
);
2616 /* generate a push. It depends on ss32, addseg and dflag */
2617 /* slower version for T1, only used for call Ev */
2618 static void gen_push_T1(DisasContext
*s
)
2620 #ifdef TARGET_X86_64
2622 gen_op_movq_A0_reg(R_ESP
);
2624 gen_op_addq_A0_im(-8);
2625 gen_op_st_T1_A0(OT_QUAD
+ s
->mem_index
);
2627 gen_op_addq_A0_im(-2);
2628 gen_op_st_T0_A0(OT_WORD
+ s
->mem_index
);
2630 gen_op_mov_reg_A0(2, R_ESP
);
2634 gen_op_movl_A0_reg(R_ESP
);
2636 gen_op_addl_A0_im(-2);
2638 gen_op_addl_A0_im(-4);
2641 gen_op_addl_A0_seg(s
, R_SS
);
2644 gen_op_andl_A0_ffff();
2645 gen_op_addl_A0_seg(s
, R_SS
);
2647 gen_op_st_T1_A0(s
->dflag
+ 1 + s
->mem_index
);
2649 if (s
->ss32
&& !s
->addseg
)
2650 gen_op_mov_reg_A0(1, R_ESP
);
2652 gen_stack_update(s
, (-2) << s
->dflag
);
2656 /* two step pop is necessary for precise exceptions */
2657 static void gen_pop_T0(DisasContext
*s
)
2659 #ifdef TARGET_X86_64
2661 gen_op_movq_A0_reg(R_ESP
);
2662 gen_op_ld_T0_A0((s
->dflag
? OT_QUAD
: OT_WORD
) + s
->mem_index
);
2666 gen_op_movl_A0_reg(R_ESP
);
2669 gen_op_addl_A0_seg(s
, R_SS
);
2671 gen_op_andl_A0_ffff();
2672 gen_op_addl_A0_seg(s
, R_SS
);
2674 gen_op_ld_T0_A0(s
->dflag
+ 1 + s
->mem_index
);
2678 static void gen_pop_update(DisasContext
*s
)
2680 #ifdef TARGET_X86_64
2681 if (CODE64(s
) && s
->dflag
) {
2682 gen_stack_update(s
, 8);
2686 gen_stack_update(s
, 2 << s
->dflag
);
2690 static void gen_stack_A0(DisasContext
*s
)
2692 gen_op_movl_A0_reg(R_ESP
);
2694 gen_op_andl_A0_ffff();
2695 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2697 gen_op_addl_A0_seg(s
, R_SS
);
2700 /* NOTE: wrap around in 16 bit not fully handled */
2701 static void gen_pusha(DisasContext
*s
)
2704 gen_op_movl_A0_reg(R_ESP
);
2705 gen_op_addl_A0_im(-16 << s
->dflag
);
2707 gen_op_andl_A0_ffff();
2708 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2710 gen_op_addl_A0_seg(s
, R_SS
);
2711 for(i
= 0;i
< 8; i
++) {
2712 gen_op_mov_TN_reg(OT_LONG
, 0, 7 - i
);
2713 gen_op_st_T0_A0(OT_WORD
+ s
->dflag
+ s
->mem_index
);
2714 gen_op_addl_A0_im(2 << s
->dflag
);
2716 gen_op_mov_reg_T1(OT_WORD
+ s
->ss32
, R_ESP
);
2719 /* NOTE: wrap around in 16 bit not fully handled */
2720 static void gen_popa(DisasContext
*s
)
2723 gen_op_movl_A0_reg(R_ESP
);
2725 gen_op_andl_A0_ffff();
2726 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2727 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], 16 << s
->dflag
);
2729 gen_op_addl_A0_seg(s
, R_SS
);
2730 for(i
= 0;i
< 8; i
++) {
2731 /* ESP is not reloaded */
2733 gen_op_ld_T0_A0(OT_WORD
+ s
->dflag
+ s
->mem_index
);
2734 gen_op_mov_reg_T0(OT_WORD
+ s
->dflag
, 7 - i
);
2736 gen_op_addl_A0_im(2 << s
->dflag
);
2738 gen_op_mov_reg_T1(OT_WORD
+ s
->ss32
, R_ESP
);
2741 static void gen_enter(DisasContext
*s
, int esp_addend
, int level
)
2746 #ifdef TARGET_X86_64
2748 ot
= s
->dflag
? OT_QUAD
: OT_WORD
;
2751 gen_op_movl_A0_reg(R_ESP
);
2752 gen_op_addq_A0_im(-opsize
);
2753 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2756 gen_op_mov_TN_reg(OT_LONG
, 0, R_EBP
);
2757 gen_op_st_T0_A0(ot
+ s
->mem_index
);
2759 /* XXX: must save state */
2760 gen_helper_enter64_level(cpu_env
, tcg_const_i32(level
),
2761 tcg_const_i32((ot
== OT_QUAD
)),
2764 gen_op_mov_reg_T1(ot
, R_EBP
);
2765 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], -esp_addend
+ (-opsize
* level
));
2766 gen_op_mov_reg_T1(OT_QUAD
, R_ESP
);
2770 ot
= s
->dflag
+ OT_WORD
;
2771 opsize
= 2 << s
->dflag
;
2773 gen_op_movl_A0_reg(R_ESP
);
2774 gen_op_addl_A0_im(-opsize
);
2776 gen_op_andl_A0_ffff();
2777 tcg_gen_mov_tl(cpu_T
[1], cpu_A0
);
2779 gen_op_addl_A0_seg(s
, R_SS
);
2781 gen_op_mov_TN_reg(OT_LONG
, 0, R_EBP
);
2782 gen_op_st_T0_A0(ot
+ s
->mem_index
);
2784 /* XXX: must save state */
2785 gen_helper_enter_level(cpu_env
, tcg_const_i32(level
),
2786 tcg_const_i32(s
->dflag
),
2789 gen_op_mov_reg_T1(ot
, R_EBP
);
2790 tcg_gen_addi_tl(cpu_T
[1], cpu_T
[1], -esp_addend
+ (-opsize
* level
));
2791 gen_op_mov_reg_T1(OT_WORD
+ s
->ss32
, R_ESP
);
2795 static void gen_exception(DisasContext
*s
, int trapno
, target_ulong cur_eip
)
2797 gen_update_cc_op(s
);
2798 gen_jmp_im(cur_eip
);
2799 gen_helper_raise_exception(cpu_env
, tcg_const_i32(trapno
));
2800 s
->is_jmp
= DISAS_TB_JUMP
;
2803 /* an interrupt is different from an exception because of the
2805 static void gen_interrupt(DisasContext
*s
, int intno
,
2806 target_ulong cur_eip
, target_ulong next_eip
)
2808 gen_update_cc_op(s
);
2809 gen_jmp_im(cur_eip
);
2810 gen_helper_raise_interrupt(cpu_env
, tcg_const_i32(intno
),
2811 tcg_const_i32(next_eip
- cur_eip
));
2812 s
->is_jmp
= DISAS_TB_JUMP
;
2815 static void gen_debug(DisasContext
*s
, target_ulong cur_eip
)
2817 gen_update_cc_op(s
);
2818 gen_jmp_im(cur_eip
);
2819 gen_helper_debug(cpu_env
);
2820 s
->is_jmp
= DISAS_TB_JUMP
;
2823 /* generate a generic end of block. Trace exception is also generated
2825 static void gen_eob(DisasContext
*s
)
2827 gen_update_cc_op(s
);
2828 if (s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
) {
2829 gen_helper_reset_inhibit_irq(cpu_env
);
2831 if (s
->tb
->flags
& HF_RF_MASK
) {
2832 gen_helper_reset_rf(cpu_env
);
2834 if (s
->singlestep_enabled
) {
2835 gen_helper_debug(cpu_env
);
2837 gen_helper_single_step(cpu_env
);
2841 s
->is_jmp
= DISAS_TB_JUMP
;
2844 /* generate a jump to eip. No segment change must happen before as a
2845 direct call to the next block may occur */
2846 static void gen_jmp_tb(DisasContext
*s
, target_ulong eip
, int tb_num
)
2848 gen_update_cc_op(s
);
2849 set_cc_op(s
, CC_OP_DYNAMIC
);
2851 gen_goto_tb(s
, tb_num
, eip
);
2852 s
->is_jmp
= DISAS_TB_JUMP
;
2859 static void gen_jmp(DisasContext
*s
, target_ulong eip
)
2861 gen_jmp_tb(s
, eip
, 0);
2864 static inline void gen_ldq_env_A0(int idx
, int offset
)
2866 int mem_index
= (idx
>> 2) - 1;
2867 tcg_gen_qemu_ld64(cpu_tmp1_i64
, cpu_A0
, mem_index
);
2868 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2871 static inline void gen_stq_env_A0(int idx
, int offset
)
2873 int mem_index
= (idx
>> 2) - 1;
2874 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
);
2875 tcg_gen_qemu_st64(cpu_tmp1_i64
, cpu_A0
, mem_index
);
2878 static inline void gen_ldo_env_A0(int idx
, int offset
)
2880 int mem_index
= (idx
>> 2) - 1;
2881 tcg_gen_qemu_ld64(cpu_tmp1_i64
, cpu_A0
, mem_index
);
2882 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(0)));
2883 tcg_gen_addi_tl(cpu_tmp0
, cpu_A0
, 8);
2884 tcg_gen_qemu_ld64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
);
2885 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(1)));
2888 static inline void gen_sto_env_A0(int idx
, int offset
)
2890 int mem_index
= (idx
>> 2) - 1;
2891 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(0)));
2892 tcg_gen_qemu_st64(cpu_tmp1_i64
, cpu_A0
, mem_index
);
2893 tcg_gen_addi_tl(cpu_tmp0
, cpu_A0
, 8);
2894 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, offset
+ offsetof(XMMReg
, XMM_Q(1)));
2895 tcg_gen_qemu_st64(cpu_tmp1_i64
, cpu_tmp0
, mem_index
);
2898 static inline void gen_op_movo(int d_offset
, int s_offset
)
2900 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
);
2901 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2902 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
+ 8);
2903 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
+ 8);
2906 static inline void gen_op_movq(int d_offset
, int s_offset
)
2908 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
, s_offset
);
2909 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2912 static inline void gen_op_movl(int d_offset
, int s_offset
)
2914 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
, s_offset
);
2915 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, d_offset
);
2918 static inline void gen_op_movq_env_0(int d_offset
)
2920 tcg_gen_movi_i64(cpu_tmp1_i64
, 0);
2921 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
, d_offset
);
2924 typedef void (*SSEFunc_i_ep
)(TCGv_i32 val
, TCGv_ptr env
, TCGv_ptr reg
);
2925 typedef void (*SSEFunc_l_ep
)(TCGv_i64 val
, TCGv_ptr env
, TCGv_ptr reg
);
2926 typedef void (*SSEFunc_0_epi
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i32 val
);
2927 typedef void (*SSEFunc_0_epl
)(TCGv_ptr env
, TCGv_ptr reg
, TCGv_i64 val
);
2928 typedef void (*SSEFunc_0_epp
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
);
2929 typedef void (*SSEFunc_0_eppi
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2931 typedef void (*SSEFunc_0_ppi
)(TCGv_ptr reg_a
, TCGv_ptr reg_b
, TCGv_i32 val
);
2932 typedef void (*SSEFunc_0_eppt
)(TCGv_ptr env
, TCGv_ptr reg_a
, TCGv_ptr reg_b
,
2935 #define SSE_SPECIAL ((void *)1)
2936 #define SSE_DUMMY ((void *)2)
2938 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2939 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2940 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2942 static const SSEFunc_0_epp sse_op_table1
[256][4] = {
2943 /* 3DNow! extensions */
2944 [0x0e] = { SSE_DUMMY
}, /* femms */
2945 [0x0f] = { SSE_DUMMY
}, /* pf... */
2946 /* pure SSE operations */
2947 [0x10] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2948 [0x11] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movups, movupd, movss, movsd */
2949 [0x12] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd, movsldup, movddup */
2950 [0x13] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movlps, movlpd */
2951 [0x14] = { gen_helper_punpckldq_xmm
, gen_helper_punpcklqdq_xmm
},
2952 [0x15] = { gen_helper_punpckhdq_xmm
, gen_helper_punpckhqdq_xmm
},
2953 [0x16] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd, movshdup */
2954 [0x17] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movhps, movhpd */
2956 [0x28] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2957 [0x29] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movaps, movapd */
2958 [0x2a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2959 [0x2b] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movntps, movntpd, movntss, movntsd */
2960 [0x2c] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2961 [0x2d] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2962 [0x2e] = { gen_helper_ucomiss
, gen_helper_ucomisd
},
2963 [0x2f] = { gen_helper_comiss
, gen_helper_comisd
},
2964 [0x50] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movmskps, movmskpd */
2965 [0x51] = SSE_FOP(sqrt
),
2966 [0x52] = { gen_helper_rsqrtps
, NULL
, gen_helper_rsqrtss
, NULL
},
2967 [0x53] = { gen_helper_rcpps
, NULL
, gen_helper_rcpss
, NULL
},
2968 [0x54] = { gen_helper_pand_xmm
, gen_helper_pand_xmm
}, /* andps, andpd */
2969 [0x55] = { gen_helper_pandn_xmm
, gen_helper_pandn_xmm
}, /* andnps, andnpd */
2970 [0x56] = { gen_helper_por_xmm
, gen_helper_por_xmm
}, /* orps, orpd */
2971 [0x57] = { gen_helper_pxor_xmm
, gen_helper_pxor_xmm
}, /* xorps, xorpd */
2972 [0x58] = SSE_FOP(add
),
2973 [0x59] = SSE_FOP(mul
),
2974 [0x5a] = { gen_helper_cvtps2pd
, gen_helper_cvtpd2ps
,
2975 gen_helper_cvtss2sd
, gen_helper_cvtsd2ss
},
2976 [0x5b] = { gen_helper_cvtdq2ps
, gen_helper_cvtps2dq
, gen_helper_cvttps2dq
},
2977 [0x5c] = SSE_FOP(sub
),
2978 [0x5d] = SSE_FOP(min
),
2979 [0x5e] = SSE_FOP(div
),
2980 [0x5f] = SSE_FOP(max
),
2982 [0xc2] = SSE_FOP(cmpeq
),
2983 [0xc6] = { (SSEFunc_0_epp
)gen_helper_shufps
,
2984 (SSEFunc_0_epp
)gen_helper_shufpd
}, /* XXX: casts */
2986 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */
2987 [0x38] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2988 [0x3a] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
2990 /* MMX ops and their SSE extensions */
2991 [0x60] = MMX_OP2(punpcklbw
),
2992 [0x61] = MMX_OP2(punpcklwd
),
2993 [0x62] = MMX_OP2(punpckldq
),
2994 [0x63] = MMX_OP2(packsswb
),
2995 [0x64] = MMX_OP2(pcmpgtb
),
2996 [0x65] = MMX_OP2(pcmpgtw
),
2997 [0x66] = MMX_OP2(pcmpgtl
),
2998 [0x67] = MMX_OP2(packuswb
),
2999 [0x68] = MMX_OP2(punpckhbw
),
3000 [0x69] = MMX_OP2(punpckhwd
),
3001 [0x6a] = MMX_OP2(punpckhdq
),
3002 [0x6b] = MMX_OP2(packssdw
),
3003 [0x6c] = { NULL
, gen_helper_punpcklqdq_xmm
},
3004 [0x6d] = { NULL
, gen_helper_punpckhqdq_xmm
},
3005 [0x6e] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movd mm, ea */
3006 [0x6f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, , movqdu */
3007 [0x70] = { (SSEFunc_0_epp
)gen_helper_pshufw_mmx
,
3008 (SSEFunc_0_epp
)gen_helper_pshufd_xmm
,
3009 (SSEFunc_0_epp
)gen_helper_pshufhw_xmm
,
3010 (SSEFunc_0_epp
)gen_helper_pshuflw_xmm
}, /* XXX: casts */
3011 [0x71] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftw */
3012 [0x72] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftd */
3013 [0x73] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* shiftq */
3014 [0x74] = MMX_OP2(pcmpeqb
),
3015 [0x75] = MMX_OP2(pcmpeqw
),
3016 [0x76] = MMX_OP2(pcmpeql
),
3017 [0x77] = { SSE_DUMMY
}, /* emms */
3018 [0x78] = { NULL
, SSE_SPECIAL
, NULL
, SSE_SPECIAL
}, /* extrq_i, insertq_i */
3019 [0x79] = { NULL
, gen_helper_extrq_r
, NULL
, gen_helper_insertq_r
},
3020 [0x7c] = { NULL
, gen_helper_haddpd
, NULL
, gen_helper_haddps
},
3021 [0x7d] = { NULL
, gen_helper_hsubpd
, NULL
, gen_helper_hsubps
},
3022 [0x7e] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movd, movd, , movq */
3023 [0x7f] = { SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
}, /* movq, movdqa, movdqu */
3024 [0xc4] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pinsrw */
3025 [0xc5] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pextrw */
3026 [0xd0] = { NULL
, gen_helper_addsubpd
, NULL
, gen_helper_addsubps
},
3027 [0xd1] = MMX_OP2(psrlw
),
3028 [0xd2] = MMX_OP2(psrld
),
3029 [0xd3] = MMX_OP2(psrlq
),
3030 [0xd4] = MMX_OP2(paddq
),
3031 [0xd5] = MMX_OP2(pmullw
),
3032 [0xd6] = { NULL
, SSE_SPECIAL
, SSE_SPECIAL
, SSE_SPECIAL
},
3033 [0xd7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* pmovmskb */
3034 [0xd8] = MMX_OP2(psubusb
),
3035 [0xd9] = MMX_OP2(psubusw
),
3036 [0xda] = MMX_OP2(pminub
),
3037 [0xdb] = MMX_OP2(pand
),
3038 [0xdc] = MMX_OP2(paddusb
),
3039 [0xdd] = MMX_OP2(paddusw
),
3040 [0xde] = MMX_OP2(pmaxub
),
3041 [0xdf] = MMX_OP2(pandn
),
3042 [0xe0] = MMX_OP2(pavgb
),
3043 [0xe1] = MMX_OP2(psraw
),
3044 [0xe2] = MMX_OP2(psrad
),
3045 [0xe3] = MMX_OP2(pavgw
),
3046 [0xe4] = MMX_OP2(pmulhuw
),
3047 [0xe5] = MMX_OP2(pmulhw
),
3048 [0xe6] = { NULL
, gen_helper_cvttpd2dq
, gen_helper_cvtdq2pd
, gen_helper_cvtpd2dq
},
3049 [0xe7] = { SSE_SPECIAL
, SSE_SPECIAL
}, /* movntq, movntq */
3050 [0xe8] = MMX_OP2(psubsb
),
3051 [0xe9] = MMX_OP2(psubsw
),
3052 [0xea] = MMX_OP2(pminsw
),
3053 [0xeb] = MMX_OP2(por
),
3054 [0xec] = MMX_OP2(paddsb
),
3055 [0xed] = MMX_OP2(paddsw
),
3056 [0xee] = MMX_OP2(pmaxsw
),
3057 [0xef] = MMX_OP2(pxor
),
3058 [0xf0] = { NULL
, NULL
, NULL
, SSE_SPECIAL
}, /* lddqu */
3059 [0xf1] = MMX_OP2(psllw
),
3060 [0xf2] = MMX_OP2(pslld
),
3061 [0xf3] = MMX_OP2(psllq
),
3062 [0xf4] = MMX_OP2(pmuludq
),
3063 [0xf5] = MMX_OP2(pmaddwd
),
3064 [0xf6] = MMX_OP2(psadbw
),
3065 [0xf7] = { (SSEFunc_0_epp
)gen_helper_maskmov_mmx
,
3066 (SSEFunc_0_epp
)gen_helper_maskmov_xmm
}, /* XXX: casts */
3067 [0xf8] = MMX_OP2(psubb
),
3068 [0xf9] = MMX_OP2(psubw
),
3069 [0xfa] = MMX_OP2(psubl
),
3070 [0xfb] = MMX_OP2(psubq
),
3071 [0xfc] = MMX_OP2(paddb
),
3072 [0xfd] = MMX_OP2(paddw
),
3073 [0xfe] = MMX_OP2(paddl
),
3076 static const SSEFunc_0_epp sse_op_table2
[3 * 8][2] = {
3077 [0 + 2] = MMX_OP2(psrlw
),
3078 [0 + 4] = MMX_OP2(psraw
),
3079 [0 + 6] = MMX_OP2(psllw
),
3080 [8 + 2] = MMX_OP2(psrld
),
3081 [8 + 4] = MMX_OP2(psrad
),
3082 [8 + 6] = MMX_OP2(pslld
),
3083 [16 + 2] = MMX_OP2(psrlq
),
3084 [16 + 3] = { NULL
, gen_helper_psrldq_xmm
},
3085 [16 + 6] = MMX_OP2(psllq
),
3086 [16 + 7] = { NULL
, gen_helper_pslldq_xmm
},
3089 static const SSEFunc_0_epi sse_op_table3ai
[] = {
3090 gen_helper_cvtsi2ss
,
3094 #ifdef TARGET_X86_64
3095 static const SSEFunc_0_epl sse_op_table3aq
[] = {
3096 gen_helper_cvtsq2ss
,
3101 static const SSEFunc_i_ep sse_op_table3bi
[] = {
3102 gen_helper_cvttss2si
,
3103 gen_helper_cvtss2si
,
3104 gen_helper_cvttsd2si
,
3108 #ifdef TARGET_X86_64
3109 static const SSEFunc_l_ep sse_op_table3bq
[] = {
3110 gen_helper_cvttss2sq
,
3111 gen_helper_cvtss2sq
,
3112 gen_helper_cvttsd2sq
,
3117 static const SSEFunc_0_epp sse_op_table4
[8][4] = {
3128 static const SSEFunc_0_epp sse_op_table5
[256] = {
3129 [0x0c] = gen_helper_pi2fw
,
3130 [0x0d] = gen_helper_pi2fd
,
3131 [0x1c] = gen_helper_pf2iw
,
3132 [0x1d] = gen_helper_pf2id
,
3133 [0x8a] = gen_helper_pfnacc
,
3134 [0x8e] = gen_helper_pfpnacc
,
3135 [0x90] = gen_helper_pfcmpge
,
3136 [0x94] = gen_helper_pfmin
,
3137 [0x96] = gen_helper_pfrcp
,
3138 [0x97] = gen_helper_pfrsqrt
,
3139 [0x9a] = gen_helper_pfsub
,
3140 [0x9e] = gen_helper_pfadd
,
3141 [0xa0] = gen_helper_pfcmpgt
,
3142 [0xa4] = gen_helper_pfmax
,
3143 [0xa6] = gen_helper_movq
, /* pfrcpit1; no need to actually increase precision */
3144 [0xa7] = gen_helper_movq
, /* pfrsqit1 */
3145 [0xaa] = gen_helper_pfsubr
,
3146 [0xae] = gen_helper_pfacc
,
3147 [0xb0] = gen_helper_pfcmpeq
,
3148 [0xb4] = gen_helper_pfmul
,
3149 [0xb6] = gen_helper_movq
, /* pfrcpit2 */
3150 [0xb7] = gen_helper_pmulhrw_mmx
,
3151 [0xbb] = gen_helper_pswapd
,
3152 [0xbf] = gen_helper_pavgb_mmx
/* pavgusb */
3155 struct SSEOpHelper_epp
{
3156 SSEFunc_0_epp op
[2];
3160 struct SSEOpHelper_eppi
{
3161 SSEFunc_0_eppi op
[2];
3165 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
3166 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
3167 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
3168 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
3170 static const struct SSEOpHelper_epp sse_op_table6
[256] = {
3171 [0x00] = SSSE3_OP(pshufb
),
3172 [0x01] = SSSE3_OP(phaddw
),
3173 [0x02] = SSSE3_OP(phaddd
),
3174 [0x03] = SSSE3_OP(phaddsw
),
3175 [0x04] = SSSE3_OP(pmaddubsw
),
3176 [0x05] = SSSE3_OP(phsubw
),
3177 [0x06] = SSSE3_OP(phsubd
),
3178 [0x07] = SSSE3_OP(phsubsw
),
3179 [0x08] = SSSE3_OP(psignb
),
3180 [0x09] = SSSE3_OP(psignw
),
3181 [0x0a] = SSSE3_OP(psignd
),
3182 [0x0b] = SSSE3_OP(pmulhrsw
),
3183 [0x10] = SSE41_OP(pblendvb
),
3184 [0x14] = SSE41_OP(blendvps
),
3185 [0x15] = SSE41_OP(blendvpd
),
3186 [0x17] = SSE41_OP(ptest
),
3187 [0x1c] = SSSE3_OP(pabsb
),
3188 [0x1d] = SSSE3_OP(pabsw
),
3189 [0x1e] = SSSE3_OP(pabsd
),
3190 [0x20] = SSE41_OP(pmovsxbw
),
3191 [0x21] = SSE41_OP(pmovsxbd
),
3192 [0x22] = SSE41_OP(pmovsxbq
),
3193 [0x23] = SSE41_OP(pmovsxwd
),
3194 [0x24] = SSE41_OP(pmovsxwq
),
3195 [0x25] = SSE41_OP(pmovsxdq
),
3196 [0x28] = SSE41_OP(pmuldq
),
3197 [0x29] = SSE41_OP(pcmpeqq
),
3198 [0x2a] = SSE41_SPECIAL
, /* movntqda */
3199 [0x2b] = SSE41_OP(packusdw
),
3200 [0x30] = SSE41_OP(pmovzxbw
),
3201 [0x31] = SSE41_OP(pmovzxbd
),
3202 [0x32] = SSE41_OP(pmovzxbq
),
3203 [0x33] = SSE41_OP(pmovzxwd
),
3204 [0x34] = SSE41_OP(pmovzxwq
),
3205 [0x35] = SSE41_OP(pmovzxdq
),
3206 [0x37] = SSE42_OP(pcmpgtq
),
3207 [0x38] = SSE41_OP(pminsb
),
3208 [0x39] = SSE41_OP(pminsd
),
3209 [0x3a] = SSE41_OP(pminuw
),
3210 [0x3b] = SSE41_OP(pminud
),
3211 [0x3c] = SSE41_OP(pmaxsb
),
3212 [0x3d] = SSE41_OP(pmaxsd
),
3213 [0x3e] = SSE41_OP(pmaxuw
),
3214 [0x3f] = SSE41_OP(pmaxud
),
3215 [0x40] = SSE41_OP(pmulld
),
3216 [0x41] = SSE41_OP(phminposuw
),
3219 static const struct SSEOpHelper_eppi sse_op_table7
[256] = {
3220 [0x08] = SSE41_OP(roundps
),
3221 [0x09] = SSE41_OP(roundpd
),
3222 [0x0a] = SSE41_OP(roundss
),
3223 [0x0b] = SSE41_OP(roundsd
),
3224 [0x0c] = SSE41_OP(blendps
),
3225 [0x0d] = SSE41_OP(blendpd
),
3226 [0x0e] = SSE41_OP(pblendw
),
3227 [0x0f] = SSSE3_OP(palignr
),
3228 [0x14] = SSE41_SPECIAL
, /* pextrb */
3229 [0x15] = SSE41_SPECIAL
, /* pextrw */
3230 [0x16] = SSE41_SPECIAL
, /* pextrd/pextrq */
3231 [0x17] = SSE41_SPECIAL
, /* extractps */
3232 [0x20] = SSE41_SPECIAL
, /* pinsrb */
3233 [0x21] = SSE41_SPECIAL
, /* insertps */
3234 [0x22] = SSE41_SPECIAL
, /* pinsrd/pinsrq */
3235 [0x40] = SSE41_OP(dpps
),
3236 [0x41] = SSE41_OP(dppd
),
3237 [0x42] = SSE41_OP(mpsadbw
),
3238 [0x60] = SSE42_OP(pcmpestrm
),
3239 [0x61] = SSE42_OP(pcmpestri
),
3240 [0x62] = SSE42_OP(pcmpistrm
),
3241 [0x63] = SSE42_OP(pcmpistri
),
3244 static void gen_sse(CPUX86State
*env
, DisasContext
*s
, int b
,
3245 target_ulong pc_start
, int rex_r
)
3247 int b1
, op1_offset
, op2_offset
, is_xmm
, val
, ot
;
3248 int modrm
, mod
, rm
, reg
, reg_addr
, offset_addr
;
3249 SSEFunc_0_epp sse_fn_epp
;
3250 SSEFunc_0_eppi sse_fn_eppi
;
3251 SSEFunc_0_ppi sse_fn_ppi
;
3252 SSEFunc_0_eppt sse_fn_eppt
;
3255 if (s
->prefix
& PREFIX_DATA
)
3257 else if (s
->prefix
& PREFIX_REPZ
)
3259 else if (s
->prefix
& PREFIX_REPNZ
)
3263 sse_fn_epp
= sse_op_table1
[b
][b1
];
3267 if ((b
<= 0x5f && b
>= 0x10) || b
== 0xc6 || b
== 0xc2) {
3277 /* simple MMX/SSE operation */
3278 if (s
->flags
& HF_TS_MASK
) {
3279 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
3282 if (s
->flags
& HF_EM_MASK
) {
3284 gen_exception(s
, EXCP06_ILLOP
, pc_start
- s
->cs_base
);
3287 if (is_xmm
&& !(s
->flags
& HF_OSFXSR_MASK
))
3288 if ((b
!= 0x38 && b
!= 0x3a) || (s
->prefix
& PREFIX_DATA
))
3291 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
))
3294 gen_helper_emms(cpu_env
);
3299 gen_helper_emms(cpu_env
);
3302 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3303 the static cpu state) */
3305 gen_helper_enter_mmx(cpu_env
);
3308 modrm
= cpu_ldub_code(env
, s
->pc
++);
3309 reg
= ((modrm
>> 3) & 7);
3312 mod
= (modrm
>> 6) & 3;
3313 if (sse_fn_epp
== SSE_SPECIAL
) {
3316 case 0x0e7: /* movntq */
3319 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3320 gen_stq_env_A0(s
->mem_index
, offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3322 case 0x1e7: /* movntdq */
3323 case 0x02b: /* movntps */
3324 case 0x12b: /* movntps */
3327 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3328 gen_sto_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
]));
3330 case 0x3f0: /* lddqu */
3333 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3334 gen_ldo_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
]));
3336 case 0x22b: /* movntss */
3337 case 0x32b: /* movntsd */
3340 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3342 gen_stq_env_A0(s
->mem_index
, offsetof(CPUX86State
,
3345 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
3346 xmm_regs
[reg
].XMM_L(0)));
3347 gen_op_st_T0_A0(OT_LONG
+ s
->mem_index
);
3350 case 0x6e: /* movd mm, ea */
3351 #ifdef TARGET_X86_64
3352 if (s
->dflag
== 2) {
3353 gen_ldst_modrm(env
, s
, modrm
, OT_QUAD
, OR_TMP0
, 0);
3354 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3358 gen_ldst_modrm(env
, s
, modrm
, OT_LONG
, OR_TMP0
, 0);
3359 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3360 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3361 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3362 gen_helper_movl_mm_T0_mmx(cpu_ptr0
, cpu_tmp2_i32
);
3365 case 0x16e: /* movd xmm, ea */
3366 #ifdef TARGET_X86_64
3367 if (s
->dflag
== 2) {
3368 gen_ldst_modrm(env
, s
, modrm
, OT_QUAD
, OR_TMP0
, 0);
3369 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3370 offsetof(CPUX86State
,xmm_regs
[reg
]));
3371 gen_helper_movq_mm_T0_xmm(cpu_ptr0
, cpu_T
[0]);
3375 gen_ldst_modrm(env
, s
, modrm
, OT_LONG
, OR_TMP0
, 0);
3376 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3377 offsetof(CPUX86State
,xmm_regs
[reg
]));
3378 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3379 gen_helper_movl_mm_T0_xmm(cpu_ptr0
, cpu_tmp2_i32
);
3382 case 0x6f: /* movq mm, ea */
3384 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3385 gen_ldq_env_A0(s
->mem_index
, offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3388 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
3389 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3390 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
3391 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3394 case 0x010: /* movups */
3395 case 0x110: /* movupd */
3396 case 0x028: /* movaps */
3397 case 0x128: /* movapd */
3398 case 0x16f: /* movdqa xmm, ea */
3399 case 0x26f: /* movdqu xmm, ea */
3401 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3402 gen_ldo_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
]));
3404 rm
= (modrm
& 7) | REX_B(s
);
3405 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[reg
]),
3406 offsetof(CPUX86State
,xmm_regs
[rm
]));
3409 case 0x210: /* movss xmm, ea */
3411 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3412 gen_op_ld_T0_A0(OT_LONG
+ s
->mem_index
);
3413 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3415 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(1)));
3416 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)));
3417 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)));
3419 rm
= (modrm
& 7) | REX_B(s
);
3420 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)),
3421 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(0)));
3424 case 0x310: /* movsd xmm, ea */
3426 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3427 gen_ldq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3429 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)));
3430 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)));
3432 rm
= (modrm
& 7) | REX_B(s
);
3433 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3434 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3437 case 0x012: /* movlps */
3438 case 0x112: /* movlpd */
3440 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3441 gen_ldq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
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(1)));
3449 case 0x212: /* movsldup */
3451 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3452 gen_ldo_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
]));
3454 rm
= (modrm
& 7) | REX_B(s
);
3455 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)),
3456 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(0)));
3457 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)),
3458 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(2)));
3460 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(1)),
3461 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3462 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)),
3463 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)));
3465 case 0x312: /* movddup */
3467 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3468 gen_ldq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3470 rm
= (modrm
& 7) | REX_B(s
);
3471 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3472 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3474 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)),
3475 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3477 case 0x016: /* movhps */
3478 case 0x116: /* movhpd */
3480 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3481 gen_ldq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)));
3484 rm
= (modrm
& 7) | REX_B(s
);
3485 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)),
3486 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3489 case 0x216: /* movshdup */
3491 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3492 gen_ldo_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
]));
3494 rm
= (modrm
& 7) | REX_B(s
);
3495 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(1)),
3496 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(1)));
3497 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)),
3498 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(3)));
3500 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)),
3501 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(1)));
3502 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(2)),
3503 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(3)));
3508 int bit_index
, field_length
;
3510 if (b1
== 1 && reg
!= 0)
3512 field_length
= cpu_ldub_code(env
, s
->pc
++) & 0x3F;
3513 bit_index
= cpu_ldub_code(env
, s
->pc
++) & 0x3F;
3514 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3515 offsetof(CPUX86State
,xmm_regs
[reg
]));
3517 gen_helper_extrq_i(cpu_env
, cpu_ptr0
,
3518 tcg_const_i32(bit_index
),
3519 tcg_const_i32(field_length
));
3521 gen_helper_insertq_i(cpu_env
, cpu_ptr0
,
3522 tcg_const_i32(bit_index
),
3523 tcg_const_i32(field_length
));
3526 case 0x7e: /* movd ea, mm */
3527 #ifdef TARGET_X86_64
3528 if (s
->dflag
== 2) {
3529 tcg_gen_ld_i64(cpu_T
[0], cpu_env
,
3530 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3531 gen_ldst_modrm(env
, s
, modrm
, OT_QUAD
, OR_TMP0
, 1);
3535 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
,
3536 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_L(0)));
3537 gen_ldst_modrm(env
, s
, modrm
, OT_LONG
, OR_TMP0
, 1);
3540 case 0x17e: /* movd ea, xmm */
3541 #ifdef TARGET_X86_64
3542 if (s
->dflag
== 2) {
3543 tcg_gen_ld_i64(cpu_T
[0], cpu_env
,
3544 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3545 gen_ldst_modrm(env
, s
, modrm
, OT_QUAD
, OR_TMP0
, 1);
3549 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
,
3550 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3551 gen_ldst_modrm(env
, s
, modrm
, OT_LONG
, OR_TMP0
, 1);
3554 case 0x27e: /* movq xmm, ea */
3556 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3557 gen_ldq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3559 rm
= (modrm
& 7) | REX_B(s
);
3560 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3561 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3563 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)));
3565 case 0x7f: /* movq ea, mm */
3567 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3568 gen_stq_env_A0(s
->mem_index
, offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3571 gen_op_movq(offsetof(CPUX86State
,fpregs
[rm
].mmx
),
3572 offsetof(CPUX86State
,fpregs
[reg
].mmx
));
3575 case 0x011: /* movups */
3576 case 0x111: /* movupd */
3577 case 0x029: /* movaps */
3578 case 0x129: /* movapd */
3579 case 0x17f: /* movdqa ea, xmm */
3580 case 0x27f: /* movdqu ea, xmm */
3582 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3583 gen_sto_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
]));
3585 rm
= (modrm
& 7) | REX_B(s
);
3586 gen_op_movo(offsetof(CPUX86State
,xmm_regs
[rm
]),
3587 offsetof(CPUX86State
,xmm_regs
[reg
]));
3590 case 0x211: /* movss ea, xmm */
3592 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3593 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3594 gen_op_st_T0_A0(OT_LONG
+ s
->mem_index
);
3596 rm
= (modrm
& 7) | REX_B(s
);
3597 gen_op_movl(offsetof(CPUX86State
,xmm_regs
[rm
].XMM_L(0)),
3598 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_L(0)));
3601 case 0x311: /* movsd ea, xmm */
3603 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3604 gen_stq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3606 rm
= (modrm
& 7) | REX_B(s
);
3607 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)),
3608 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3611 case 0x013: /* movlps */
3612 case 0x113: /* movlpd */
3614 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3615 gen_stq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3620 case 0x017: /* movhps */
3621 case 0x117: /* movhpd */
3623 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3624 gen_stq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)));
3629 case 0x71: /* shift mm, im */
3632 case 0x171: /* shift xmm, im */
3638 val
= cpu_ldub_code(env
, s
->pc
++);
3640 gen_op_movl_T0_im(val
);
3641 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.XMM_L(0)));
3643 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.XMM_L(1)));
3644 op1_offset
= offsetof(CPUX86State
,xmm_t0
);
3646 gen_op_movl_T0_im(val
);
3647 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,mmx_t0
.MMX_L(0)));
3649 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,mmx_t0
.MMX_L(1)));
3650 op1_offset
= offsetof(CPUX86State
,mmx_t0
);
3652 sse_fn_epp
= sse_op_table2
[((b
- 1) & 3) * 8 +
3653 (((modrm
>> 3)) & 7)][b1
];
3658 rm
= (modrm
& 7) | REX_B(s
);
3659 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3662 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3664 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3665 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op1_offset
);
3666 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3668 case 0x050: /* movmskps */
3669 rm
= (modrm
& 7) | REX_B(s
);
3670 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3671 offsetof(CPUX86State
,xmm_regs
[rm
]));
3672 gen_helper_movmskps(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3673 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
3674 gen_op_mov_reg_T0(OT_LONG
, reg
);
3676 case 0x150: /* movmskpd */
3677 rm
= (modrm
& 7) | REX_B(s
);
3678 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
,
3679 offsetof(CPUX86State
,xmm_regs
[rm
]));
3680 gen_helper_movmskpd(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3681 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
3682 gen_op_mov_reg_T0(OT_LONG
, reg
);
3684 case 0x02a: /* cvtpi2ps */
3685 case 0x12a: /* cvtpi2pd */
3686 gen_helper_enter_mmx(cpu_env
);
3688 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3689 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3690 gen_ldq_env_A0(s
->mem_index
, op2_offset
);
3693 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3695 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3696 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3697 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3700 gen_helper_cvtpi2ps(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3704 gen_helper_cvtpi2pd(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3708 case 0x22a: /* cvtsi2ss */
3709 case 0x32a: /* cvtsi2sd */
3710 ot
= (s
->dflag
== 2) ? OT_QUAD
: OT_LONG
;
3711 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3712 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3713 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3714 if (ot
== OT_LONG
) {
3715 SSEFunc_0_epi sse_fn_epi
= sse_op_table3ai
[(b
>> 8) & 1];
3716 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3717 sse_fn_epi(cpu_env
, cpu_ptr0
, cpu_tmp2_i32
);
3719 #ifdef TARGET_X86_64
3720 SSEFunc_0_epl sse_fn_epl
= sse_op_table3aq
[(b
>> 8) & 1];
3721 sse_fn_epl(cpu_env
, cpu_ptr0
, cpu_T
[0]);
3727 case 0x02c: /* cvttps2pi */
3728 case 0x12c: /* cvttpd2pi */
3729 case 0x02d: /* cvtps2pi */
3730 case 0x12d: /* cvtpd2pi */
3731 gen_helper_enter_mmx(cpu_env
);
3733 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3734 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3735 gen_ldo_env_A0(s
->mem_index
, op2_offset
);
3737 rm
= (modrm
& 7) | REX_B(s
);
3738 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3740 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
);
3741 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3742 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3745 gen_helper_cvttps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3748 gen_helper_cvttpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3751 gen_helper_cvtps2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3754 gen_helper_cvtpd2pi(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3758 case 0x22c: /* cvttss2si */
3759 case 0x32c: /* cvttsd2si */
3760 case 0x22d: /* cvtss2si */
3761 case 0x32d: /* cvtsd2si */
3762 ot
= (s
->dflag
== 2) ? OT_QUAD
: OT_LONG
;
3764 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3766 gen_ldq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_t0
.XMM_Q(0)));
3768 gen_op_ld_T0_A0(OT_LONG
+ s
->mem_index
);
3769 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.XMM_L(0)));
3771 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3773 rm
= (modrm
& 7) | REX_B(s
);
3774 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
3776 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op2_offset
);
3777 if (ot
== OT_LONG
) {
3778 SSEFunc_i_ep sse_fn_i_ep
=
3779 sse_op_table3bi
[((b
>> 7) & 2) | (b
& 1)];
3780 sse_fn_i_ep(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3781 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
3783 #ifdef TARGET_X86_64
3784 SSEFunc_l_ep sse_fn_l_ep
=
3785 sse_op_table3bq
[((b
>> 7) & 2) | (b
& 1)];
3786 sse_fn_l_ep(cpu_T
[0], cpu_env
, cpu_ptr0
);
3791 gen_op_mov_reg_T0(ot
, reg
);
3793 case 0xc4: /* pinsrw */
3796 gen_ldst_modrm(env
, s
, modrm
, OT_WORD
, OR_TMP0
, 0);
3797 val
= cpu_ldub_code(env
, s
->pc
++);
3800 tcg_gen_st16_tl(cpu_T
[0], cpu_env
,
3801 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_W(val
)));
3804 tcg_gen_st16_tl(cpu_T
[0], cpu_env
,
3805 offsetof(CPUX86State
,fpregs
[reg
].mmx
.MMX_W(val
)));
3808 case 0xc5: /* pextrw */
3812 ot
= (s
->dflag
== 2) ? OT_QUAD
: OT_LONG
;
3813 val
= cpu_ldub_code(env
, s
->pc
++);
3816 rm
= (modrm
& 7) | REX_B(s
);
3817 tcg_gen_ld16u_tl(cpu_T
[0], cpu_env
,
3818 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_W(val
)));
3822 tcg_gen_ld16u_tl(cpu_T
[0], cpu_env
,
3823 offsetof(CPUX86State
,fpregs
[rm
].mmx
.MMX_W(val
)));
3825 reg
= ((modrm
>> 3) & 7) | rex_r
;
3826 gen_op_mov_reg_T0(ot
, reg
);
3828 case 0x1d6: /* movq ea, xmm */
3830 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3831 gen_stq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3833 rm
= (modrm
& 7) | REX_B(s
);
3834 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)),
3835 offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)));
3836 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(1)));
3839 case 0x2d6: /* movq2dq */
3840 gen_helper_enter_mmx(cpu_env
);
3842 gen_op_movq(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(0)),
3843 offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3844 gen_op_movq_env_0(offsetof(CPUX86State
,xmm_regs
[reg
].XMM_Q(1)));
3846 case 0x3d6: /* movdq2q */
3847 gen_helper_enter_mmx(cpu_env
);
3848 rm
= (modrm
& 7) | REX_B(s
);
3849 gen_op_movq(offsetof(CPUX86State
,fpregs
[reg
& 7].mmx
),
3850 offsetof(CPUX86State
,xmm_regs
[rm
].XMM_Q(0)));
3852 case 0xd7: /* pmovmskb */
3857 rm
= (modrm
& 7) | REX_B(s
);
3858 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,xmm_regs
[rm
]));
3859 gen_helper_pmovmskb_xmm(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3862 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, offsetof(CPUX86State
,fpregs
[rm
].mmx
));
3863 gen_helper_pmovmskb_mmx(cpu_tmp2_i32
, cpu_env
, cpu_ptr0
);
3865 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
3866 reg
= ((modrm
>> 3) & 7) | rex_r
;
3867 gen_op_mov_reg_T0(OT_LONG
, reg
);
3873 if ((b
& 0xf0) == 0xf0) {
3876 modrm
= cpu_ldub_code(env
, s
->pc
++);
3878 reg
= ((modrm
>> 3) & 7) | rex_r
;
3879 mod
= (modrm
>> 6) & 3;
3884 sse_fn_epp
= sse_op_table6
[b
].op
[b1
];
3888 if (!(s
->cpuid_ext_features
& sse_op_table6
[b
].ext_mask
))
3892 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
3894 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
3896 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
3897 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3899 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3900 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3901 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3902 gen_ldq_env_A0(s
->mem_index
, op2_offset
+
3903 offsetof(XMMReg
, XMM_Q(0)));
3905 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3906 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3907 tcg_gen_qemu_ld32u(cpu_tmp0
, cpu_A0
,
3908 (s
->mem_index
>> 2) - 1);
3909 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_tmp0
);
3910 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, op2_offset
+
3911 offsetof(XMMReg
, XMM_L(0)));
3913 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3914 tcg_gen_qemu_ld16u(cpu_tmp0
, cpu_A0
,
3915 (s
->mem_index
>> 2) - 1);
3916 tcg_gen_st16_tl(cpu_tmp0
, cpu_env
, op2_offset
+
3917 offsetof(XMMReg
, XMM_W(0)));
3919 case 0x2a: /* movntqda */
3920 gen_ldo_env_A0(s
->mem_index
, op1_offset
);
3923 gen_ldo_env_A0(s
->mem_index
, op2_offset
);
3927 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
3929 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
3931 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
3932 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
3933 gen_ldq_env_A0(s
->mem_index
, op2_offset
);
3936 if (sse_fn_epp
== SSE_SPECIAL
) {
3940 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
3941 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
3942 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
3945 set_cc_op(s
, CC_OP_EFLAGS
);
3952 /* Various integer extensions at 0f 38 f[0-f]. */
3953 b
= modrm
| (b1
<< 8);
3954 modrm
= cpu_ldub_code(env
, s
->pc
++);
3955 reg
= ((modrm
>> 3) & 7) | rex_r
;
3958 case 0x3f0: /* crc32 Gd,Eb */
3959 case 0x3f1: /* crc32 Gd,Ey */
3961 if (!(s
->cpuid_ext_features
& CPUID_EXT_SSE42
)) {
3964 if ((b
& 0xff) == 0xf0) {
3966 } else if (s
->dflag
!= 2) {
3967 ot
= (s
->prefix
& PREFIX_DATA
? OT_WORD
: OT_LONG
);
3972 gen_op_mov_TN_reg(OT_LONG
, 0, reg
);
3973 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
3974 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
3975 gen_helper_crc32(cpu_T
[0], cpu_tmp2_i32
,
3976 cpu_T
[0], tcg_const_i32(8 << ot
));
3978 ot
= (s
->dflag
== 2) ? OT_QUAD
: OT_LONG
;
3979 gen_op_mov_reg_T0(ot
, reg
);
3982 case 0x1f0: /* crc32 or movbe */
3984 /* For these insns, the f3 prefix is supposed to have priority
3985 over the 66 prefix, but that's not what we implement above
3987 if (s
->prefix
& PREFIX_REPNZ
) {
3991 case 0x0f0: /* movbe Gy,My */
3992 case 0x0f1: /* movbe My,Gy */
3993 if (!(s
->cpuid_ext_features
& CPUID_EXT_MOVBE
)) {
3996 if (s
->dflag
!= 2) {
3997 ot
= (s
->prefix
& PREFIX_DATA
? OT_WORD
: OT_LONG
);
4002 /* Load the data incoming to the bswap. Note that the TCG
4003 implementation of bswap requires the input be zero
4004 extended. In the case of the loads, we simply know that
4005 gen_op_ld_v via gen_ldst_modrm does that already. */
4007 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4011 tcg_gen_ext16u_tl(cpu_T
[0], cpu_regs
[reg
]);
4014 tcg_gen_ext32u_tl(cpu_T
[0], cpu_regs
[reg
]);
4017 tcg_gen_mov_tl(cpu_T
[0], cpu_regs
[reg
]);
4024 tcg_gen_bswap16_tl(cpu_T
[0], cpu_T
[0]);
4027 tcg_gen_bswap32_tl(cpu_T
[0], cpu_T
[0]);
4029 #ifdef TARGET_X86_64
4031 tcg_gen_bswap64_tl(cpu_T
[0], cpu_T
[0]);
4037 gen_op_mov_reg_T0(ot
, reg
);
4039 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
4043 case 0x0f2: /* andn Gy, By, Ey */
4044 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
4045 || !(s
->prefix
& PREFIX_VEX
)
4049 ot
= s
->dflag
== 2 ? OT_QUAD
: OT_LONG
;
4050 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4051 tcg_gen_andc_tl(cpu_T
[0], cpu_regs
[s
->vex_v
], cpu_T
[0]);
4052 gen_op_mov_reg_T0(ot
, reg
);
4053 gen_op_update1_cc();
4054 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4057 case 0x0f7: /* bextr Gy, Ey, By */
4058 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
4059 || !(s
->prefix
& PREFIX_VEX
)
4063 ot
= s
->dflag
== 2 ? OT_QUAD
: OT_LONG
;
4067 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4068 /* Extract START, and shift the operand.
4069 Shifts larger than operand size get zeros. */
4070 tcg_gen_ext8u_tl(cpu_A0
, cpu_regs
[s
->vex_v
]);
4071 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], cpu_A0
);
4073 bound
= tcg_const_tl(ot
== OT_QUAD
? 63 : 31);
4074 zero
= tcg_const_tl(0);
4075 tcg_gen_movcond_tl(TCG_COND_LEU
, cpu_T
[0], cpu_A0
, bound
,
4077 tcg_temp_free(zero
);
4079 /* Extract the LEN into a mask. Lengths larger than
4080 operand size get all ones. */
4081 tcg_gen_shri_tl(cpu_A0
, cpu_regs
[s
->vex_v
], 8);
4082 tcg_gen_ext8u_tl(cpu_A0
, cpu_A0
);
4083 tcg_gen_movcond_tl(TCG_COND_LEU
, cpu_A0
, cpu_A0
, bound
,
4085 tcg_temp_free(bound
);
4086 tcg_gen_movi_tl(cpu_T
[1], 1);
4087 tcg_gen_shl_tl(cpu_T
[1], cpu_T
[1], cpu_A0
);
4088 tcg_gen_subi_tl(cpu_T
[1], cpu_T
[1], 1);
4089 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4091 gen_op_mov_reg_T0(ot
, reg
);
4092 gen_op_update1_cc();
4093 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4097 case 0x0f5: /* bzhi Gy, Ey, By */
4098 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4099 || !(s
->prefix
& PREFIX_VEX
)
4103 ot
= s
->dflag
== 2 ? OT_QUAD
: OT_LONG
;
4104 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4105 tcg_gen_ext8u_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
4107 TCGv bound
= tcg_const_tl(ot
== OT_QUAD
? 63 : 31);
4108 /* Note that since we're using BMILG (in order to get O
4109 cleared) we need to store the inverse into C. */
4110 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_cc_src
,
4112 tcg_gen_movcond_tl(TCG_COND_GT
, cpu_T
[1], cpu_T
[1],
4113 bound
, bound
, cpu_T
[1]);
4114 tcg_temp_free(bound
);
4116 tcg_gen_movi_tl(cpu_A0
, -1);
4117 tcg_gen_shl_tl(cpu_A0
, cpu_A0
, cpu_T
[1]);
4118 tcg_gen_andc_tl(cpu_T
[0], cpu_T
[0], cpu_A0
);
4119 gen_op_mov_reg_T0(ot
, reg
);
4120 gen_op_update1_cc();
4121 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4124 case 0x3f6: /* mulx By, Gy, rdx, Ey */
4125 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4126 || !(s
->prefix
& PREFIX_VEX
)
4130 ot
= s
->dflag
== 2 ? OT_QUAD
: OT_LONG
;
4131 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4135 t0
= tcg_temp_new_i64();
4136 t1
= tcg_temp_new_i64();
4137 #ifdef TARGET_X86_64
4138 tcg_gen_ext32u_i64(t0
, cpu_T
[0]);
4139 tcg_gen_ext32u_i64(t1
, cpu_regs
[R_EDX
]);
4141 tcg_gen_extu_i32_i64(t0
, cpu_T
[0]);
4142 tcg_gen_extu_i32_i64(t0
, cpu_regs
[R_EDX
]);
4144 tcg_gen_mul_i64(t0
, t0
, t1
);
4145 tcg_gen_trunc_i64_tl(cpu_T
[0], t0
);
4146 tcg_gen_shri_i64(t0
, t0
, 32);
4147 tcg_gen_trunc_i64_tl(cpu_T
[1], t0
);
4148 tcg_temp_free_i64(t0
);
4149 tcg_temp_free_i64(t1
);
4150 gen_op_mov_reg_T0(OT_LONG
, s
->vex_v
);
4151 gen_op_mov_reg_T1(OT_LONG
, reg
);
4153 #ifdef TARGET_X86_64
4155 tcg_gen_mov_tl(cpu_T
[1], cpu_regs
[R_EDX
]);
4156 tcg_gen_mul_tl(cpu_regs
[s
->vex_v
], cpu_T
[0], cpu_T
[1]);
4157 gen_helper_umulh(cpu_regs
[reg
], cpu_T
[0], cpu_T
[1]);
4163 case 0x3f5: /* pdep Gy, By, Ey */
4164 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4165 || !(s
->prefix
& PREFIX_VEX
)
4169 ot
= s
->dflag
== 2 ? OT_QUAD
: OT_LONG
;
4170 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4171 /* Note that by zero-extending the mask operand, we
4172 automatically handle zero-extending the result. */
4173 if (s
->dflag
== 2) {
4174 tcg_gen_mov_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
4176 tcg_gen_ext32u_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
4178 gen_helper_pdep(cpu_regs
[reg
], cpu_T
[0], cpu_T
[1]);
4181 case 0x2f5: /* pext Gy, By, Ey */
4182 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4183 || !(s
->prefix
& PREFIX_VEX
)
4187 ot
= s
->dflag
== 2 ? OT_QUAD
: OT_LONG
;
4188 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4189 /* Note that by zero-extending the mask operand, we
4190 automatically handle zero-extending the result. */
4191 if (s
->dflag
== 2) {
4192 tcg_gen_mov_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
4194 tcg_gen_ext32u_tl(cpu_T
[1], cpu_regs
[s
->vex_v
]);
4196 gen_helper_pext(cpu_regs
[reg
], cpu_T
[0], cpu_T
[1]);
4199 case 0x1f6: /* adcx Gy, Ey */
4200 case 0x2f6: /* adox Gy, Ey */
4201 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_ADX
)) {
4204 TCGv carry_in
, carry_out
;
4207 ot
= (s
->dflag
== 2 ? OT_QUAD
: OT_LONG
);
4208 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4210 /* Re-use the carry-out from a previous round. */
4211 TCGV_UNUSED(carry_in
);
4212 carry_out
= (b
== 0x1f6 ? cpu_cc_dst
: cpu_cc_src2
);
4216 carry_in
= cpu_cc_dst
;
4217 end_op
= CC_OP_ADCX
;
4219 end_op
= CC_OP_ADCOX
;
4224 end_op
= CC_OP_ADCOX
;
4226 carry_in
= cpu_cc_src2
;
4227 end_op
= CC_OP_ADOX
;
4231 end_op
= CC_OP_ADCOX
;
4232 carry_in
= carry_out
;
4235 end_op
= (b
== 0x1f6 ? CC_OP_ADCX
: CC_OP_ADCOX
);
4238 /* If we can't reuse carry-out, get it out of EFLAGS. */
4239 if (TCGV_IS_UNUSED(carry_in
)) {
4240 if (s
->cc_op
!= CC_OP_ADCX
&& s
->cc_op
!= CC_OP_ADOX
) {
4241 gen_compute_eflags(s
);
4243 carry_in
= cpu_tmp0
;
4244 tcg_gen_shri_tl(carry_in
, cpu_cc_src
,
4245 ctz32(b
== 0x1f6 ? CC_C
: CC_O
));
4246 tcg_gen_andi_tl(carry_in
, carry_in
, 1);
4250 #ifdef TARGET_X86_64
4252 /* If we know TL is 64-bit, and we want a 32-bit
4253 result, just do everything in 64-bit arithmetic. */
4254 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_regs
[reg
]);
4255 tcg_gen_ext32u_i64(cpu_T
[0], cpu_T
[0]);
4256 tcg_gen_add_i64(cpu_T
[0], cpu_T
[0], cpu_regs
[reg
]);
4257 tcg_gen_add_i64(cpu_T
[0], cpu_T
[0], carry_in
);
4258 tcg_gen_ext32u_i64(cpu_regs
[reg
], cpu_T
[0]);
4259 tcg_gen_shri_i64(carry_out
, cpu_T
[0], 32);
4263 /* Otherwise compute the carry-out in two steps. */
4264 tcg_gen_add_tl(cpu_T
[0], cpu_T
[0], cpu_regs
[reg
]);
4265 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_tmp4
,
4266 cpu_T
[0], cpu_regs
[reg
]);
4267 tcg_gen_add_tl(cpu_regs
[reg
], cpu_T
[0], carry_in
);
4268 tcg_gen_setcond_tl(TCG_COND_LTU
, carry_out
,
4269 cpu_regs
[reg
], cpu_T
[0]);
4270 tcg_gen_or_tl(carry_out
, carry_out
, cpu_tmp4
);
4273 /* We began with all flags computed to CC_SRC, and we
4274 have now placed the carry-out in CC_DST. All that
4275 is left is to record the CC_OP. */
4276 set_cc_op(s
, end_op
);
4280 case 0x1f7: /* shlx Gy, Ey, By */
4281 case 0x2f7: /* sarx Gy, Ey, By */
4282 case 0x3f7: /* shrx Gy, Ey, By */
4283 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4284 || !(s
->prefix
& PREFIX_VEX
)
4288 ot
= (s
->dflag
== 2 ? OT_QUAD
: OT_LONG
);
4289 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4290 if (ot
== OT_QUAD
) {
4291 tcg_gen_andi_tl(cpu_T
[1], cpu_regs
[s
->vex_v
], 63);
4293 tcg_gen_andi_tl(cpu_T
[1], cpu_regs
[s
->vex_v
], 31);
4296 tcg_gen_shl_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4297 } else if (b
== 0x2f7) {
4298 if (ot
!= OT_QUAD
) {
4299 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
4301 tcg_gen_sar_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4303 if (ot
!= OT_QUAD
) {
4304 tcg_gen_ext32u_tl(cpu_T
[0], cpu_T
[0]);
4306 tcg_gen_shr_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4308 gen_op_mov_reg_T0(ot
, reg
);
4314 case 0x3f3: /* Group 17 */
4315 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)
4316 || !(s
->prefix
& PREFIX_VEX
)
4320 ot
= s
->dflag
== 2 ? OT_QUAD
: OT_LONG
;
4321 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4324 case 1: /* blsr By,Ey */
4325 tcg_gen_neg_tl(cpu_T
[1], cpu_T
[0]);
4326 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
4327 gen_op_mov_reg_T0(ot
, s
->vex_v
);
4328 gen_op_update2_cc();
4329 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4332 case 2: /* blsmsk By,Ey */
4333 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
4334 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], 1);
4335 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_cc_src
);
4336 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4337 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4340 case 3: /* blsi By, Ey */
4341 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
4342 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], 1);
4343 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_cc_src
);
4344 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
4345 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
4361 modrm
= cpu_ldub_code(env
, s
->pc
++);
4363 reg
= ((modrm
>> 3) & 7) | rex_r
;
4364 mod
= (modrm
>> 6) & 3;
4369 sse_fn_eppi
= sse_op_table7
[b
].op
[b1
];
4373 if (!(s
->cpuid_ext_features
& sse_op_table7
[b
].ext_mask
))
4376 if (sse_fn_eppi
== SSE_SPECIAL
) {
4377 ot
= (s
->dflag
== 2) ? OT_QUAD
: OT_LONG
;
4378 rm
= (modrm
& 7) | REX_B(s
);
4380 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4381 reg
= ((modrm
>> 3) & 7) | rex_r
;
4382 val
= cpu_ldub_code(env
, s
->pc
++);
4384 case 0x14: /* pextrb */
4385 tcg_gen_ld8u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4386 xmm_regs
[reg
].XMM_B(val
& 15)));
4388 gen_op_mov_reg_T0(ot
, rm
);
4390 tcg_gen_qemu_st8(cpu_T
[0], cpu_A0
,
4391 (s
->mem_index
>> 2) - 1);
4393 case 0x15: /* pextrw */
4394 tcg_gen_ld16u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4395 xmm_regs
[reg
].XMM_W(val
& 7)));
4397 gen_op_mov_reg_T0(ot
, rm
);
4399 tcg_gen_qemu_st16(cpu_T
[0], cpu_A0
,
4400 (s
->mem_index
>> 2) - 1);
4403 if (ot
== OT_LONG
) { /* pextrd */
4404 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4405 offsetof(CPUX86State
,
4406 xmm_regs
[reg
].XMM_L(val
& 3)));
4407 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
4409 gen_op_mov_reg_v(ot
, rm
, cpu_T
[0]);
4411 tcg_gen_qemu_st32(cpu_T
[0], cpu_A0
,
4412 (s
->mem_index
>> 2) - 1);
4413 } else { /* pextrq */
4414 #ifdef TARGET_X86_64
4415 tcg_gen_ld_i64(cpu_tmp1_i64
, cpu_env
,
4416 offsetof(CPUX86State
,
4417 xmm_regs
[reg
].XMM_Q(val
& 1)));
4419 gen_op_mov_reg_v(ot
, rm
, cpu_tmp1_i64
);
4421 tcg_gen_qemu_st64(cpu_tmp1_i64
, cpu_A0
,
4422 (s
->mem_index
>> 2) - 1);
4428 case 0x17: /* extractps */
4429 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,
4430 xmm_regs
[reg
].XMM_L(val
& 3)));
4432 gen_op_mov_reg_T0(ot
, rm
);
4434 tcg_gen_qemu_st32(cpu_T
[0], cpu_A0
,
4435 (s
->mem_index
>> 2) - 1);
4437 case 0x20: /* pinsrb */
4439 gen_op_mov_TN_reg(OT_LONG
, 0, rm
);
4441 tcg_gen_qemu_ld8u(cpu_tmp0
, cpu_A0
,
4442 (s
->mem_index
>> 2) - 1);
4443 tcg_gen_st8_tl(cpu_tmp0
, cpu_env
, offsetof(CPUX86State
,
4444 xmm_regs
[reg
].XMM_B(val
& 15)));
4446 case 0x21: /* insertps */
4448 tcg_gen_ld_i32(cpu_tmp2_i32
, cpu_env
,
4449 offsetof(CPUX86State
,xmm_regs
[rm
]
4450 .XMM_L((val
>> 6) & 3)));
4452 tcg_gen_qemu_ld32u(cpu_tmp0
, cpu_A0
,
4453 (s
->mem_index
>> 2) - 1);
4454 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_tmp0
);
4456 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4457 offsetof(CPUX86State
,xmm_regs
[reg
]
4458 .XMM_L((val
>> 4) & 3)));
4460 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4461 cpu_env
, offsetof(CPUX86State
,
4462 xmm_regs
[reg
].XMM_L(0)));
4464 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4465 cpu_env
, offsetof(CPUX86State
,
4466 xmm_regs
[reg
].XMM_L(1)));
4468 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4469 cpu_env
, offsetof(CPUX86State
,
4470 xmm_regs
[reg
].XMM_L(2)));
4472 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4473 cpu_env
, offsetof(CPUX86State
,
4474 xmm_regs
[reg
].XMM_L(3)));
4477 if (ot
== OT_LONG
) { /* pinsrd */
4479 gen_op_mov_v_reg(ot
, cpu_tmp0
, rm
);
4481 tcg_gen_qemu_ld32u(cpu_tmp0
, cpu_A0
,
4482 (s
->mem_index
>> 2) - 1);
4483 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_tmp0
);
4484 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
,
4485 offsetof(CPUX86State
,
4486 xmm_regs
[reg
].XMM_L(val
& 3)));
4487 } else { /* pinsrq */
4488 #ifdef TARGET_X86_64
4490 gen_op_mov_v_reg(ot
, cpu_tmp1_i64
, rm
);
4492 tcg_gen_qemu_ld64(cpu_tmp1_i64
, cpu_A0
,
4493 (s
->mem_index
>> 2) - 1);
4494 tcg_gen_st_i64(cpu_tmp1_i64
, cpu_env
,
4495 offsetof(CPUX86State
,
4496 xmm_regs
[reg
].XMM_Q(val
& 1)));
4507 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4509 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
| REX_B(s
)]);
4511 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4512 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4513 gen_ldo_env_A0(s
->mem_index
, op2_offset
);
4516 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4518 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4520 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4521 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4522 gen_ldq_env_A0(s
->mem_index
, op2_offset
);
4525 val
= cpu_ldub_code(env
, s
->pc
++);
4527 if ((b
& 0xfc) == 0x60) { /* pcmpXstrX */
4528 set_cc_op(s
, CC_OP_EFLAGS
);
4531 /* The helper must use entire 64-bit gp registers */
4535 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4536 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4537 sse_fn_eppi(cpu_env
, cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4541 /* Various integer extensions at 0f 3a f[0-f]. */
4542 b
= modrm
| (b1
<< 8);
4543 modrm
= cpu_ldub_code(env
, s
->pc
++);
4544 reg
= ((modrm
>> 3) & 7) | rex_r
;
4547 case 0x3f0: /* rorx Gy,Ey, Ib */
4548 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI2
)
4549 || !(s
->prefix
& PREFIX_VEX
)
4553 ot
= s
->dflag
== 2 ? OT_QUAD
: OT_LONG
;
4554 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
4555 b
= cpu_ldub_code(env
, s
->pc
++);
4556 if (ot
== OT_QUAD
) {
4557 tcg_gen_rotri_tl(cpu_T
[0], cpu_T
[0], b
& 63);
4559 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
4560 tcg_gen_rotri_i32(cpu_tmp2_i32
, cpu_tmp2_i32
, b
& 31);
4561 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
4563 gen_op_mov_reg_T0(ot
, reg
);
4575 /* generic MMX or SSE operation */
4577 case 0x70: /* pshufx insn */
4578 case 0xc6: /* pshufx insn */
4579 case 0xc2: /* compare insns */
4586 op1_offset
= offsetof(CPUX86State
,xmm_regs
[reg
]);
4588 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4589 op2_offset
= offsetof(CPUX86State
,xmm_t0
);
4590 if (b1
>= 2 && ((b
>= 0x50 && b
<= 0x5f && b
!= 0x5b) ||
4592 /* specific case for SSE single instructions */
4595 gen_op_ld_T0_A0(OT_LONG
+ s
->mem_index
);
4596 tcg_gen_st32_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,xmm_t0
.XMM_L(0)));
4599 gen_ldq_env_A0(s
->mem_index
, offsetof(CPUX86State
,xmm_t0
.XMM_D(0)));
4602 gen_ldo_env_A0(s
->mem_index
, op2_offset
);
4605 rm
= (modrm
& 7) | REX_B(s
);
4606 op2_offset
= offsetof(CPUX86State
,xmm_regs
[rm
]);
4609 op1_offset
= offsetof(CPUX86State
,fpregs
[reg
].mmx
);
4611 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4612 op2_offset
= offsetof(CPUX86State
,mmx_t0
);
4613 gen_ldq_env_A0(s
->mem_index
, op2_offset
);
4616 op2_offset
= offsetof(CPUX86State
,fpregs
[rm
].mmx
);
4620 case 0x0f: /* 3DNow! data insns */
4621 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_3DNOW
))
4623 val
= cpu_ldub_code(env
, s
->pc
++);
4624 sse_fn_epp
= sse_op_table5
[val
];
4628 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4629 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4630 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4632 case 0x70: /* pshufx insn */
4633 case 0xc6: /* pshufx insn */
4634 val
= cpu_ldub_code(env
, s
->pc
++);
4635 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4636 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4637 /* XXX: introduce a new table? */
4638 sse_fn_ppi
= (SSEFunc_0_ppi
)sse_fn_epp
;
4639 sse_fn_ppi(cpu_ptr0
, cpu_ptr1
, tcg_const_i32(val
));
4643 val
= cpu_ldub_code(env
, s
->pc
++);
4646 sse_fn_epp
= sse_op_table4
[val
][b1
];
4648 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4649 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4650 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4653 /* maskmov : we must prepare A0 */
4656 #ifdef TARGET_X86_64
4657 if (s
->aflag
== 2) {
4658 gen_op_movq_A0_reg(R_EDI
);
4662 gen_op_movl_A0_reg(R_EDI
);
4664 gen_op_andl_A0_ffff();
4666 gen_add_A0_ds_seg(s
);
4668 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4669 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4670 /* XXX: introduce a new table? */
4671 sse_fn_eppt
= (SSEFunc_0_eppt
)sse_fn_epp
;
4672 sse_fn_eppt(cpu_env
, cpu_ptr0
, cpu_ptr1
, cpu_A0
);
4675 tcg_gen_addi_ptr(cpu_ptr0
, cpu_env
, op1_offset
);
4676 tcg_gen_addi_ptr(cpu_ptr1
, cpu_env
, op2_offset
);
4677 sse_fn_epp(cpu_env
, cpu_ptr0
, cpu_ptr1
);
4680 if (b
== 0x2e || b
== 0x2f) {
4681 set_cc_op(s
, CC_OP_EFLAGS
);
4686 /* convert one instruction. s->is_jmp is set if the translation must
4687 be stopped. Return the next pc value */
4688 static target_ulong
disas_insn(CPUX86State
*env
, DisasContext
*s
,
4689 target_ulong pc_start
)
4691 int b
, prefixes
, aflag
, dflag
;
4693 int modrm
, reg
, rm
, mod
, reg_addr
, op
, opreg
, offset_addr
, val
;
4694 target_ulong next_eip
, tval
;
4697 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
4698 tcg_gen_debug_insn_start(pc_start
);
4707 #ifdef TARGET_X86_64
4712 s
->rip_offset
= 0; /* for relative ip address */
4716 b
= cpu_ldub_code(env
, s
->pc
);
4718 /* Collect prefixes. */
4721 prefixes
|= PREFIX_REPZ
;
4724 prefixes
|= PREFIX_REPNZ
;
4727 prefixes
|= PREFIX_LOCK
;
4748 prefixes
|= PREFIX_DATA
;
4751 prefixes
|= PREFIX_ADR
;
4753 #ifdef TARGET_X86_64
4757 rex_w
= (b
>> 3) & 1;
4758 rex_r
= (b
& 0x4) << 1;
4759 s
->rex_x
= (b
& 0x2) << 2;
4760 REX_B(s
) = (b
& 0x1) << 3;
4761 x86_64_hregs
= 1; /* select uniform byte register addressing */
4766 case 0xc5: /* 2-byte VEX */
4767 case 0xc4: /* 3-byte VEX */
4768 /* VEX prefixes cannot be used except in 32-bit mode.
4769 Otherwise the instruction is LES or LDS. */
4770 if (s
->code32
&& !s
->vm86
) {
4771 static const int pp_prefix
[4] = {
4772 0, PREFIX_DATA
, PREFIX_REPZ
, PREFIX_REPNZ
4774 int vex3
, vex2
= cpu_ldub_code(env
, s
->pc
);
4776 if (!CODE64(s
) && (vex2
& 0xc0) != 0xc0) {
4777 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4778 otherwise the instruction is LES or LDS. */
4783 /* 4.1.1-4.1.3: No preceeding lock, 66, f2, f3, or rex prefixes. */
4784 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
4785 | PREFIX_LOCK
| PREFIX_DATA
)) {
4788 #ifdef TARGET_X86_64
4793 rex_r
= (~vex2
>> 4) & 8;
4796 b
= cpu_ldub_code(env
, s
->pc
++);
4798 #ifdef TARGET_X86_64
4799 s
->rex_x
= (~vex2
>> 3) & 8;
4800 s
->rex_b
= (~vex2
>> 2) & 8;
4802 vex3
= cpu_ldub_code(env
, s
->pc
++);
4803 rex_w
= (vex3
>> 7) & 1;
4804 switch (vex2
& 0x1f) {
4805 case 0x01: /* Implied 0f leading opcode bytes. */
4806 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4808 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4811 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4814 default: /* Reserved for future use. */
4818 s
->vex_v
= (~vex3
>> 3) & 0xf;
4819 s
->vex_l
= (vex3
>> 2) & 1;
4820 prefixes
|= pp_prefix
[vex3
& 3] | PREFIX_VEX
;
4825 /* Post-process prefixes. */
4826 if (prefixes
& PREFIX_DATA
) {
4829 if (prefixes
& PREFIX_ADR
) {
4832 #ifdef TARGET_X86_64
4835 /* 0x66 is ignored if rex.w is set */
4838 if (!(prefixes
& PREFIX_ADR
)) {
4844 s
->prefix
= prefixes
;
4848 /* lock generation */
4849 if (prefixes
& PREFIX_LOCK
)
4852 /* now check op code */
4856 /**************************/
4857 /* extended op code */
4858 b
= cpu_ldub_code(env
, s
->pc
++) | 0x100;
4861 /**************************/
4879 ot
= dflag
+ OT_WORD
;
4882 case 0: /* OP Ev, Gv */
4883 modrm
= cpu_ldub_code(env
, s
->pc
++);
4884 reg
= ((modrm
>> 3) & 7) | rex_r
;
4885 mod
= (modrm
>> 6) & 3;
4886 rm
= (modrm
& 7) | REX_B(s
);
4888 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4890 } else if (op
== OP_XORL
&& rm
== reg
) {
4892 /* xor reg, reg optimisation */
4894 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
4895 gen_op_mov_reg_T0(ot
, reg
);
4896 gen_op_update1_cc();
4901 gen_op_mov_TN_reg(ot
, 1, reg
);
4902 gen_op(s
, op
, ot
, opreg
);
4904 case 1: /* OP Gv, Ev */
4905 modrm
= cpu_ldub_code(env
, s
->pc
++);
4906 mod
= (modrm
>> 6) & 3;
4907 reg
= ((modrm
>> 3) & 7) | rex_r
;
4908 rm
= (modrm
& 7) | REX_B(s
);
4910 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4911 gen_op_ld_T1_A0(ot
+ s
->mem_index
);
4912 } else if (op
== OP_XORL
&& rm
== reg
) {
4915 gen_op_mov_TN_reg(ot
, 1, rm
);
4917 gen_op(s
, op
, ot
, reg
);
4919 case 2: /* OP A, Iv */
4920 val
= insn_get(env
, s
, ot
);
4921 gen_op_movl_T1_im(val
);
4922 gen_op(s
, op
, ot
, OR_EAX
);
4931 case 0x80: /* GRP1 */
4940 ot
= dflag
+ OT_WORD
;
4942 modrm
= cpu_ldub_code(env
, s
->pc
++);
4943 mod
= (modrm
>> 6) & 3;
4944 rm
= (modrm
& 7) | REX_B(s
);
4945 op
= (modrm
>> 3) & 7;
4951 s
->rip_offset
= insn_const_size(ot
);
4952 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4963 val
= insn_get(env
, s
, ot
);
4966 val
= (int8_t)insn_get(env
, s
, OT_BYTE
);
4969 gen_op_movl_T1_im(val
);
4970 gen_op(s
, op
, ot
, opreg
);
4974 /**************************/
4975 /* inc, dec, and other misc arith */
4976 case 0x40 ... 0x47: /* inc Gv */
4977 ot
= dflag
? OT_LONG
: OT_WORD
;
4978 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), 1);
4980 case 0x48 ... 0x4f: /* dec Gv */
4981 ot
= dflag
? OT_LONG
: OT_WORD
;
4982 gen_inc(s
, ot
, OR_EAX
+ (b
& 7), -1);
4984 case 0xf6: /* GRP3 */
4989 ot
= dflag
+ OT_WORD
;
4991 modrm
= cpu_ldub_code(env
, s
->pc
++);
4992 mod
= (modrm
>> 6) & 3;
4993 rm
= (modrm
& 7) | REX_B(s
);
4994 op
= (modrm
>> 3) & 7;
4997 s
->rip_offset
= insn_const_size(ot
);
4998 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
4999 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
5001 gen_op_mov_TN_reg(ot
, 0, rm
);
5006 val
= insn_get(env
, s
, ot
);
5007 gen_op_movl_T1_im(val
);
5008 gen_op_testl_T0_T1_cc();
5009 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5012 tcg_gen_not_tl(cpu_T
[0], cpu_T
[0]);
5014 gen_op_st_T0_A0(ot
+ s
->mem_index
);
5016 gen_op_mov_reg_T0(ot
, rm
);
5020 tcg_gen_neg_tl(cpu_T
[0], cpu_T
[0]);
5022 gen_op_st_T0_A0(ot
+ s
->mem_index
);
5024 gen_op_mov_reg_T0(ot
, rm
);
5026 gen_op_update_neg_cc();
5027 set_cc_op(s
, CC_OP_SUBB
+ ot
);
5032 gen_op_mov_TN_reg(OT_BYTE
, 1, R_EAX
);
5033 tcg_gen_ext8u_tl(cpu_T
[0], cpu_T
[0]);
5034 tcg_gen_ext8u_tl(cpu_T
[1], cpu_T
[1]);
5035 /* XXX: use 32 bit mul which could be faster */
5036 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5037 gen_op_mov_reg_T0(OT_WORD
, R_EAX
);
5038 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5039 tcg_gen_andi_tl(cpu_cc_src
, cpu_T
[0], 0xff00);
5040 set_cc_op(s
, CC_OP_MULB
);
5043 gen_op_mov_TN_reg(OT_WORD
, 1, R_EAX
);
5044 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
5045 tcg_gen_ext16u_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_shri_tl(cpu_T
[0], cpu_T
[0], 16);
5051 gen_op_mov_reg_T0(OT_WORD
, R_EDX
);
5052 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
5053 set_cc_op(s
, CC_OP_MULW
);
5057 #ifdef TARGET_X86_64
5058 gen_op_mov_TN_reg(OT_LONG
, 1, R_EAX
);
5059 tcg_gen_ext32u_tl(cpu_T
[0], cpu_T
[0]);
5060 tcg_gen_ext32u_tl(cpu_T
[1], cpu_T
[1]);
5061 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5062 gen_op_mov_reg_T0(OT_LONG
, R_EAX
);
5063 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5064 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], 32);
5065 gen_op_mov_reg_T0(OT_LONG
, R_EDX
);
5066 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
5070 t0
= tcg_temp_new_i64();
5071 t1
= tcg_temp_new_i64();
5072 gen_op_mov_TN_reg(OT_LONG
, 1, R_EAX
);
5073 tcg_gen_extu_i32_i64(t0
, cpu_T
[0]);
5074 tcg_gen_extu_i32_i64(t1
, cpu_T
[1]);
5075 tcg_gen_mul_i64(t0
, t0
, t1
);
5076 tcg_gen_trunc_i64_i32(cpu_T
[0], t0
);
5077 gen_op_mov_reg_T0(OT_LONG
, R_EAX
);
5078 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5079 tcg_gen_shri_i64(t0
, t0
, 32);
5080 tcg_gen_trunc_i64_i32(cpu_T
[0], t0
);
5081 gen_op_mov_reg_T0(OT_LONG
, R_EDX
);
5082 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
5085 set_cc_op(s
, CC_OP_MULL
);
5087 #ifdef TARGET_X86_64
5089 gen_helper_mulq_EAX_T0(cpu_env
, cpu_T
[0]);
5090 set_cc_op(s
, CC_OP_MULQ
);
5098 gen_op_mov_TN_reg(OT_BYTE
, 1, R_EAX
);
5099 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
5100 tcg_gen_ext8s_tl(cpu_T
[1], cpu_T
[1]);
5101 /* XXX: use 32 bit mul which could be faster */
5102 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5103 gen_op_mov_reg_T0(OT_WORD
, R_EAX
);
5104 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5105 tcg_gen_ext8s_tl(cpu_tmp0
, cpu_T
[0]);
5106 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
5107 set_cc_op(s
, CC_OP_MULB
);
5110 gen_op_mov_TN_reg(OT_WORD
, 1, R_EAX
);
5111 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5112 tcg_gen_ext16s_tl(cpu_T
[1], cpu_T
[1]);
5113 /* XXX: use 32 bit mul which could be faster */
5114 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5115 gen_op_mov_reg_T0(OT_WORD
, R_EAX
);
5116 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5117 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T
[0]);
5118 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
5119 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], 16);
5120 gen_op_mov_reg_T0(OT_WORD
, R_EDX
);
5121 set_cc_op(s
, CC_OP_MULW
);
5125 #ifdef TARGET_X86_64
5126 gen_op_mov_TN_reg(OT_LONG
, 1, R_EAX
);
5127 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
5128 tcg_gen_ext32s_tl(cpu_T
[1], cpu_T
[1]);
5129 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5130 gen_op_mov_reg_T0(OT_LONG
, R_EAX
);
5131 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5132 tcg_gen_ext32s_tl(cpu_tmp0
, cpu_T
[0]);
5133 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
5134 tcg_gen_shri_tl(cpu_T
[0], cpu_T
[0], 32);
5135 gen_op_mov_reg_T0(OT_LONG
, R_EDX
);
5139 t0
= tcg_temp_new_i64();
5140 t1
= tcg_temp_new_i64();
5141 gen_op_mov_TN_reg(OT_LONG
, 1, R_EAX
);
5142 tcg_gen_ext_i32_i64(t0
, cpu_T
[0]);
5143 tcg_gen_ext_i32_i64(t1
, cpu_T
[1]);
5144 tcg_gen_mul_i64(t0
, t0
, t1
);
5145 tcg_gen_trunc_i64_i32(cpu_T
[0], t0
);
5146 gen_op_mov_reg_T0(OT_LONG
, R_EAX
);
5147 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5148 tcg_gen_sari_tl(cpu_tmp0
, cpu_T
[0], 31);
5149 tcg_gen_shri_i64(t0
, t0
, 32);
5150 tcg_gen_trunc_i64_i32(cpu_T
[0], t0
);
5151 gen_op_mov_reg_T0(OT_LONG
, R_EDX
);
5152 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
5155 set_cc_op(s
, CC_OP_MULL
);
5157 #ifdef TARGET_X86_64
5159 gen_helper_imulq_EAX_T0(cpu_env
, cpu_T
[0]);
5160 set_cc_op(s
, CC_OP_MULQ
);
5168 gen_jmp_im(pc_start
- s
->cs_base
);
5169 gen_helper_divb_AL(cpu_env
, cpu_T
[0]);
5172 gen_jmp_im(pc_start
- s
->cs_base
);
5173 gen_helper_divw_AX(cpu_env
, cpu_T
[0]);
5177 gen_jmp_im(pc_start
- s
->cs_base
);
5178 gen_helper_divl_EAX(cpu_env
, cpu_T
[0]);
5180 #ifdef TARGET_X86_64
5182 gen_jmp_im(pc_start
- s
->cs_base
);
5183 gen_helper_divq_EAX(cpu_env
, cpu_T
[0]);
5191 gen_jmp_im(pc_start
- s
->cs_base
);
5192 gen_helper_idivb_AL(cpu_env
, cpu_T
[0]);
5195 gen_jmp_im(pc_start
- s
->cs_base
);
5196 gen_helper_idivw_AX(cpu_env
, cpu_T
[0]);
5200 gen_jmp_im(pc_start
- s
->cs_base
);
5201 gen_helper_idivl_EAX(cpu_env
, cpu_T
[0]);
5203 #ifdef TARGET_X86_64
5205 gen_jmp_im(pc_start
- s
->cs_base
);
5206 gen_helper_idivq_EAX(cpu_env
, cpu_T
[0]);
5216 case 0xfe: /* GRP4 */
5217 case 0xff: /* GRP5 */
5221 ot
= dflag
+ OT_WORD
;
5223 modrm
= cpu_ldub_code(env
, s
->pc
++);
5224 mod
= (modrm
>> 6) & 3;
5225 rm
= (modrm
& 7) | REX_B(s
);
5226 op
= (modrm
>> 3) & 7;
5227 if (op
>= 2 && b
== 0xfe) {
5231 if (op
== 2 || op
== 4) {
5232 /* operand size for jumps is 64 bit */
5234 } else if (op
== 3 || op
== 5) {
5235 ot
= dflag
? OT_LONG
+ (rex_w
== 1) : OT_WORD
;
5236 } else if (op
== 6) {
5237 /* default push size is 64 bit */
5238 ot
= dflag
? OT_QUAD
: OT_WORD
;
5242 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5243 if (op
>= 2 && op
!= 3 && op
!= 5)
5244 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
5246 gen_op_mov_TN_reg(ot
, 0, rm
);
5250 case 0: /* inc Ev */
5255 gen_inc(s
, ot
, opreg
, 1);
5257 case 1: /* dec Ev */
5262 gen_inc(s
, ot
, opreg
, -1);
5264 case 2: /* call Ev */
5265 /* XXX: optimize if memory (no 'and' is necessary) */
5267 gen_op_andl_T0_ffff();
5268 next_eip
= s
->pc
- s
->cs_base
;
5269 gen_movtl_T1_im(next_eip
);
5274 case 3: /* lcall Ev */
5275 gen_op_ld_T1_A0(ot
+ s
->mem_index
);
5276 gen_add_A0_im(s
, 1 << (ot
- OT_WORD
+ 1));
5277 gen_op_ldu_T0_A0(OT_WORD
+ s
->mem_index
);
5279 if (s
->pe
&& !s
->vm86
) {
5280 gen_update_cc_op(s
);
5281 gen_jmp_im(pc_start
- s
->cs_base
);
5282 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5283 gen_helper_lcall_protected(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
5284 tcg_const_i32(dflag
),
5285 tcg_const_i32(s
->pc
- pc_start
));
5287 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5288 gen_helper_lcall_real(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
5289 tcg_const_i32(dflag
),
5290 tcg_const_i32(s
->pc
- s
->cs_base
));
5294 case 4: /* jmp Ev */
5296 gen_op_andl_T0_ffff();
5300 case 5: /* ljmp Ev */
5301 gen_op_ld_T1_A0(ot
+ s
->mem_index
);
5302 gen_add_A0_im(s
, 1 << (ot
- OT_WORD
+ 1));
5303 gen_op_ldu_T0_A0(OT_WORD
+ s
->mem_index
);
5305 if (s
->pe
&& !s
->vm86
) {
5306 gen_update_cc_op(s
);
5307 gen_jmp_im(pc_start
- s
->cs_base
);
5308 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
5309 gen_helper_ljmp_protected(cpu_env
, cpu_tmp2_i32
, cpu_T
[1],
5310 tcg_const_i32(s
->pc
- pc_start
));
5312 gen_op_movl_seg_T0_vm(R_CS
);
5313 gen_op_movl_T0_T1();
5318 case 6: /* push Ev */
5326 case 0x84: /* test Ev, Gv */
5331 ot
= dflag
+ OT_WORD
;
5333 modrm
= cpu_ldub_code(env
, s
->pc
++);
5334 reg
= ((modrm
>> 3) & 7) | rex_r
;
5336 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5337 gen_op_mov_TN_reg(ot
, 1, reg
);
5338 gen_op_testl_T0_T1_cc();
5339 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5342 case 0xa8: /* test eAX, Iv */
5347 ot
= dflag
+ OT_WORD
;
5348 val
= insn_get(env
, s
, ot
);
5350 gen_op_mov_TN_reg(ot
, 0, OR_EAX
);
5351 gen_op_movl_T1_im(val
);
5352 gen_op_testl_T0_T1_cc();
5353 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
5356 case 0x98: /* CWDE/CBW */
5357 #ifdef TARGET_X86_64
5359 gen_op_mov_TN_reg(OT_LONG
, 0, R_EAX
);
5360 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
5361 gen_op_mov_reg_T0(OT_QUAD
, R_EAX
);
5365 gen_op_mov_TN_reg(OT_WORD
, 0, R_EAX
);
5366 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5367 gen_op_mov_reg_T0(OT_LONG
, R_EAX
);
5369 gen_op_mov_TN_reg(OT_BYTE
, 0, R_EAX
);
5370 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
5371 gen_op_mov_reg_T0(OT_WORD
, R_EAX
);
5374 case 0x99: /* CDQ/CWD */
5375 #ifdef TARGET_X86_64
5377 gen_op_mov_TN_reg(OT_QUAD
, 0, R_EAX
);
5378 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 63);
5379 gen_op_mov_reg_T0(OT_QUAD
, R_EDX
);
5383 gen_op_mov_TN_reg(OT_LONG
, 0, R_EAX
);
5384 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
5385 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 31);
5386 gen_op_mov_reg_T0(OT_LONG
, R_EDX
);
5388 gen_op_mov_TN_reg(OT_WORD
, 0, R_EAX
);
5389 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5390 tcg_gen_sari_tl(cpu_T
[0], cpu_T
[0], 15);
5391 gen_op_mov_reg_T0(OT_WORD
, R_EDX
);
5394 case 0x1af: /* imul Gv, Ev */
5395 case 0x69: /* imul Gv, Ev, I */
5397 ot
= dflag
+ OT_WORD
;
5398 modrm
= cpu_ldub_code(env
, s
->pc
++);
5399 reg
= ((modrm
>> 3) & 7) | rex_r
;
5401 s
->rip_offset
= insn_const_size(ot
);
5404 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5406 val
= insn_get(env
, s
, ot
);
5407 gen_op_movl_T1_im(val
);
5408 } else if (b
== 0x6b) {
5409 val
= (int8_t)insn_get(env
, s
, OT_BYTE
);
5410 gen_op_movl_T1_im(val
);
5412 gen_op_mov_TN_reg(ot
, 1, reg
);
5415 #ifdef TARGET_X86_64
5416 if (ot
== OT_QUAD
) {
5417 gen_helper_imulq_T0_T1(cpu_T
[0], cpu_env
, cpu_T
[0], cpu_T
[1]);
5420 if (ot
== OT_LONG
) {
5421 #ifdef TARGET_X86_64
5422 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
5423 tcg_gen_ext32s_tl(cpu_T
[1], cpu_T
[1]);
5424 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5425 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5426 tcg_gen_ext32s_tl(cpu_tmp0
, cpu_T
[0]);
5427 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
5431 t0
= tcg_temp_new_i64();
5432 t1
= tcg_temp_new_i64();
5433 tcg_gen_ext_i32_i64(t0
, cpu_T
[0]);
5434 tcg_gen_ext_i32_i64(t1
, cpu_T
[1]);
5435 tcg_gen_mul_i64(t0
, t0
, t1
);
5436 tcg_gen_trunc_i64_i32(cpu_T
[0], t0
);
5437 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5438 tcg_gen_sari_tl(cpu_tmp0
, cpu_T
[0], 31);
5439 tcg_gen_shri_i64(t0
, t0
, 32);
5440 tcg_gen_trunc_i64_i32(cpu_T
[1], t0
);
5441 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[1], cpu_tmp0
);
5445 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5446 tcg_gen_ext16s_tl(cpu_T
[1], cpu_T
[1]);
5447 /* XXX: use 32 bit mul which could be faster */
5448 tcg_gen_mul_tl(cpu_T
[0], cpu_T
[0], cpu_T
[1]);
5449 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
5450 tcg_gen_ext16s_tl(cpu_tmp0
, cpu_T
[0]);
5451 tcg_gen_sub_tl(cpu_cc_src
, cpu_T
[0], cpu_tmp0
);
5453 gen_op_mov_reg_T0(ot
, reg
);
5454 set_cc_op(s
, CC_OP_MULB
+ ot
);
5457 case 0x1c1: /* xadd Ev, Gv */
5461 ot
= dflag
+ OT_WORD
;
5462 modrm
= cpu_ldub_code(env
, s
->pc
++);
5463 reg
= ((modrm
>> 3) & 7) | rex_r
;
5464 mod
= (modrm
>> 6) & 3;
5466 rm
= (modrm
& 7) | REX_B(s
);
5467 gen_op_mov_TN_reg(ot
, 0, reg
);
5468 gen_op_mov_TN_reg(ot
, 1, rm
);
5469 gen_op_addl_T0_T1();
5470 gen_op_mov_reg_T1(ot
, reg
);
5471 gen_op_mov_reg_T0(ot
, rm
);
5473 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5474 gen_op_mov_TN_reg(ot
, 0, reg
);
5475 gen_op_ld_T1_A0(ot
+ s
->mem_index
);
5476 gen_op_addl_T0_T1();
5477 gen_op_st_T0_A0(ot
+ s
->mem_index
);
5478 gen_op_mov_reg_T1(ot
, reg
);
5480 gen_op_update2_cc();
5481 set_cc_op(s
, CC_OP_ADDB
+ ot
);
5484 case 0x1b1: /* cmpxchg Ev, Gv */
5487 TCGv t0
, t1
, t2
, a0
;
5492 ot
= dflag
+ OT_WORD
;
5493 modrm
= cpu_ldub_code(env
, s
->pc
++);
5494 reg
= ((modrm
>> 3) & 7) | rex_r
;
5495 mod
= (modrm
>> 6) & 3;
5496 t0
= tcg_temp_local_new();
5497 t1
= tcg_temp_local_new();
5498 t2
= tcg_temp_local_new();
5499 a0
= tcg_temp_local_new();
5500 gen_op_mov_v_reg(ot
, t1
, reg
);
5502 rm
= (modrm
& 7) | REX_B(s
);
5503 gen_op_mov_v_reg(ot
, t0
, rm
);
5505 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5506 tcg_gen_mov_tl(a0
, cpu_A0
);
5507 gen_op_ld_v(ot
+ s
->mem_index
, t0
, a0
);
5508 rm
= 0; /* avoid warning */
5510 label1
= gen_new_label();
5511 tcg_gen_mov_tl(t2
, cpu_regs
[R_EAX
]);
5514 tcg_gen_brcond_tl(TCG_COND_EQ
, t2
, t0
, label1
);
5515 label2
= gen_new_label();
5517 gen_op_mov_reg_v(ot
, R_EAX
, t0
);
5519 gen_set_label(label1
);
5520 gen_op_mov_reg_v(ot
, rm
, t1
);
5522 /* perform no-op store cycle like physical cpu; must be
5523 before changing accumulator to ensure idempotency if
5524 the store faults and the instruction is restarted */
5525 gen_op_st_v(ot
+ s
->mem_index
, t0
, a0
);
5526 gen_op_mov_reg_v(ot
, R_EAX
, t0
);
5528 gen_set_label(label1
);
5529 gen_op_st_v(ot
+ s
->mem_index
, t1
, a0
);
5531 gen_set_label(label2
);
5532 tcg_gen_mov_tl(cpu_cc_src
, t0
);
5533 tcg_gen_mov_tl(cpu_cc_srcT
, t2
);
5534 tcg_gen_sub_tl(cpu_cc_dst
, t2
, t0
);
5535 set_cc_op(s
, CC_OP_SUBB
+ ot
);
5542 case 0x1c7: /* cmpxchg8b */
5543 modrm
= cpu_ldub_code(env
, s
->pc
++);
5544 mod
= (modrm
>> 6) & 3;
5545 if ((mod
== 3) || ((modrm
& 0x38) != 0x8))
5547 #ifdef TARGET_X86_64
5549 if (!(s
->cpuid_ext_features
& CPUID_EXT_CX16
))
5551 gen_jmp_im(pc_start
- s
->cs_base
);
5552 gen_update_cc_op(s
);
5553 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5554 gen_helper_cmpxchg16b(cpu_env
, cpu_A0
);
5558 if (!(s
->cpuid_features
& CPUID_CX8
))
5560 gen_jmp_im(pc_start
- s
->cs_base
);
5561 gen_update_cc_op(s
);
5562 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5563 gen_helper_cmpxchg8b(cpu_env
, cpu_A0
);
5565 set_cc_op(s
, CC_OP_EFLAGS
);
5568 /**************************/
5570 case 0x50 ... 0x57: /* push */
5571 gen_op_mov_TN_reg(OT_LONG
, 0, (b
& 7) | REX_B(s
));
5574 case 0x58 ... 0x5f: /* pop */
5576 ot
= dflag
? OT_QUAD
: OT_WORD
;
5578 ot
= dflag
+ OT_WORD
;
5581 /* NOTE: order is important for pop %sp */
5583 gen_op_mov_reg_T0(ot
, (b
& 7) | REX_B(s
));
5585 case 0x60: /* pusha */
5590 case 0x61: /* popa */
5595 case 0x68: /* push Iv */
5598 ot
= dflag
? OT_QUAD
: OT_WORD
;
5600 ot
= dflag
+ OT_WORD
;
5603 val
= insn_get(env
, s
, ot
);
5605 val
= (int8_t)insn_get(env
, s
, OT_BYTE
);
5606 gen_op_movl_T0_im(val
);
5609 case 0x8f: /* pop Ev */
5611 ot
= dflag
? OT_QUAD
: OT_WORD
;
5613 ot
= dflag
+ OT_WORD
;
5615 modrm
= cpu_ldub_code(env
, s
->pc
++);
5616 mod
= (modrm
>> 6) & 3;
5619 /* NOTE: order is important for pop %sp */
5621 rm
= (modrm
& 7) | REX_B(s
);
5622 gen_op_mov_reg_T0(ot
, rm
);
5624 /* NOTE: order is important too for MMU exceptions */
5625 s
->popl_esp_hack
= 1 << ot
;
5626 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5627 s
->popl_esp_hack
= 0;
5631 case 0xc8: /* enter */
5634 val
= cpu_lduw_code(env
, s
->pc
);
5636 level
= cpu_ldub_code(env
, s
->pc
++);
5637 gen_enter(s
, val
, level
);
5640 case 0xc9: /* leave */
5641 /* XXX: exception not precise (ESP is updated before potential exception) */
5643 gen_op_mov_TN_reg(OT_QUAD
, 0, R_EBP
);
5644 gen_op_mov_reg_T0(OT_QUAD
, R_ESP
);
5645 } else if (s
->ss32
) {
5646 gen_op_mov_TN_reg(OT_LONG
, 0, R_EBP
);
5647 gen_op_mov_reg_T0(OT_LONG
, R_ESP
);
5649 gen_op_mov_TN_reg(OT_WORD
, 0, R_EBP
);
5650 gen_op_mov_reg_T0(OT_WORD
, R_ESP
);
5654 ot
= dflag
? OT_QUAD
: OT_WORD
;
5656 ot
= dflag
+ OT_WORD
;
5658 gen_op_mov_reg_T0(ot
, R_EBP
);
5661 case 0x06: /* push es */
5662 case 0x0e: /* push cs */
5663 case 0x16: /* push ss */
5664 case 0x1e: /* push ds */
5667 gen_op_movl_T0_seg(b
>> 3);
5670 case 0x1a0: /* push fs */
5671 case 0x1a8: /* push gs */
5672 gen_op_movl_T0_seg((b
>> 3) & 7);
5675 case 0x07: /* pop es */
5676 case 0x17: /* pop ss */
5677 case 0x1f: /* pop ds */
5682 gen_movl_seg_T0(s
, reg
, pc_start
- s
->cs_base
);
5685 /* if reg == SS, inhibit interrupts/trace. */
5686 /* If several instructions disable interrupts, only the
5688 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
5689 gen_helper_set_inhibit_irq(cpu_env
);
5693 gen_jmp_im(s
->pc
- s
->cs_base
);
5697 case 0x1a1: /* pop fs */
5698 case 0x1a9: /* pop gs */
5700 gen_movl_seg_T0(s
, (b
>> 3) & 7, pc_start
- s
->cs_base
);
5703 gen_jmp_im(s
->pc
- s
->cs_base
);
5708 /**************************/
5711 case 0x89: /* mov Gv, Ev */
5715 ot
= dflag
+ OT_WORD
;
5716 modrm
= cpu_ldub_code(env
, s
->pc
++);
5717 reg
= ((modrm
>> 3) & 7) | rex_r
;
5719 /* generate a generic store */
5720 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
5723 case 0xc7: /* mov Ev, Iv */
5727 ot
= dflag
+ OT_WORD
;
5728 modrm
= cpu_ldub_code(env
, s
->pc
++);
5729 mod
= (modrm
>> 6) & 3;
5731 s
->rip_offset
= insn_const_size(ot
);
5732 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5734 val
= insn_get(env
, s
, ot
);
5735 gen_op_movl_T0_im(val
);
5737 gen_op_st_T0_A0(ot
+ s
->mem_index
);
5739 gen_op_mov_reg_T0(ot
, (modrm
& 7) | REX_B(s
));
5742 case 0x8b: /* mov Ev, Gv */
5746 ot
= OT_WORD
+ dflag
;
5747 modrm
= cpu_ldub_code(env
, s
->pc
++);
5748 reg
= ((modrm
>> 3) & 7) | rex_r
;
5750 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
5751 gen_op_mov_reg_T0(ot
, reg
);
5753 case 0x8e: /* mov seg, Gv */
5754 modrm
= cpu_ldub_code(env
, s
->pc
++);
5755 reg
= (modrm
>> 3) & 7;
5756 if (reg
>= 6 || reg
== R_CS
)
5758 gen_ldst_modrm(env
, s
, modrm
, OT_WORD
, OR_TMP0
, 0);
5759 gen_movl_seg_T0(s
, reg
, pc_start
- s
->cs_base
);
5761 /* if reg == SS, inhibit interrupts/trace */
5762 /* If several instructions disable interrupts, only the
5764 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
5765 gen_helper_set_inhibit_irq(cpu_env
);
5769 gen_jmp_im(s
->pc
- s
->cs_base
);
5773 case 0x8c: /* mov Gv, seg */
5774 modrm
= cpu_ldub_code(env
, s
->pc
++);
5775 reg
= (modrm
>> 3) & 7;
5776 mod
= (modrm
>> 6) & 3;
5779 gen_op_movl_T0_seg(reg
);
5781 ot
= OT_WORD
+ dflag
;
5784 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
5787 case 0x1b6: /* movzbS Gv, Eb */
5788 case 0x1b7: /* movzwS Gv, Eb */
5789 case 0x1be: /* movsbS Gv, Eb */
5790 case 0x1bf: /* movswS Gv, Eb */
5793 /* d_ot is the size of destination */
5794 d_ot
= dflag
+ OT_WORD
;
5795 /* ot is the size of source */
5796 ot
= (b
& 1) + OT_BYTE
;
5797 modrm
= cpu_ldub_code(env
, s
->pc
++);
5798 reg
= ((modrm
>> 3) & 7) | rex_r
;
5799 mod
= (modrm
>> 6) & 3;
5800 rm
= (modrm
& 7) | REX_B(s
);
5803 gen_op_mov_TN_reg(ot
, 0, rm
);
5804 switch(ot
| (b
& 8)) {
5806 tcg_gen_ext8u_tl(cpu_T
[0], cpu_T
[0]);
5809 tcg_gen_ext8s_tl(cpu_T
[0], cpu_T
[0]);
5812 tcg_gen_ext16u_tl(cpu_T
[0], cpu_T
[0]);
5816 tcg_gen_ext16s_tl(cpu_T
[0], cpu_T
[0]);
5819 gen_op_mov_reg_T0(d_ot
, reg
);
5821 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5823 gen_op_lds_T0_A0(ot
+ s
->mem_index
);
5825 gen_op_ldu_T0_A0(ot
+ s
->mem_index
);
5827 gen_op_mov_reg_T0(d_ot
, reg
);
5832 case 0x8d: /* lea */
5833 ot
= dflag
+ OT_WORD
;
5834 modrm
= cpu_ldub_code(env
, s
->pc
++);
5835 mod
= (modrm
>> 6) & 3;
5838 reg
= ((modrm
>> 3) & 7) | rex_r
;
5839 /* we must ensure that no segment is added */
5843 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5845 gen_op_mov_reg_A0(ot
- OT_WORD
, reg
);
5848 case 0xa0: /* mov EAX, Ov */
5850 case 0xa2: /* mov Ov, EAX */
5853 target_ulong offset_addr
;
5858 ot
= dflag
+ OT_WORD
;
5859 #ifdef TARGET_X86_64
5860 if (s
->aflag
== 2) {
5861 offset_addr
= cpu_ldq_code(env
, s
->pc
);
5863 gen_op_movq_A0_im(offset_addr
);
5868 offset_addr
= insn_get(env
, s
, OT_LONG
);
5870 offset_addr
= insn_get(env
, s
, OT_WORD
);
5872 gen_op_movl_A0_im(offset_addr
);
5874 gen_add_A0_ds_seg(s
);
5876 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
5877 gen_op_mov_reg_T0(ot
, R_EAX
);
5879 gen_op_mov_TN_reg(ot
, 0, R_EAX
);
5880 gen_op_st_T0_A0(ot
+ s
->mem_index
);
5884 case 0xd7: /* xlat */
5885 #ifdef TARGET_X86_64
5886 if (s
->aflag
== 2) {
5887 gen_op_movq_A0_reg(R_EBX
);
5888 gen_op_mov_TN_reg(OT_QUAD
, 0, R_EAX
);
5889 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xff);
5890 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_T
[0]);
5894 gen_op_movl_A0_reg(R_EBX
);
5895 gen_op_mov_TN_reg(OT_LONG
, 0, R_EAX
);
5896 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], 0xff);
5897 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_T
[0]);
5899 gen_op_andl_A0_ffff();
5901 tcg_gen_andi_tl(cpu_A0
, cpu_A0
, 0xffffffff);
5903 gen_add_A0_ds_seg(s
);
5904 gen_op_ldu_T0_A0(OT_BYTE
+ s
->mem_index
);
5905 gen_op_mov_reg_T0(OT_BYTE
, R_EAX
);
5907 case 0xb0 ... 0xb7: /* mov R, Ib */
5908 val
= insn_get(env
, s
, OT_BYTE
);
5909 gen_op_movl_T0_im(val
);
5910 gen_op_mov_reg_T0(OT_BYTE
, (b
& 7) | REX_B(s
));
5912 case 0xb8 ... 0xbf: /* mov R, Iv */
5913 #ifdef TARGET_X86_64
5917 tmp
= cpu_ldq_code(env
, s
->pc
);
5919 reg
= (b
& 7) | REX_B(s
);
5920 gen_movtl_T0_im(tmp
);
5921 gen_op_mov_reg_T0(OT_QUAD
, reg
);
5925 ot
= dflag
? OT_LONG
: OT_WORD
;
5926 val
= insn_get(env
, s
, ot
);
5927 reg
= (b
& 7) | REX_B(s
);
5928 gen_op_movl_T0_im(val
);
5929 gen_op_mov_reg_T0(ot
, reg
);
5933 case 0x91 ... 0x97: /* xchg R, EAX */
5935 ot
= dflag
+ OT_WORD
;
5936 reg
= (b
& 7) | REX_B(s
);
5940 case 0x87: /* xchg Ev, Gv */
5944 ot
= dflag
+ OT_WORD
;
5945 modrm
= cpu_ldub_code(env
, s
->pc
++);
5946 reg
= ((modrm
>> 3) & 7) | rex_r
;
5947 mod
= (modrm
>> 6) & 3;
5949 rm
= (modrm
& 7) | REX_B(s
);
5951 gen_op_mov_TN_reg(ot
, 0, reg
);
5952 gen_op_mov_TN_reg(ot
, 1, rm
);
5953 gen_op_mov_reg_T0(ot
, rm
);
5954 gen_op_mov_reg_T1(ot
, reg
);
5956 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5957 gen_op_mov_TN_reg(ot
, 0, reg
);
5958 /* for xchg, lock is implicit */
5959 if (!(prefixes
& PREFIX_LOCK
))
5961 gen_op_ld_T1_A0(ot
+ s
->mem_index
);
5962 gen_op_st_T0_A0(ot
+ s
->mem_index
);
5963 if (!(prefixes
& PREFIX_LOCK
))
5964 gen_helper_unlock();
5965 gen_op_mov_reg_T1(ot
, reg
);
5968 case 0xc4: /* les Gv */
5969 /* In CODE64 this is VEX3; see above. */
5972 case 0xc5: /* lds Gv */
5973 /* In CODE64 this is VEX2; see above. */
5976 case 0x1b2: /* lss Gv */
5979 case 0x1b4: /* lfs Gv */
5982 case 0x1b5: /* lgs Gv */
5985 ot
= dflag
? OT_LONG
: OT_WORD
;
5986 modrm
= cpu_ldub_code(env
, s
->pc
++);
5987 reg
= ((modrm
>> 3) & 7) | rex_r
;
5988 mod
= (modrm
>> 6) & 3;
5991 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
5992 gen_op_ld_T1_A0(ot
+ s
->mem_index
);
5993 gen_add_A0_im(s
, 1 << (ot
- OT_WORD
+ 1));
5994 /* load the segment first to handle exceptions properly */
5995 gen_op_ldu_T0_A0(OT_WORD
+ s
->mem_index
);
5996 gen_movl_seg_T0(s
, op
, pc_start
- s
->cs_base
);
5997 /* then put the data */
5998 gen_op_mov_reg_T1(ot
, reg
);
6000 gen_jmp_im(s
->pc
- s
->cs_base
);
6005 /************************/
6016 ot
= dflag
+ OT_WORD
;
6018 modrm
= cpu_ldub_code(env
, s
->pc
++);
6019 mod
= (modrm
>> 6) & 3;
6020 op
= (modrm
>> 3) & 7;
6026 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
6029 opreg
= (modrm
& 7) | REX_B(s
);
6034 gen_shift(s
, op
, ot
, opreg
, OR_ECX
);
6037 shift
= cpu_ldub_code(env
, s
->pc
++);
6039 gen_shifti(s
, op
, ot
, opreg
, shift
);
6054 case 0x1a4: /* shld imm */
6058 case 0x1a5: /* shld cl */
6062 case 0x1ac: /* shrd imm */
6066 case 0x1ad: /* shrd cl */
6070 ot
= dflag
+ OT_WORD
;
6071 modrm
= cpu_ldub_code(env
, s
->pc
++);
6072 mod
= (modrm
>> 6) & 3;
6073 rm
= (modrm
& 7) | REX_B(s
);
6074 reg
= ((modrm
>> 3) & 7) | rex_r
;
6076 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
6081 gen_op_mov_TN_reg(ot
, 1, reg
);
6084 TCGv imm
= tcg_const_tl(cpu_ldub_code(env
, s
->pc
++));
6085 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, imm
);
6088 gen_shiftd_rm_T1(s
, ot
, opreg
, op
, cpu_regs
[R_ECX
]);
6092 /************************/
6095 if (s
->flags
& (HF_EM_MASK
| HF_TS_MASK
)) {
6096 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
6097 /* XXX: what to do if illegal op ? */
6098 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
6101 modrm
= cpu_ldub_code(env
, s
->pc
++);
6102 mod
= (modrm
>> 6) & 3;
6104 op
= ((b
& 7) << 3) | ((modrm
>> 3) & 7);
6107 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
6109 case 0x00 ... 0x07: /* fxxxs */
6110 case 0x10 ... 0x17: /* fixxxl */
6111 case 0x20 ... 0x27: /* fxxxl */
6112 case 0x30 ... 0x37: /* fixxx */
6119 gen_op_ld_T0_A0(OT_LONG
+ s
->mem_index
);
6120 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6121 gen_helper_flds_FT0(cpu_env
, cpu_tmp2_i32
);
6124 gen_op_ld_T0_A0(OT_LONG
+ s
->mem_index
);
6125 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6126 gen_helper_fildl_FT0(cpu_env
, cpu_tmp2_i32
);
6129 tcg_gen_qemu_ld64(cpu_tmp1_i64
, cpu_A0
,
6130 (s
->mem_index
>> 2) - 1);
6131 gen_helper_fldl_FT0(cpu_env
, cpu_tmp1_i64
);
6135 gen_op_lds_T0_A0(OT_WORD
+ 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
);
6141 gen_helper_fp_arith_ST0_FT0(op1
);
6143 /* fcomp needs pop */
6144 gen_helper_fpop(cpu_env
);
6148 case 0x08: /* flds */
6149 case 0x0a: /* fsts */
6150 case 0x0b: /* fstps */
6151 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
6152 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
6153 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
6158 gen_op_ld_T0_A0(OT_LONG
+ s
->mem_index
);
6159 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6160 gen_helper_flds_ST0(cpu_env
, cpu_tmp2_i32
);
6163 gen_op_ld_T0_A0(OT_LONG
+ s
->mem_index
);
6164 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6165 gen_helper_fildl_ST0(cpu_env
, cpu_tmp2_i32
);
6168 tcg_gen_qemu_ld64(cpu_tmp1_i64
, cpu_A0
,
6169 (s
->mem_index
>> 2) - 1);
6170 gen_helper_fldl_ST0(cpu_env
, cpu_tmp1_i64
);
6174 gen_op_lds_T0_A0(OT_WORD
+ 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
);
6181 /* XXX: the corresponding CPUID bit must be tested ! */
6184 gen_helper_fisttl_ST0(cpu_tmp2_i32
, cpu_env
);
6185 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6186 gen_op_st_T0_A0(OT_LONG
+ s
->mem_index
);
6189 gen_helper_fisttll_ST0(cpu_tmp1_i64
, cpu_env
);
6190 tcg_gen_qemu_st64(cpu_tmp1_i64
, cpu_A0
,
6191 (s
->mem_index
>> 2) - 1);
6195 gen_helper_fistt_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_WORD
+ s
->mem_index
);
6200 gen_helper_fpop(cpu_env
);
6205 gen_helper_fsts_ST0(cpu_tmp2_i32
, cpu_env
);
6206 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6207 gen_op_st_T0_A0(OT_LONG
+ s
->mem_index
);
6210 gen_helper_fistl_ST0(cpu_tmp2_i32
, cpu_env
);
6211 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6212 gen_op_st_T0_A0(OT_LONG
+ s
->mem_index
);
6215 gen_helper_fstl_ST0(cpu_tmp1_i64
, cpu_env
);
6216 tcg_gen_qemu_st64(cpu_tmp1_i64
, cpu_A0
,
6217 (s
->mem_index
>> 2) - 1);
6221 gen_helper_fist_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_WORD
+ s
->mem_index
);
6227 gen_helper_fpop(cpu_env
);
6231 case 0x0c: /* fldenv mem */
6232 gen_update_cc_op(s
);
6233 gen_jmp_im(pc_start
- s
->cs_base
);
6234 gen_helper_fldenv(cpu_env
, cpu_A0
, tcg_const_i32(s
->dflag
));
6236 case 0x0d: /* fldcw mem */
6237 gen_op_ld_T0_A0(OT_WORD
+ s
->mem_index
);
6238 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6239 gen_helper_fldcw(cpu_env
, cpu_tmp2_i32
);
6241 case 0x0e: /* fnstenv mem */
6242 gen_update_cc_op(s
);
6243 gen_jmp_im(pc_start
- s
->cs_base
);
6244 gen_helper_fstenv(cpu_env
, cpu_A0
, tcg_const_i32(s
->dflag
));
6246 case 0x0f: /* fnstcw mem */
6247 gen_helper_fnstcw(cpu_tmp2_i32
, cpu_env
);
6248 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6249 gen_op_st_T0_A0(OT_WORD
+ s
->mem_index
);
6251 case 0x1d: /* fldt mem */
6252 gen_update_cc_op(s
);
6253 gen_jmp_im(pc_start
- s
->cs_base
);
6254 gen_helper_fldt_ST0(cpu_env
, cpu_A0
);
6256 case 0x1f: /* fstpt mem */
6257 gen_update_cc_op(s
);
6258 gen_jmp_im(pc_start
- s
->cs_base
);
6259 gen_helper_fstt_ST0(cpu_env
, cpu_A0
);
6260 gen_helper_fpop(cpu_env
);
6262 case 0x2c: /* frstor mem */
6263 gen_update_cc_op(s
);
6264 gen_jmp_im(pc_start
- s
->cs_base
);
6265 gen_helper_frstor(cpu_env
, cpu_A0
, tcg_const_i32(s
->dflag
));
6267 case 0x2e: /* fnsave mem */
6268 gen_update_cc_op(s
);
6269 gen_jmp_im(pc_start
- s
->cs_base
);
6270 gen_helper_fsave(cpu_env
, cpu_A0
, tcg_const_i32(s
->dflag
));
6272 case 0x2f: /* fnstsw mem */
6273 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
6274 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6275 gen_op_st_T0_A0(OT_WORD
+ s
->mem_index
);
6277 case 0x3c: /* fbld */
6278 gen_update_cc_op(s
);
6279 gen_jmp_im(pc_start
- s
->cs_base
);
6280 gen_helper_fbld_ST0(cpu_env
, cpu_A0
);
6282 case 0x3e: /* fbstp */
6283 gen_update_cc_op(s
);
6284 gen_jmp_im(pc_start
- s
->cs_base
);
6285 gen_helper_fbst_ST0(cpu_env
, cpu_A0
);
6286 gen_helper_fpop(cpu_env
);
6288 case 0x3d: /* fildll */
6289 tcg_gen_qemu_ld64(cpu_tmp1_i64
, cpu_A0
,
6290 (s
->mem_index
>> 2) - 1);
6291 gen_helper_fildll_ST0(cpu_env
, cpu_tmp1_i64
);
6293 case 0x3f: /* fistpll */
6294 gen_helper_fistll_ST0(cpu_tmp1_i64
, cpu_env
);
6295 tcg_gen_qemu_st64(cpu_tmp1_i64
, cpu_A0
,
6296 (s
->mem_index
>> 2) - 1);
6297 gen_helper_fpop(cpu_env
);
6303 /* register float ops */
6307 case 0x08: /* fld sti */
6308 gen_helper_fpush(cpu_env
);
6309 gen_helper_fmov_ST0_STN(cpu_env
,
6310 tcg_const_i32((opreg
+ 1) & 7));
6312 case 0x09: /* fxchg sti */
6313 case 0x29: /* fxchg4 sti, undocumented op */
6314 case 0x39: /* fxchg7 sti, undocumented op */
6315 gen_helper_fxchg_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6317 case 0x0a: /* grp d9/2 */
6320 /* check exceptions (FreeBSD FPU probe) */
6321 gen_update_cc_op(s
);
6322 gen_jmp_im(pc_start
- s
->cs_base
);
6323 gen_helper_fwait(cpu_env
);
6329 case 0x0c: /* grp d9/4 */
6332 gen_helper_fchs_ST0(cpu_env
);
6335 gen_helper_fabs_ST0(cpu_env
);
6338 gen_helper_fldz_FT0(cpu_env
);
6339 gen_helper_fcom_ST0_FT0(cpu_env
);
6342 gen_helper_fxam_ST0(cpu_env
);
6348 case 0x0d: /* grp d9/5 */
6352 gen_helper_fpush(cpu_env
);
6353 gen_helper_fld1_ST0(cpu_env
);
6356 gen_helper_fpush(cpu_env
);
6357 gen_helper_fldl2t_ST0(cpu_env
);
6360 gen_helper_fpush(cpu_env
);
6361 gen_helper_fldl2e_ST0(cpu_env
);
6364 gen_helper_fpush(cpu_env
);
6365 gen_helper_fldpi_ST0(cpu_env
);
6368 gen_helper_fpush(cpu_env
);
6369 gen_helper_fldlg2_ST0(cpu_env
);
6372 gen_helper_fpush(cpu_env
);
6373 gen_helper_fldln2_ST0(cpu_env
);
6376 gen_helper_fpush(cpu_env
);
6377 gen_helper_fldz_ST0(cpu_env
);
6384 case 0x0e: /* grp d9/6 */
6387 gen_helper_f2xm1(cpu_env
);
6390 gen_helper_fyl2x(cpu_env
);
6393 gen_helper_fptan(cpu_env
);
6395 case 3: /* fpatan */
6396 gen_helper_fpatan(cpu_env
);
6398 case 4: /* fxtract */
6399 gen_helper_fxtract(cpu_env
);
6401 case 5: /* fprem1 */
6402 gen_helper_fprem1(cpu_env
);
6404 case 6: /* fdecstp */
6405 gen_helper_fdecstp(cpu_env
);
6408 case 7: /* fincstp */
6409 gen_helper_fincstp(cpu_env
);
6413 case 0x0f: /* grp d9/7 */
6416 gen_helper_fprem(cpu_env
);
6418 case 1: /* fyl2xp1 */
6419 gen_helper_fyl2xp1(cpu_env
);
6422 gen_helper_fsqrt(cpu_env
);
6424 case 3: /* fsincos */
6425 gen_helper_fsincos(cpu_env
);
6427 case 5: /* fscale */
6428 gen_helper_fscale(cpu_env
);
6430 case 4: /* frndint */
6431 gen_helper_frndint(cpu_env
);
6434 gen_helper_fsin(cpu_env
);
6438 gen_helper_fcos(cpu_env
);
6442 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6443 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6444 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6450 gen_helper_fp_arith_STN_ST0(op1
, opreg
);
6452 gen_helper_fpop(cpu_env
);
6454 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6455 gen_helper_fp_arith_ST0_FT0(op1
);
6459 case 0x02: /* fcom */
6460 case 0x22: /* fcom2, undocumented op */
6461 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6462 gen_helper_fcom_ST0_FT0(cpu_env
);
6464 case 0x03: /* fcomp */
6465 case 0x23: /* fcomp3, undocumented op */
6466 case 0x32: /* fcomp5, undocumented op */
6467 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6468 gen_helper_fcom_ST0_FT0(cpu_env
);
6469 gen_helper_fpop(cpu_env
);
6471 case 0x15: /* da/5 */
6473 case 1: /* fucompp */
6474 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6475 gen_helper_fucom_ST0_FT0(cpu_env
);
6476 gen_helper_fpop(cpu_env
);
6477 gen_helper_fpop(cpu_env
);
6485 case 0: /* feni (287 only, just do nop here) */
6487 case 1: /* fdisi (287 only, just do nop here) */
6490 gen_helper_fclex(cpu_env
);
6492 case 3: /* fninit */
6493 gen_helper_fninit(cpu_env
);
6495 case 4: /* fsetpm (287 only, just do nop here) */
6501 case 0x1d: /* fucomi */
6502 gen_update_cc_op(s
);
6503 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6504 gen_helper_fucomi_ST0_FT0(cpu_env
);
6505 set_cc_op(s
, CC_OP_EFLAGS
);
6507 case 0x1e: /* fcomi */
6508 gen_update_cc_op(s
);
6509 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6510 gen_helper_fcomi_ST0_FT0(cpu_env
);
6511 set_cc_op(s
, CC_OP_EFLAGS
);
6513 case 0x28: /* ffree sti */
6514 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6516 case 0x2a: /* fst sti */
6517 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6519 case 0x2b: /* fstp sti */
6520 case 0x0b: /* fstp1 sti, undocumented op */
6521 case 0x3a: /* fstp8 sti, undocumented op */
6522 case 0x3b: /* fstp9 sti, undocumented op */
6523 gen_helper_fmov_STN_ST0(cpu_env
, tcg_const_i32(opreg
));
6524 gen_helper_fpop(cpu_env
);
6526 case 0x2c: /* fucom st(i) */
6527 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6528 gen_helper_fucom_ST0_FT0(cpu_env
);
6530 case 0x2d: /* fucomp st(i) */
6531 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6532 gen_helper_fucom_ST0_FT0(cpu_env
);
6533 gen_helper_fpop(cpu_env
);
6535 case 0x33: /* de/3 */
6537 case 1: /* fcompp */
6538 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(1));
6539 gen_helper_fcom_ST0_FT0(cpu_env
);
6540 gen_helper_fpop(cpu_env
);
6541 gen_helper_fpop(cpu_env
);
6547 case 0x38: /* ffreep sti, undocumented op */
6548 gen_helper_ffree_STN(cpu_env
, tcg_const_i32(opreg
));
6549 gen_helper_fpop(cpu_env
);
6551 case 0x3c: /* df/4 */
6554 gen_helper_fnstsw(cpu_tmp2_i32
, cpu_env
);
6555 tcg_gen_extu_i32_tl(cpu_T
[0], cpu_tmp2_i32
);
6556 gen_op_mov_reg_T0(OT_WORD
, R_EAX
);
6562 case 0x3d: /* fucomip */
6563 gen_update_cc_op(s
);
6564 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6565 gen_helper_fucomi_ST0_FT0(cpu_env
);
6566 gen_helper_fpop(cpu_env
);
6567 set_cc_op(s
, CC_OP_EFLAGS
);
6569 case 0x3e: /* fcomip */
6570 gen_update_cc_op(s
);
6571 gen_helper_fmov_FT0_STN(cpu_env
, tcg_const_i32(opreg
));
6572 gen_helper_fcomi_ST0_FT0(cpu_env
);
6573 gen_helper_fpop(cpu_env
);
6574 set_cc_op(s
, CC_OP_EFLAGS
);
6576 case 0x10 ... 0x13: /* fcmovxx */
6580 static const uint8_t fcmov_cc
[8] = {
6586 op1
= fcmov_cc
[op
& 3] | (((op
>> 3) & 1) ^ 1);
6587 l1
= gen_new_label();
6588 gen_jcc1_noeob(s
, op1
, l1
);
6589 gen_helper_fmov_ST0_STN(cpu_env
, tcg_const_i32(opreg
));
6598 /************************/
6601 case 0xa4: /* movsS */
6606 ot
= dflag
+ OT_WORD
;
6608 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6609 gen_repz_movs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6615 case 0xaa: /* stosS */
6620 ot
= dflag
+ OT_WORD
;
6622 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6623 gen_repz_stos(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6628 case 0xac: /* lodsS */
6633 ot
= dflag
+ OT_WORD
;
6634 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6635 gen_repz_lods(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6640 case 0xae: /* scasS */
6645 ot
= dflag
+ OT_WORD
;
6646 if (prefixes
& PREFIX_REPNZ
) {
6647 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6648 } else if (prefixes
& PREFIX_REPZ
) {
6649 gen_repz_scas(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6655 case 0xa6: /* cmpsS */
6660 ot
= dflag
+ OT_WORD
;
6661 if (prefixes
& PREFIX_REPNZ
) {
6662 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 1);
6663 } else if (prefixes
& PREFIX_REPZ
) {
6664 gen_repz_cmps(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
, 0);
6669 case 0x6c: /* insS */
6674 ot
= dflag
? OT_LONG
: OT_WORD
;
6675 gen_op_mov_TN_reg(OT_WORD
, 0, R_EDX
);
6676 gen_op_andl_T0_ffff();
6677 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6678 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
) | 4);
6679 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6680 gen_repz_ins(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6684 gen_jmp(s
, s
->pc
- s
->cs_base
);
6688 case 0x6e: /* outsS */
6693 ot
= dflag
? OT_LONG
: OT_WORD
;
6694 gen_op_mov_TN_reg(OT_WORD
, 0, R_EDX
);
6695 gen_op_andl_T0_ffff();
6696 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6697 svm_is_rep(prefixes
) | 4);
6698 if (prefixes
& (PREFIX_REPZ
| PREFIX_REPNZ
)) {
6699 gen_repz_outs(s
, ot
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
6703 gen_jmp(s
, s
->pc
- s
->cs_base
);
6708 /************************/
6716 ot
= dflag
? OT_LONG
: OT_WORD
;
6717 val
= cpu_ldub_code(env
, s
->pc
++);
6718 gen_op_movl_T0_im(val
);
6719 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6720 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6723 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6724 gen_helper_in_func(ot
, cpu_T
[1], cpu_tmp2_i32
);
6725 gen_op_mov_reg_T1(ot
, R_EAX
);
6728 gen_jmp(s
, s
->pc
- s
->cs_base
);
6736 ot
= dflag
? OT_LONG
: OT_WORD
;
6737 val
= cpu_ldub_code(env
, s
->pc
++);
6738 gen_op_movl_T0_im(val
);
6739 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6740 svm_is_rep(prefixes
));
6741 gen_op_mov_TN_reg(ot
, 1, R_EAX
);
6745 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6746 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
6747 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6750 gen_jmp(s
, s
->pc
- s
->cs_base
);
6758 ot
= dflag
? OT_LONG
: OT_WORD
;
6759 gen_op_mov_TN_reg(OT_WORD
, 0, R_EDX
);
6760 gen_op_andl_T0_ffff();
6761 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6762 SVM_IOIO_TYPE_MASK
| svm_is_rep(prefixes
));
6765 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6766 gen_helper_in_func(ot
, cpu_T
[1], cpu_tmp2_i32
);
6767 gen_op_mov_reg_T1(ot
, R_EAX
);
6770 gen_jmp(s
, s
->pc
- s
->cs_base
);
6778 ot
= dflag
? OT_LONG
: OT_WORD
;
6779 gen_op_mov_TN_reg(OT_WORD
, 0, R_EDX
);
6780 gen_op_andl_T0_ffff();
6781 gen_check_io(s
, ot
, pc_start
- s
->cs_base
,
6782 svm_is_rep(prefixes
));
6783 gen_op_mov_TN_reg(ot
, 1, R_EAX
);
6787 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
6788 tcg_gen_trunc_tl_i32(cpu_tmp3_i32
, cpu_T
[1]);
6789 gen_helper_out_func(ot
, cpu_tmp2_i32
, cpu_tmp3_i32
);
6792 gen_jmp(s
, s
->pc
- s
->cs_base
);
6796 /************************/
6798 case 0xc2: /* ret im */
6799 val
= cpu_ldsw_code(env
, s
->pc
);
6802 if (CODE64(s
) && s
->dflag
)
6804 gen_stack_update(s
, val
+ (2 << s
->dflag
));
6806 gen_op_andl_T0_ffff();
6810 case 0xc3: /* ret */
6814 gen_op_andl_T0_ffff();
6818 case 0xca: /* lret im */
6819 val
= cpu_ldsw_code(env
, s
->pc
);
6822 if (s
->pe
&& !s
->vm86
) {
6823 gen_update_cc_op(s
);
6824 gen_jmp_im(pc_start
- s
->cs_base
);
6825 gen_helper_lret_protected(cpu_env
, tcg_const_i32(s
->dflag
),
6826 tcg_const_i32(val
));
6830 gen_op_ld_T0_A0(1 + s
->dflag
+ s
->mem_index
);
6832 gen_op_andl_T0_ffff();
6833 /* NOTE: keeping EIP updated is not a problem in case of
6837 gen_op_addl_A0_im(2 << s
->dflag
);
6838 gen_op_ld_T0_A0(1 + s
->dflag
+ s
->mem_index
);
6839 gen_op_movl_seg_T0_vm(R_CS
);
6840 /* add stack offset */
6841 gen_stack_update(s
, val
+ (4 << s
->dflag
));
6845 case 0xcb: /* lret */
6848 case 0xcf: /* iret */
6849 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IRET
);
6852 gen_helper_iret_real(cpu_env
, tcg_const_i32(s
->dflag
));
6853 set_cc_op(s
, CC_OP_EFLAGS
);
6854 } else if (s
->vm86
) {
6856 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6858 gen_helper_iret_real(cpu_env
, tcg_const_i32(s
->dflag
));
6859 set_cc_op(s
, CC_OP_EFLAGS
);
6862 gen_update_cc_op(s
);
6863 gen_jmp_im(pc_start
- s
->cs_base
);
6864 gen_helper_iret_protected(cpu_env
, tcg_const_i32(s
->dflag
),
6865 tcg_const_i32(s
->pc
- s
->cs_base
));
6866 set_cc_op(s
, CC_OP_EFLAGS
);
6870 case 0xe8: /* call im */
6873 tval
= (int32_t)insn_get(env
, s
, OT_LONG
);
6875 tval
= (int16_t)insn_get(env
, s
, OT_WORD
);
6876 next_eip
= s
->pc
- s
->cs_base
;
6882 gen_movtl_T0_im(next_eip
);
6887 case 0x9a: /* lcall im */
6889 unsigned int selector
, offset
;
6893 ot
= dflag
? OT_LONG
: OT_WORD
;
6894 offset
= insn_get(env
, s
, ot
);
6895 selector
= insn_get(env
, s
, OT_WORD
);
6897 gen_op_movl_T0_im(selector
);
6898 gen_op_movl_T1_imu(offset
);
6901 case 0xe9: /* jmp im */
6903 tval
= (int32_t)insn_get(env
, s
, OT_LONG
);
6905 tval
= (int16_t)insn_get(env
, s
, OT_WORD
);
6906 tval
+= s
->pc
- s
->cs_base
;
6913 case 0xea: /* ljmp im */
6915 unsigned int selector
, offset
;
6919 ot
= dflag
? OT_LONG
: OT_WORD
;
6920 offset
= insn_get(env
, s
, ot
);
6921 selector
= insn_get(env
, s
, OT_WORD
);
6923 gen_op_movl_T0_im(selector
);
6924 gen_op_movl_T1_imu(offset
);
6927 case 0xeb: /* jmp Jb */
6928 tval
= (int8_t)insn_get(env
, s
, OT_BYTE
);
6929 tval
+= s
->pc
- s
->cs_base
;
6934 case 0x70 ... 0x7f: /* jcc Jb */
6935 tval
= (int8_t)insn_get(env
, s
, OT_BYTE
);
6937 case 0x180 ... 0x18f: /* jcc Jv */
6939 tval
= (int32_t)insn_get(env
, s
, OT_LONG
);
6941 tval
= (int16_t)insn_get(env
, s
, OT_WORD
);
6944 next_eip
= s
->pc
- s
->cs_base
;
6948 gen_jcc(s
, b
, tval
, next_eip
);
6951 case 0x190 ... 0x19f: /* setcc Gv */
6952 modrm
= cpu_ldub_code(env
, s
->pc
++);
6953 gen_setcc1(s
, b
, cpu_T
[0]);
6954 gen_ldst_modrm(env
, s
, modrm
, OT_BYTE
, OR_TMP0
, 1);
6956 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6957 ot
= dflag
+ OT_WORD
;
6958 modrm
= cpu_ldub_code(env
, s
->pc
++);
6959 reg
= ((modrm
>> 3) & 7) | rex_r
;
6960 gen_cmovcc1(env
, s
, ot
, b
, modrm
, reg
);
6963 /************************/
6965 case 0x9c: /* pushf */
6966 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_PUSHF
);
6967 if (s
->vm86
&& s
->iopl
!= 3) {
6968 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6970 gen_update_cc_op(s
);
6971 gen_helper_read_eflags(cpu_T
[0], cpu_env
);
6975 case 0x9d: /* popf */
6976 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_POPF
);
6977 if (s
->vm86
&& s
->iopl
!= 3) {
6978 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
6983 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6984 tcg_const_i32((TF_MASK
| AC_MASK
|
6989 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6990 tcg_const_i32((TF_MASK
| AC_MASK
|
6992 IF_MASK
| IOPL_MASK
)
6996 if (s
->cpl
<= s
->iopl
) {
6998 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
6999 tcg_const_i32((TF_MASK
|
7005 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
7006 tcg_const_i32((TF_MASK
|
7015 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
7016 tcg_const_i32((TF_MASK
| AC_MASK
|
7017 ID_MASK
| NT_MASK
)));
7019 gen_helper_write_eflags(cpu_env
, cpu_T
[0],
7020 tcg_const_i32((TF_MASK
| AC_MASK
|
7027 set_cc_op(s
, CC_OP_EFLAGS
);
7028 /* abort translation because TF/AC flag may change */
7029 gen_jmp_im(s
->pc
- s
->cs_base
);
7033 case 0x9e: /* sahf */
7034 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
7036 gen_op_mov_TN_reg(OT_BYTE
, 0, R_AH
);
7037 gen_compute_eflags(s
);
7038 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, CC_O
);
7039 tcg_gen_andi_tl(cpu_T
[0], cpu_T
[0], CC_S
| CC_Z
| CC_A
| CC_P
| CC_C
);
7040 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, cpu_T
[0]);
7042 case 0x9f: /* lahf */
7043 if (CODE64(s
) && !(s
->cpuid_ext3_features
& CPUID_EXT3_LAHF_LM
))
7045 gen_compute_eflags(s
);
7046 /* Note: gen_compute_eflags() only gives the condition codes */
7047 tcg_gen_ori_tl(cpu_T
[0], cpu_cc_src
, 0x02);
7048 gen_op_mov_reg_T0(OT_BYTE
, R_AH
);
7050 case 0xf5: /* cmc */
7051 gen_compute_eflags(s
);
7052 tcg_gen_xori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
7054 case 0xf8: /* clc */
7055 gen_compute_eflags(s
);
7056 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_C
);
7058 case 0xf9: /* stc */
7059 gen_compute_eflags(s
);
7060 tcg_gen_ori_tl(cpu_cc_src
, cpu_cc_src
, CC_C
);
7062 case 0xfc: /* cld */
7063 tcg_gen_movi_i32(cpu_tmp2_i32
, 1);
7064 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
7066 case 0xfd: /* std */
7067 tcg_gen_movi_i32(cpu_tmp2_i32
, -1);
7068 tcg_gen_st_i32(cpu_tmp2_i32
, cpu_env
, offsetof(CPUX86State
, df
));
7071 /************************/
7072 /* bit operations */
7073 case 0x1ba: /* bt/bts/btr/btc Gv, im */
7074 ot
= dflag
+ OT_WORD
;
7075 modrm
= cpu_ldub_code(env
, s
->pc
++);
7076 op
= (modrm
>> 3) & 7;
7077 mod
= (modrm
>> 6) & 3;
7078 rm
= (modrm
& 7) | REX_B(s
);
7081 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7082 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
7084 gen_op_mov_TN_reg(ot
, 0, rm
);
7087 val
= cpu_ldub_code(env
, s
->pc
++);
7088 gen_op_movl_T1_im(val
);
7093 case 0x1a3: /* bt Gv, Ev */
7096 case 0x1ab: /* bts */
7099 case 0x1b3: /* btr */
7102 case 0x1bb: /* btc */
7105 ot
= dflag
+ OT_WORD
;
7106 modrm
= cpu_ldub_code(env
, s
->pc
++);
7107 reg
= ((modrm
>> 3) & 7) | rex_r
;
7108 mod
= (modrm
>> 6) & 3;
7109 rm
= (modrm
& 7) | REX_B(s
);
7110 gen_op_mov_TN_reg(OT_LONG
, 1, reg
);
7112 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7113 /* specific case: we need to add a displacement */
7114 gen_exts(ot
, cpu_T
[1]);
7115 tcg_gen_sari_tl(cpu_tmp0
, cpu_T
[1], 3 + ot
);
7116 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, ot
);
7117 tcg_gen_add_tl(cpu_A0
, cpu_A0
, cpu_tmp0
);
7118 gen_op_ld_T0_A0(ot
+ s
->mem_index
);
7120 gen_op_mov_TN_reg(ot
, 0, rm
);
7123 tcg_gen_andi_tl(cpu_T
[1], cpu_T
[1], (1 << (3 + ot
)) - 1);
7126 tcg_gen_shr_tl(cpu_cc_src
, cpu_T
[0], cpu_T
[1]);
7127 tcg_gen_movi_tl(cpu_cc_dst
, 0);
7130 tcg_gen_shr_tl(cpu_tmp4
, cpu_T
[0], cpu_T
[1]);
7131 tcg_gen_movi_tl(cpu_tmp0
, 1);
7132 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
7133 tcg_gen_or_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
7136 tcg_gen_shr_tl(cpu_tmp4
, cpu_T
[0], cpu_T
[1]);
7137 tcg_gen_movi_tl(cpu_tmp0
, 1);
7138 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
7139 tcg_gen_not_tl(cpu_tmp0
, cpu_tmp0
);
7140 tcg_gen_and_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
7144 tcg_gen_shr_tl(cpu_tmp4
, cpu_T
[0], cpu_T
[1]);
7145 tcg_gen_movi_tl(cpu_tmp0
, 1);
7146 tcg_gen_shl_tl(cpu_tmp0
, cpu_tmp0
, cpu_T
[1]);
7147 tcg_gen_xor_tl(cpu_T
[0], cpu_T
[0], cpu_tmp0
);
7150 set_cc_op(s
, CC_OP_SARB
+ ot
);
7153 gen_op_st_T0_A0(ot
+ s
->mem_index
);
7155 gen_op_mov_reg_T0(ot
, rm
);
7156 tcg_gen_mov_tl(cpu_cc_src
, cpu_tmp4
);
7157 tcg_gen_movi_tl(cpu_cc_dst
, 0);
7160 case 0x1bc: /* bsf / tzcnt */
7161 case 0x1bd: /* bsr / lzcnt */
7162 ot
= dflag
+ OT_WORD
;
7163 modrm
= cpu_ldub_code(env
, s
->pc
++);
7164 reg
= ((modrm
>> 3) & 7) | rex_r
;
7165 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
7166 gen_extu(ot
, cpu_T
[0]);
7168 /* Note that lzcnt and tzcnt are in different extensions. */
7169 if ((prefixes
& PREFIX_REPZ
)
7171 ? s
->cpuid_ext3_features
& CPUID_EXT3_ABM
7172 : s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_BMI1
)) {
7174 tcg_gen_mov_tl(cpu_cc_src
, cpu_T
[0]);
7176 /* For lzcnt, reduce the target_ulong result by the
7177 number of zeros that we expect to find at the top. */
7178 gen_helper_clz(cpu_T
[0], cpu_T
[0]);
7179 tcg_gen_subi_tl(cpu_T
[0], cpu_T
[0], TARGET_LONG_BITS
- size
);
7181 /* For tzcnt, a zero input must return the operand size:
7182 force all bits outside the operand size to 1. */
7183 target_ulong mask
= (target_ulong
)-2 << (size
- 1);
7184 tcg_gen_ori_tl(cpu_T
[0], cpu_T
[0], mask
);
7185 gen_helper_ctz(cpu_T
[0], cpu_T
[0]);
7187 /* For lzcnt/tzcnt, C and Z bits are defined and are
7188 related to the result. */
7189 gen_op_update1_cc();
7190 set_cc_op(s
, CC_OP_BMILGB
+ ot
);
7192 /* For bsr/bsf, only the Z bit is defined and it is related
7193 to the input and not the result. */
7194 tcg_gen_mov_tl(cpu_cc_dst
, cpu_T
[0]);
7195 set_cc_op(s
, CC_OP_LOGICB
+ ot
);
7197 /* For bsr, return the bit index of the first 1 bit,
7198 not the count of leading zeros. */
7199 gen_helper_clz(cpu_T
[0], cpu_T
[0]);
7200 tcg_gen_xori_tl(cpu_T
[0], cpu_T
[0], TARGET_LONG_BITS
- 1);
7202 gen_helper_ctz(cpu_T
[0], cpu_T
[0]);
7204 /* ??? The manual says that the output is undefined when the
7205 input is zero, but real hardware leaves it unchanged, and
7206 real programs appear to depend on that. */
7207 tcg_gen_movi_tl(cpu_tmp0
, 0);
7208 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_T
[0], cpu_cc_dst
, cpu_tmp0
,
7209 cpu_regs
[reg
], cpu_T
[0]);
7211 gen_op_mov_reg_T0(ot
, reg
);
7213 /************************/
7215 case 0x27: /* daa */
7218 gen_update_cc_op(s
);
7219 gen_helper_daa(cpu_env
);
7220 set_cc_op(s
, CC_OP_EFLAGS
);
7222 case 0x2f: /* das */
7225 gen_update_cc_op(s
);
7226 gen_helper_das(cpu_env
);
7227 set_cc_op(s
, CC_OP_EFLAGS
);
7229 case 0x37: /* aaa */
7232 gen_update_cc_op(s
);
7233 gen_helper_aaa(cpu_env
);
7234 set_cc_op(s
, CC_OP_EFLAGS
);
7236 case 0x3f: /* aas */
7239 gen_update_cc_op(s
);
7240 gen_helper_aas(cpu_env
);
7241 set_cc_op(s
, CC_OP_EFLAGS
);
7243 case 0xd4: /* aam */
7246 val
= cpu_ldub_code(env
, s
->pc
++);
7248 gen_exception(s
, EXCP00_DIVZ
, pc_start
- s
->cs_base
);
7250 gen_helper_aam(cpu_env
, tcg_const_i32(val
));
7251 set_cc_op(s
, CC_OP_LOGICB
);
7254 case 0xd5: /* aad */
7257 val
= cpu_ldub_code(env
, s
->pc
++);
7258 gen_helper_aad(cpu_env
, tcg_const_i32(val
));
7259 set_cc_op(s
, CC_OP_LOGICB
);
7261 /************************/
7263 case 0x90: /* nop */
7264 /* XXX: correct lock test for all insn */
7265 if (prefixes
& PREFIX_LOCK
) {
7268 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
7270 goto do_xchg_reg_eax
;
7272 if (prefixes
& PREFIX_REPZ
) {
7273 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_PAUSE
);
7276 case 0x9b: /* fwait */
7277 if ((s
->flags
& (HF_MP_MASK
| HF_TS_MASK
)) ==
7278 (HF_MP_MASK
| HF_TS_MASK
)) {
7279 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
7281 gen_update_cc_op(s
);
7282 gen_jmp_im(pc_start
- s
->cs_base
);
7283 gen_helper_fwait(cpu_env
);
7286 case 0xcc: /* int3 */
7287 gen_interrupt(s
, EXCP03_INT3
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
7289 case 0xcd: /* int N */
7290 val
= cpu_ldub_code(env
, s
->pc
++);
7291 if (s
->vm86
&& s
->iopl
!= 3) {
7292 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7294 gen_interrupt(s
, val
, pc_start
- s
->cs_base
, s
->pc
- s
->cs_base
);
7297 case 0xce: /* into */
7300 gen_update_cc_op(s
);
7301 gen_jmp_im(pc_start
- s
->cs_base
);
7302 gen_helper_into(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7305 case 0xf1: /* icebp (undocumented, exits to external debugger) */
7306 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_ICEBP
);
7308 gen_debug(s
, pc_start
- s
->cs_base
);
7312 qemu_set_log(CPU_LOG_INT
| CPU_LOG_TB_IN_ASM
);
7316 case 0xfa: /* cli */
7318 if (s
->cpl
<= s
->iopl
) {
7319 gen_helper_cli(cpu_env
);
7321 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7325 gen_helper_cli(cpu_env
);
7327 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7331 case 0xfb: /* sti */
7333 if (s
->cpl
<= s
->iopl
) {
7335 gen_helper_sti(cpu_env
);
7336 /* interruptions are enabled only the first insn after sti */
7337 /* If several instructions disable interrupts, only the
7339 if (!(s
->tb
->flags
& HF_INHIBIT_IRQ_MASK
))
7340 gen_helper_set_inhibit_irq(cpu_env
);
7341 /* give a chance to handle pending irqs */
7342 gen_jmp_im(s
->pc
- s
->cs_base
);
7345 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7351 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7355 case 0x62: /* bound */
7358 ot
= dflag
? OT_LONG
: OT_WORD
;
7359 modrm
= cpu_ldub_code(env
, s
->pc
++);
7360 reg
= (modrm
>> 3) & 7;
7361 mod
= (modrm
>> 6) & 3;
7364 gen_op_mov_TN_reg(ot
, 0, reg
);
7365 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7366 gen_jmp_im(pc_start
- s
->cs_base
);
7367 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
7368 if (ot
== OT_WORD
) {
7369 gen_helper_boundw(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
7371 gen_helper_boundl(cpu_env
, cpu_A0
, cpu_tmp2_i32
);
7374 case 0x1c8 ... 0x1cf: /* bswap reg */
7375 reg
= (b
& 7) | REX_B(s
);
7376 #ifdef TARGET_X86_64
7378 gen_op_mov_TN_reg(OT_QUAD
, 0, reg
);
7379 tcg_gen_bswap64_i64(cpu_T
[0], cpu_T
[0]);
7380 gen_op_mov_reg_T0(OT_QUAD
, reg
);
7384 gen_op_mov_TN_reg(OT_LONG
, 0, reg
);
7385 tcg_gen_ext32u_tl(cpu_T
[0], cpu_T
[0]);
7386 tcg_gen_bswap32_tl(cpu_T
[0], cpu_T
[0]);
7387 gen_op_mov_reg_T0(OT_LONG
, reg
);
7390 case 0xd6: /* salc */
7393 gen_compute_eflags_c(s
, cpu_T
[0]);
7394 tcg_gen_neg_tl(cpu_T
[0], cpu_T
[0]);
7395 gen_op_mov_reg_T0(OT_BYTE
, R_EAX
);
7397 case 0xe0: /* loopnz */
7398 case 0xe1: /* loopz */
7399 case 0xe2: /* loop */
7400 case 0xe3: /* jecxz */
7404 tval
= (int8_t)insn_get(env
, s
, OT_BYTE
);
7405 next_eip
= s
->pc
- s
->cs_base
;
7410 l1
= gen_new_label();
7411 l2
= gen_new_label();
7412 l3
= gen_new_label();
7415 case 0: /* loopnz */
7417 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
7418 gen_op_jz_ecx(s
->aflag
, l3
);
7419 gen_jcc1(s
, (JCC_Z
<< 1) | (b
^ 1), l1
);
7422 gen_op_add_reg_im(s
->aflag
, R_ECX
, -1);
7423 gen_op_jnz_ecx(s
->aflag
, l1
);
7427 gen_op_jz_ecx(s
->aflag
, l1
);
7432 gen_jmp_im(next_eip
);
7441 case 0x130: /* wrmsr */
7442 case 0x132: /* rdmsr */
7444 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7446 gen_update_cc_op(s
);
7447 gen_jmp_im(pc_start
- s
->cs_base
);
7449 gen_helper_rdmsr(cpu_env
);
7451 gen_helper_wrmsr(cpu_env
);
7455 case 0x131: /* rdtsc */
7456 gen_update_cc_op(s
);
7457 gen_jmp_im(pc_start
- s
->cs_base
);
7460 gen_helper_rdtsc(cpu_env
);
7463 gen_jmp(s
, s
->pc
- s
->cs_base
);
7466 case 0x133: /* rdpmc */
7467 gen_update_cc_op(s
);
7468 gen_jmp_im(pc_start
- s
->cs_base
);
7469 gen_helper_rdpmc(cpu_env
);
7471 case 0x134: /* sysenter */
7472 /* For Intel SYSENTER is valid on 64-bit */
7473 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7476 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7478 gen_update_cc_op(s
);
7479 gen_jmp_im(pc_start
- s
->cs_base
);
7480 gen_helper_sysenter(cpu_env
);
7484 case 0x135: /* sysexit */
7485 /* For Intel SYSEXIT is valid on 64-bit */
7486 if (CODE64(s
) && env
->cpuid_vendor1
!= CPUID_VENDOR_INTEL_1
)
7489 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7491 gen_update_cc_op(s
);
7492 gen_jmp_im(pc_start
- s
->cs_base
);
7493 gen_helper_sysexit(cpu_env
, tcg_const_i32(dflag
));
7497 #ifdef TARGET_X86_64
7498 case 0x105: /* syscall */
7499 /* XXX: is it usable in real mode ? */
7500 gen_update_cc_op(s
);
7501 gen_jmp_im(pc_start
- s
->cs_base
);
7502 gen_helper_syscall(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7505 case 0x107: /* sysret */
7507 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7509 gen_update_cc_op(s
);
7510 gen_jmp_im(pc_start
- s
->cs_base
);
7511 gen_helper_sysret(cpu_env
, tcg_const_i32(s
->dflag
));
7512 /* condition codes are modified only in long mode */
7514 set_cc_op(s
, CC_OP_EFLAGS
);
7520 case 0x1a2: /* cpuid */
7521 gen_update_cc_op(s
);
7522 gen_jmp_im(pc_start
- s
->cs_base
);
7523 gen_helper_cpuid(cpu_env
);
7525 case 0xf4: /* hlt */
7527 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7529 gen_update_cc_op(s
);
7530 gen_jmp_im(pc_start
- s
->cs_base
);
7531 gen_helper_hlt(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7532 s
->is_jmp
= DISAS_TB_JUMP
;
7536 modrm
= cpu_ldub_code(env
, s
->pc
++);
7537 mod
= (modrm
>> 6) & 3;
7538 op
= (modrm
>> 3) & 7;
7541 if (!s
->pe
|| s
->vm86
)
7543 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_READ
);
7544 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,ldt
.selector
));
7548 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7551 if (!s
->pe
|| s
->vm86
)
7554 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7556 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_LDTR_WRITE
);
7557 gen_ldst_modrm(env
, s
, modrm
, OT_WORD
, OR_TMP0
, 0);
7558 gen_jmp_im(pc_start
- s
->cs_base
);
7559 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
7560 gen_helper_lldt(cpu_env
, cpu_tmp2_i32
);
7564 if (!s
->pe
|| s
->vm86
)
7566 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_READ
);
7567 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,tr
.selector
));
7571 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 1);
7574 if (!s
->pe
|| s
->vm86
)
7577 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7579 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_TR_WRITE
);
7580 gen_ldst_modrm(env
, s
, modrm
, OT_WORD
, OR_TMP0
, 0);
7581 gen_jmp_im(pc_start
- s
->cs_base
);
7582 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
7583 gen_helper_ltr(cpu_env
, cpu_tmp2_i32
);
7588 if (!s
->pe
|| s
->vm86
)
7590 gen_ldst_modrm(env
, s
, modrm
, OT_WORD
, OR_TMP0
, 0);
7591 gen_update_cc_op(s
);
7593 gen_helper_verr(cpu_env
, cpu_T
[0]);
7595 gen_helper_verw(cpu_env
, cpu_T
[0]);
7597 set_cc_op(s
, CC_OP_EFLAGS
);
7604 modrm
= cpu_ldub_code(env
, s
->pc
++);
7605 mod
= (modrm
>> 6) & 3;
7606 op
= (modrm
>> 3) & 7;
7612 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_GDTR_READ
);
7613 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7614 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, gdt
.limit
));
7615 gen_op_st_T0_A0(OT_WORD
+ s
->mem_index
);
7616 gen_add_A0_im(s
, 2);
7617 tcg_gen_ld_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, gdt
.base
));
7619 gen_op_andl_T0_im(0xffffff);
7620 gen_op_st_T0_A0(CODE64(s
) + OT_LONG
+ s
->mem_index
);
7625 case 0: /* monitor */
7626 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) ||
7629 gen_update_cc_op(s
);
7630 gen_jmp_im(pc_start
- s
->cs_base
);
7631 #ifdef TARGET_X86_64
7632 if (s
->aflag
== 2) {
7633 gen_op_movq_A0_reg(R_EAX
);
7637 gen_op_movl_A0_reg(R_EAX
);
7639 gen_op_andl_A0_ffff();
7641 gen_add_A0_ds_seg(s
);
7642 gen_helper_monitor(cpu_env
, cpu_A0
);
7645 if (!(s
->cpuid_ext_features
& CPUID_EXT_MONITOR
) ||
7648 gen_update_cc_op(s
);
7649 gen_jmp_im(pc_start
- s
->cs_base
);
7650 gen_helper_mwait(cpu_env
, tcg_const_i32(s
->pc
- pc_start
));
7654 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
) ||
7658 gen_helper_clac(cpu_env
);
7659 gen_jmp_im(s
->pc
- s
->cs_base
);
7663 if (!(s
->cpuid_7_0_ebx_features
& CPUID_7_0_EBX_SMAP
) ||
7667 gen_helper_stac(cpu_env
);
7668 gen_jmp_im(s
->pc
- s
->cs_base
);
7675 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_IDTR_READ
);
7676 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7677 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, idt
.limit
));
7678 gen_op_st_T0_A0(OT_WORD
+ s
->mem_index
);
7679 gen_add_A0_im(s
, 2);
7680 tcg_gen_ld_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, idt
.base
));
7682 gen_op_andl_T0_im(0xffffff);
7683 gen_op_st_T0_A0(CODE64(s
) + OT_LONG
+ s
->mem_index
);
7689 gen_update_cc_op(s
);
7690 gen_jmp_im(pc_start
- s
->cs_base
);
7693 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7696 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7699 gen_helper_vmrun(cpu_env
, tcg_const_i32(s
->aflag
),
7700 tcg_const_i32(s
->pc
- pc_start
));
7702 s
->is_jmp
= DISAS_TB_JUMP
;
7705 case 1: /* VMMCALL */
7706 if (!(s
->flags
& HF_SVME_MASK
))
7708 gen_helper_vmmcall(cpu_env
);
7710 case 2: /* VMLOAD */
7711 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7714 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7717 gen_helper_vmload(cpu_env
, tcg_const_i32(s
->aflag
));
7720 case 3: /* VMSAVE */
7721 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7724 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7727 gen_helper_vmsave(cpu_env
, tcg_const_i32(s
->aflag
));
7731 if ((!(s
->flags
& HF_SVME_MASK
) &&
7732 !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
)) ||
7736 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7739 gen_helper_stgi(cpu_env
);
7743 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7746 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7749 gen_helper_clgi(cpu_env
);
7752 case 6: /* SKINIT */
7753 if ((!(s
->flags
& HF_SVME_MASK
) &&
7754 !(s
->cpuid_ext3_features
& CPUID_EXT3_SKINIT
)) ||
7757 gen_helper_skinit(cpu_env
);
7759 case 7: /* INVLPGA */
7760 if (!(s
->flags
& HF_SVME_MASK
) || !s
->pe
)
7763 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7766 gen_helper_invlpga(cpu_env
, tcg_const_i32(s
->aflag
));
7772 } else if (s
->cpl
!= 0) {
7773 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7775 gen_svm_check_intercept(s
, pc_start
,
7776 op
==2 ? SVM_EXIT_GDTR_WRITE
: SVM_EXIT_IDTR_WRITE
);
7777 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7778 gen_op_ld_T1_A0(OT_WORD
+ s
->mem_index
);
7779 gen_add_A0_im(s
, 2);
7780 gen_op_ld_T0_A0(CODE64(s
) + OT_LONG
+ s
->mem_index
);
7782 gen_op_andl_T0_im(0xffffff);
7784 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,gdt
.base
));
7785 tcg_gen_st32_tl(cpu_T
[1], cpu_env
, offsetof(CPUX86State
,gdt
.limit
));
7787 tcg_gen_st_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,idt
.base
));
7788 tcg_gen_st32_tl(cpu_T
[1], cpu_env
, offsetof(CPUX86State
,idt
.limit
));
7793 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_CR0
);
7794 #if defined TARGET_X86_64 && defined HOST_WORDS_BIGENDIAN
7795 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,cr
[0]) + 4);
7797 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,cr
[0]));
7799 gen_ldst_modrm(env
, s
, modrm
, OT_WORD
, OR_TMP0
, 1);
7803 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7805 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
7806 gen_ldst_modrm(env
, s
, modrm
, OT_WORD
, OR_TMP0
, 0);
7807 gen_helper_lmsw(cpu_env
, cpu_T
[0]);
7808 gen_jmp_im(s
->pc
- s
->cs_base
);
7813 if (mod
!= 3) { /* invlpg */
7815 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7817 gen_update_cc_op(s
);
7818 gen_jmp_im(pc_start
- s
->cs_base
);
7819 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7820 gen_helper_invlpg(cpu_env
, cpu_A0
);
7821 gen_jmp_im(s
->pc
- s
->cs_base
);
7826 case 0: /* swapgs */
7827 #ifdef TARGET_X86_64
7830 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7832 tcg_gen_ld_tl(cpu_T
[0], cpu_env
,
7833 offsetof(CPUX86State
,segs
[R_GS
].base
));
7834 tcg_gen_ld_tl(cpu_T
[1], cpu_env
,
7835 offsetof(CPUX86State
,kernelgsbase
));
7836 tcg_gen_st_tl(cpu_T
[1], cpu_env
,
7837 offsetof(CPUX86State
,segs
[R_GS
].base
));
7838 tcg_gen_st_tl(cpu_T
[0], cpu_env
,
7839 offsetof(CPUX86State
,kernelgsbase
));
7847 case 1: /* rdtscp */
7848 if (!(s
->cpuid_ext2_features
& CPUID_EXT2_RDTSCP
))
7850 gen_update_cc_op(s
);
7851 gen_jmp_im(pc_start
- s
->cs_base
);
7854 gen_helper_rdtscp(cpu_env
);
7857 gen_jmp(s
, s
->pc
- s
->cs_base
);
7869 case 0x108: /* invd */
7870 case 0x109: /* wbinvd */
7872 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
7874 gen_svm_check_intercept(s
, pc_start
, (b
& 2) ? SVM_EXIT_INVD
: SVM_EXIT_WBINVD
);
7878 case 0x63: /* arpl or movslS (x86_64) */
7879 #ifdef TARGET_X86_64
7882 /* d_ot is the size of destination */
7883 d_ot
= dflag
+ OT_WORD
;
7885 modrm
= cpu_ldub_code(env
, s
->pc
++);
7886 reg
= ((modrm
>> 3) & 7) | rex_r
;
7887 mod
= (modrm
>> 6) & 3;
7888 rm
= (modrm
& 7) | REX_B(s
);
7891 gen_op_mov_TN_reg(OT_LONG
, 0, rm
);
7893 if (d_ot
== OT_QUAD
)
7894 tcg_gen_ext32s_tl(cpu_T
[0], cpu_T
[0]);
7895 gen_op_mov_reg_T0(d_ot
, reg
);
7897 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7898 if (d_ot
== OT_QUAD
) {
7899 gen_op_lds_T0_A0(OT_LONG
+ s
->mem_index
);
7901 gen_op_ld_T0_A0(OT_LONG
+ s
->mem_index
);
7903 gen_op_mov_reg_T0(d_ot
, reg
);
7909 TCGv t0
, t1
, t2
, a0
;
7911 if (!s
->pe
|| s
->vm86
)
7913 t0
= tcg_temp_local_new();
7914 t1
= tcg_temp_local_new();
7915 t2
= tcg_temp_local_new();
7917 modrm
= cpu_ldub_code(env
, s
->pc
++);
7918 reg
= (modrm
>> 3) & 7;
7919 mod
= (modrm
>> 6) & 3;
7922 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7923 gen_op_ld_v(ot
+ s
->mem_index
, t0
, cpu_A0
);
7924 a0
= tcg_temp_local_new();
7925 tcg_gen_mov_tl(a0
, cpu_A0
);
7927 gen_op_mov_v_reg(ot
, t0
, rm
);
7930 gen_op_mov_v_reg(ot
, t1
, reg
);
7931 tcg_gen_andi_tl(cpu_tmp0
, t0
, 3);
7932 tcg_gen_andi_tl(t1
, t1
, 3);
7933 tcg_gen_movi_tl(t2
, 0);
7934 label1
= gen_new_label();
7935 tcg_gen_brcond_tl(TCG_COND_GE
, cpu_tmp0
, t1
, label1
);
7936 tcg_gen_andi_tl(t0
, t0
, ~3);
7937 tcg_gen_or_tl(t0
, t0
, t1
);
7938 tcg_gen_movi_tl(t2
, CC_Z
);
7939 gen_set_label(label1
);
7941 gen_op_st_v(ot
+ s
->mem_index
, t0
, a0
);
7944 gen_op_mov_reg_v(ot
, rm
, t0
);
7946 gen_compute_eflags(s
);
7947 tcg_gen_andi_tl(cpu_cc_src
, cpu_cc_src
, ~CC_Z
);
7948 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, t2
);
7954 case 0x102: /* lar */
7955 case 0x103: /* lsl */
7959 if (!s
->pe
|| s
->vm86
)
7961 ot
= dflag
? OT_LONG
: OT_WORD
;
7962 modrm
= cpu_ldub_code(env
, s
->pc
++);
7963 reg
= ((modrm
>> 3) & 7) | rex_r
;
7964 gen_ldst_modrm(env
, s
, modrm
, OT_WORD
, OR_TMP0
, 0);
7965 t0
= tcg_temp_local_new();
7966 gen_update_cc_op(s
);
7968 gen_helper_lar(t0
, cpu_env
, cpu_T
[0]);
7970 gen_helper_lsl(t0
, cpu_env
, cpu_T
[0]);
7972 tcg_gen_andi_tl(cpu_tmp0
, cpu_cc_src
, CC_Z
);
7973 label1
= gen_new_label();
7974 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, label1
);
7975 gen_op_mov_reg_v(ot
, reg
, t0
);
7976 gen_set_label(label1
);
7977 set_cc_op(s
, CC_OP_EFLAGS
);
7982 modrm
= cpu_ldub_code(env
, s
->pc
++);
7983 mod
= (modrm
>> 6) & 3;
7984 op
= (modrm
>> 3) & 7;
7986 case 0: /* prefetchnta */
7987 case 1: /* prefetchnt0 */
7988 case 2: /* prefetchnt0 */
7989 case 3: /* prefetchnt0 */
7992 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
7993 /* nothing more to do */
7995 default: /* nop (multi byte) */
7996 gen_nop_modrm(env
, s
, modrm
);
8000 case 0x119 ... 0x11f: /* nop (multi byte) */
8001 modrm
= cpu_ldub_code(env
, s
->pc
++);
8002 gen_nop_modrm(env
, s
, modrm
);
8004 case 0x120: /* mov reg, crN */
8005 case 0x122: /* mov crN, reg */
8007 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
8009 modrm
= cpu_ldub_code(env
, s
->pc
++);
8010 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
8011 * AMD documentation (24594.pdf) and testing of
8012 * intel 386 and 486 processors all show that the mod bits
8013 * are assumed to be 1's, regardless of actual values.
8015 rm
= (modrm
& 7) | REX_B(s
);
8016 reg
= ((modrm
>> 3) & 7) | rex_r
;
8021 if ((prefixes
& PREFIX_LOCK
) && (reg
== 0) &&
8022 (s
->cpuid_ext3_features
& CPUID_EXT3_CR8LEG
)) {
8031 gen_update_cc_op(s
);
8032 gen_jmp_im(pc_start
- s
->cs_base
);
8034 gen_op_mov_TN_reg(ot
, 0, rm
);
8035 gen_helper_write_crN(cpu_env
, tcg_const_i32(reg
),
8037 gen_jmp_im(s
->pc
- s
->cs_base
);
8040 gen_helper_read_crN(cpu_T
[0], cpu_env
, tcg_const_i32(reg
));
8041 gen_op_mov_reg_T0(ot
, rm
);
8049 case 0x121: /* mov reg, drN */
8050 case 0x123: /* mov drN, reg */
8052 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
8054 modrm
= cpu_ldub_code(env
, s
->pc
++);
8055 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
8056 * AMD documentation (24594.pdf) and testing of
8057 * intel 386 and 486 processors all show that the mod bits
8058 * are assumed to be 1's, regardless of actual values.
8060 rm
= (modrm
& 7) | REX_B(s
);
8061 reg
= ((modrm
>> 3) & 7) | rex_r
;
8066 /* XXX: do it dynamically with CR4.DE bit */
8067 if (reg
== 4 || reg
== 5 || reg
>= 8)
8070 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_DR0
+ reg
);
8071 gen_op_mov_TN_reg(ot
, 0, rm
);
8072 gen_helper_movl_drN_T0(cpu_env
, tcg_const_i32(reg
), cpu_T
[0]);
8073 gen_jmp_im(s
->pc
- s
->cs_base
);
8076 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_READ_DR0
+ reg
);
8077 tcg_gen_ld_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
,dr
[reg
]));
8078 gen_op_mov_reg_T0(ot
, rm
);
8082 case 0x106: /* clts */
8084 gen_exception(s
, EXCP0D_GPF
, pc_start
- s
->cs_base
);
8086 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_WRITE_CR0
);
8087 gen_helper_clts(cpu_env
);
8088 /* abort block because static cpu state changed */
8089 gen_jmp_im(s
->pc
- s
->cs_base
);
8093 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
8094 case 0x1c3: /* MOVNTI reg, mem */
8095 if (!(s
->cpuid_features
& CPUID_SSE2
))
8097 ot
= s
->dflag
== 2 ? OT_QUAD
: OT_LONG
;
8098 modrm
= cpu_ldub_code(env
, s
->pc
++);
8099 mod
= (modrm
>> 6) & 3;
8102 reg
= ((modrm
>> 3) & 7) | rex_r
;
8103 /* generate a generic store */
8104 gen_ldst_modrm(env
, s
, modrm
, ot
, reg
, 1);
8107 modrm
= cpu_ldub_code(env
, s
->pc
++);
8108 mod
= (modrm
>> 6) & 3;
8109 op
= (modrm
>> 3) & 7;
8111 case 0: /* fxsave */
8112 if (mod
== 3 || !(s
->cpuid_features
& CPUID_FXSR
) ||
8113 (s
->prefix
& PREFIX_LOCK
))
8115 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
8116 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8119 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
8120 gen_update_cc_op(s
);
8121 gen_jmp_im(pc_start
- s
->cs_base
);
8122 gen_helper_fxsave(cpu_env
, cpu_A0
, tcg_const_i32((s
->dflag
== 2)));
8124 case 1: /* fxrstor */
8125 if (mod
== 3 || !(s
->cpuid_features
& CPUID_FXSR
) ||
8126 (s
->prefix
& PREFIX_LOCK
))
8128 if ((s
->flags
& HF_EM_MASK
) || (s
->flags
& HF_TS_MASK
)) {
8129 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8132 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
8133 gen_update_cc_op(s
);
8134 gen_jmp_im(pc_start
- s
->cs_base
);
8135 gen_helper_fxrstor(cpu_env
, cpu_A0
,
8136 tcg_const_i32((s
->dflag
== 2)));
8138 case 2: /* ldmxcsr */
8139 case 3: /* stmxcsr */
8140 if (s
->flags
& HF_TS_MASK
) {
8141 gen_exception(s
, EXCP07_PREX
, pc_start
- s
->cs_base
);
8144 if ((s
->flags
& HF_EM_MASK
) || !(s
->flags
& HF_OSFXSR_MASK
) ||
8147 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
8149 gen_op_ld_T0_A0(OT_LONG
+ s
->mem_index
);
8150 tcg_gen_trunc_tl_i32(cpu_tmp2_i32
, cpu_T
[0]);
8151 gen_helper_ldmxcsr(cpu_env
, cpu_tmp2_i32
);
8153 tcg_gen_ld32u_tl(cpu_T
[0], cpu_env
, offsetof(CPUX86State
, mxcsr
));
8154 gen_op_st_T0_A0(OT_LONG
+ s
->mem_index
);
8157 case 5: /* lfence */
8158 case 6: /* mfence */
8159 if ((modrm
& 0xc7) != 0xc0 || !(s
->cpuid_features
& CPUID_SSE2
))
8162 case 7: /* sfence / clflush */
8163 if ((modrm
& 0xc7) == 0xc0) {
8165 /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX */
8166 if (!(s
->cpuid_features
& CPUID_SSE
))
8170 if (!(s
->cpuid_features
& CPUID_CLFLUSH
))
8172 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
8179 case 0x10d: /* 3DNow! prefetch(w) */
8180 modrm
= cpu_ldub_code(env
, s
->pc
++);
8181 mod
= (modrm
>> 6) & 3;
8184 gen_lea_modrm(env
, s
, modrm
, ®_addr
, &offset_addr
);
8185 /* ignore for now */
8187 case 0x1aa: /* rsm */
8188 gen_svm_check_intercept(s
, pc_start
, SVM_EXIT_RSM
);
8189 if (!(s
->flags
& HF_SMM_MASK
))
8191 gen_update_cc_op(s
);
8192 gen_jmp_im(s
->pc
- s
->cs_base
);
8193 gen_helper_rsm(cpu_env
);
8196 case 0x1b8: /* SSE4.2 popcnt */
8197 if ((prefixes
& (PREFIX_REPZ
| PREFIX_LOCK
| PREFIX_REPNZ
)) !=
8200 if (!(s
->cpuid_ext_features
& CPUID_EXT_POPCNT
))
8203 modrm
= cpu_ldub_code(env
, s
->pc
++);
8204 reg
= ((modrm
>> 3) & 7) | rex_r
;
8206 if (s
->prefix
& PREFIX_DATA
)
8208 else if (s
->dflag
!= 2)
8213 gen_ldst_modrm(env
, s
, modrm
, ot
, OR_TMP0
, 0);
8214 gen_helper_popcnt(cpu_T
[0], cpu_env
, cpu_T
[0], tcg_const_i32(ot
));
8215 gen_op_mov_reg_T0(ot
, reg
);
8217 set_cc_op(s
, CC_OP_EFLAGS
);
8219 case 0x10e ... 0x10f:
8220 /* 3DNow! instructions, ignore prefixes */
8221 s
->prefix
&= ~(PREFIX_REPZ
| PREFIX_REPNZ
| PREFIX_DATA
);
8222 case 0x110 ... 0x117:
8223 case 0x128 ... 0x12f:
8224 case 0x138 ... 0x13a:
8225 case 0x150 ... 0x179:
8226 case 0x17c ... 0x17f:
8228 case 0x1c4 ... 0x1c6:
8229 case 0x1d0 ... 0x1fe:
8230 gen_sse(env
, s
, b
, pc_start
, rex_r
);
8235 /* lock generation */
8236 if (s
->prefix
& PREFIX_LOCK
)
8237 gen_helper_unlock();
8240 if (s
->prefix
& PREFIX_LOCK
)
8241 gen_helper_unlock();
8242 /* XXX: ensure that no lock was generated */
8243 gen_exception(s
, EXCP06_ILLOP
, pc_start
- s
->cs_base
);
8247 void optimize_flags_init(void)
8249 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
8250 cpu_cc_op
= tcg_global_mem_new_i32(TCG_AREG0
,
8251 offsetof(CPUX86State
, cc_op
), "cc_op");
8252 cpu_cc_dst
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_dst
),
8254 cpu_cc_src
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_src
),
8256 cpu_cc_src2
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUX86State
, cc_src2
),
8259 #ifdef TARGET_X86_64
8260 cpu_regs
[R_EAX
] = tcg_global_mem_new_i64(TCG_AREG0
,
8261 offsetof(CPUX86State
, regs
[R_EAX
]), "rax");
8262 cpu_regs
[R_ECX
] = tcg_global_mem_new_i64(TCG_AREG0
,
8263 offsetof(CPUX86State
, regs
[R_ECX
]), "rcx");
8264 cpu_regs
[R_EDX
] = tcg_global_mem_new_i64(TCG_AREG0
,
8265 offsetof(CPUX86State
, regs
[R_EDX
]), "rdx");
8266 cpu_regs
[R_EBX
] = tcg_global_mem_new_i64(TCG_AREG0
,
8267 offsetof(CPUX86State
, regs
[R_EBX
]), "rbx");
8268 cpu_regs
[R_ESP
] = tcg_global_mem_new_i64(TCG_AREG0
,
8269 offsetof(CPUX86State
, regs
[R_ESP
]), "rsp");
8270 cpu_regs
[R_EBP
] = tcg_global_mem_new_i64(TCG_AREG0
,
8271 offsetof(CPUX86State
, regs
[R_EBP
]), "rbp");
8272 cpu_regs
[R_ESI
] = tcg_global_mem_new_i64(TCG_AREG0
,
8273 offsetof(CPUX86State
, regs
[R_ESI
]), "rsi");
8274 cpu_regs
[R_EDI
] = tcg_global_mem_new_i64(TCG_AREG0
,
8275 offsetof(CPUX86State
, regs
[R_EDI
]), "rdi");
8276 cpu_regs
[8] = tcg_global_mem_new_i64(TCG_AREG0
,
8277 offsetof(CPUX86State
, regs
[8]), "r8");
8278 cpu_regs
[9] = tcg_global_mem_new_i64(TCG_AREG0
,
8279 offsetof(CPUX86State
, regs
[9]), "r9");
8280 cpu_regs
[10] = tcg_global_mem_new_i64(TCG_AREG0
,
8281 offsetof(CPUX86State
, regs
[10]), "r10");
8282 cpu_regs
[11] = tcg_global_mem_new_i64(TCG_AREG0
,
8283 offsetof(CPUX86State
, regs
[11]), "r11");
8284 cpu_regs
[12] = tcg_global_mem_new_i64(TCG_AREG0
,
8285 offsetof(CPUX86State
, regs
[12]), "r12");
8286 cpu_regs
[13] = tcg_global_mem_new_i64(TCG_AREG0
,
8287 offsetof(CPUX86State
, regs
[13]), "r13");
8288 cpu_regs
[14] = tcg_global_mem_new_i64(TCG_AREG0
,
8289 offsetof(CPUX86State
, regs
[14]), "r14");
8290 cpu_regs
[15] = tcg_global_mem_new_i64(TCG_AREG0
,
8291 offsetof(CPUX86State
, regs
[15]), "r15");
8293 cpu_regs
[R_EAX
] = tcg_global_mem_new_i32(TCG_AREG0
,
8294 offsetof(CPUX86State
, regs
[R_EAX
]), "eax");
8295 cpu_regs
[R_ECX
] = tcg_global_mem_new_i32(TCG_AREG0
,
8296 offsetof(CPUX86State
, regs
[R_ECX
]), "ecx");
8297 cpu_regs
[R_EDX
] = tcg_global_mem_new_i32(TCG_AREG0
,
8298 offsetof(CPUX86State
, regs
[R_EDX
]), "edx");
8299 cpu_regs
[R_EBX
] = tcg_global_mem_new_i32(TCG_AREG0
,
8300 offsetof(CPUX86State
, regs
[R_EBX
]), "ebx");
8301 cpu_regs
[R_ESP
] = tcg_global_mem_new_i32(TCG_AREG0
,
8302 offsetof(CPUX86State
, regs
[R_ESP
]), "esp");
8303 cpu_regs
[R_EBP
] = tcg_global_mem_new_i32(TCG_AREG0
,
8304 offsetof(CPUX86State
, regs
[R_EBP
]), "ebp");
8305 cpu_regs
[R_ESI
] = tcg_global_mem_new_i32(TCG_AREG0
,
8306 offsetof(CPUX86State
, regs
[R_ESI
]), "esi");
8307 cpu_regs
[R_EDI
] = tcg_global_mem_new_i32(TCG_AREG0
,
8308 offsetof(CPUX86State
, regs
[R_EDI
]), "edi");
8311 /* register helpers */
8312 #define GEN_HELPER 2
8316 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
8317 basic block 'tb'. If search_pc is TRUE, also generate PC
8318 information for each intermediate instruction. */
8319 static inline void gen_intermediate_code_internal(CPUX86State
*env
,
8320 TranslationBlock
*tb
,
8323 DisasContext dc1
, *dc
= &dc1
;
8324 target_ulong pc_ptr
;
8325 uint16_t *gen_opc_end
;
8329 target_ulong pc_start
;
8330 target_ulong cs_base
;
8334 /* generate intermediate code */
8336 cs_base
= tb
->cs_base
;
8339 dc
->pe
= (flags
>> HF_PE_SHIFT
) & 1;
8340 dc
->code32
= (flags
>> HF_CS32_SHIFT
) & 1;
8341 dc
->ss32
= (flags
>> HF_SS32_SHIFT
) & 1;
8342 dc
->addseg
= (flags
>> HF_ADDSEG_SHIFT
) & 1;
8344 dc
->vm86
= (flags
>> VM_SHIFT
) & 1;
8345 dc
->cpl
= (flags
>> HF_CPL_SHIFT
) & 3;
8346 dc
->iopl
= (flags
>> IOPL_SHIFT
) & 3;
8347 dc
->tf
= (flags
>> TF_SHIFT
) & 1;
8348 dc
->singlestep_enabled
= env
->singlestep_enabled
;
8349 dc
->cc_op
= CC_OP_DYNAMIC
;
8350 dc
->cc_op_dirty
= false;
8351 dc
->cs_base
= cs_base
;
8353 dc
->popl_esp_hack
= 0;
8354 /* select memory access functions */
8356 if (flags
& HF_SOFTMMU_MASK
) {
8357 dc
->mem_index
= (cpu_mmu_index(env
) + 1) << 2;
8359 dc
->cpuid_features
= env
->cpuid_features
;
8360 dc
->cpuid_ext_features
= env
->cpuid_ext_features
;
8361 dc
->cpuid_ext2_features
= env
->cpuid_ext2_features
;
8362 dc
->cpuid_ext3_features
= env
->cpuid_ext3_features
;
8363 dc
->cpuid_7_0_ebx_features
= env
->cpuid_7_0_ebx_features
;
8364 #ifdef TARGET_X86_64
8365 dc
->lma
= (flags
>> HF_LMA_SHIFT
) & 1;
8366 dc
->code64
= (flags
>> HF_CS64_SHIFT
) & 1;
8369 dc
->jmp_opt
= !(dc
->tf
|| env
->singlestep_enabled
||
8370 (flags
& HF_INHIBIT_IRQ_MASK
)
8371 #ifndef CONFIG_SOFTMMU
8372 || (flags
& HF_SOFTMMU_MASK
)
8376 /* check addseg logic */
8377 if (!dc
->addseg
&& (dc
->vm86
|| !dc
->pe
|| !dc
->code32
))
8378 printf("ERROR addseg\n");
8381 cpu_T
[0] = tcg_temp_new();
8382 cpu_T
[1] = tcg_temp_new();
8383 cpu_A0
= tcg_temp_new();
8385 cpu_tmp0
= tcg_temp_new();
8386 cpu_tmp1_i64
= tcg_temp_new_i64();
8387 cpu_tmp2_i32
= tcg_temp_new_i32();
8388 cpu_tmp3_i32
= tcg_temp_new_i32();
8389 cpu_tmp4
= tcg_temp_new();
8390 cpu_tmp5
= tcg_temp_new();
8391 cpu_ptr0
= tcg_temp_new_ptr();
8392 cpu_ptr1
= tcg_temp_new_ptr();
8393 cpu_cc_srcT
= tcg_temp_local_new();
8395 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
8397 dc
->is_jmp
= DISAS_NEXT
;
8401 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
8403 max_insns
= CF_COUNT_MASK
;
8407 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
8408 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
8409 if (bp
->pc
== pc_ptr
&&
8410 !((bp
->flags
& BP_CPU
) && (tb
->flags
& HF_RF_MASK
))) {
8411 gen_debug(dc
, pc_ptr
- dc
->cs_base
);
8417 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
8421 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
8423 tcg_ctx
.gen_opc_pc
[lj
] = pc_ptr
;
8424 gen_opc_cc_op
[lj
] = dc
->cc_op
;
8425 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
8426 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
8428 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
8431 pc_ptr
= disas_insn(env
, dc
, pc_ptr
);
8433 /* stop translation if indicated */
8436 /* if single step mode, we generate only one instruction and
8437 generate an exception */
8438 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
8439 the flag and abort the translation to give the irqs a
8440 change to be happen */
8441 if (dc
->tf
|| dc
->singlestep_enabled
||
8442 (flags
& HF_INHIBIT_IRQ_MASK
)) {
8443 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8447 /* if too long translation, stop generation too */
8448 if (tcg_ctx
.gen_opc_ptr
>= gen_opc_end
||
8449 (pc_ptr
- pc_start
) >= (TARGET_PAGE_SIZE
- 32) ||
8450 num_insns
>= max_insns
) {
8451 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8456 gen_jmp_im(pc_ptr
- dc
->cs_base
);
8461 if (tb
->cflags
& CF_LAST_IO
)
8463 gen_icount_end(tb
, num_insns
);
8464 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
8465 /* we don't forget to fill the last values */
8467 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
8470 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
8474 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
8476 qemu_log("----------------\n");
8477 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
8478 #ifdef TARGET_X86_64
8483 disas_flags
= !dc
->code32
;
8484 log_target_disas(env
, pc_start
, pc_ptr
- pc_start
, disas_flags
);
8490 tb
->size
= pc_ptr
- pc_start
;
8491 tb
->icount
= num_insns
;
8495 void gen_intermediate_code(CPUX86State
*env
, TranslationBlock
*tb
)
8497 gen_intermediate_code_internal(env
, tb
, 0);
8500 void gen_intermediate_code_pc(CPUX86State
*env
, TranslationBlock
*tb
)
8502 gen_intermediate_code_internal(env
, tb
, 1);
8505 void restore_state_to_opc(CPUX86State
*env
, TranslationBlock
*tb
, int pc_pos
)
8509 if (qemu_loglevel_mask(CPU_LOG_TB_OP
)) {
8511 qemu_log("RESTORE:\n");
8512 for(i
= 0;i
<= pc_pos
; i
++) {
8513 if (tcg_ctx
.gen_opc_instr_start
[i
]) {
8514 qemu_log("0x%04x: " TARGET_FMT_lx
"\n", i
,
8515 tcg_ctx
.gen_opc_pc
[i
]);
8518 qemu_log("pc_pos=0x%x eip=" TARGET_FMT_lx
" cs_base=%x\n",
8519 pc_pos
, tcg_ctx
.gen_opc_pc
[pc_pos
] - tb
->cs_base
,
8520 (uint32_t)tb
->cs_base
);
8523 env
->eip
= tcg_ctx
.gen_opc_pc
[pc_pos
] - tb
->cs_base
;
8524 cc_op
= gen_opc_cc_op
[pc_pos
];
8525 if (cc_op
!= CC_OP_DYNAMIC
)