]> git.proxmox.com Git - mirror_qemu.git/blob - target/i386/translate.c
target-i386: Use new deposit and extract ops
[mirror_qemu.git] / target / i386 / translate.c
1 /*
2 * i386 translation
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
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.
10 *
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.
15 *
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/>.
18 */
19 #include "qemu/osdep.h"
20
21 #include "qemu/host-utils.h"
22 #include "cpu.h"
23 #include "disas/disas.h"
24 #include "exec/exec-all.h"
25 #include "tcg-op.h"
26 #include "exec/cpu_ldst.h"
27
28 #include "exec/helper-proto.h"
29 #include "exec/helper-gen.h"
30
31 #include "trace-tcg.h"
32 #include "exec/log.h"
33
34
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
41
42 #ifdef TARGET_X86_64
43 #define CODE64(s) ((s)->code64)
44 #define REX_X(s) ((s)->rex_x)
45 #define REX_B(s) ((s)->rex_b)
46 #else
47 #define CODE64(s) 0
48 #define REX_X(s) 0
49 #define REX_B(s) 0
50 #endif
51
52 #ifdef TARGET_X86_64
53 # define ctztl ctz64
54 # define clztl clz64
55 #else
56 # define ctztl ctz32
57 # define clztl clz32
58 #endif
59
60 /* For a switch indexed by MODRM, match all memory operands for a given OP. */
61 #define CASE_MODRM_MEM_OP(OP) \
62 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
63 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
64 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7
65
66 #define CASE_MODRM_OP(OP) \
67 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
68 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
69 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7: \
70 case (3 << 6) | (OP << 3) | 0 ... (3 << 6) | (OP << 3) | 7
71
72 //#define MACRO_TEST 1
73
74 /* global register indexes */
75 static TCGv_env cpu_env;
76 static TCGv cpu_A0;
77 static TCGv cpu_cc_dst, cpu_cc_src, cpu_cc_src2, cpu_cc_srcT;
78 static TCGv_i32 cpu_cc_op;
79 static TCGv cpu_regs[CPU_NB_REGS];
80 static TCGv cpu_seg_base[6];
81 static TCGv_i64 cpu_bndl[4];
82 static TCGv_i64 cpu_bndu[4];
83 /* local temps */
84 static TCGv cpu_T0, cpu_T1;
85 /* local register indexes (only used inside old micro ops) */
86 static TCGv cpu_tmp0, cpu_tmp4;
87 static TCGv_ptr cpu_ptr0, cpu_ptr1;
88 static TCGv_i32 cpu_tmp2_i32, cpu_tmp3_i32;
89 static TCGv_i64 cpu_tmp1_i64;
90
91 #include "exec/gen-icount.h"
92
93 #ifdef TARGET_X86_64
94 static int x86_64_hregs;
95 #endif
96
97 typedef struct DisasContext {
98 /* current insn context */
99 int override; /* -1 if no override */
100 int prefix;
101 TCGMemOp aflag;
102 TCGMemOp dflag;
103 target_ulong pc_start;
104 target_ulong pc; /* pc = eip + cs_base */
105 int is_jmp; /* 1 = means jump (stop translation), 2 means CPU
106 static state change (stop translation) */
107 /* current block context */
108 target_ulong cs_base; /* base of CS segment */
109 int pe; /* protected mode */
110 int code32; /* 32 bit code segment */
111 #ifdef TARGET_X86_64
112 int lma; /* long mode active */
113 int code64; /* 64 bit code segment */
114 int rex_x, rex_b;
115 #endif
116 int vex_l; /* vex vector length */
117 int vex_v; /* vex vvvv register, without 1's compliment. */
118 int ss32; /* 32 bit stack segment */
119 CCOp cc_op; /* current CC operation */
120 bool cc_op_dirty;
121 int addseg; /* non zero if either DS/ES/SS have a non zero base */
122 int f_st; /* currently unused */
123 int vm86; /* vm86 mode */
124 int cpl;
125 int iopl;
126 int tf; /* TF cpu flag */
127 int singlestep_enabled; /* "hardware" single step enabled */
128 int jmp_opt; /* use direct block chaining for direct jumps */
129 int repz_opt; /* optimize jumps within repz instructions */
130 int mem_index; /* select memory access functions */
131 uint64_t flags; /* all execution flags */
132 struct TranslationBlock *tb;
133 int popl_esp_hack; /* for correct popl with esp base handling */
134 int rip_offset; /* only used in x86_64, but left for simplicity */
135 int cpuid_features;
136 int cpuid_ext_features;
137 int cpuid_ext2_features;
138 int cpuid_ext3_features;
139 int cpuid_7_0_ebx_features;
140 int cpuid_xsave_features;
141 } DisasContext;
142
143 static void gen_eob(DisasContext *s);
144 static void gen_jmp(DisasContext *s, target_ulong eip);
145 static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num);
146 static void gen_op(DisasContext *s1, int op, TCGMemOp ot, int d);
147
148 /* i386 arith/logic operations */
149 enum {
150 OP_ADDL,
151 OP_ORL,
152 OP_ADCL,
153 OP_SBBL,
154 OP_ANDL,
155 OP_SUBL,
156 OP_XORL,
157 OP_CMPL,
158 };
159
160 /* i386 shift ops */
161 enum {
162 OP_ROL,
163 OP_ROR,
164 OP_RCL,
165 OP_RCR,
166 OP_SHL,
167 OP_SHR,
168 OP_SHL1, /* undocumented */
169 OP_SAR = 7,
170 };
171
172 enum {
173 JCC_O,
174 JCC_B,
175 JCC_Z,
176 JCC_BE,
177 JCC_S,
178 JCC_P,
179 JCC_L,
180 JCC_LE,
181 };
182
183 enum {
184 /* I386 int registers */
185 OR_EAX, /* MUST be even numbered */
186 OR_ECX,
187 OR_EDX,
188 OR_EBX,
189 OR_ESP,
190 OR_EBP,
191 OR_ESI,
192 OR_EDI,
193
194 OR_TMP0 = 16, /* temporary operand register */
195 OR_TMP1,
196 OR_A0, /* temporary register used when doing address evaluation */
197 };
198
199 enum {
200 USES_CC_DST = 1,
201 USES_CC_SRC = 2,
202 USES_CC_SRC2 = 4,
203 USES_CC_SRCT = 8,
204 };
205
206 /* Bit set if the global variable is live after setting CC_OP to X. */
207 static const uint8_t cc_op_live[CC_OP_NB] = {
208 [CC_OP_DYNAMIC] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
209 [CC_OP_EFLAGS] = USES_CC_SRC,
210 [CC_OP_MULB ... CC_OP_MULQ] = USES_CC_DST | USES_CC_SRC,
211 [CC_OP_ADDB ... CC_OP_ADDQ] = USES_CC_DST | USES_CC_SRC,
212 [CC_OP_ADCB ... CC_OP_ADCQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
213 [CC_OP_SUBB ... CC_OP_SUBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRCT,
214 [CC_OP_SBBB ... CC_OP_SBBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
215 [CC_OP_LOGICB ... CC_OP_LOGICQ] = USES_CC_DST,
216 [CC_OP_INCB ... CC_OP_INCQ] = USES_CC_DST | USES_CC_SRC,
217 [CC_OP_DECB ... CC_OP_DECQ] = USES_CC_DST | USES_CC_SRC,
218 [CC_OP_SHLB ... CC_OP_SHLQ] = USES_CC_DST | USES_CC_SRC,
219 [CC_OP_SARB ... CC_OP_SARQ] = USES_CC_DST | USES_CC_SRC,
220 [CC_OP_BMILGB ... CC_OP_BMILGQ] = USES_CC_DST | USES_CC_SRC,
221 [CC_OP_ADCX] = USES_CC_DST | USES_CC_SRC,
222 [CC_OP_ADOX] = USES_CC_SRC | USES_CC_SRC2,
223 [CC_OP_ADCOX] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
224 [CC_OP_CLR] = 0,
225 };
226
227 static void set_cc_op(DisasContext *s, CCOp op)
228 {
229 int dead;
230
231 if (s->cc_op == op) {
232 return;
233 }
234
235 /* Discard CC computation that will no longer be used. */
236 dead = cc_op_live[s->cc_op] & ~cc_op_live[op];
237 if (dead & USES_CC_DST) {
238 tcg_gen_discard_tl(cpu_cc_dst);
239 }
240 if (dead & USES_CC_SRC) {
241 tcg_gen_discard_tl(cpu_cc_src);
242 }
243 if (dead & USES_CC_SRC2) {
244 tcg_gen_discard_tl(cpu_cc_src2);
245 }
246 if (dead & USES_CC_SRCT) {
247 tcg_gen_discard_tl(cpu_cc_srcT);
248 }
249
250 if (op == CC_OP_DYNAMIC) {
251 /* The DYNAMIC setting is translator only, and should never be
252 stored. Thus we always consider it clean. */
253 s->cc_op_dirty = false;
254 } else {
255 /* Discard any computed CC_OP value (see shifts). */
256 if (s->cc_op == CC_OP_DYNAMIC) {
257 tcg_gen_discard_i32(cpu_cc_op);
258 }
259 s->cc_op_dirty = true;
260 }
261 s->cc_op = op;
262 }
263
264 static void gen_update_cc_op(DisasContext *s)
265 {
266 if (s->cc_op_dirty) {
267 tcg_gen_movi_i32(cpu_cc_op, s->cc_op);
268 s->cc_op_dirty = false;
269 }
270 }
271
272 #ifdef TARGET_X86_64
273
274 #define NB_OP_SIZES 4
275
276 #else /* !TARGET_X86_64 */
277
278 #define NB_OP_SIZES 3
279
280 #endif /* !TARGET_X86_64 */
281
282 #if defined(HOST_WORDS_BIGENDIAN)
283 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
284 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
285 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
286 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
287 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
288 #else
289 #define REG_B_OFFSET 0
290 #define REG_H_OFFSET 1
291 #define REG_W_OFFSET 0
292 #define REG_L_OFFSET 0
293 #define REG_LH_OFFSET 4
294 #endif
295
296 /* In instruction encodings for byte register accesses the
297 * register number usually indicates "low 8 bits of register N";
298 * however there are some special cases where N 4..7 indicates
299 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
300 * true for this special case, false otherwise.
301 */
302 static inline bool byte_reg_is_xH(int reg)
303 {
304 if (reg < 4) {
305 return false;
306 }
307 #ifdef TARGET_X86_64
308 if (reg >= 8 || x86_64_hregs) {
309 return false;
310 }
311 #endif
312 return true;
313 }
314
315 /* Select the size of a push/pop operation. */
316 static inline TCGMemOp mo_pushpop(DisasContext *s, TCGMemOp ot)
317 {
318 if (CODE64(s)) {
319 return ot == MO_16 ? MO_16 : MO_64;
320 } else {
321 return ot;
322 }
323 }
324
325 /* Select the size of the stack pointer. */
326 static inline TCGMemOp mo_stacksize(DisasContext *s)
327 {
328 return CODE64(s) ? MO_64 : s->ss32 ? MO_32 : MO_16;
329 }
330
331 /* Select only size 64 else 32. Used for SSE operand sizes. */
332 static inline TCGMemOp mo_64_32(TCGMemOp ot)
333 {
334 #ifdef TARGET_X86_64
335 return ot == MO_64 ? MO_64 : MO_32;
336 #else
337 return MO_32;
338 #endif
339 }
340
341 /* Select size 8 if lsb of B is clear, else OT. Used for decoding
342 byte vs word opcodes. */
343 static inline TCGMemOp mo_b_d(int b, TCGMemOp ot)
344 {
345 return b & 1 ? ot : MO_8;
346 }
347
348 /* Select size 8 if lsb of B is clear, else OT capped at 32.
349 Used for decoding operand size of port opcodes. */
350 static inline TCGMemOp mo_b_d32(int b, TCGMemOp ot)
351 {
352 return b & 1 ? (ot == MO_16 ? MO_16 : MO_32) : MO_8;
353 }
354
355 static void gen_op_mov_reg_v(TCGMemOp ot, int reg, TCGv t0)
356 {
357 switch(ot) {
358 case MO_8:
359 if (!byte_reg_is_xH(reg)) {
360 tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 8);
361 } else {
362 tcg_gen_deposit_tl(cpu_regs[reg - 4], cpu_regs[reg - 4], t0, 8, 8);
363 }
364 break;
365 case MO_16:
366 tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 16);
367 break;
368 case MO_32:
369 /* For x86_64, this sets the higher half of register to zero.
370 For i386, this is equivalent to a mov. */
371 tcg_gen_ext32u_tl(cpu_regs[reg], t0);
372 break;
373 #ifdef TARGET_X86_64
374 case MO_64:
375 tcg_gen_mov_tl(cpu_regs[reg], t0);
376 break;
377 #endif
378 default:
379 tcg_abort();
380 }
381 }
382
383 static inline void gen_op_mov_v_reg(TCGMemOp ot, TCGv t0, int reg)
384 {
385 if (ot == MO_8 && byte_reg_is_xH(reg)) {
386 tcg_gen_extract_tl(t0, cpu_regs[reg - 4], 8, 8);
387 } else {
388 tcg_gen_mov_tl(t0, cpu_regs[reg]);
389 }
390 }
391
392 static void gen_add_A0_im(DisasContext *s, int val)
393 {
394 tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
395 if (!CODE64(s)) {
396 tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
397 }
398 }
399
400 static inline void gen_op_jmp_v(TCGv dest)
401 {
402 tcg_gen_st_tl(dest, cpu_env, offsetof(CPUX86State, eip));
403 }
404
405 static inline void gen_op_add_reg_im(TCGMemOp size, int reg, int32_t val)
406 {
407 tcg_gen_addi_tl(cpu_tmp0, cpu_regs[reg], val);
408 gen_op_mov_reg_v(size, reg, cpu_tmp0);
409 }
410
411 static inline void gen_op_add_reg_T0(TCGMemOp size, int reg)
412 {
413 tcg_gen_add_tl(cpu_tmp0, cpu_regs[reg], cpu_T0);
414 gen_op_mov_reg_v(size, reg, cpu_tmp0);
415 }
416
417 static inline void gen_op_ld_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
418 {
419 tcg_gen_qemu_ld_tl(t0, a0, s->mem_index, idx | MO_LE);
420 }
421
422 static inline void gen_op_st_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
423 {
424 tcg_gen_qemu_st_tl(t0, a0, s->mem_index, idx | MO_LE);
425 }
426
427 static inline void gen_op_st_rm_T0_A0(DisasContext *s, int idx, int d)
428 {
429 if (d == OR_TMP0) {
430 gen_op_st_v(s, idx, cpu_T0, cpu_A0);
431 } else {
432 gen_op_mov_reg_v(idx, d, cpu_T0);
433 }
434 }
435
436 static inline void gen_jmp_im(target_ulong pc)
437 {
438 tcg_gen_movi_tl(cpu_tmp0, pc);
439 gen_op_jmp_v(cpu_tmp0);
440 }
441
442 /* Compute SEG:REG into A0. SEG is selected from the override segment
443 (OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to
444 indicate no override. */
445 static void gen_lea_v_seg(DisasContext *s, TCGMemOp aflag, TCGv a0,
446 int def_seg, int ovr_seg)
447 {
448 switch (aflag) {
449 #ifdef TARGET_X86_64
450 case MO_64:
451 if (ovr_seg < 0) {
452 tcg_gen_mov_tl(cpu_A0, a0);
453 return;
454 }
455 break;
456 #endif
457 case MO_32:
458 /* 32 bit address */
459 if (ovr_seg < 0 && s->addseg) {
460 ovr_seg = def_seg;
461 }
462 if (ovr_seg < 0) {
463 tcg_gen_ext32u_tl(cpu_A0, a0);
464 return;
465 }
466 break;
467 case MO_16:
468 /* 16 bit address */
469 tcg_gen_ext16u_tl(cpu_A0, a0);
470 a0 = cpu_A0;
471 if (ovr_seg < 0) {
472 if (s->addseg) {
473 ovr_seg = def_seg;
474 } else {
475 return;
476 }
477 }
478 break;
479 default:
480 tcg_abort();
481 }
482
483 if (ovr_seg >= 0) {
484 TCGv seg = cpu_seg_base[ovr_seg];
485
486 if (aflag == MO_64) {
487 tcg_gen_add_tl(cpu_A0, a0, seg);
488 } else if (CODE64(s)) {
489 tcg_gen_ext32u_tl(cpu_A0, a0);
490 tcg_gen_add_tl(cpu_A0, cpu_A0, seg);
491 } else {
492 tcg_gen_add_tl(cpu_A0, a0, seg);
493 tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
494 }
495 }
496 }
497
498 static inline void gen_string_movl_A0_ESI(DisasContext *s)
499 {
500 gen_lea_v_seg(s, s->aflag, cpu_regs[R_ESI], R_DS, s->override);
501 }
502
503 static inline void gen_string_movl_A0_EDI(DisasContext *s)
504 {
505 gen_lea_v_seg(s, s->aflag, cpu_regs[R_EDI], R_ES, -1);
506 }
507
508 static inline void gen_op_movl_T0_Dshift(TCGMemOp ot)
509 {
510 tcg_gen_ld32s_tl(cpu_T0, cpu_env, offsetof(CPUX86State, df));
511 tcg_gen_shli_tl(cpu_T0, cpu_T0, ot);
512 };
513
514 static TCGv gen_ext_tl(TCGv dst, TCGv src, TCGMemOp size, bool sign)
515 {
516 switch (size) {
517 case MO_8:
518 if (sign) {
519 tcg_gen_ext8s_tl(dst, src);
520 } else {
521 tcg_gen_ext8u_tl(dst, src);
522 }
523 return dst;
524 case MO_16:
525 if (sign) {
526 tcg_gen_ext16s_tl(dst, src);
527 } else {
528 tcg_gen_ext16u_tl(dst, src);
529 }
530 return dst;
531 #ifdef TARGET_X86_64
532 case MO_32:
533 if (sign) {
534 tcg_gen_ext32s_tl(dst, src);
535 } else {
536 tcg_gen_ext32u_tl(dst, src);
537 }
538 return dst;
539 #endif
540 default:
541 return src;
542 }
543 }
544
545 static void gen_extu(TCGMemOp ot, TCGv reg)
546 {
547 gen_ext_tl(reg, reg, ot, false);
548 }
549
550 static void gen_exts(TCGMemOp ot, TCGv reg)
551 {
552 gen_ext_tl(reg, reg, ot, true);
553 }
554
555 static inline void gen_op_jnz_ecx(TCGMemOp size, TCGLabel *label1)
556 {
557 tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
558 gen_extu(size, cpu_tmp0);
559 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_tmp0, 0, label1);
560 }
561
562 static inline void gen_op_jz_ecx(TCGMemOp size, TCGLabel *label1)
563 {
564 tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
565 gen_extu(size, cpu_tmp0);
566 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
567 }
568
569 static void gen_helper_in_func(TCGMemOp ot, TCGv v, TCGv_i32 n)
570 {
571 switch (ot) {
572 case MO_8:
573 gen_helper_inb(v, cpu_env, n);
574 break;
575 case MO_16:
576 gen_helper_inw(v, cpu_env, n);
577 break;
578 case MO_32:
579 gen_helper_inl(v, cpu_env, n);
580 break;
581 default:
582 tcg_abort();
583 }
584 }
585
586 static void gen_helper_out_func(TCGMemOp ot, TCGv_i32 v, TCGv_i32 n)
587 {
588 switch (ot) {
589 case MO_8:
590 gen_helper_outb(cpu_env, v, n);
591 break;
592 case MO_16:
593 gen_helper_outw(cpu_env, v, n);
594 break;
595 case MO_32:
596 gen_helper_outl(cpu_env, v, n);
597 break;
598 default:
599 tcg_abort();
600 }
601 }
602
603 static void gen_check_io(DisasContext *s, TCGMemOp ot, target_ulong cur_eip,
604 uint32_t svm_flags)
605 {
606 target_ulong next_eip;
607
608 if (s->pe && (s->cpl > s->iopl || s->vm86)) {
609 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
610 switch (ot) {
611 case MO_8:
612 gen_helper_check_iob(cpu_env, cpu_tmp2_i32);
613 break;
614 case MO_16:
615 gen_helper_check_iow(cpu_env, cpu_tmp2_i32);
616 break;
617 case MO_32:
618 gen_helper_check_iol(cpu_env, cpu_tmp2_i32);
619 break;
620 default:
621 tcg_abort();
622 }
623 }
624 if(s->flags & HF_SVMI_MASK) {
625 gen_update_cc_op(s);
626 gen_jmp_im(cur_eip);
627 svm_flags |= (1 << (4 + ot));
628 next_eip = s->pc - s->cs_base;
629 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
630 gen_helper_svm_check_io(cpu_env, cpu_tmp2_i32,
631 tcg_const_i32(svm_flags),
632 tcg_const_i32(next_eip - cur_eip));
633 }
634 }
635
636 static inline void gen_movs(DisasContext *s, TCGMemOp ot)
637 {
638 gen_string_movl_A0_ESI(s);
639 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
640 gen_string_movl_A0_EDI(s);
641 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
642 gen_op_movl_T0_Dshift(ot);
643 gen_op_add_reg_T0(s->aflag, R_ESI);
644 gen_op_add_reg_T0(s->aflag, R_EDI);
645 }
646
647 static void gen_op_update1_cc(void)
648 {
649 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
650 }
651
652 static void gen_op_update2_cc(void)
653 {
654 tcg_gen_mov_tl(cpu_cc_src, cpu_T1);
655 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
656 }
657
658 static void gen_op_update3_cc(TCGv reg)
659 {
660 tcg_gen_mov_tl(cpu_cc_src2, reg);
661 tcg_gen_mov_tl(cpu_cc_src, cpu_T1);
662 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
663 }
664
665 static inline void gen_op_testl_T0_T1_cc(void)
666 {
667 tcg_gen_and_tl(cpu_cc_dst, cpu_T0, cpu_T1);
668 }
669
670 static void gen_op_update_neg_cc(void)
671 {
672 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
673 tcg_gen_neg_tl(cpu_cc_src, cpu_T0);
674 tcg_gen_movi_tl(cpu_cc_srcT, 0);
675 }
676
677 /* compute all eflags to cc_src */
678 static void gen_compute_eflags(DisasContext *s)
679 {
680 TCGv zero, dst, src1, src2;
681 int live, dead;
682
683 if (s->cc_op == CC_OP_EFLAGS) {
684 return;
685 }
686 if (s->cc_op == CC_OP_CLR) {
687 tcg_gen_movi_tl(cpu_cc_src, CC_Z | CC_P);
688 set_cc_op(s, CC_OP_EFLAGS);
689 return;
690 }
691
692 TCGV_UNUSED(zero);
693 dst = cpu_cc_dst;
694 src1 = cpu_cc_src;
695 src2 = cpu_cc_src2;
696
697 /* Take care to not read values that are not live. */
698 live = cc_op_live[s->cc_op] & ~USES_CC_SRCT;
699 dead = live ^ (USES_CC_DST | USES_CC_SRC | USES_CC_SRC2);
700 if (dead) {
701 zero = tcg_const_tl(0);
702 if (dead & USES_CC_DST) {
703 dst = zero;
704 }
705 if (dead & USES_CC_SRC) {
706 src1 = zero;
707 }
708 if (dead & USES_CC_SRC2) {
709 src2 = zero;
710 }
711 }
712
713 gen_update_cc_op(s);
714 gen_helper_cc_compute_all(cpu_cc_src, dst, src1, src2, cpu_cc_op);
715 set_cc_op(s, CC_OP_EFLAGS);
716
717 if (dead) {
718 tcg_temp_free(zero);
719 }
720 }
721
722 typedef struct CCPrepare {
723 TCGCond cond;
724 TCGv reg;
725 TCGv reg2;
726 target_ulong imm;
727 target_ulong mask;
728 bool use_reg2;
729 bool no_setcond;
730 } CCPrepare;
731
732 /* compute eflags.C to reg */
733 static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg)
734 {
735 TCGv t0, t1;
736 int size, shift;
737
738 switch (s->cc_op) {
739 case CC_OP_SUBB ... CC_OP_SUBQ:
740 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
741 size = s->cc_op - CC_OP_SUBB;
742 t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
743 /* If no temporary was used, be careful not to alias t1 and t0. */
744 t0 = TCGV_EQUAL(t1, cpu_cc_src) ? cpu_tmp0 : reg;
745 tcg_gen_mov_tl(t0, cpu_cc_srcT);
746 gen_extu(size, t0);
747 goto add_sub;
748
749 case CC_OP_ADDB ... CC_OP_ADDQ:
750 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
751 size = s->cc_op - CC_OP_ADDB;
752 t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
753 t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
754 add_sub:
755 return (CCPrepare) { .cond = TCG_COND_LTU, .reg = t0,
756 .reg2 = t1, .mask = -1, .use_reg2 = true };
757
758 case CC_OP_LOGICB ... CC_OP_LOGICQ:
759 case CC_OP_CLR:
760 return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
761
762 case CC_OP_INCB ... CC_OP_INCQ:
763 case CC_OP_DECB ... CC_OP_DECQ:
764 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
765 .mask = -1, .no_setcond = true };
766
767 case CC_OP_SHLB ... CC_OP_SHLQ:
768 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
769 size = s->cc_op - CC_OP_SHLB;
770 shift = (8 << size) - 1;
771 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
772 .mask = (target_ulong)1 << shift };
773
774 case CC_OP_MULB ... CC_OP_MULQ:
775 return (CCPrepare) { .cond = TCG_COND_NE,
776 .reg = cpu_cc_src, .mask = -1 };
777
778 case CC_OP_BMILGB ... CC_OP_BMILGQ:
779 size = s->cc_op - CC_OP_BMILGB;
780 t0 = gen_ext_tl(reg, cpu_cc_src, size, false);
781 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 };
782
783 case CC_OP_ADCX:
784 case CC_OP_ADCOX:
785 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_dst,
786 .mask = -1, .no_setcond = true };
787
788 case CC_OP_EFLAGS:
789 case CC_OP_SARB ... CC_OP_SARQ:
790 /* CC_SRC & 1 */
791 return (CCPrepare) { .cond = TCG_COND_NE,
792 .reg = cpu_cc_src, .mask = CC_C };
793
794 default:
795 /* The need to compute only C from CC_OP_DYNAMIC is important
796 in efficiently implementing e.g. INC at the start of a TB. */
797 gen_update_cc_op(s);
798 gen_helper_cc_compute_c(reg, cpu_cc_dst, cpu_cc_src,
799 cpu_cc_src2, cpu_cc_op);
800 return (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
801 .mask = -1, .no_setcond = true };
802 }
803 }
804
805 /* compute eflags.P to reg */
806 static CCPrepare gen_prepare_eflags_p(DisasContext *s, TCGv reg)
807 {
808 gen_compute_eflags(s);
809 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
810 .mask = CC_P };
811 }
812
813 /* compute eflags.S to reg */
814 static CCPrepare gen_prepare_eflags_s(DisasContext *s, TCGv reg)
815 {
816 switch (s->cc_op) {
817 case CC_OP_DYNAMIC:
818 gen_compute_eflags(s);
819 /* FALLTHRU */
820 case CC_OP_EFLAGS:
821 case CC_OP_ADCX:
822 case CC_OP_ADOX:
823 case CC_OP_ADCOX:
824 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
825 .mask = CC_S };
826 case CC_OP_CLR:
827 return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
828 default:
829 {
830 TCGMemOp size = (s->cc_op - CC_OP_ADDB) & 3;
831 TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, true);
832 return (CCPrepare) { .cond = TCG_COND_LT, .reg = t0, .mask = -1 };
833 }
834 }
835 }
836
837 /* compute eflags.O to reg */
838 static CCPrepare gen_prepare_eflags_o(DisasContext *s, TCGv reg)
839 {
840 switch (s->cc_op) {
841 case CC_OP_ADOX:
842 case CC_OP_ADCOX:
843 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src2,
844 .mask = -1, .no_setcond = true };
845 case CC_OP_CLR:
846 return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
847 default:
848 gen_compute_eflags(s);
849 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
850 .mask = CC_O };
851 }
852 }
853
854 /* compute eflags.Z to reg */
855 static CCPrepare gen_prepare_eflags_z(DisasContext *s, TCGv reg)
856 {
857 switch (s->cc_op) {
858 case CC_OP_DYNAMIC:
859 gen_compute_eflags(s);
860 /* FALLTHRU */
861 case CC_OP_EFLAGS:
862 case CC_OP_ADCX:
863 case CC_OP_ADOX:
864 case CC_OP_ADCOX:
865 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
866 .mask = CC_Z };
867 case CC_OP_CLR:
868 return (CCPrepare) { .cond = TCG_COND_ALWAYS, .mask = -1 };
869 default:
870 {
871 TCGMemOp size = (s->cc_op - CC_OP_ADDB) & 3;
872 TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
873 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 };
874 }
875 }
876 }
877
878 /* perform a conditional store into register 'reg' according to jump opcode
879 value 'b'. In the fast case, T0 is guaranted not to be used. */
880 static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg)
881 {
882 int inv, jcc_op, cond;
883 TCGMemOp size;
884 CCPrepare cc;
885 TCGv t0;
886
887 inv = b & 1;
888 jcc_op = (b >> 1) & 7;
889
890 switch (s->cc_op) {
891 case CC_OP_SUBB ... CC_OP_SUBQ:
892 /* We optimize relational operators for the cmp/jcc case. */
893 size = s->cc_op - CC_OP_SUBB;
894 switch (jcc_op) {
895 case JCC_BE:
896 tcg_gen_mov_tl(cpu_tmp4, cpu_cc_srcT);
897 gen_extu(size, cpu_tmp4);
898 t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
899 cc = (CCPrepare) { .cond = TCG_COND_LEU, .reg = cpu_tmp4,
900 .reg2 = t0, .mask = -1, .use_reg2 = true };
901 break;
902
903 case JCC_L:
904 cond = TCG_COND_LT;
905 goto fast_jcc_l;
906 case JCC_LE:
907 cond = TCG_COND_LE;
908 fast_jcc_l:
909 tcg_gen_mov_tl(cpu_tmp4, cpu_cc_srcT);
910 gen_exts(size, cpu_tmp4);
911 t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, true);
912 cc = (CCPrepare) { .cond = cond, .reg = cpu_tmp4,
913 .reg2 = t0, .mask = -1, .use_reg2 = true };
914 break;
915
916 default:
917 goto slow_jcc;
918 }
919 break;
920
921 default:
922 slow_jcc:
923 /* This actually generates good code for JC, JZ and JS. */
924 switch (jcc_op) {
925 case JCC_O:
926 cc = gen_prepare_eflags_o(s, reg);
927 break;
928 case JCC_B:
929 cc = gen_prepare_eflags_c(s, reg);
930 break;
931 case JCC_Z:
932 cc = gen_prepare_eflags_z(s, reg);
933 break;
934 case JCC_BE:
935 gen_compute_eflags(s);
936 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
937 .mask = CC_Z | CC_C };
938 break;
939 case JCC_S:
940 cc = gen_prepare_eflags_s(s, reg);
941 break;
942 case JCC_P:
943 cc = gen_prepare_eflags_p(s, reg);
944 break;
945 case JCC_L:
946 gen_compute_eflags(s);
947 if (TCGV_EQUAL(reg, cpu_cc_src)) {
948 reg = cpu_tmp0;
949 }
950 tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */
951 tcg_gen_xor_tl(reg, reg, cpu_cc_src);
952 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
953 .mask = CC_S };
954 break;
955 default:
956 case JCC_LE:
957 gen_compute_eflags(s);
958 if (TCGV_EQUAL(reg, cpu_cc_src)) {
959 reg = cpu_tmp0;
960 }
961 tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */
962 tcg_gen_xor_tl(reg, reg, cpu_cc_src);
963 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
964 .mask = CC_S | CC_Z };
965 break;
966 }
967 break;
968 }
969
970 if (inv) {
971 cc.cond = tcg_invert_cond(cc.cond);
972 }
973 return cc;
974 }
975
976 static void gen_setcc1(DisasContext *s, int b, TCGv reg)
977 {
978 CCPrepare cc = gen_prepare_cc(s, b, reg);
979
980 if (cc.no_setcond) {
981 if (cc.cond == TCG_COND_EQ) {
982 tcg_gen_xori_tl(reg, cc.reg, 1);
983 } else {
984 tcg_gen_mov_tl(reg, cc.reg);
985 }
986 return;
987 }
988
989 if (cc.cond == TCG_COND_NE && !cc.use_reg2 && cc.imm == 0 &&
990 cc.mask != 0 && (cc.mask & (cc.mask - 1)) == 0) {
991 tcg_gen_shri_tl(reg, cc.reg, ctztl(cc.mask));
992 tcg_gen_andi_tl(reg, reg, 1);
993 return;
994 }
995 if (cc.mask != -1) {
996 tcg_gen_andi_tl(reg, cc.reg, cc.mask);
997 cc.reg = reg;
998 }
999 if (cc.use_reg2) {
1000 tcg_gen_setcond_tl(cc.cond, reg, cc.reg, cc.reg2);
1001 } else {
1002 tcg_gen_setcondi_tl(cc.cond, reg, cc.reg, cc.imm);
1003 }
1004 }
1005
1006 static inline void gen_compute_eflags_c(DisasContext *s, TCGv reg)
1007 {
1008 gen_setcc1(s, JCC_B << 1, reg);
1009 }
1010
1011 /* generate a conditional jump to label 'l1' according to jump opcode
1012 value 'b'. In the fast case, T0 is guaranted not to be used. */
1013 static inline void gen_jcc1_noeob(DisasContext *s, int b, TCGLabel *l1)
1014 {
1015 CCPrepare cc = gen_prepare_cc(s, b, cpu_T0);
1016
1017 if (cc.mask != -1) {
1018 tcg_gen_andi_tl(cpu_T0, cc.reg, cc.mask);
1019 cc.reg = cpu_T0;
1020 }
1021 if (cc.use_reg2) {
1022 tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1023 } else {
1024 tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1025 }
1026 }
1027
1028 /* Generate a conditional jump to label 'l1' according to jump opcode
1029 value 'b'. In the fast case, T0 is guaranted not to be used.
1030 A translation block must end soon. */
1031 static inline void gen_jcc1(DisasContext *s, int b, TCGLabel *l1)
1032 {
1033 CCPrepare cc = gen_prepare_cc(s, b, cpu_T0);
1034
1035 gen_update_cc_op(s);
1036 if (cc.mask != -1) {
1037 tcg_gen_andi_tl(cpu_T0, cc.reg, cc.mask);
1038 cc.reg = cpu_T0;
1039 }
1040 set_cc_op(s, CC_OP_DYNAMIC);
1041 if (cc.use_reg2) {
1042 tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1043 } else {
1044 tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1045 }
1046 }
1047
1048 /* XXX: does not work with gdbstub "ice" single step - not a
1049 serious problem */
1050 static TCGLabel *gen_jz_ecx_string(DisasContext *s, target_ulong next_eip)
1051 {
1052 TCGLabel *l1 = gen_new_label();
1053 TCGLabel *l2 = gen_new_label();
1054 gen_op_jnz_ecx(s->aflag, l1);
1055 gen_set_label(l2);
1056 gen_jmp_tb(s, next_eip, 1);
1057 gen_set_label(l1);
1058 return l2;
1059 }
1060
1061 static inline void gen_stos(DisasContext *s, TCGMemOp ot)
1062 {
1063 gen_op_mov_v_reg(MO_32, cpu_T0, R_EAX);
1064 gen_string_movl_A0_EDI(s);
1065 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
1066 gen_op_movl_T0_Dshift(ot);
1067 gen_op_add_reg_T0(s->aflag, R_EDI);
1068 }
1069
1070 static inline void gen_lods(DisasContext *s, TCGMemOp ot)
1071 {
1072 gen_string_movl_A0_ESI(s);
1073 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1074 gen_op_mov_reg_v(ot, R_EAX, cpu_T0);
1075 gen_op_movl_T0_Dshift(ot);
1076 gen_op_add_reg_T0(s->aflag, R_ESI);
1077 }
1078
1079 static inline void gen_scas(DisasContext *s, TCGMemOp ot)
1080 {
1081 gen_string_movl_A0_EDI(s);
1082 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
1083 gen_op(s, OP_CMPL, ot, R_EAX);
1084 gen_op_movl_T0_Dshift(ot);
1085 gen_op_add_reg_T0(s->aflag, R_EDI);
1086 }
1087
1088 static inline void gen_cmps(DisasContext *s, TCGMemOp ot)
1089 {
1090 gen_string_movl_A0_EDI(s);
1091 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
1092 gen_string_movl_A0_ESI(s);
1093 gen_op(s, OP_CMPL, ot, OR_TMP0);
1094 gen_op_movl_T0_Dshift(ot);
1095 gen_op_add_reg_T0(s->aflag, R_ESI);
1096 gen_op_add_reg_T0(s->aflag, R_EDI);
1097 }
1098
1099 static void gen_bpt_io(DisasContext *s, TCGv_i32 t_port, int ot)
1100 {
1101 if (s->flags & HF_IOBPT_MASK) {
1102 TCGv_i32 t_size = tcg_const_i32(1 << ot);
1103 TCGv t_next = tcg_const_tl(s->pc - s->cs_base);
1104
1105 gen_helper_bpt_io(cpu_env, t_port, t_size, t_next);
1106 tcg_temp_free_i32(t_size);
1107 tcg_temp_free(t_next);
1108 }
1109 }
1110
1111
1112 static inline void gen_ins(DisasContext *s, TCGMemOp ot)
1113 {
1114 if (s->tb->cflags & CF_USE_ICOUNT) {
1115 gen_io_start();
1116 }
1117 gen_string_movl_A0_EDI(s);
1118 /* Note: we must do this dummy write first to be restartable in
1119 case of page fault. */
1120 tcg_gen_movi_tl(cpu_T0, 0);
1121 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
1122 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_EDX]);
1123 tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1124 gen_helper_in_func(ot, cpu_T0, cpu_tmp2_i32);
1125 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
1126 gen_op_movl_T0_Dshift(ot);
1127 gen_op_add_reg_T0(s->aflag, R_EDI);
1128 gen_bpt_io(s, cpu_tmp2_i32, ot);
1129 if (s->tb->cflags & CF_USE_ICOUNT) {
1130 gen_io_end();
1131 }
1132 }
1133
1134 static inline void gen_outs(DisasContext *s, TCGMemOp ot)
1135 {
1136 if (s->tb->cflags & CF_USE_ICOUNT) {
1137 gen_io_start();
1138 }
1139 gen_string_movl_A0_ESI(s);
1140 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1141
1142 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_EDX]);
1143 tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1144 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T0);
1145 gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
1146 gen_op_movl_T0_Dshift(ot);
1147 gen_op_add_reg_T0(s->aflag, R_ESI);
1148 gen_bpt_io(s, cpu_tmp2_i32, ot);
1149 if (s->tb->cflags & CF_USE_ICOUNT) {
1150 gen_io_end();
1151 }
1152 }
1153
1154 /* same method as Valgrind : we generate jumps to current or next
1155 instruction */
1156 #define GEN_REPZ(op) \
1157 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1158 target_ulong cur_eip, target_ulong next_eip) \
1159 { \
1160 TCGLabel *l2; \
1161 gen_update_cc_op(s); \
1162 l2 = gen_jz_ecx_string(s, next_eip); \
1163 gen_ ## op(s, ot); \
1164 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1165 /* a loop would cause two single step exceptions if ECX = 1 \
1166 before rep string_insn */ \
1167 if (s->repz_opt) \
1168 gen_op_jz_ecx(s->aflag, l2); \
1169 gen_jmp(s, cur_eip); \
1170 }
1171
1172 #define GEN_REPZ2(op) \
1173 static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
1174 target_ulong cur_eip, \
1175 target_ulong next_eip, \
1176 int nz) \
1177 { \
1178 TCGLabel *l2; \
1179 gen_update_cc_op(s); \
1180 l2 = gen_jz_ecx_string(s, next_eip); \
1181 gen_ ## op(s, ot); \
1182 gen_op_add_reg_im(s->aflag, R_ECX, -1); \
1183 gen_update_cc_op(s); \
1184 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
1185 if (s->repz_opt) \
1186 gen_op_jz_ecx(s->aflag, l2); \
1187 gen_jmp(s, cur_eip); \
1188 }
1189
1190 GEN_REPZ(movs)
1191 GEN_REPZ(stos)
1192 GEN_REPZ(lods)
1193 GEN_REPZ(ins)
1194 GEN_REPZ(outs)
1195 GEN_REPZ2(scas)
1196 GEN_REPZ2(cmps)
1197
1198 static void gen_helper_fp_arith_ST0_FT0(int op)
1199 {
1200 switch (op) {
1201 case 0:
1202 gen_helper_fadd_ST0_FT0(cpu_env);
1203 break;
1204 case 1:
1205 gen_helper_fmul_ST0_FT0(cpu_env);
1206 break;
1207 case 2:
1208 gen_helper_fcom_ST0_FT0(cpu_env);
1209 break;
1210 case 3:
1211 gen_helper_fcom_ST0_FT0(cpu_env);
1212 break;
1213 case 4:
1214 gen_helper_fsub_ST0_FT0(cpu_env);
1215 break;
1216 case 5:
1217 gen_helper_fsubr_ST0_FT0(cpu_env);
1218 break;
1219 case 6:
1220 gen_helper_fdiv_ST0_FT0(cpu_env);
1221 break;
1222 case 7:
1223 gen_helper_fdivr_ST0_FT0(cpu_env);
1224 break;
1225 }
1226 }
1227
1228 /* NOTE the exception in "r" op ordering */
1229 static void gen_helper_fp_arith_STN_ST0(int op, int opreg)
1230 {
1231 TCGv_i32 tmp = tcg_const_i32(opreg);
1232 switch (op) {
1233 case 0:
1234 gen_helper_fadd_STN_ST0(cpu_env, tmp);
1235 break;
1236 case 1:
1237 gen_helper_fmul_STN_ST0(cpu_env, tmp);
1238 break;
1239 case 4:
1240 gen_helper_fsubr_STN_ST0(cpu_env, tmp);
1241 break;
1242 case 5:
1243 gen_helper_fsub_STN_ST0(cpu_env, tmp);
1244 break;
1245 case 6:
1246 gen_helper_fdivr_STN_ST0(cpu_env, tmp);
1247 break;
1248 case 7:
1249 gen_helper_fdiv_STN_ST0(cpu_env, tmp);
1250 break;
1251 }
1252 }
1253
1254 /* if d == OR_TMP0, it means memory operand (address in A0) */
1255 static void gen_op(DisasContext *s1, int op, TCGMemOp ot, int d)
1256 {
1257 if (d != OR_TMP0) {
1258 gen_op_mov_v_reg(ot, cpu_T0, d);
1259 } else if (!(s1->prefix & PREFIX_LOCK)) {
1260 gen_op_ld_v(s1, ot, cpu_T0, cpu_A0);
1261 }
1262 switch(op) {
1263 case OP_ADCL:
1264 gen_compute_eflags_c(s1, cpu_tmp4);
1265 if (s1->prefix & PREFIX_LOCK) {
1266 tcg_gen_add_tl(cpu_T0, cpu_tmp4, cpu_T1);
1267 tcg_gen_atomic_add_fetch_tl(cpu_T0, cpu_A0, cpu_T0,
1268 s1->mem_index, ot | MO_LE);
1269 } else {
1270 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
1271 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_tmp4);
1272 gen_op_st_rm_T0_A0(s1, ot, d);
1273 }
1274 gen_op_update3_cc(cpu_tmp4);
1275 set_cc_op(s1, CC_OP_ADCB + ot);
1276 break;
1277 case OP_SBBL:
1278 gen_compute_eflags_c(s1, cpu_tmp4);
1279 if (s1->prefix & PREFIX_LOCK) {
1280 tcg_gen_add_tl(cpu_T0, cpu_T1, cpu_tmp4);
1281 tcg_gen_neg_tl(cpu_T0, cpu_T0);
1282 tcg_gen_atomic_add_fetch_tl(cpu_T0, cpu_A0, cpu_T0,
1283 s1->mem_index, ot | MO_LE);
1284 } else {
1285 tcg_gen_sub_tl(cpu_T0, cpu_T0, cpu_T1);
1286 tcg_gen_sub_tl(cpu_T0, cpu_T0, cpu_tmp4);
1287 gen_op_st_rm_T0_A0(s1, ot, d);
1288 }
1289 gen_op_update3_cc(cpu_tmp4);
1290 set_cc_op(s1, CC_OP_SBBB + ot);
1291 break;
1292 case OP_ADDL:
1293 if (s1->prefix & PREFIX_LOCK) {
1294 tcg_gen_atomic_add_fetch_tl(cpu_T0, cpu_A0, cpu_T1,
1295 s1->mem_index, ot | MO_LE);
1296 } else {
1297 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
1298 gen_op_st_rm_T0_A0(s1, ot, d);
1299 }
1300 gen_op_update2_cc();
1301 set_cc_op(s1, CC_OP_ADDB + ot);
1302 break;
1303 case OP_SUBL:
1304 if (s1->prefix & PREFIX_LOCK) {
1305 tcg_gen_neg_tl(cpu_T0, cpu_T1);
1306 tcg_gen_atomic_fetch_add_tl(cpu_cc_srcT, cpu_A0, cpu_T0,
1307 s1->mem_index, ot | MO_LE);
1308 tcg_gen_sub_tl(cpu_T0, cpu_cc_srcT, cpu_T1);
1309 } else {
1310 tcg_gen_mov_tl(cpu_cc_srcT, cpu_T0);
1311 tcg_gen_sub_tl(cpu_T0, cpu_T0, cpu_T1);
1312 gen_op_st_rm_T0_A0(s1, ot, d);
1313 }
1314 gen_op_update2_cc();
1315 set_cc_op(s1, CC_OP_SUBB + ot);
1316 break;
1317 default:
1318 case OP_ANDL:
1319 if (s1->prefix & PREFIX_LOCK) {
1320 tcg_gen_atomic_and_fetch_tl(cpu_T0, cpu_A0, cpu_T1,
1321 s1->mem_index, ot | MO_LE);
1322 } else {
1323 tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1);
1324 gen_op_st_rm_T0_A0(s1, ot, d);
1325 }
1326 gen_op_update1_cc();
1327 set_cc_op(s1, CC_OP_LOGICB + ot);
1328 break;
1329 case OP_ORL:
1330 if (s1->prefix & PREFIX_LOCK) {
1331 tcg_gen_atomic_or_fetch_tl(cpu_T0, cpu_A0, cpu_T1,
1332 s1->mem_index, ot | MO_LE);
1333 } else {
1334 tcg_gen_or_tl(cpu_T0, cpu_T0, cpu_T1);
1335 gen_op_st_rm_T0_A0(s1, ot, d);
1336 }
1337 gen_op_update1_cc();
1338 set_cc_op(s1, CC_OP_LOGICB + ot);
1339 break;
1340 case OP_XORL:
1341 if (s1->prefix & PREFIX_LOCK) {
1342 tcg_gen_atomic_xor_fetch_tl(cpu_T0, cpu_A0, cpu_T1,
1343 s1->mem_index, ot | MO_LE);
1344 } else {
1345 tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_T1);
1346 gen_op_st_rm_T0_A0(s1, ot, d);
1347 }
1348 gen_op_update1_cc();
1349 set_cc_op(s1, CC_OP_LOGICB + ot);
1350 break;
1351 case OP_CMPL:
1352 tcg_gen_mov_tl(cpu_cc_src, cpu_T1);
1353 tcg_gen_mov_tl(cpu_cc_srcT, cpu_T0);
1354 tcg_gen_sub_tl(cpu_cc_dst, cpu_T0, cpu_T1);
1355 set_cc_op(s1, CC_OP_SUBB + ot);
1356 break;
1357 }
1358 }
1359
1360 /* if d == OR_TMP0, it means memory operand (address in A0) */
1361 static void gen_inc(DisasContext *s1, TCGMemOp ot, int d, int c)
1362 {
1363 if (s1->prefix & PREFIX_LOCK) {
1364 tcg_gen_movi_tl(cpu_T0, c > 0 ? 1 : -1);
1365 tcg_gen_atomic_add_fetch_tl(cpu_T0, cpu_A0, cpu_T0,
1366 s1->mem_index, ot | MO_LE);
1367 } else {
1368 if (d != OR_TMP0) {
1369 gen_op_mov_v_reg(ot, cpu_T0, d);
1370 } else {
1371 gen_op_ld_v(s1, ot, cpu_T0, cpu_A0);
1372 }
1373 tcg_gen_addi_tl(cpu_T0, cpu_T0, (c > 0 ? 1 : -1));
1374 gen_op_st_rm_T0_A0(s1, ot, d);
1375 }
1376
1377 gen_compute_eflags_c(s1, cpu_cc_src);
1378 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
1379 set_cc_op(s1, (c > 0 ? CC_OP_INCB : CC_OP_DECB) + ot);
1380 }
1381
1382 static void gen_shift_flags(DisasContext *s, TCGMemOp ot, TCGv result,
1383 TCGv shm1, TCGv count, bool is_right)
1384 {
1385 TCGv_i32 z32, s32, oldop;
1386 TCGv z_tl;
1387
1388 /* Store the results into the CC variables. If we know that the
1389 variable must be dead, store unconditionally. Otherwise we'll
1390 need to not disrupt the current contents. */
1391 z_tl = tcg_const_tl(0);
1392 if (cc_op_live[s->cc_op] & USES_CC_DST) {
1393 tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_dst, count, z_tl,
1394 result, cpu_cc_dst);
1395 } else {
1396 tcg_gen_mov_tl(cpu_cc_dst, result);
1397 }
1398 if (cc_op_live[s->cc_op] & USES_CC_SRC) {
1399 tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_src, count, z_tl,
1400 shm1, cpu_cc_src);
1401 } else {
1402 tcg_gen_mov_tl(cpu_cc_src, shm1);
1403 }
1404 tcg_temp_free(z_tl);
1405
1406 /* Get the two potential CC_OP values into temporaries. */
1407 tcg_gen_movi_i32(cpu_tmp2_i32, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot);
1408 if (s->cc_op == CC_OP_DYNAMIC) {
1409 oldop = cpu_cc_op;
1410 } else {
1411 tcg_gen_movi_i32(cpu_tmp3_i32, s->cc_op);
1412 oldop = cpu_tmp3_i32;
1413 }
1414
1415 /* Conditionally store the CC_OP value. */
1416 z32 = tcg_const_i32(0);
1417 s32 = tcg_temp_new_i32();
1418 tcg_gen_trunc_tl_i32(s32, count);
1419 tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, s32, z32, cpu_tmp2_i32, oldop);
1420 tcg_temp_free_i32(z32);
1421 tcg_temp_free_i32(s32);
1422
1423 /* The CC_OP value is no longer predictable. */
1424 set_cc_op(s, CC_OP_DYNAMIC);
1425 }
1426
1427 static void gen_shift_rm_T1(DisasContext *s, TCGMemOp ot, int op1,
1428 int is_right, int is_arith)
1429 {
1430 target_ulong mask = (ot == MO_64 ? 0x3f : 0x1f);
1431
1432 /* load */
1433 if (op1 == OR_TMP0) {
1434 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1435 } else {
1436 gen_op_mov_v_reg(ot, cpu_T0, op1);
1437 }
1438
1439 tcg_gen_andi_tl(cpu_T1, cpu_T1, mask);
1440 tcg_gen_subi_tl(cpu_tmp0, cpu_T1, 1);
1441
1442 if (is_right) {
1443 if (is_arith) {
1444 gen_exts(ot, cpu_T0);
1445 tcg_gen_sar_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1446 tcg_gen_sar_tl(cpu_T0, cpu_T0, cpu_T1);
1447 } else {
1448 gen_extu(ot, cpu_T0);
1449 tcg_gen_shr_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1450 tcg_gen_shr_tl(cpu_T0, cpu_T0, cpu_T1);
1451 }
1452 } else {
1453 tcg_gen_shl_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1454 tcg_gen_shl_tl(cpu_T0, cpu_T0, cpu_T1);
1455 }
1456
1457 /* store */
1458 gen_op_st_rm_T0_A0(s, ot, op1);
1459
1460 gen_shift_flags(s, ot, cpu_T0, cpu_tmp0, cpu_T1, is_right);
1461 }
1462
1463 static void gen_shift_rm_im(DisasContext *s, TCGMemOp ot, int op1, int op2,
1464 int is_right, int is_arith)
1465 {
1466 int mask = (ot == MO_64 ? 0x3f : 0x1f);
1467
1468 /* load */
1469 if (op1 == OR_TMP0)
1470 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1471 else
1472 gen_op_mov_v_reg(ot, cpu_T0, op1);
1473
1474 op2 &= mask;
1475 if (op2 != 0) {
1476 if (is_right) {
1477 if (is_arith) {
1478 gen_exts(ot, cpu_T0);
1479 tcg_gen_sari_tl(cpu_tmp4, cpu_T0, op2 - 1);
1480 tcg_gen_sari_tl(cpu_T0, cpu_T0, op2);
1481 } else {
1482 gen_extu(ot, cpu_T0);
1483 tcg_gen_shri_tl(cpu_tmp4, cpu_T0, op2 - 1);
1484 tcg_gen_shri_tl(cpu_T0, cpu_T0, op2);
1485 }
1486 } else {
1487 tcg_gen_shli_tl(cpu_tmp4, cpu_T0, op2 - 1);
1488 tcg_gen_shli_tl(cpu_T0, cpu_T0, op2);
1489 }
1490 }
1491
1492 /* store */
1493 gen_op_st_rm_T0_A0(s, ot, op1);
1494
1495 /* update eflags if non zero shift */
1496 if (op2 != 0) {
1497 tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
1498 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
1499 set_cc_op(s, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot);
1500 }
1501 }
1502
1503 static void gen_rot_rm_T1(DisasContext *s, TCGMemOp ot, int op1, int is_right)
1504 {
1505 target_ulong mask = (ot == MO_64 ? 0x3f : 0x1f);
1506 TCGv_i32 t0, t1;
1507
1508 /* load */
1509 if (op1 == OR_TMP0) {
1510 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1511 } else {
1512 gen_op_mov_v_reg(ot, cpu_T0, op1);
1513 }
1514
1515 tcg_gen_andi_tl(cpu_T1, cpu_T1, mask);
1516
1517 switch (ot) {
1518 case MO_8:
1519 /* Replicate the 8-bit input so that a 32-bit rotate works. */
1520 tcg_gen_ext8u_tl(cpu_T0, cpu_T0);
1521 tcg_gen_muli_tl(cpu_T0, cpu_T0, 0x01010101);
1522 goto do_long;
1523 case MO_16:
1524 /* Replicate the 16-bit input so that a 32-bit rotate works. */
1525 tcg_gen_deposit_tl(cpu_T0, cpu_T0, cpu_T0, 16, 16);
1526 goto do_long;
1527 do_long:
1528 #ifdef TARGET_X86_64
1529 case MO_32:
1530 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
1531 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T1);
1532 if (is_right) {
1533 tcg_gen_rotr_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
1534 } else {
1535 tcg_gen_rotl_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
1536 }
1537 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
1538 break;
1539 #endif
1540 default:
1541 if (is_right) {
1542 tcg_gen_rotr_tl(cpu_T0, cpu_T0, cpu_T1);
1543 } else {
1544 tcg_gen_rotl_tl(cpu_T0, cpu_T0, cpu_T1);
1545 }
1546 break;
1547 }
1548
1549 /* store */
1550 gen_op_st_rm_T0_A0(s, ot, op1);
1551
1552 /* We'll need the flags computed into CC_SRC. */
1553 gen_compute_eflags(s);
1554
1555 /* The value that was "rotated out" is now present at the other end
1556 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1557 since we've computed the flags into CC_SRC, these variables are
1558 currently dead. */
1559 if (is_right) {
1560 tcg_gen_shri_tl(cpu_cc_src2, cpu_T0, mask - 1);
1561 tcg_gen_shri_tl(cpu_cc_dst, cpu_T0, mask);
1562 tcg_gen_andi_tl(cpu_cc_dst, cpu_cc_dst, 1);
1563 } else {
1564 tcg_gen_shri_tl(cpu_cc_src2, cpu_T0, mask);
1565 tcg_gen_andi_tl(cpu_cc_dst, cpu_T0, 1);
1566 }
1567 tcg_gen_andi_tl(cpu_cc_src2, cpu_cc_src2, 1);
1568 tcg_gen_xor_tl(cpu_cc_src2, cpu_cc_src2, cpu_cc_dst);
1569
1570 /* Now conditionally store the new CC_OP value. If the shift count
1571 is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1572 Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1573 exactly as we computed above. */
1574 t0 = tcg_const_i32(0);
1575 t1 = tcg_temp_new_i32();
1576 tcg_gen_trunc_tl_i32(t1, cpu_T1);
1577 tcg_gen_movi_i32(cpu_tmp2_i32, CC_OP_ADCOX);
1578 tcg_gen_movi_i32(cpu_tmp3_i32, CC_OP_EFLAGS);
1579 tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, t1, t0,
1580 cpu_tmp2_i32, cpu_tmp3_i32);
1581 tcg_temp_free_i32(t0);
1582 tcg_temp_free_i32(t1);
1583
1584 /* The CC_OP value is no longer predictable. */
1585 set_cc_op(s, CC_OP_DYNAMIC);
1586 }
1587
1588 static void gen_rot_rm_im(DisasContext *s, TCGMemOp ot, int op1, int op2,
1589 int is_right)
1590 {
1591 int mask = (ot == MO_64 ? 0x3f : 0x1f);
1592 int shift;
1593
1594 /* load */
1595 if (op1 == OR_TMP0) {
1596 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1597 } else {
1598 gen_op_mov_v_reg(ot, cpu_T0, op1);
1599 }
1600
1601 op2 &= mask;
1602 if (op2 != 0) {
1603 switch (ot) {
1604 #ifdef TARGET_X86_64
1605 case MO_32:
1606 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
1607 if (is_right) {
1608 tcg_gen_rotri_i32(cpu_tmp2_i32, cpu_tmp2_i32, op2);
1609 } else {
1610 tcg_gen_rotli_i32(cpu_tmp2_i32, cpu_tmp2_i32, op2);
1611 }
1612 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
1613 break;
1614 #endif
1615 default:
1616 if (is_right) {
1617 tcg_gen_rotri_tl(cpu_T0, cpu_T0, op2);
1618 } else {
1619 tcg_gen_rotli_tl(cpu_T0, cpu_T0, op2);
1620 }
1621 break;
1622 case MO_8:
1623 mask = 7;
1624 goto do_shifts;
1625 case MO_16:
1626 mask = 15;
1627 do_shifts:
1628 shift = op2 & mask;
1629 if (is_right) {
1630 shift = mask + 1 - shift;
1631 }
1632 gen_extu(ot, cpu_T0);
1633 tcg_gen_shli_tl(cpu_tmp0, cpu_T0, shift);
1634 tcg_gen_shri_tl(cpu_T0, cpu_T0, mask + 1 - shift);
1635 tcg_gen_or_tl(cpu_T0, cpu_T0, cpu_tmp0);
1636 break;
1637 }
1638 }
1639
1640 /* store */
1641 gen_op_st_rm_T0_A0(s, ot, op1);
1642
1643 if (op2 != 0) {
1644 /* Compute the flags into CC_SRC. */
1645 gen_compute_eflags(s);
1646
1647 /* The value that was "rotated out" is now present at the other end
1648 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1649 since we've computed the flags into CC_SRC, these variables are
1650 currently dead. */
1651 if (is_right) {
1652 tcg_gen_shri_tl(cpu_cc_src2, cpu_T0, mask - 1);
1653 tcg_gen_shri_tl(cpu_cc_dst, cpu_T0, mask);
1654 tcg_gen_andi_tl(cpu_cc_dst, cpu_cc_dst, 1);
1655 } else {
1656 tcg_gen_shri_tl(cpu_cc_src2, cpu_T0, mask);
1657 tcg_gen_andi_tl(cpu_cc_dst, cpu_T0, 1);
1658 }
1659 tcg_gen_andi_tl(cpu_cc_src2, cpu_cc_src2, 1);
1660 tcg_gen_xor_tl(cpu_cc_src2, cpu_cc_src2, cpu_cc_dst);
1661 set_cc_op(s, CC_OP_ADCOX);
1662 }
1663 }
1664
1665 /* XXX: add faster immediate = 1 case */
1666 static void gen_rotc_rm_T1(DisasContext *s, TCGMemOp ot, int op1,
1667 int is_right)
1668 {
1669 gen_compute_eflags(s);
1670 assert(s->cc_op == CC_OP_EFLAGS);
1671
1672 /* load */
1673 if (op1 == OR_TMP0)
1674 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1675 else
1676 gen_op_mov_v_reg(ot, cpu_T0, op1);
1677
1678 if (is_right) {
1679 switch (ot) {
1680 case MO_8:
1681 gen_helper_rcrb(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1682 break;
1683 case MO_16:
1684 gen_helper_rcrw(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1685 break;
1686 case MO_32:
1687 gen_helper_rcrl(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1688 break;
1689 #ifdef TARGET_X86_64
1690 case MO_64:
1691 gen_helper_rcrq(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1692 break;
1693 #endif
1694 default:
1695 tcg_abort();
1696 }
1697 } else {
1698 switch (ot) {
1699 case MO_8:
1700 gen_helper_rclb(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1701 break;
1702 case MO_16:
1703 gen_helper_rclw(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1704 break;
1705 case MO_32:
1706 gen_helper_rcll(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1707 break;
1708 #ifdef TARGET_X86_64
1709 case MO_64:
1710 gen_helper_rclq(cpu_T0, cpu_env, cpu_T0, cpu_T1);
1711 break;
1712 #endif
1713 default:
1714 tcg_abort();
1715 }
1716 }
1717 /* store */
1718 gen_op_st_rm_T0_A0(s, ot, op1);
1719 }
1720
1721 /* XXX: add faster immediate case */
1722 static void gen_shiftd_rm_T1(DisasContext *s, TCGMemOp ot, int op1,
1723 bool is_right, TCGv count_in)
1724 {
1725 target_ulong mask = (ot == MO_64 ? 63 : 31);
1726 TCGv count;
1727
1728 /* load */
1729 if (op1 == OR_TMP0) {
1730 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
1731 } else {
1732 gen_op_mov_v_reg(ot, cpu_T0, op1);
1733 }
1734
1735 count = tcg_temp_new();
1736 tcg_gen_andi_tl(count, count_in, mask);
1737
1738 switch (ot) {
1739 case MO_16:
1740 /* Note: we implement the Intel behaviour for shift count > 16.
1741 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A
1742 portion by constructing it as a 32-bit value. */
1743 if (is_right) {
1744 tcg_gen_deposit_tl(cpu_tmp0, cpu_T0, cpu_T1, 16, 16);
1745 tcg_gen_mov_tl(cpu_T1, cpu_T0);
1746 tcg_gen_mov_tl(cpu_T0, cpu_tmp0);
1747 } else {
1748 tcg_gen_deposit_tl(cpu_T1, cpu_T0, cpu_T1, 16, 16);
1749 }
1750 /* FALLTHRU */
1751 #ifdef TARGET_X86_64
1752 case MO_32:
1753 /* Concatenate the two 32-bit values and use a 64-bit shift. */
1754 tcg_gen_subi_tl(cpu_tmp0, count, 1);
1755 if (is_right) {
1756 tcg_gen_concat_tl_i64(cpu_T0, cpu_T0, cpu_T1);
1757 tcg_gen_shr_i64(cpu_tmp0, cpu_T0, cpu_tmp0);
1758 tcg_gen_shr_i64(cpu_T0, cpu_T0, count);
1759 } else {
1760 tcg_gen_concat_tl_i64(cpu_T0, cpu_T1, cpu_T0);
1761 tcg_gen_shl_i64(cpu_tmp0, cpu_T0, cpu_tmp0);
1762 tcg_gen_shl_i64(cpu_T0, cpu_T0, count);
1763 tcg_gen_shri_i64(cpu_tmp0, cpu_tmp0, 32);
1764 tcg_gen_shri_i64(cpu_T0, cpu_T0, 32);
1765 }
1766 break;
1767 #endif
1768 default:
1769 tcg_gen_subi_tl(cpu_tmp0, count, 1);
1770 if (is_right) {
1771 tcg_gen_shr_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1772
1773 tcg_gen_subfi_tl(cpu_tmp4, mask + 1, count);
1774 tcg_gen_shr_tl(cpu_T0, cpu_T0, count);
1775 tcg_gen_shl_tl(cpu_T1, cpu_T1, cpu_tmp4);
1776 } else {
1777 tcg_gen_shl_tl(cpu_tmp0, cpu_T0, cpu_tmp0);
1778 if (ot == MO_16) {
1779 /* Only needed if count > 16, for Intel behaviour. */
1780 tcg_gen_subfi_tl(cpu_tmp4, 33, count);
1781 tcg_gen_shr_tl(cpu_tmp4, cpu_T1, cpu_tmp4);
1782 tcg_gen_or_tl(cpu_tmp0, cpu_tmp0, cpu_tmp4);
1783 }
1784
1785 tcg_gen_subfi_tl(cpu_tmp4, mask + 1, count);
1786 tcg_gen_shl_tl(cpu_T0, cpu_T0, count);
1787 tcg_gen_shr_tl(cpu_T1, cpu_T1, cpu_tmp4);
1788 }
1789 tcg_gen_movi_tl(cpu_tmp4, 0);
1790 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_T1, count, cpu_tmp4,
1791 cpu_tmp4, cpu_T1);
1792 tcg_gen_or_tl(cpu_T0, cpu_T0, cpu_T1);
1793 break;
1794 }
1795
1796 /* store */
1797 gen_op_st_rm_T0_A0(s, ot, op1);
1798
1799 gen_shift_flags(s, ot, cpu_T0, cpu_tmp0, count, is_right);
1800 tcg_temp_free(count);
1801 }
1802
1803 static void gen_shift(DisasContext *s1, int op, TCGMemOp ot, int d, int s)
1804 {
1805 if (s != OR_TMP1)
1806 gen_op_mov_v_reg(ot, cpu_T1, s);
1807 switch(op) {
1808 case OP_ROL:
1809 gen_rot_rm_T1(s1, ot, d, 0);
1810 break;
1811 case OP_ROR:
1812 gen_rot_rm_T1(s1, ot, d, 1);
1813 break;
1814 case OP_SHL:
1815 case OP_SHL1:
1816 gen_shift_rm_T1(s1, ot, d, 0, 0);
1817 break;
1818 case OP_SHR:
1819 gen_shift_rm_T1(s1, ot, d, 1, 0);
1820 break;
1821 case OP_SAR:
1822 gen_shift_rm_T1(s1, ot, d, 1, 1);
1823 break;
1824 case OP_RCL:
1825 gen_rotc_rm_T1(s1, ot, d, 0);
1826 break;
1827 case OP_RCR:
1828 gen_rotc_rm_T1(s1, ot, d, 1);
1829 break;
1830 }
1831 }
1832
1833 static void gen_shifti(DisasContext *s1, int op, TCGMemOp ot, int d, int c)
1834 {
1835 switch(op) {
1836 case OP_ROL:
1837 gen_rot_rm_im(s1, ot, d, c, 0);
1838 break;
1839 case OP_ROR:
1840 gen_rot_rm_im(s1, ot, d, c, 1);
1841 break;
1842 case OP_SHL:
1843 case OP_SHL1:
1844 gen_shift_rm_im(s1, ot, d, c, 0, 0);
1845 break;
1846 case OP_SHR:
1847 gen_shift_rm_im(s1, ot, d, c, 1, 0);
1848 break;
1849 case OP_SAR:
1850 gen_shift_rm_im(s1, ot, d, c, 1, 1);
1851 break;
1852 default:
1853 /* currently not optimized */
1854 tcg_gen_movi_tl(cpu_T1, c);
1855 gen_shift(s1, op, ot, d, OR_TMP1);
1856 break;
1857 }
1858 }
1859
1860 /* Decompose an address. */
1861
1862 typedef struct AddressParts {
1863 int def_seg;
1864 int base;
1865 int index;
1866 int scale;
1867 target_long disp;
1868 } AddressParts;
1869
1870 static AddressParts gen_lea_modrm_0(CPUX86State *env, DisasContext *s,
1871 int modrm)
1872 {
1873 int def_seg, base, index, scale, mod, rm;
1874 target_long disp;
1875 bool havesib;
1876
1877 def_seg = R_DS;
1878 index = -1;
1879 scale = 0;
1880 disp = 0;
1881
1882 mod = (modrm >> 6) & 3;
1883 rm = modrm & 7;
1884 base = rm | REX_B(s);
1885
1886 if (mod == 3) {
1887 /* Normally filtered out earlier, but including this path
1888 simplifies multi-byte nop, as well as bndcl, bndcu, bndcn. */
1889 goto done;
1890 }
1891
1892 switch (s->aflag) {
1893 case MO_64:
1894 case MO_32:
1895 havesib = 0;
1896 if (rm == 4) {
1897 int code = cpu_ldub_code(env, s->pc++);
1898 scale = (code >> 6) & 3;
1899 index = ((code >> 3) & 7) | REX_X(s);
1900 if (index == 4) {
1901 index = -1; /* no index */
1902 }
1903 base = (code & 7) | REX_B(s);
1904 havesib = 1;
1905 }
1906
1907 switch (mod) {
1908 case 0:
1909 if ((base & 7) == 5) {
1910 base = -1;
1911 disp = (int32_t)cpu_ldl_code(env, s->pc);
1912 s->pc += 4;
1913 if (CODE64(s) && !havesib) {
1914 base = -2;
1915 disp += s->pc + s->rip_offset;
1916 }
1917 }
1918 break;
1919 case 1:
1920 disp = (int8_t)cpu_ldub_code(env, s->pc++);
1921 break;
1922 default:
1923 case 2:
1924 disp = (int32_t)cpu_ldl_code(env, s->pc);
1925 s->pc += 4;
1926 break;
1927 }
1928
1929 /* For correct popl handling with esp. */
1930 if (base == R_ESP && s->popl_esp_hack) {
1931 disp += s->popl_esp_hack;
1932 }
1933 if (base == R_EBP || base == R_ESP) {
1934 def_seg = R_SS;
1935 }
1936 break;
1937
1938 case MO_16:
1939 if (mod == 0) {
1940 if (rm == 6) {
1941 base = -1;
1942 disp = cpu_lduw_code(env, s->pc);
1943 s->pc += 2;
1944 break;
1945 }
1946 } else if (mod == 1) {
1947 disp = (int8_t)cpu_ldub_code(env, s->pc++);
1948 } else {
1949 disp = (int16_t)cpu_lduw_code(env, s->pc);
1950 s->pc += 2;
1951 }
1952
1953 switch (rm) {
1954 case 0:
1955 base = R_EBX;
1956 index = R_ESI;
1957 break;
1958 case 1:
1959 base = R_EBX;
1960 index = R_EDI;
1961 break;
1962 case 2:
1963 base = R_EBP;
1964 index = R_ESI;
1965 def_seg = R_SS;
1966 break;
1967 case 3:
1968 base = R_EBP;
1969 index = R_EDI;
1970 def_seg = R_SS;
1971 break;
1972 case 4:
1973 base = R_ESI;
1974 break;
1975 case 5:
1976 base = R_EDI;
1977 break;
1978 case 6:
1979 base = R_EBP;
1980 def_seg = R_SS;
1981 break;
1982 default:
1983 case 7:
1984 base = R_EBX;
1985 break;
1986 }
1987 break;
1988
1989 default:
1990 tcg_abort();
1991 }
1992
1993 done:
1994 return (AddressParts){ def_seg, base, index, scale, disp };
1995 }
1996
1997 /* Compute the address, with a minimum number of TCG ops. */
1998 static TCGv gen_lea_modrm_1(AddressParts a)
1999 {
2000 TCGv ea;
2001
2002 TCGV_UNUSED(ea);
2003 if (a.index >= 0) {
2004 if (a.scale == 0) {
2005 ea = cpu_regs[a.index];
2006 } else {
2007 tcg_gen_shli_tl(cpu_A0, cpu_regs[a.index], a.scale);
2008 ea = cpu_A0;
2009 }
2010 if (a.base >= 0) {
2011 tcg_gen_add_tl(cpu_A0, ea, cpu_regs[a.base]);
2012 ea = cpu_A0;
2013 }
2014 } else if (a.base >= 0) {
2015 ea = cpu_regs[a.base];
2016 }
2017 if (TCGV_IS_UNUSED(ea)) {
2018 tcg_gen_movi_tl(cpu_A0, a.disp);
2019 ea = cpu_A0;
2020 } else if (a.disp != 0) {
2021 tcg_gen_addi_tl(cpu_A0, ea, a.disp);
2022 ea = cpu_A0;
2023 }
2024
2025 return ea;
2026 }
2027
2028 static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm)
2029 {
2030 AddressParts a = gen_lea_modrm_0(env, s, modrm);
2031 TCGv ea = gen_lea_modrm_1(a);
2032 gen_lea_v_seg(s, s->aflag, ea, a.def_seg, s->override);
2033 }
2034
2035 static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm)
2036 {
2037 (void)gen_lea_modrm_0(env, s, modrm);
2038 }
2039
2040 /* Used for BNDCL, BNDCU, BNDCN. */
2041 static void gen_bndck(CPUX86State *env, DisasContext *s, int modrm,
2042 TCGCond cond, TCGv_i64 bndv)
2043 {
2044 TCGv ea = gen_lea_modrm_1(gen_lea_modrm_0(env, s, modrm));
2045
2046 tcg_gen_extu_tl_i64(cpu_tmp1_i64, ea);
2047 if (!CODE64(s)) {
2048 tcg_gen_ext32u_i64(cpu_tmp1_i64, cpu_tmp1_i64);
2049 }
2050 tcg_gen_setcond_i64(cond, cpu_tmp1_i64, cpu_tmp1_i64, bndv);
2051 tcg_gen_extrl_i64_i32(cpu_tmp2_i32, cpu_tmp1_i64);
2052 gen_helper_bndck(cpu_env, cpu_tmp2_i32);
2053 }
2054
2055 /* used for LEA and MOV AX, mem */
2056 static void gen_add_A0_ds_seg(DisasContext *s)
2057 {
2058 gen_lea_v_seg(s, s->aflag, cpu_A0, R_DS, s->override);
2059 }
2060
2061 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2062 OR_TMP0 */
2063 static void gen_ldst_modrm(CPUX86State *env, DisasContext *s, int modrm,
2064 TCGMemOp ot, int reg, int is_store)
2065 {
2066 int mod, rm;
2067
2068 mod = (modrm >> 6) & 3;
2069 rm = (modrm & 7) | REX_B(s);
2070 if (mod == 3) {
2071 if (is_store) {
2072 if (reg != OR_TMP0)
2073 gen_op_mov_v_reg(ot, cpu_T0, reg);
2074 gen_op_mov_reg_v(ot, rm, cpu_T0);
2075 } else {
2076 gen_op_mov_v_reg(ot, cpu_T0, rm);
2077 if (reg != OR_TMP0)
2078 gen_op_mov_reg_v(ot, reg, cpu_T0);
2079 }
2080 } else {
2081 gen_lea_modrm(env, s, modrm);
2082 if (is_store) {
2083 if (reg != OR_TMP0)
2084 gen_op_mov_v_reg(ot, cpu_T0, reg);
2085 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
2086 } else {
2087 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
2088 if (reg != OR_TMP0)
2089 gen_op_mov_reg_v(ot, reg, cpu_T0);
2090 }
2091 }
2092 }
2093
2094 static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, TCGMemOp ot)
2095 {
2096 uint32_t ret;
2097
2098 switch (ot) {
2099 case MO_8:
2100 ret = cpu_ldub_code(env, s->pc);
2101 s->pc++;
2102 break;
2103 case MO_16:
2104 ret = cpu_lduw_code(env, s->pc);
2105 s->pc += 2;
2106 break;
2107 case MO_32:
2108 #ifdef TARGET_X86_64
2109 case MO_64:
2110 #endif
2111 ret = cpu_ldl_code(env, s->pc);
2112 s->pc += 4;
2113 break;
2114 default:
2115 tcg_abort();
2116 }
2117 return ret;
2118 }
2119
2120 static inline int insn_const_size(TCGMemOp ot)
2121 {
2122 if (ot <= MO_32) {
2123 return 1 << ot;
2124 } else {
2125 return 4;
2126 }
2127 }
2128
2129 static inline bool use_goto_tb(DisasContext *s, target_ulong pc)
2130 {
2131 #ifndef CONFIG_USER_ONLY
2132 return (pc & TARGET_PAGE_MASK) == (s->tb->pc & TARGET_PAGE_MASK) ||
2133 (pc & TARGET_PAGE_MASK) == (s->pc_start & TARGET_PAGE_MASK);
2134 #else
2135 return true;
2136 #endif
2137 }
2138
2139 static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
2140 {
2141 target_ulong pc = s->cs_base + eip;
2142
2143 if (use_goto_tb(s, pc)) {
2144 /* jump to same page: we can use a direct jump */
2145 tcg_gen_goto_tb(tb_num);
2146 gen_jmp_im(eip);
2147 tcg_gen_exit_tb((uintptr_t)s->tb + tb_num);
2148 } else {
2149 /* jump to another page: currently not optimized */
2150 gen_jmp_im(eip);
2151 gen_eob(s);
2152 }
2153 }
2154
2155 static inline void gen_jcc(DisasContext *s, int b,
2156 target_ulong val, target_ulong next_eip)
2157 {
2158 TCGLabel *l1, *l2;
2159
2160 if (s->jmp_opt) {
2161 l1 = gen_new_label();
2162 gen_jcc1(s, b, l1);
2163
2164 gen_goto_tb(s, 0, next_eip);
2165
2166 gen_set_label(l1);
2167 gen_goto_tb(s, 1, val);
2168 s->is_jmp = DISAS_TB_JUMP;
2169 } else {
2170 l1 = gen_new_label();
2171 l2 = gen_new_label();
2172 gen_jcc1(s, b, l1);
2173
2174 gen_jmp_im(next_eip);
2175 tcg_gen_br(l2);
2176
2177 gen_set_label(l1);
2178 gen_jmp_im(val);
2179 gen_set_label(l2);
2180 gen_eob(s);
2181 }
2182 }
2183
2184 static void gen_cmovcc1(CPUX86State *env, DisasContext *s, TCGMemOp ot, int b,
2185 int modrm, int reg)
2186 {
2187 CCPrepare cc;
2188
2189 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
2190
2191 cc = gen_prepare_cc(s, b, cpu_T1);
2192 if (cc.mask != -1) {
2193 TCGv t0 = tcg_temp_new();
2194 tcg_gen_andi_tl(t0, cc.reg, cc.mask);
2195 cc.reg = t0;
2196 }
2197 if (!cc.use_reg2) {
2198 cc.reg2 = tcg_const_tl(cc.imm);
2199 }
2200
2201 tcg_gen_movcond_tl(cc.cond, cpu_T0, cc.reg, cc.reg2,
2202 cpu_T0, cpu_regs[reg]);
2203 gen_op_mov_reg_v(ot, reg, cpu_T0);
2204
2205 if (cc.mask != -1) {
2206 tcg_temp_free(cc.reg);
2207 }
2208 if (!cc.use_reg2) {
2209 tcg_temp_free(cc.reg2);
2210 }
2211 }
2212
2213 static inline void gen_op_movl_T0_seg(int seg_reg)
2214 {
2215 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
2216 offsetof(CPUX86State,segs[seg_reg].selector));
2217 }
2218
2219 static inline void gen_op_movl_seg_T0_vm(int seg_reg)
2220 {
2221 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
2222 tcg_gen_st32_tl(cpu_T0, cpu_env,
2223 offsetof(CPUX86State,segs[seg_reg].selector));
2224 tcg_gen_shli_tl(cpu_seg_base[seg_reg], cpu_T0, 4);
2225 }
2226
2227 /* move T0 to seg_reg and compute if the CPU state may change. Never
2228 call this function with seg_reg == R_CS */
2229 static void gen_movl_seg_T0(DisasContext *s, int seg_reg)
2230 {
2231 if (s->pe && !s->vm86) {
2232 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
2233 gen_helper_load_seg(cpu_env, tcg_const_i32(seg_reg), cpu_tmp2_i32);
2234 /* abort translation because the addseg value may change or
2235 because ss32 may change. For R_SS, translation must always
2236 stop as a special handling must be done to disable hardware
2237 interrupts for the next instruction */
2238 if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS))
2239 s->is_jmp = DISAS_TB_JUMP;
2240 } else {
2241 gen_op_movl_seg_T0_vm(seg_reg);
2242 if (seg_reg == R_SS)
2243 s->is_jmp = DISAS_TB_JUMP;
2244 }
2245 }
2246
2247 static inline int svm_is_rep(int prefixes)
2248 {
2249 return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0);
2250 }
2251
2252 static inline void
2253 gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
2254 uint32_t type, uint64_t param)
2255 {
2256 /* no SVM activated; fast case */
2257 if (likely(!(s->flags & HF_SVMI_MASK)))
2258 return;
2259 gen_update_cc_op(s);
2260 gen_jmp_im(pc_start - s->cs_base);
2261 gen_helper_svm_check_intercept_param(cpu_env, tcg_const_i32(type),
2262 tcg_const_i64(param));
2263 }
2264
2265 static inline void
2266 gen_svm_check_intercept(DisasContext *s, target_ulong pc_start, uint64_t type)
2267 {
2268 gen_svm_check_intercept_param(s, pc_start, type, 0);
2269 }
2270
2271 static inline void gen_stack_update(DisasContext *s, int addend)
2272 {
2273 gen_op_add_reg_im(mo_stacksize(s), R_ESP, addend);
2274 }
2275
2276 /* Generate a push. It depends on ss32, addseg and dflag. */
2277 static void gen_push_v(DisasContext *s, TCGv val)
2278 {
2279 TCGMemOp d_ot = mo_pushpop(s, s->dflag);
2280 TCGMemOp a_ot = mo_stacksize(s);
2281 int size = 1 << d_ot;
2282 TCGv new_esp = cpu_A0;
2283
2284 tcg_gen_subi_tl(cpu_A0, cpu_regs[R_ESP], size);
2285
2286 if (!CODE64(s)) {
2287 if (s->addseg) {
2288 new_esp = cpu_tmp4;
2289 tcg_gen_mov_tl(new_esp, cpu_A0);
2290 }
2291 gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1);
2292 }
2293
2294 gen_op_st_v(s, d_ot, val, cpu_A0);
2295 gen_op_mov_reg_v(a_ot, R_ESP, new_esp);
2296 }
2297
2298 /* two step pop is necessary for precise exceptions */
2299 static TCGMemOp gen_pop_T0(DisasContext *s)
2300 {
2301 TCGMemOp d_ot = mo_pushpop(s, s->dflag);
2302
2303 gen_lea_v_seg(s, mo_stacksize(s), cpu_regs[R_ESP], R_SS, -1);
2304 gen_op_ld_v(s, d_ot, cpu_T0, cpu_A0);
2305
2306 return d_ot;
2307 }
2308
2309 static inline void gen_pop_update(DisasContext *s, TCGMemOp ot)
2310 {
2311 gen_stack_update(s, 1 << ot);
2312 }
2313
2314 static inline void gen_stack_A0(DisasContext *s)
2315 {
2316 gen_lea_v_seg(s, s->ss32 ? MO_32 : MO_16, cpu_regs[R_ESP], R_SS, -1);
2317 }
2318
2319 static void gen_pusha(DisasContext *s)
2320 {
2321 TCGMemOp s_ot = s->ss32 ? MO_32 : MO_16;
2322 TCGMemOp d_ot = s->dflag;
2323 int size = 1 << d_ot;
2324 int i;
2325
2326 for (i = 0; i < 8; i++) {
2327 tcg_gen_addi_tl(cpu_A0, cpu_regs[R_ESP], (i - 8) * size);
2328 gen_lea_v_seg(s, s_ot, cpu_A0, R_SS, -1);
2329 gen_op_st_v(s, d_ot, cpu_regs[7 - i], cpu_A0);
2330 }
2331
2332 gen_stack_update(s, -8 * size);
2333 }
2334
2335 static void gen_popa(DisasContext *s)
2336 {
2337 TCGMemOp s_ot = s->ss32 ? MO_32 : MO_16;
2338 TCGMemOp d_ot = s->dflag;
2339 int size = 1 << d_ot;
2340 int i;
2341
2342 for (i = 0; i < 8; i++) {
2343 /* ESP is not reloaded */
2344 if (7 - i == R_ESP) {
2345 continue;
2346 }
2347 tcg_gen_addi_tl(cpu_A0, cpu_regs[R_ESP], i * size);
2348 gen_lea_v_seg(s, s_ot, cpu_A0, R_SS, -1);
2349 gen_op_ld_v(s, d_ot, cpu_T0, cpu_A0);
2350 gen_op_mov_reg_v(d_ot, 7 - i, cpu_T0);
2351 }
2352
2353 gen_stack_update(s, 8 * size);
2354 }
2355
2356 static void gen_enter(DisasContext *s, int esp_addend, int level)
2357 {
2358 TCGMemOp d_ot = mo_pushpop(s, s->dflag);
2359 TCGMemOp a_ot = CODE64(s) ? MO_64 : s->ss32 ? MO_32 : MO_16;
2360 int size = 1 << d_ot;
2361
2362 /* Push BP; compute FrameTemp into T1. */
2363 tcg_gen_subi_tl(cpu_T1, cpu_regs[R_ESP], size);
2364 gen_lea_v_seg(s, a_ot, cpu_T1, R_SS, -1);
2365 gen_op_st_v(s, d_ot, cpu_regs[R_EBP], cpu_A0);
2366
2367 level &= 31;
2368 if (level != 0) {
2369 int i;
2370
2371 /* Copy level-1 pointers from the previous frame. */
2372 for (i = 1; i < level; ++i) {
2373 tcg_gen_subi_tl(cpu_A0, cpu_regs[R_EBP], size * i);
2374 gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1);
2375 gen_op_ld_v(s, d_ot, cpu_tmp0, cpu_A0);
2376
2377 tcg_gen_subi_tl(cpu_A0, cpu_T1, size * i);
2378 gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1);
2379 gen_op_st_v(s, d_ot, cpu_tmp0, cpu_A0);
2380 }
2381
2382 /* Push the current FrameTemp as the last level. */
2383 tcg_gen_subi_tl(cpu_A0, cpu_T1, size * level);
2384 gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1);
2385 gen_op_st_v(s, d_ot, cpu_T1, cpu_A0);
2386 }
2387
2388 /* Copy the FrameTemp value to EBP. */
2389 gen_op_mov_reg_v(a_ot, R_EBP, cpu_T1);
2390
2391 /* Compute the final value of ESP. */
2392 tcg_gen_subi_tl(cpu_T1, cpu_T1, esp_addend + size * level);
2393 gen_op_mov_reg_v(a_ot, R_ESP, cpu_T1);
2394 }
2395
2396 static void gen_leave(DisasContext *s)
2397 {
2398 TCGMemOp d_ot = mo_pushpop(s, s->dflag);
2399 TCGMemOp a_ot = mo_stacksize(s);
2400
2401 gen_lea_v_seg(s, a_ot, cpu_regs[R_EBP], R_SS, -1);
2402 gen_op_ld_v(s, d_ot, cpu_T0, cpu_A0);
2403
2404 tcg_gen_addi_tl(cpu_T1, cpu_regs[R_EBP], 1 << d_ot);
2405
2406 gen_op_mov_reg_v(d_ot, R_EBP, cpu_T0);
2407 gen_op_mov_reg_v(a_ot, R_ESP, cpu_T1);
2408 }
2409
2410 static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
2411 {
2412 gen_update_cc_op(s);
2413 gen_jmp_im(cur_eip);
2414 gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno));
2415 s->is_jmp = DISAS_TB_JUMP;
2416 }
2417
2418 /* Generate #UD for the current instruction. The assumption here is that
2419 the instruction is known, but it isn't allowed in the current cpu mode. */
2420 static void gen_illegal_opcode(DisasContext *s)
2421 {
2422 gen_exception(s, EXCP06_ILLOP, s->pc_start - s->cs_base);
2423 }
2424
2425 /* Similarly, except that the assumption here is that we don't decode
2426 the instruction at all -- either a missing opcode, an unimplemented
2427 feature, or just a bogus instruction stream. */
2428 static void gen_unknown_opcode(CPUX86State *env, DisasContext *s)
2429 {
2430 gen_illegal_opcode(s);
2431
2432 if (qemu_loglevel_mask(LOG_UNIMP)) {
2433 target_ulong pc = s->pc_start, end = s->pc;
2434 qemu_log_lock();
2435 qemu_log("ILLOPC: " TARGET_FMT_lx ":", pc);
2436 for (; pc < end; ++pc) {
2437 qemu_log(" %02x", cpu_ldub_code(env, pc));
2438 }
2439 qemu_log("\n");
2440 qemu_log_unlock();
2441 }
2442 }
2443
2444 /* an interrupt is different from an exception because of the
2445 privilege checks */
2446 static void gen_interrupt(DisasContext *s, int intno,
2447 target_ulong cur_eip, target_ulong next_eip)
2448 {
2449 gen_update_cc_op(s);
2450 gen_jmp_im(cur_eip);
2451 gen_helper_raise_interrupt(cpu_env, tcg_const_i32(intno),
2452 tcg_const_i32(next_eip - cur_eip));
2453 s->is_jmp = DISAS_TB_JUMP;
2454 }
2455
2456 static void gen_debug(DisasContext *s, target_ulong cur_eip)
2457 {
2458 gen_update_cc_op(s);
2459 gen_jmp_im(cur_eip);
2460 gen_helper_debug(cpu_env);
2461 s->is_jmp = DISAS_TB_JUMP;
2462 }
2463
2464 static void gen_set_hflag(DisasContext *s, uint32_t mask)
2465 {
2466 if ((s->flags & mask) == 0) {
2467 TCGv_i32 t = tcg_temp_new_i32();
2468 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2469 tcg_gen_ori_i32(t, t, mask);
2470 tcg_gen_st_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2471 tcg_temp_free_i32(t);
2472 s->flags |= mask;
2473 }
2474 }
2475
2476 static void gen_reset_hflag(DisasContext *s, uint32_t mask)
2477 {
2478 if (s->flags & mask) {
2479 TCGv_i32 t = tcg_temp_new_i32();
2480 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2481 tcg_gen_andi_i32(t, t, ~mask);
2482 tcg_gen_st_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2483 tcg_temp_free_i32(t);
2484 s->flags &= ~mask;
2485 }
2486 }
2487
2488 /* Clear BND registers during legacy branches. */
2489 static void gen_bnd_jmp(DisasContext *s)
2490 {
2491 /* Clear the registers only if BND prefix is missing, MPX is enabled,
2492 and if the BNDREGs are known to be in use (non-zero) already.
2493 The helper itself will check BNDPRESERVE at runtime. */
2494 if ((s->prefix & PREFIX_REPNZ) == 0
2495 && (s->flags & HF_MPX_EN_MASK) != 0
2496 && (s->flags & HF_MPX_IU_MASK) != 0) {
2497 gen_helper_bnd_jmp(cpu_env);
2498 }
2499 }
2500
2501 /* Generate an end of block. Trace exception is also generated if needed.
2502 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set.
2503 If RECHECK_TF, emit a rechecking helper for #DB, ignoring the state of
2504 S->TF. This is used by the syscall/sysret insns. */
2505 static void gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf)
2506 {
2507 gen_update_cc_op(s);
2508
2509 /* If several instructions disable interrupts, only the first does it. */
2510 if (inhibit && !(s->flags & HF_INHIBIT_IRQ_MASK)) {
2511 gen_set_hflag(s, HF_INHIBIT_IRQ_MASK);
2512 } else {
2513 gen_reset_hflag(s, HF_INHIBIT_IRQ_MASK);
2514 }
2515
2516 if (s->tb->flags & HF_RF_MASK) {
2517 gen_helper_reset_rf(cpu_env);
2518 }
2519 if (s->singlestep_enabled) {
2520 gen_helper_debug(cpu_env);
2521 } else if (recheck_tf) {
2522 gen_helper_rechecking_single_step(cpu_env);
2523 tcg_gen_exit_tb(0);
2524 } else if (s->tf) {
2525 gen_helper_single_step(cpu_env);
2526 } else {
2527 tcg_gen_exit_tb(0);
2528 }
2529 s->is_jmp = DISAS_TB_JUMP;
2530 }
2531
2532 /* End of block.
2533 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set. */
2534 static void gen_eob_inhibit_irq(DisasContext *s, bool inhibit)
2535 {
2536 gen_eob_worker(s, inhibit, false);
2537 }
2538
2539 /* End of block, resetting the inhibit irq flag. */
2540 static void gen_eob(DisasContext *s)
2541 {
2542 gen_eob_worker(s, false, false);
2543 }
2544
2545 /* generate a jump to eip. No segment change must happen before as a
2546 direct call to the next block may occur */
2547 static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
2548 {
2549 gen_update_cc_op(s);
2550 set_cc_op(s, CC_OP_DYNAMIC);
2551 if (s->jmp_opt) {
2552 gen_goto_tb(s, tb_num, eip);
2553 s->is_jmp = DISAS_TB_JUMP;
2554 } else {
2555 gen_jmp_im(eip);
2556 gen_eob(s);
2557 }
2558 }
2559
2560 static void gen_jmp(DisasContext *s, target_ulong eip)
2561 {
2562 gen_jmp_tb(s, eip, 0);
2563 }
2564
2565 static inline void gen_ldq_env_A0(DisasContext *s, int offset)
2566 {
2567 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
2568 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset);
2569 }
2570
2571 static inline void gen_stq_env_A0(DisasContext *s, int offset)
2572 {
2573 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset);
2574 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
2575 }
2576
2577 static inline void gen_ldo_env_A0(DisasContext *s, int offset)
2578 {
2579 int mem_index = s->mem_index;
2580 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, mem_index, MO_LEQ);
2581 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(0)));
2582 tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2583 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_tmp0, mem_index, MO_LEQ);
2584 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(1)));
2585 }
2586
2587 static inline void gen_sto_env_A0(DisasContext *s, int offset)
2588 {
2589 int mem_index = s->mem_index;
2590 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(0)));
2591 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, mem_index, MO_LEQ);
2592 tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2593 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(1)));
2594 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_tmp0, mem_index, MO_LEQ);
2595 }
2596
2597 static inline void gen_op_movo(int d_offset, int s_offset)
2598 {
2599 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + offsetof(ZMMReg, ZMM_Q(0)));
2600 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + offsetof(ZMMReg, ZMM_Q(0)));
2601 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + offsetof(ZMMReg, ZMM_Q(1)));
2602 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + offsetof(ZMMReg, ZMM_Q(1)));
2603 }
2604
2605 static inline void gen_op_movq(int d_offset, int s_offset)
2606 {
2607 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
2608 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2609 }
2610
2611 static inline void gen_op_movl(int d_offset, int s_offset)
2612 {
2613 tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env, s_offset);
2614 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, d_offset);
2615 }
2616
2617 static inline void gen_op_movq_env_0(int d_offset)
2618 {
2619 tcg_gen_movi_i64(cpu_tmp1_i64, 0);
2620 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
2621 }
2622
2623 typedef void (*SSEFunc_i_ep)(TCGv_i32 val, TCGv_ptr env, TCGv_ptr reg);
2624 typedef void (*SSEFunc_l_ep)(TCGv_i64 val, TCGv_ptr env, TCGv_ptr reg);
2625 typedef void (*SSEFunc_0_epi)(TCGv_ptr env, TCGv_ptr reg, TCGv_i32 val);
2626 typedef void (*SSEFunc_0_epl)(TCGv_ptr env, TCGv_ptr reg, TCGv_i64 val);
2627 typedef void (*SSEFunc_0_epp)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b);
2628 typedef void (*SSEFunc_0_eppi)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2629 TCGv_i32 val);
2630 typedef void (*SSEFunc_0_ppi)(TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv_i32 val);
2631 typedef void (*SSEFunc_0_eppt)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2632 TCGv val);
2633
2634 #define SSE_SPECIAL ((void *)1)
2635 #define SSE_DUMMY ((void *)2)
2636
2637 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2638 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2639 gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2640
2641 static const SSEFunc_0_epp sse_op_table1[256][4] = {
2642 /* 3DNow! extensions */
2643 [0x0e] = { SSE_DUMMY }, /* femms */
2644 [0x0f] = { SSE_DUMMY }, /* pf... */
2645 /* pure SSE operations */
2646 [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2647 [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2648 [0x12] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd, movsldup, movddup */
2649 [0x13] = { SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd */
2650 [0x14] = { gen_helper_punpckldq_xmm, gen_helper_punpcklqdq_xmm },
2651 [0x15] = { gen_helper_punpckhdq_xmm, gen_helper_punpckhqdq_xmm },
2652 [0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movhps, movhpd, movshdup */
2653 [0x17] = { SSE_SPECIAL, SSE_SPECIAL }, /* movhps, movhpd */
2654
2655 [0x28] = { SSE_SPECIAL, SSE_SPECIAL }, /* movaps, movapd */
2656 [0x29] = { SSE_SPECIAL, SSE_SPECIAL }, /* movaps, movapd */
2657 [0x2a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2658 [0x2b] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movntps, movntpd, movntss, movntsd */
2659 [0x2c] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2660 [0x2d] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2661 [0x2e] = { gen_helper_ucomiss, gen_helper_ucomisd },
2662 [0x2f] = { gen_helper_comiss, gen_helper_comisd },
2663 [0x50] = { SSE_SPECIAL, SSE_SPECIAL }, /* movmskps, movmskpd */
2664 [0x51] = SSE_FOP(sqrt),
2665 [0x52] = { gen_helper_rsqrtps, NULL, gen_helper_rsqrtss, NULL },
2666 [0x53] = { gen_helper_rcpps, NULL, gen_helper_rcpss, NULL },
2667 [0x54] = { gen_helper_pand_xmm, gen_helper_pand_xmm }, /* andps, andpd */
2668 [0x55] = { gen_helper_pandn_xmm, gen_helper_pandn_xmm }, /* andnps, andnpd */
2669 [0x56] = { gen_helper_por_xmm, gen_helper_por_xmm }, /* orps, orpd */
2670 [0x57] = { gen_helper_pxor_xmm, gen_helper_pxor_xmm }, /* xorps, xorpd */
2671 [0x58] = SSE_FOP(add),
2672 [0x59] = SSE_FOP(mul),
2673 [0x5a] = { gen_helper_cvtps2pd, gen_helper_cvtpd2ps,
2674 gen_helper_cvtss2sd, gen_helper_cvtsd2ss },
2675 [0x5b] = { gen_helper_cvtdq2ps, gen_helper_cvtps2dq, gen_helper_cvttps2dq },
2676 [0x5c] = SSE_FOP(sub),
2677 [0x5d] = SSE_FOP(min),
2678 [0x5e] = SSE_FOP(div),
2679 [0x5f] = SSE_FOP(max),
2680
2681 [0xc2] = SSE_FOP(cmpeq),
2682 [0xc6] = { (SSEFunc_0_epp)gen_helper_shufps,
2683 (SSEFunc_0_epp)gen_helper_shufpd }, /* XXX: casts */
2684
2685 /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX. */
2686 [0x38] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2687 [0x3a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2688
2689 /* MMX ops and their SSE extensions */
2690 [0x60] = MMX_OP2(punpcklbw),
2691 [0x61] = MMX_OP2(punpcklwd),
2692 [0x62] = MMX_OP2(punpckldq),
2693 [0x63] = MMX_OP2(packsswb),
2694 [0x64] = MMX_OP2(pcmpgtb),
2695 [0x65] = MMX_OP2(pcmpgtw),
2696 [0x66] = MMX_OP2(pcmpgtl),
2697 [0x67] = MMX_OP2(packuswb),
2698 [0x68] = MMX_OP2(punpckhbw),
2699 [0x69] = MMX_OP2(punpckhwd),
2700 [0x6a] = MMX_OP2(punpckhdq),
2701 [0x6b] = MMX_OP2(packssdw),
2702 [0x6c] = { NULL, gen_helper_punpcklqdq_xmm },
2703 [0x6d] = { NULL, gen_helper_punpckhqdq_xmm },
2704 [0x6e] = { SSE_SPECIAL, SSE_SPECIAL }, /* movd mm, ea */
2705 [0x6f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, , movqdu */
2706 [0x70] = { (SSEFunc_0_epp)gen_helper_pshufw_mmx,
2707 (SSEFunc_0_epp)gen_helper_pshufd_xmm,
2708 (SSEFunc_0_epp)gen_helper_pshufhw_xmm,
2709 (SSEFunc_0_epp)gen_helper_pshuflw_xmm }, /* XXX: casts */
2710 [0x71] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftw */
2711 [0x72] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftd */
2712 [0x73] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftq */
2713 [0x74] = MMX_OP2(pcmpeqb),
2714 [0x75] = MMX_OP2(pcmpeqw),
2715 [0x76] = MMX_OP2(pcmpeql),
2716 [0x77] = { SSE_DUMMY }, /* emms */
2717 [0x78] = { NULL, SSE_SPECIAL, NULL, SSE_SPECIAL }, /* extrq_i, insertq_i */
2718 [0x79] = { NULL, gen_helper_extrq_r, NULL, gen_helper_insertq_r },
2719 [0x7c] = { NULL, gen_helper_haddpd, NULL, gen_helper_haddps },
2720 [0x7d] = { NULL, gen_helper_hsubpd, NULL, gen_helper_hsubps },
2721 [0x7e] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movd, movd, , movq */
2722 [0x7f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, movdqu */
2723 [0xc4] = { SSE_SPECIAL, SSE_SPECIAL }, /* pinsrw */
2724 [0xc5] = { SSE_SPECIAL, SSE_SPECIAL }, /* pextrw */
2725 [0xd0] = { NULL, gen_helper_addsubpd, NULL, gen_helper_addsubps },
2726 [0xd1] = MMX_OP2(psrlw),
2727 [0xd2] = MMX_OP2(psrld),
2728 [0xd3] = MMX_OP2(psrlq),
2729 [0xd4] = MMX_OP2(paddq),
2730 [0xd5] = MMX_OP2(pmullw),
2731 [0xd6] = { NULL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2732 [0xd7] = { SSE_SPECIAL, SSE_SPECIAL }, /* pmovmskb */
2733 [0xd8] = MMX_OP2(psubusb),
2734 [0xd9] = MMX_OP2(psubusw),
2735 [0xda] = MMX_OP2(pminub),
2736 [0xdb] = MMX_OP2(pand),
2737 [0xdc] = MMX_OP2(paddusb),
2738 [0xdd] = MMX_OP2(paddusw),
2739 [0xde] = MMX_OP2(pmaxub),
2740 [0xdf] = MMX_OP2(pandn),
2741 [0xe0] = MMX_OP2(pavgb),
2742 [0xe1] = MMX_OP2(psraw),
2743 [0xe2] = MMX_OP2(psrad),
2744 [0xe3] = MMX_OP2(pavgw),
2745 [0xe4] = MMX_OP2(pmulhuw),
2746 [0xe5] = MMX_OP2(pmulhw),
2747 [0xe6] = { NULL, gen_helper_cvttpd2dq, gen_helper_cvtdq2pd, gen_helper_cvtpd2dq },
2748 [0xe7] = { SSE_SPECIAL , SSE_SPECIAL }, /* movntq, movntq */
2749 [0xe8] = MMX_OP2(psubsb),
2750 [0xe9] = MMX_OP2(psubsw),
2751 [0xea] = MMX_OP2(pminsw),
2752 [0xeb] = MMX_OP2(por),
2753 [0xec] = MMX_OP2(paddsb),
2754 [0xed] = MMX_OP2(paddsw),
2755 [0xee] = MMX_OP2(pmaxsw),
2756 [0xef] = MMX_OP2(pxor),
2757 [0xf0] = { NULL, NULL, NULL, SSE_SPECIAL }, /* lddqu */
2758 [0xf1] = MMX_OP2(psllw),
2759 [0xf2] = MMX_OP2(pslld),
2760 [0xf3] = MMX_OP2(psllq),
2761 [0xf4] = MMX_OP2(pmuludq),
2762 [0xf5] = MMX_OP2(pmaddwd),
2763 [0xf6] = MMX_OP2(psadbw),
2764 [0xf7] = { (SSEFunc_0_epp)gen_helper_maskmov_mmx,
2765 (SSEFunc_0_epp)gen_helper_maskmov_xmm }, /* XXX: casts */
2766 [0xf8] = MMX_OP2(psubb),
2767 [0xf9] = MMX_OP2(psubw),
2768 [0xfa] = MMX_OP2(psubl),
2769 [0xfb] = MMX_OP2(psubq),
2770 [0xfc] = MMX_OP2(paddb),
2771 [0xfd] = MMX_OP2(paddw),
2772 [0xfe] = MMX_OP2(paddl),
2773 };
2774
2775 static const SSEFunc_0_epp sse_op_table2[3 * 8][2] = {
2776 [0 + 2] = MMX_OP2(psrlw),
2777 [0 + 4] = MMX_OP2(psraw),
2778 [0 + 6] = MMX_OP2(psllw),
2779 [8 + 2] = MMX_OP2(psrld),
2780 [8 + 4] = MMX_OP2(psrad),
2781 [8 + 6] = MMX_OP2(pslld),
2782 [16 + 2] = MMX_OP2(psrlq),
2783 [16 + 3] = { NULL, gen_helper_psrldq_xmm },
2784 [16 + 6] = MMX_OP2(psllq),
2785 [16 + 7] = { NULL, gen_helper_pslldq_xmm },
2786 };
2787
2788 static const SSEFunc_0_epi sse_op_table3ai[] = {
2789 gen_helper_cvtsi2ss,
2790 gen_helper_cvtsi2sd
2791 };
2792
2793 #ifdef TARGET_X86_64
2794 static const SSEFunc_0_epl sse_op_table3aq[] = {
2795 gen_helper_cvtsq2ss,
2796 gen_helper_cvtsq2sd
2797 };
2798 #endif
2799
2800 static const SSEFunc_i_ep sse_op_table3bi[] = {
2801 gen_helper_cvttss2si,
2802 gen_helper_cvtss2si,
2803 gen_helper_cvttsd2si,
2804 gen_helper_cvtsd2si
2805 };
2806
2807 #ifdef TARGET_X86_64
2808 static const SSEFunc_l_ep sse_op_table3bq[] = {
2809 gen_helper_cvttss2sq,
2810 gen_helper_cvtss2sq,
2811 gen_helper_cvttsd2sq,
2812 gen_helper_cvtsd2sq
2813 };
2814 #endif
2815
2816 static const SSEFunc_0_epp sse_op_table4[8][4] = {
2817 SSE_FOP(cmpeq),
2818 SSE_FOP(cmplt),
2819 SSE_FOP(cmple),
2820 SSE_FOP(cmpunord),
2821 SSE_FOP(cmpneq),
2822 SSE_FOP(cmpnlt),
2823 SSE_FOP(cmpnle),
2824 SSE_FOP(cmpord),
2825 };
2826
2827 static const SSEFunc_0_epp sse_op_table5[256] = {
2828 [0x0c] = gen_helper_pi2fw,
2829 [0x0d] = gen_helper_pi2fd,
2830 [0x1c] = gen_helper_pf2iw,
2831 [0x1d] = gen_helper_pf2id,
2832 [0x8a] = gen_helper_pfnacc,
2833 [0x8e] = gen_helper_pfpnacc,
2834 [0x90] = gen_helper_pfcmpge,
2835 [0x94] = gen_helper_pfmin,
2836 [0x96] = gen_helper_pfrcp,
2837 [0x97] = gen_helper_pfrsqrt,
2838 [0x9a] = gen_helper_pfsub,
2839 [0x9e] = gen_helper_pfadd,
2840 [0xa0] = gen_helper_pfcmpgt,
2841 [0xa4] = gen_helper_pfmax,
2842 [0xa6] = gen_helper_movq, /* pfrcpit1; no need to actually increase precision */
2843 [0xa7] = gen_helper_movq, /* pfrsqit1 */
2844 [0xaa] = gen_helper_pfsubr,
2845 [0xae] = gen_helper_pfacc,
2846 [0xb0] = gen_helper_pfcmpeq,
2847 [0xb4] = gen_helper_pfmul,
2848 [0xb6] = gen_helper_movq, /* pfrcpit2 */
2849 [0xb7] = gen_helper_pmulhrw_mmx,
2850 [0xbb] = gen_helper_pswapd,
2851 [0xbf] = gen_helper_pavgb_mmx /* pavgusb */
2852 };
2853
2854 struct SSEOpHelper_epp {
2855 SSEFunc_0_epp op[2];
2856 uint32_t ext_mask;
2857 };
2858
2859 struct SSEOpHelper_eppi {
2860 SSEFunc_0_eppi op[2];
2861 uint32_t ext_mask;
2862 };
2863
2864 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
2865 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
2866 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
2867 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
2868 #define PCLMULQDQ_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, \
2869 CPUID_EXT_PCLMULQDQ }
2870 #define AESNI_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_AES }
2871
2872 static const struct SSEOpHelper_epp sse_op_table6[256] = {
2873 [0x00] = SSSE3_OP(pshufb),
2874 [0x01] = SSSE3_OP(phaddw),
2875 [0x02] = SSSE3_OP(phaddd),
2876 [0x03] = SSSE3_OP(phaddsw),
2877 [0x04] = SSSE3_OP(pmaddubsw),
2878 [0x05] = SSSE3_OP(phsubw),
2879 [0x06] = SSSE3_OP(phsubd),
2880 [0x07] = SSSE3_OP(phsubsw),
2881 [0x08] = SSSE3_OP(psignb),
2882 [0x09] = SSSE3_OP(psignw),
2883 [0x0a] = SSSE3_OP(psignd),
2884 [0x0b] = SSSE3_OP(pmulhrsw),
2885 [0x10] = SSE41_OP(pblendvb),
2886 [0x14] = SSE41_OP(blendvps),
2887 [0x15] = SSE41_OP(blendvpd),
2888 [0x17] = SSE41_OP(ptest),
2889 [0x1c] = SSSE3_OP(pabsb),
2890 [0x1d] = SSSE3_OP(pabsw),
2891 [0x1e] = SSSE3_OP(pabsd),
2892 [0x20] = SSE41_OP(pmovsxbw),
2893 [0x21] = SSE41_OP(pmovsxbd),
2894 [0x22] = SSE41_OP(pmovsxbq),
2895 [0x23] = SSE41_OP(pmovsxwd),
2896 [0x24] = SSE41_OP(pmovsxwq),
2897 [0x25] = SSE41_OP(pmovsxdq),
2898 [0x28] = SSE41_OP(pmuldq),
2899 [0x29] = SSE41_OP(pcmpeqq),
2900 [0x2a] = SSE41_SPECIAL, /* movntqda */
2901 [0x2b] = SSE41_OP(packusdw),
2902 [0x30] = SSE41_OP(pmovzxbw),
2903 [0x31] = SSE41_OP(pmovzxbd),
2904 [0x32] = SSE41_OP(pmovzxbq),
2905 [0x33] = SSE41_OP(pmovzxwd),
2906 [0x34] = SSE41_OP(pmovzxwq),
2907 [0x35] = SSE41_OP(pmovzxdq),
2908 [0x37] = SSE42_OP(pcmpgtq),
2909 [0x38] = SSE41_OP(pminsb),
2910 [0x39] = SSE41_OP(pminsd),
2911 [0x3a] = SSE41_OP(pminuw),
2912 [0x3b] = SSE41_OP(pminud),
2913 [0x3c] = SSE41_OP(pmaxsb),
2914 [0x3d] = SSE41_OP(pmaxsd),
2915 [0x3e] = SSE41_OP(pmaxuw),
2916 [0x3f] = SSE41_OP(pmaxud),
2917 [0x40] = SSE41_OP(pmulld),
2918 [0x41] = SSE41_OP(phminposuw),
2919 [0xdb] = AESNI_OP(aesimc),
2920 [0xdc] = AESNI_OP(aesenc),
2921 [0xdd] = AESNI_OP(aesenclast),
2922 [0xde] = AESNI_OP(aesdec),
2923 [0xdf] = AESNI_OP(aesdeclast),
2924 };
2925
2926 static const struct SSEOpHelper_eppi sse_op_table7[256] = {
2927 [0x08] = SSE41_OP(roundps),
2928 [0x09] = SSE41_OP(roundpd),
2929 [0x0a] = SSE41_OP(roundss),
2930 [0x0b] = SSE41_OP(roundsd),
2931 [0x0c] = SSE41_OP(blendps),
2932 [0x0d] = SSE41_OP(blendpd),
2933 [0x0e] = SSE41_OP(pblendw),
2934 [0x0f] = SSSE3_OP(palignr),
2935 [0x14] = SSE41_SPECIAL, /* pextrb */
2936 [0x15] = SSE41_SPECIAL, /* pextrw */
2937 [0x16] = SSE41_SPECIAL, /* pextrd/pextrq */
2938 [0x17] = SSE41_SPECIAL, /* extractps */
2939 [0x20] = SSE41_SPECIAL, /* pinsrb */
2940 [0x21] = SSE41_SPECIAL, /* insertps */
2941 [0x22] = SSE41_SPECIAL, /* pinsrd/pinsrq */
2942 [0x40] = SSE41_OP(dpps),
2943 [0x41] = SSE41_OP(dppd),
2944 [0x42] = SSE41_OP(mpsadbw),
2945 [0x44] = PCLMULQDQ_OP(pclmulqdq),
2946 [0x60] = SSE42_OP(pcmpestrm),
2947 [0x61] = SSE42_OP(pcmpestri),
2948 [0x62] = SSE42_OP(pcmpistrm),
2949 [0x63] = SSE42_OP(pcmpistri),
2950 [0xdf] = AESNI_OP(aeskeygenassist),
2951 };
2952
2953 static void gen_sse(CPUX86State *env, DisasContext *s, int b,
2954 target_ulong pc_start, int rex_r)
2955 {
2956 int b1, op1_offset, op2_offset, is_xmm, val;
2957 int modrm, mod, rm, reg;
2958 SSEFunc_0_epp sse_fn_epp;
2959 SSEFunc_0_eppi sse_fn_eppi;
2960 SSEFunc_0_ppi sse_fn_ppi;
2961 SSEFunc_0_eppt sse_fn_eppt;
2962 TCGMemOp ot;
2963
2964 b &= 0xff;
2965 if (s->prefix & PREFIX_DATA)
2966 b1 = 1;
2967 else if (s->prefix & PREFIX_REPZ)
2968 b1 = 2;
2969 else if (s->prefix & PREFIX_REPNZ)
2970 b1 = 3;
2971 else
2972 b1 = 0;
2973 sse_fn_epp = sse_op_table1[b][b1];
2974 if (!sse_fn_epp) {
2975 goto unknown_op;
2976 }
2977 if ((b <= 0x5f && b >= 0x10) || b == 0xc6 || b == 0xc2) {
2978 is_xmm = 1;
2979 } else {
2980 if (b1 == 0) {
2981 /* MMX case */
2982 is_xmm = 0;
2983 } else {
2984 is_xmm = 1;
2985 }
2986 }
2987 /* simple MMX/SSE operation */
2988 if (s->flags & HF_TS_MASK) {
2989 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
2990 return;
2991 }
2992 if (s->flags & HF_EM_MASK) {
2993 illegal_op:
2994 gen_illegal_opcode(s);
2995 return;
2996 }
2997 if (is_xmm
2998 && !(s->flags & HF_OSFXSR_MASK)
2999 && ((b != 0x38 && b != 0x3a) || (s->prefix & PREFIX_DATA))) {
3000 goto unknown_op;
3001 }
3002 if (b == 0x0e) {
3003 if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) {
3004 /* If we were fully decoding this we might use illegal_op. */
3005 goto unknown_op;
3006 }
3007 /* femms */
3008 gen_helper_emms(cpu_env);
3009 return;
3010 }
3011 if (b == 0x77) {
3012 /* emms */
3013 gen_helper_emms(cpu_env);
3014 return;
3015 }
3016 /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3017 the static cpu state) */
3018 if (!is_xmm) {
3019 gen_helper_enter_mmx(cpu_env);
3020 }
3021
3022 modrm = cpu_ldub_code(env, s->pc++);
3023 reg = ((modrm >> 3) & 7);
3024 if (is_xmm)
3025 reg |= rex_r;
3026 mod = (modrm >> 6) & 3;
3027 if (sse_fn_epp == SSE_SPECIAL) {
3028 b |= (b1 << 8);
3029 switch(b) {
3030 case 0x0e7: /* movntq */
3031 if (mod == 3) {
3032 goto illegal_op;
3033 }
3034 gen_lea_modrm(env, s, modrm);
3035 gen_stq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
3036 break;
3037 case 0x1e7: /* movntdq */
3038 case 0x02b: /* movntps */
3039 case 0x12b: /* movntps */
3040 if (mod == 3)
3041 goto illegal_op;
3042 gen_lea_modrm(env, s, modrm);
3043 gen_sto_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3044 break;
3045 case 0x3f0: /* lddqu */
3046 if (mod == 3)
3047 goto illegal_op;
3048 gen_lea_modrm(env, s, modrm);
3049 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3050 break;
3051 case 0x22b: /* movntss */
3052 case 0x32b: /* movntsd */
3053 if (mod == 3)
3054 goto illegal_op;
3055 gen_lea_modrm(env, s, modrm);
3056 if (b1 & 1) {
3057 gen_stq_env_A0(s, offsetof(CPUX86State,
3058 xmm_regs[reg].ZMM_Q(0)));
3059 } else {
3060 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
3061 xmm_regs[reg].ZMM_L(0)));
3062 gen_op_st_v(s, MO_32, cpu_T0, cpu_A0);
3063 }
3064 break;
3065 case 0x6e: /* movd mm, ea */
3066 #ifdef TARGET_X86_64
3067 if (s->dflag == MO_64) {
3068 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 0);
3069 tcg_gen_st_tl(cpu_T0, cpu_env, offsetof(CPUX86State,fpregs[reg].mmx));
3070 } else
3071 #endif
3072 {
3073 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 0);
3074 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3075 offsetof(CPUX86State,fpregs[reg].mmx));
3076 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
3077 gen_helper_movl_mm_T0_mmx(cpu_ptr0, cpu_tmp2_i32);
3078 }
3079 break;
3080 case 0x16e: /* movd xmm, ea */
3081 #ifdef TARGET_X86_64
3082 if (s->dflag == MO_64) {
3083 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 0);
3084 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3085 offsetof(CPUX86State,xmm_regs[reg]));
3086 gen_helper_movq_mm_T0_xmm(cpu_ptr0, cpu_T0);
3087 } else
3088 #endif
3089 {
3090 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 0);
3091 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3092 offsetof(CPUX86State,xmm_regs[reg]));
3093 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
3094 gen_helper_movl_mm_T0_xmm(cpu_ptr0, cpu_tmp2_i32);
3095 }
3096 break;
3097 case 0x6f: /* movq mm, ea */
3098 if (mod != 3) {
3099 gen_lea_modrm(env, s, modrm);
3100 gen_ldq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
3101 } else {
3102 rm = (modrm & 7);
3103 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
3104 offsetof(CPUX86State,fpregs[rm].mmx));
3105 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
3106 offsetof(CPUX86State,fpregs[reg].mmx));
3107 }
3108 break;
3109 case 0x010: /* movups */
3110 case 0x110: /* movupd */
3111 case 0x028: /* movaps */
3112 case 0x128: /* movapd */
3113 case 0x16f: /* movdqa xmm, ea */
3114 case 0x26f: /* movdqu xmm, ea */
3115 if (mod != 3) {
3116 gen_lea_modrm(env, s, modrm);
3117 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3118 } else {
3119 rm = (modrm & 7) | REX_B(s);
3120 gen_op_movo(offsetof(CPUX86State,xmm_regs[reg]),
3121 offsetof(CPUX86State,xmm_regs[rm]));
3122 }
3123 break;
3124 case 0x210: /* movss xmm, ea */
3125 if (mod != 3) {
3126 gen_lea_modrm(env, s, modrm);
3127 gen_op_ld_v(s, MO_32, cpu_T0, cpu_A0);
3128 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3129 tcg_gen_movi_tl(cpu_T0, 0);
3130 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)));
3131 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)));
3132 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)));
3133 } else {
3134 rm = (modrm & 7) | REX_B(s);
3135 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)),
3136 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0)));
3137 }
3138 break;
3139 case 0x310: /* movsd xmm, ea */
3140 if (mod != 3) {
3141 gen_lea_modrm(env, s, modrm);
3142 gen_ldq_env_A0(s, offsetof(CPUX86State,
3143 xmm_regs[reg].ZMM_Q(0)));
3144 tcg_gen_movi_tl(cpu_T0, 0);
3145 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)));
3146 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)));
3147 } else {
3148 rm = (modrm & 7) | REX_B(s);
3149 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3150 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3151 }
3152 break;
3153 case 0x012: /* movlps */
3154 case 0x112: /* movlpd */
3155 if (mod != 3) {
3156 gen_lea_modrm(env, s, modrm);
3157 gen_ldq_env_A0(s, offsetof(CPUX86State,
3158 xmm_regs[reg].ZMM_Q(0)));
3159 } else {
3160 /* movhlps */
3161 rm = (modrm & 7) | REX_B(s);
3162 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3163 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(1)));
3164 }
3165 break;
3166 case 0x212: /* movsldup */
3167 if (mod != 3) {
3168 gen_lea_modrm(env, s, modrm);
3169 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3170 } else {
3171 rm = (modrm & 7) | REX_B(s);
3172 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)),
3173 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0)));
3174 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)),
3175 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(2)));
3176 }
3177 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)),
3178 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3179 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)),
3180 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)));
3181 break;
3182 case 0x312: /* movddup */
3183 if (mod != 3) {
3184 gen_lea_modrm(env, s, modrm);
3185 gen_ldq_env_A0(s, offsetof(CPUX86State,
3186 xmm_regs[reg].ZMM_Q(0)));
3187 } else {
3188 rm = (modrm & 7) | REX_B(s);
3189 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3190 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3191 }
3192 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)),
3193 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3194 break;
3195 case 0x016: /* movhps */
3196 case 0x116: /* movhpd */
3197 if (mod != 3) {
3198 gen_lea_modrm(env, s, modrm);
3199 gen_ldq_env_A0(s, offsetof(CPUX86State,
3200 xmm_regs[reg].ZMM_Q(1)));
3201 } else {
3202 /* movlhps */
3203 rm = (modrm & 7) | REX_B(s);
3204 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)),
3205 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3206 }
3207 break;
3208 case 0x216: /* movshdup */
3209 if (mod != 3) {
3210 gen_lea_modrm(env, s, modrm);
3211 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3212 } else {
3213 rm = (modrm & 7) | REX_B(s);
3214 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)),
3215 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(1)));
3216 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)),
3217 offsetof(CPUX86State,xmm_regs[rm].ZMM_L(3)));
3218 }
3219 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)),
3220 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)));
3221 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)),
3222 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)));
3223 break;
3224 case 0x178:
3225 case 0x378:
3226 {
3227 int bit_index, field_length;
3228
3229 if (b1 == 1 && reg != 0)
3230 goto illegal_op;
3231 field_length = cpu_ldub_code(env, s->pc++) & 0x3F;
3232 bit_index = cpu_ldub_code(env, s->pc++) & 0x3F;
3233 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3234 offsetof(CPUX86State,xmm_regs[reg]));
3235 if (b1 == 1)
3236 gen_helper_extrq_i(cpu_env, cpu_ptr0,
3237 tcg_const_i32(bit_index),
3238 tcg_const_i32(field_length));
3239 else
3240 gen_helper_insertq_i(cpu_env, cpu_ptr0,
3241 tcg_const_i32(bit_index),
3242 tcg_const_i32(field_length));
3243 }
3244 break;
3245 case 0x7e: /* movd ea, mm */
3246 #ifdef TARGET_X86_64
3247 if (s->dflag == MO_64) {
3248 tcg_gen_ld_i64(cpu_T0, cpu_env,
3249 offsetof(CPUX86State,fpregs[reg].mmx));
3250 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 1);
3251 } else
3252 #endif
3253 {
3254 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
3255 offsetof(CPUX86State,fpregs[reg].mmx.MMX_L(0)));
3256 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 1);
3257 }
3258 break;
3259 case 0x17e: /* movd ea, xmm */
3260 #ifdef TARGET_X86_64
3261 if (s->dflag == MO_64) {
3262 tcg_gen_ld_i64(cpu_T0, cpu_env,
3263 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3264 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 1);
3265 } else
3266 #endif
3267 {
3268 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
3269 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3270 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 1);
3271 }
3272 break;
3273 case 0x27e: /* movq xmm, ea */
3274 if (mod != 3) {
3275 gen_lea_modrm(env, s, modrm);
3276 gen_ldq_env_A0(s, offsetof(CPUX86State,
3277 xmm_regs[reg].ZMM_Q(0)));
3278 } else {
3279 rm = (modrm & 7) | REX_B(s);
3280 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3281 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3282 }
3283 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)));
3284 break;
3285 case 0x7f: /* movq ea, mm */
3286 if (mod != 3) {
3287 gen_lea_modrm(env, s, modrm);
3288 gen_stq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
3289 } else {
3290 rm = (modrm & 7);
3291 gen_op_movq(offsetof(CPUX86State,fpregs[rm].mmx),
3292 offsetof(CPUX86State,fpregs[reg].mmx));
3293 }
3294 break;
3295 case 0x011: /* movups */
3296 case 0x111: /* movupd */
3297 case 0x029: /* movaps */
3298 case 0x129: /* movapd */
3299 case 0x17f: /* movdqa ea, xmm */
3300 case 0x27f: /* movdqu ea, xmm */
3301 if (mod != 3) {
3302 gen_lea_modrm(env, s, modrm);
3303 gen_sto_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3304 } else {
3305 rm = (modrm & 7) | REX_B(s);
3306 gen_op_movo(offsetof(CPUX86State,xmm_regs[rm]),
3307 offsetof(CPUX86State,xmm_regs[reg]));
3308 }
3309 break;
3310 case 0x211: /* movss ea, xmm */
3311 if (mod != 3) {
3312 gen_lea_modrm(env, s, modrm);
3313 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3314 gen_op_st_v(s, MO_32, cpu_T0, cpu_A0);
3315 } else {
3316 rm = (modrm & 7) | REX_B(s);
3317 gen_op_movl(offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0)),
3318 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3319 }
3320 break;
3321 case 0x311: /* movsd ea, xmm */
3322 if (mod != 3) {
3323 gen_lea_modrm(env, s, modrm);
3324 gen_stq_env_A0(s, offsetof(CPUX86State,
3325 xmm_regs[reg].ZMM_Q(0)));
3326 } else {
3327 rm = (modrm & 7) | REX_B(s);
3328 gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)),
3329 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3330 }
3331 break;
3332 case 0x013: /* movlps */
3333 case 0x113: /* movlpd */
3334 if (mod != 3) {
3335 gen_lea_modrm(env, s, modrm);
3336 gen_stq_env_A0(s, offsetof(CPUX86State,
3337 xmm_regs[reg].ZMM_Q(0)));
3338 } else {
3339 goto illegal_op;
3340 }
3341 break;
3342 case 0x017: /* movhps */
3343 case 0x117: /* movhpd */
3344 if (mod != 3) {
3345 gen_lea_modrm(env, s, modrm);
3346 gen_stq_env_A0(s, offsetof(CPUX86State,
3347 xmm_regs[reg].ZMM_Q(1)));
3348 } else {
3349 goto illegal_op;
3350 }
3351 break;
3352 case 0x71: /* shift mm, im */
3353 case 0x72:
3354 case 0x73:
3355 case 0x171: /* shift xmm, im */
3356 case 0x172:
3357 case 0x173:
3358 if (b1 >= 2) {
3359 goto unknown_op;
3360 }
3361 val = cpu_ldub_code(env, s->pc++);
3362 if (is_xmm) {
3363 tcg_gen_movi_tl(cpu_T0, val);
3364 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(0)));
3365 tcg_gen_movi_tl(cpu_T0, 0);
3366 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(1)));
3367 op1_offset = offsetof(CPUX86State,xmm_t0);
3368 } else {
3369 tcg_gen_movi_tl(cpu_T0, val);
3370 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(0)));
3371 tcg_gen_movi_tl(cpu_T0, 0);
3372 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(1)));
3373 op1_offset = offsetof(CPUX86State,mmx_t0);
3374 }
3375 sse_fn_epp = sse_op_table2[((b - 1) & 3) * 8 +
3376 (((modrm >> 3)) & 7)][b1];
3377 if (!sse_fn_epp) {
3378 goto unknown_op;
3379 }
3380 if (is_xmm) {
3381 rm = (modrm & 7) | REX_B(s);
3382 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3383 } else {
3384 rm = (modrm & 7);
3385 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3386 }
3387 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
3388 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op1_offset);
3389 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
3390 break;
3391 case 0x050: /* movmskps */
3392 rm = (modrm & 7) | REX_B(s);
3393 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3394 offsetof(CPUX86State,xmm_regs[rm]));
3395 gen_helper_movmskps(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3396 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
3397 break;
3398 case 0x150: /* movmskpd */
3399 rm = (modrm & 7) | REX_B(s);
3400 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
3401 offsetof(CPUX86State,xmm_regs[rm]));
3402 gen_helper_movmskpd(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3403 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
3404 break;
3405 case 0x02a: /* cvtpi2ps */
3406 case 0x12a: /* cvtpi2pd */
3407 gen_helper_enter_mmx(cpu_env);
3408 if (mod != 3) {
3409 gen_lea_modrm(env, s, modrm);
3410 op2_offset = offsetof(CPUX86State,mmx_t0);
3411 gen_ldq_env_A0(s, op2_offset);
3412 } else {
3413 rm = (modrm & 7);
3414 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3415 }
3416 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3417 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3418 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3419 switch(b >> 8) {
3420 case 0x0:
3421 gen_helper_cvtpi2ps(cpu_env, cpu_ptr0, cpu_ptr1);
3422 break;
3423 default:
3424 case 0x1:
3425 gen_helper_cvtpi2pd(cpu_env, cpu_ptr0, cpu_ptr1);
3426 break;
3427 }
3428 break;
3429 case 0x22a: /* cvtsi2ss */
3430 case 0x32a: /* cvtsi2sd */
3431 ot = mo_64_32(s->dflag);
3432 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3433 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3434 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3435 if (ot == MO_32) {
3436 SSEFunc_0_epi sse_fn_epi = sse_op_table3ai[(b >> 8) & 1];
3437 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
3438 sse_fn_epi(cpu_env, cpu_ptr0, cpu_tmp2_i32);
3439 } else {
3440 #ifdef TARGET_X86_64
3441 SSEFunc_0_epl sse_fn_epl = sse_op_table3aq[(b >> 8) & 1];
3442 sse_fn_epl(cpu_env, cpu_ptr0, cpu_T0);
3443 #else
3444 goto illegal_op;
3445 #endif
3446 }
3447 break;
3448 case 0x02c: /* cvttps2pi */
3449 case 0x12c: /* cvttpd2pi */
3450 case 0x02d: /* cvtps2pi */
3451 case 0x12d: /* cvtpd2pi */
3452 gen_helper_enter_mmx(cpu_env);
3453 if (mod != 3) {
3454 gen_lea_modrm(env, s, modrm);
3455 op2_offset = offsetof(CPUX86State,xmm_t0);
3456 gen_ldo_env_A0(s, op2_offset);
3457 } else {
3458 rm = (modrm & 7) | REX_B(s);
3459 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3460 }
3461 op1_offset = offsetof(CPUX86State,fpregs[reg & 7].mmx);
3462 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3463 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3464 switch(b) {
3465 case 0x02c:
3466 gen_helper_cvttps2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3467 break;
3468 case 0x12c:
3469 gen_helper_cvttpd2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3470 break;
3471 case 0x02d:
3472 gen_helper_cvtps2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3473 break;
3474 case 0x12d:
3475 gen_helper_cvtpd2pi(cpu_env, cpu_ptr0, cpu_ptr1);
3476 break;
3477 }
3478 break;
3479 case 0x22c: /* cvttss2si */
3480 case 0x32c: /* cvttsd2si */
3481 case 0x22d: /* cvtss2si */
3482 case 0x32d: /* cvtsd2si */
3483 ot = mo_64_32(s->dflag);
3484 if (mod != 3) {
3485 gen_lea_modrm(env, s, modrm);
3486 if ((b >> 8) & 1) {
3487 gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_Q(0)));
3488 } else {
3489 gen_op_ld_v(s, MO_32, cpu_T0, cpu_A0);
3490 tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(0)));
3491 }
3492 op2_offset = offsetof(CPUX86State,xmm_t0);
3493 } else {
3494 rm = (modrm & 7) | REX_B(s);
3495 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3496 }
3497 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
3498 if (ot == MO_32) {
3499 SSEFunc_i_ep sse_fn_i_ep =
3500 sse_op_table3bi[((b >> 7) & 2) | (b & 1)];
3501 sse_fn_i_ep(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3502 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
3503 } else {
3504 #ifdef TARGET_X86_64
3505 SSEFunc_l_ep sse_fn_l_ep =
3506 sse_op_table3bq[((b >> 7) & 2) | (b & 1)];
3507 sse_fn_l_ep(cpu_T0, cpu_env, cpu_ptr0);
3508 #else
3509 goto illegal_op;
3510 #endif
3511 }
3512 gen_op_mov_reg_v(ot, reg, cpu_T0);
3513 break;
3514 case 0xc4: /* pinsrw */
3515 case 0x1c4:
3516 s->rip_offset = 1;
3517 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
3518 val = cpu_ldub_code(env, s->pc++);
3519 if (b1) {
3520 val &= 7;
3521 tcg_gen_st16_tl(cpu_T0, cpu_env,
3522 offsetof(CPUX86State,xmm_regs[reg].ZMM_W(val)));
3523 } else {
3524 val &= 3;
3525 tcg_gen_st16_tl(cpu_T0, cpu_env,
3526 offsetof(CPUX86State,fpregs[reg].mmx.MMX_W(val)));
3527 }
3528 break;
3529 case 0xc5: /* pextrw */
3530 case 0x1c5:
3531 if (mod != 3)
3532 goto illegal_op;
3533 ot = mo_64_32(s->dflag);
3534 val = cpu_ldub_code(env, s->pc++);
3535 if (b1) {
3536 val &= 7;
3537 rm = (modrm & 7) | REX_B(s);
3538 tcg_gen_ld16u_tl(cpu_T0, cpu_env,
3539 offsetof(CPUX86State,xmm_regs[rm].ZMM_W(val)));
3540 } else {
3541 val &= 3;
3542 rm = (modrm & 7);
3543 tcg_gen_ld16u_tl(cpu_T0, cpu_env,
3544 offsetof(CPUX86State,fpregs[rm].mmx.MMX_W(val)));
3545 }
3546 reg = ((modrm >> 3) & 7) | rex_r;
3547 gen_op_mov_reg_v(ot, reg, cpu_T0);
3548 break;
3549 case 0x1d6: /* movq ea, xmm */
3550 if (mod != 3) {
3551 gen_lea_modrm(env, s, modrm);
3552 gen_stq_env_A0(s, offsetof(CPUX86State,
3553 xmm_regs[reg].ZMM_Q(0)));
3554 } else {
3555 rm = (modrm & 7) | REX_B(s);
3556 gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)),
3557 offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3558 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(1)));
3559 }
3560 break;
3561 case 0x2d6: /* movq2dq */
3562 gen_helper_enter_mmx(cpu_env);
3563 rm = (modrm & 7);
3564 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),
3565 offsetof(CPUX86State,fpregs[rm].mmx));
3566 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)));
3567 break;
3568 case 0x3d6: /* movdq2q */
3569 gen_helper_enter_mmx(cpu_env);
3570 rm = (modrm & 7) | REX_B(s);
3571 gen_op_movq(offsetof(CPUX86State,fpregs[reg & 7].mmx),
3572 offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3573 break;
3574 case 0xd7: /* pmovmskb */
3575 case 0x1d7:
3576 if (mod != 3)
3577 goto illegal_op;
3578 if (b1) {
3579 rm = (modrm & 7) | REX_B(s);
3580 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[rm]));
3581 gen_helper_pmovmskb_xmm(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3582 } else {
3583 rm = (modrm & 7);
3584 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,fpregs[rm].mmx));
3585 gen_helper_pmovmskb_mmx(cpu_tmp2_i32, cpu_env, cpu_ptr0);
3586 }
3587 reg = ((modrm >> 3) & 7) | rex_r;
3588 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
3589 break;
3590
3591 case 0x138:
3592 case 0x038:
3593 b = modrm;
3594 if ((b & 0xf0) == 0xf0) {
3595 goto do_0f_38_fx;
3596 }
3597 modrm = cpu_ldub_code(env, s->pc++);
3598 rm = modrm & 7;
3599 reg = ((modrm >> 3) & 7) | rex_r;
3600 mod = (modrm >> 6) & 3;
3601 if (b1 >= 2) {
3602 goto unknown_op;
3603 }
3604
3605 sse_fn_epp = sse_op_table6[b].op[b1];
3606 if (!sse_fn_epp) {
3607 goto unknown_op;
3608 }
3609 if (!(s->cpuid_ext_features & sse_op_table6[b].ext_mask))
3610 goto illegal_op;
3611
3612 if (b1) {
3613 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3614 if (mod == 3) {
3615 op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
3616 } else {
3617 op2_offset = offsetof(CPUX86State,xmm_t0);
3618 gen_lea_modrm(env, s, modrm);
3619 switch (b) {
3620 case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3621 case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3622 case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3623 gen_ldq_env_A0(s, op2_offset +
3624 offsetof(ZMMReg, ZMM_Q(0)));
3625 break;
3626 case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3627 case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3628 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
3629 s->mem_index, MO_LEUL);
3630 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, op2_offset +
3631 offsetof(ZMMReg, ZMM_L(0)));
3632 break;
3633 case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3634 tcg_gen_qemu_ld_tl(cpu_tmp0, cpu_A0,
3635 s->mem_index, MO_LEUW);
3636 tcg_gen_st16_tl(cpu_tmp0, cpu_env, op2_offset +
3637 offsetof(ZMMReg, ZMM_W(0)));
3638 break;
3639 case 0x2a: /* movntqda */
3640 gen_ldo_env_A0(s, op1_offset);
3641 return;
3642 default:
3643 gen_ldo_env_A0(s, op2_offset);
3644 }
3645 }
3646 } else {
3647 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
3648 if (mod == 3) {
3649 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3650 } else {
3651 op2_offset = offsetof(CPUX86State,mmx_t0);
3652 gen_lea_modrm(env, s, modrm);
3653 gen_ldq_env_A0(s, op2_offset);
3654 }
3655 }
3656 if (sse_fn_epp == SSE_SPECIAL) {
3657 goto unknown_op;
3658 }
3659
3660 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
3661 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
3662 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
3663
3664 if (b == 0x17) {
3665 set_cc_op(s, CC_OP_EFLAGS);
3666 }
3667 break;
3668
3669 case 0x238:
3670 case 0x338:
3671 do_0f_38_fx:
3672 /* Various integer extensions at 0f 38 f[0-f]. */
3673 b = modrm | (b1 << 8);
3674 modrm = cpu_ldub_code(env, s->pc++);
3675 reg = ((modrm >> 3) & 7) | rex_r;
3676
3677 switch (b) {
3678 case 0x3f0: /* crc32 Gd,Eb */
3679 case 0x3f1: /* crc32 Gd,Ey */
3680 do_crc32:
3681 if (!(s->cpuid_ext_features & CPUID_EXT_SSE42)) {
3682 goto illegal_op;
3683 }
3684 if ((b & 0xff) == 0xf0) {
3685 ot = MO_8;
3686 } else if (s->dflag != MO_64) {
3687 ot = (s->prefix & PREFIX_DATA ? MO_16 : MO_32);
3688 } else {
3689 ot = MO_64;
3690 }
3691
3692 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[reg]);
3693 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3694 gen_helper_crc32(cpu_T0, cpu_tmp2_i32,
3695 cpu_T0, tcg_const_i32(8 << ot));
3696
3697 ot = mo_64_32(s->dflag);
3698 gen_op_mov_reg_v(ot, reg, cpu_T0);
3699 break;
3700
3701 case 0x1f0: /* crc32 or movbe */
3702 case 0x1f1:
3703 /* For these insns, the f3 prefix is supposed to have priority
3704 over the 66 prefix, but that's not what we implement above
3705 setting b1. */
3706 if (s->prefix & PREFIX_REPNZ) {
3707 goto do_crc32;
3708 }
3709 /* FALLTHRU */
3710 case 0x0f0: /* movbe Gy,My */
3711 case 0x0f1: /* movbe My,Gy */
3712 if (!(s->cpuid_ext_features & CPUID_EXT_MOVBE)) {
3713 goto illegal_op;
3714 }
3715 if (s->dflag != MO_64) {
3716 ot = (s->prefix & PREFIX_DATA ? MO_16 : MO_32);
3717 } else {
3718 ot = MO_64;
3719 }
3720
3721 gen_lea_modrm(env, s, modrm);
3722 if ((b & 1) == 0) {
3723 tcg_gen_qemu_ld_tl(cpu_T0, cpu_A0,
3724 s->mem_index, ot | MO_BE);
3725 gen_op_mov_reg_v(ot, reg, cpu_T0);
3726 } else {
3727 tcg_gen_qemu_st_tl(cpu_regs[reg], cpu_A0,
3728 s->mem_index, ot | MO_BE);
3729 }
3730 break;
3731
3732 case 0x0f2: /* andn Gy, By, Ey */
3733 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
3734 || !(s->prefix & PREFIX_VEX)
3735 || s->vex_l != 0) {
3736 goto illegal_op;
3737 }
3738 ot = mo_64_32(s->dflag);
3739 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3740 tcg_gen_andc_tl(cpu_T0, cpu_regs[s->vex_v], cpu_T0);
3741 gen_op_mov_reg_v(ot, reg, cpu_T0);
3742 gen_op_update1_cc();
3743 set_cc_op(s, CC_OP_LOGICB + ot);
3744 break;
3745
3746 case 0x0f7: /* bextr Gy, Ey, By */
3747 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
3748 || !(s->prefix & PREFIX_VEX)
3749 || s->vex_l != 0) {
3750 goto illegal_op;
3751 }
3752 ot = mo_64_32(s->dflag);
3753 {
3754 TCGv bound, zero;
3755
3756 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3757 /* Extract START, and shift the operand.
3758 Shifts larger than operand size get zeros. */
3759 tcg_gen_ext8u_tl(cpu_A0, cpu_regs[s->vex_v]);
3760 tcg_gen_shr_tl(cpu_T0, cpu_T0, cpu_A0);
3761
3762 bound = tcg_const_tl(ot == MO_64 ? 63 : 31);
3763 zero = tcg_const_tl(0);
3764 tcg_gen_movcond_tl(TCG_COND_LEU, cpu_T0, cpu_A0, bound,
3765 cpu_T0, zero);
3766 tcg_temp_free(zero);
3767
3768 /* Extract the LEN into a mask. Lengths larger than
3769 operand size get all ones. */
3770 tcg_gen_extract_tl(cpu_A0, cpu_regs[s->vex_v], 8, 8);
3771 tcg_gen_movcond_tl(TCG_COND_LEU, cpu_A0, cpu_A0, bound,
3772 cpu_A0, bound);
3773 tcg_temp_free(bound);
3774 tcg_gen_movi_tl(cpu_T1, 1);
3775 tcg_gen_shl_tl(cpu_T1, cpu_T1, cpu_A0);
3776 tcg_gen_subi_tl(cpu_T1, cpu_T1, 1);
3777 tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1);
3778
3779 gen_op_mov_reg_v(ot, reg, cpu_T0);
3780 gen_op_update1_cc();
3781 set_cc_op(s, CC_OP_LOGICB + ot);
3782 }
3783 break;
3784
3785 case 0x0f5: /* bzhi Gy, Ey, By */
3786 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3787 || !(s->prefix & PREFIX_VEX)
3788 || s->vex_l != 0) {
3789 goto illegal_op;
3790 }
3791 ot = mo_64_32(s->dflag);
3792 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3793 tcg_gen_ext8u_tl(cpu_T1, cpu_regs[s->vex_v]);
3794 {
3795 TCGv bound = tcg_const_tl(ot == MO_64 ? 63 : 31);
3796 /* Note that since we're using BMILG (in order to get O
3797 cleared) we need to store the inverse into C. */
3798 tcg_gen_setcond_tl(TCG_COND_LT, cpu_cc_src,
3799 cpu_T1, bound);
3800 tcg_gen_movcond_tl(TCG_COND_GT, cpu_T1, cpu_T1,
3801 bound, bound, cpu_T1);
3802 tcg_temp_free(bound);
3803 }
3804 tcg_gen_movi_tl(cpu_A0, -1);
3805 tcg_gen_shl_tl(cpu_A0, cpu_A0, cpu_T1);
3806 tcg_gen_andc_tl(cpu_T0, cpu_T0, cpu_A0);
3807 gen_op_mov_reg_v(ot, reg, cpu_T0);
3808 gen_op_update1_cc();
3809 set_cc_op(s, CC_OP_BMILGB + ot);
3810 break;
3811
3812 case 0x3f6: /* mulx By, Gy, rdx, Ey */
3813 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3814 || !(s->prefix & PREFIX_VEX)
3815 || s->vex_l != 0) {
3816 goto illegal_op;
3817 }
3818 ot = mo_64_32(s->dflag);
3819 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3820 switch (ot) {
3821 default:
3822 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
3823 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_regs[R_EDX]);
3824 tcg_gen_mulu2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
3825 cpu_tmp2_i32, cpu_tmp3_i32);
3826 tcg_gen_extu_i32_tl(cpu_regs[s->vex_v], cpu_tmp2_i32);
3827 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp3_i32);
3828 break;
3829 #ifdef TARGET_X86_64
3830 case MO_64:
3831 tcg_gen_mulu2_i64(cpu_T0, cpu_T1,
3832 cpu_T0, cpu_regs[R_EDX]);
3833 tcg_gen_mov_i64(cpu_regs[s->vex_v], cpu_T0);
3834 tcg_gen_mov_i64(cpu_regs[reg], cpu_T1);
3835 break;
3836 #endif
3837 }
3838 break;
3839
3840 case 0x3f5: /* pdep Gy, By, Ey */
3841 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3842 || !(s->prefix & PREFIX_VEX)
3843 || s->vex_l != 0) {
3844 goto illegal_op;
3845 }
3846 ot = mo_64_32(s->dflag);
3847 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3848 /* Note that by zero-extending the mask operand, we
3849 automatically handle zero-extending the result. */
3850 if (ot == MO_64) {
3851 tcg_gen_mov_tl(cpu_T1, cpu_regs[s->vex_v]);
3852 } else {
3853 tcg_gen_ext32u_tl(cpu_T1, cpu_regs[s->vex_v]);
3854 }
3855 gen_helper_pdep(cpu_regs[reg], cpu_T0, cpu_T1);
3856 break;
3857
3858 case 0x2f5: /* pext Gy, By, Ey */
3859 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3860 || !(s->prefix & PREFIX_VEX)
3861 || s->vex_l != 0) {
3862 goto illegal_op;
3863 }
3864 ot = mo_64_32(s->dflag);
3865 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3866 /* Note that by zero-extending the mask operand, we
3867 automatically handle zero-extending the result. */
3868 if (ot == MO_64) {
3869 tcg_gen_mov_tl(cpu_T1, cpu_regs[s->vex_v]);
3870 } else {
3871 tcg_gen_ext32u_tl(cpu_T1, cpu_regs[s->vex_v]);
3872 }
3873 gen_helper_pext(cpu_regs[reg], cpu_T0, cpu_T1);
3874 break;
3875
3876 case 0x1f6: /* adcx Gy, Ey */
3877 case 0x2f6: /* adox Gy, Ey */
3878 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_ADX)) {
3879 goto illegal_op;
3880 } else {
3881 TCGv carry_in, carry_out, zero;
3882 int end_op;
3883
3884 ot = mo_64_32(s->dflag);
3885 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3886
3887 /* Re-use the carry-out from a previous round. */
3888 TCGV_UNUSED(carry_in);
3889 carry_out = (b == 0x1f6 ? cpu_cc_dst : cpu_cc_src2);
3890 switch (s->cc_op) {
3891 case CC_OP_ADCX:
3892 if (b == 0x1f6) {
3893 carry_in = cpu_cc_dst;
3894 end_op = CC_OP_ADCX;
3895 } else {
3896 end_op = CC_OP_ADCOX;
3897 }
3898 break;
3899 case CC_OP_ADOX:
3900 if (b == 0x1f6) {
3901 end_op = CC_OP_ADCOX;
3902 } else {
3903 carry_in = cpu_cc_src2;
3904 end_op = CC_OP_ADOX;
3905 }
3906 break;
3907 case CC_OP_ADCOX:
3908 end_op = CC_OP_ADCOX;
3909 carry_in = carry_out;
3910 break;
3911 default:
3912 end_op = (b == 0x1f6 ? CC_OP_ADCX : CC_OP_ADOX);
3913 break;
3914 }
3915 /* If we can't reuse carry-out, get it out of EFLAGS. */
3916 if (TCGV_IS_UNUSED(carry_in)) {
3917 if (s->cc_op != CC_OP_ADCX && s->cc_op != CC_OP_ADOX) {
3918 gen_compute_eflags(s);
3919 }
3920 carry_in = cpu_tmp0;
3921 tcg_gen_extract_tl(carry_in, cpu_cc_src,
3922 ctz32(b == 0x1f6 ? CC_C : CC_O), 1);
3923 }
3924
3925 switch (ot) {
3926 #ifdef TARGET_X86_64
3927 case MO_32:
3928 /* If we know TL is 64-bit, and we want a 32-bit
3929 result, just do everything in 64-bit arithmetic. */
3930 tcg_gen_ext32u_i64(cpu_regs[reg], cpu_regs[reg]);
3931 tcg_gen_ext32u_i64(cpu_T0, cpu_T0);
3932 tcg_gen_add_i64(cpu_T0, cpu_T0, cpu_regs[reg]);
3933 tcg_gen_add_i64(cpu_T0, cpu_T0, carry_in);
3934 tcg_gen_ext32u_i64(cpu_regs[reg], cpu_T0);
3935 tcg_gen_shri_i64(carry_out, cpu_T0, 32);
3936 break;
3937 #endif
3938 default:
3939 /* Otherwise compute the carry-out in two steps. */
3940 zero = tcg_const_tl(0);
3941 tcg_gen_add2_tl(cpu_T0, carry_out,
3942 cpu_T0, zero,
3943 carry_in, zero);
3944 tcg_gen_add2_tl(cpu_regs[reg], carry_out,
3945 cpu_regs[reg], carry_out,
3946 cpu_T0, zero);
3947 tcg_temp_free(zero);
3948 break;
3949 }
3950 set_cc_op(s, end_op);
3951 }
3952 break;
3953
3954 case 0x1f7: /* shlx Gy, Ey, By */
3955 case 0x2f7: /* sarx Gy, Ey, By */
3956 case 0x3f7: /* shrx Gy, Ey, By */
3957 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3958 || !(s->prefix & PREFIX_VEX)
3959 || s->vex_l != 0) {
3960 goto illegal_op;
3961 }
3962 ot = mo_64_32(s->dflag);
3963 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3964 if (ot == MO_64) {
3965 tcg_gen_andi_tl(cpu_T1, cpu_regs[s->vex_v], 63);
3966 } else {
3967 tcg_gen_andi_tl(cpu_T1, cpu_regs[s->vex_v], 31);
3968 }
3969 if (b == 0x1f7) {
3970 tcg_gen_shl_tl(cpu_T0, cpu_T0, cpu_T1);
3971 } else if (b == 0x2f7) {
3972 if (ot != MO_64) {
3973 tcg_gen_ext32s_tl(cpu_T0, cpu_T0);
3974 }
3975 tcg_gen_sar_tl(cpu_T0, cpu_T0, cpu_T1);
3976 } else {
3977 if (ot != MO_64) {
3978 tcg_gen_ext32u_tl(cpu_T0, cpu_T0);
3979 }
3980 tcg_gen_shr_tl(cpu_T0, cpu_T0, cpu_T1);
3981 }
3982 gen_op_mov_reg_v(ot, reg, cpu_T0);
3983 break;
3984
3985 case 0x0f3:
3986 case 0x1f3:
3987 case 0x2f3:
3988 case 0x3f3: /* Group 17 */
3989 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
3990 || !(s->prefix & PREFIX_VEX)
3991 || s->vex_l != 0) {
3992 goto illegal_op;
3993 }
3994 ot = mo_64_32(s->dflag);
3995 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3996
3997 switch (reg & 7) {
3998 case 1: /* blsr By,Ey */
3999 tcg_gen_neg_tl(cpu_T1, cpu_T0);
4000 tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1);
4001 gen_op_mov_reg_v(ot, s->vex_v, cpu_T0);
4002 gen_op_update2_cc();
4003 set_cc_op(s, CC_OP_BMILGB + ot);
4004 break;
4005
4006 case 2: /* blsmsk By,Ey */
4007 tcg_gen_mov_tl(cpu_cc_src, cpu_T0);
4008 tcg_gen_subi_tl(cpu_T0, cpu_T0, 1);
4009 tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_cc_src);
4010 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4011 set_cc_op(s, CC_OP_BMILGB + ot);
4012 break;
4013
4014 case 3: /* blsi By, Ey */
4015 tcg_gen_mov_tl(cpu_cc_src, cpu_T0);
4016 tcg_gen_subi_tl(cpu_T0, cpu_T0, 1);
4017 tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_cc_src);
4018 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4019 set_cc_op(s, CC_OP_BMILGB + ot);
4020 break;
4021
4022 default:
4023 goto unknown_op;
4024 }
4025 break;
4026
4027 default:
4028 goto unknown_op;
4029 }
4030 break;
4031
4032 case 0x03a:
4033 case 0x13a:
4034 b = modrm;
4035 modrm = cpu_ldub_code(env, s->pc++);
4036 rm = modrm & 7;
4037 reg = ((modrm >> 3) & 7) | rex_r;
4038 mod = (modrm >> 6) & 3;
4039 if (b1 >= 2) {
4040 goto unknown_op;
4041 }
4042
4043 sse_fn_eppi = sse_op_table7[b].op[b1];
4044 if (!sse_fn_eppi) {
4045 goto unknown_op;
4046 }
4047 if (!(s->cpuid_ext_features & sse_op_table7[b].ext_mask))
4048 goto illegal_op;
4049
4050 if (sse_fn_eppi == SSE_SPECIAL) {
4051 ot = mo_64_32(s->dflag);
4052 rm = (modrm & 7) | REX_B(s);
4053 if (mod != 3)
4054 gen_lea_modrm(env, s, modrm);
4055 reg = ((modrm >> 3) & 7) | rex_r;
4056 val = cpu_ldub_code(env, s->pc++);
4057 switch (b) {
4058 case 0x14: /* pextrb */
4059 tcg_gen_ld8u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
4060 xmm_regs[reg].ZMM_B(val & 15)));
4061 if (mod == 3) {
4062 gen_op_mov_reg_v(ot, rm, cpu_T0);
4063 } else {
4064 tcg_gen_qemu_st_tl(cpu_T0, cpu_A0,
4065 s->mem_index, MO_UB);
4066 }
4067 break;
4068 case 0x15: /* pextrw */
4069 tcg_gen_ld16u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
4070 xmm_regs[reg].ZMM_W(val & 7)));
4071 if (mod == 3) {
4072 gen_op_mov_reg_v(ot, rm, cpu_T0);
4073 } else {
4074 tcg_gen_qemu_st_tl(cpu_T0, cpu_A0,
4075 s->mem_index, MO_LEUW);
4076 }
4077 break;
4078 case 0x16:
4079 if (ot == MO_32) { /* pextrd */
4080 tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
4081 offsetof(CPUX86State,
4082 xmm_regs[reg].ZMM_L(val & 3)));
4083 if (mod == 3) {
4084 tcg_gen_extu_i32_tl(cpu_regs[rm], cpu_tmp2_i32);
4085 } else {
4086 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
4087 s->mem_index, MO_LEUL);
4088 }
4089 } else { /* pextrq */
4090 #ifdef TARGET_X86_64
4091 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
4092 offsetof(CPUX86State,
4093 xmm_regs[reg].ZMM_Q(val & 1)));
4094 if (mod == 3) {
4095 tcg_gen_mov_i64(cpu_regs[rm], cpu_tmp1_i64);
4096 } else {
4097 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0,
4098 s->mem_index, MO_LEQ);
4099 }
4100 #else
4101 goto illegal_op;
4102 #endif
4103 }
4104 break;
4105 case 0x17: /* extractps */
4106 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
4107 xmm_regs[reg].ZMM_L(val & 3)));
4108 if (mod == 3) {
4109 gen_op_mov_reg_v(ot, rm, cpu_T0);
4110 } else {
4111 tcg_gen_qemu_st_tl(cpu_T0, cpu_A0,
4112 s->mem_index, MO_LEUL);
4113 }
4114 break;
4115 case 0x20: /* pinsrb */
4116 if (mod == 3) {
4117 gen_op_mov_v_reg(MO_32, cpu_T0, rm);
4118 } else {
4119 tcg_gen_qemu_ld_tl(cpu_T0, cpu_A0,
4120 s->mem_index, MO_UB);
4121 }
4122 tcg_gen_st8_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
4123 xmm_regs[reg].ZMM_B(val & 15)));
4124 break;
4125 case 0x21: /* insertps */
4126 if (mod == 3) {
4127 tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
4128 offsetof(CPUX86State,xmm_regs[rm]
4129 .ZMM_L((val >> 6) & 3)));
4130 } else {
4131 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
4132 s->mem_index, MO_LEUL);
4133 }
4134 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
4135 offsetof(CPUX86State,xmm_regs[reg]
4136 .ZMM_L((val >> 4) & 3)));
4137 if ((val >> 0) & 1)
4138 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4139 cpu_env, offsetof(CPUX86State,
4140 xmm_regs[reg].ZMM_L(0)));
4141 if ((val >> 1) & 1)
4142 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4143 cpu_env, offsetof(CPUX86State,
4144 xmm_regs[reg].ZMM_L(1)));
4145 if ((val >> 2) & 1)
4146 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4147 cpu_env, offsetof(CPUX86State,
4148 xmm_regs[reg].ZMM_L(2)));
4149 if ((val >> 3) & 1)
4150 tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4151 cpu_env, offsetof(CPUX86State,
4152 xmm_regs[reg].ZMM_L(3)));
4153 break;
4154 case 0x22:
4155 if (ot == MO_32) { /* pinsrd */
4156 if (mod == 3) {
4157 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[rm]);
4158 } else {
4159 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
4160 s->mem_index, MO_LEUL);
4161 }
4162 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
4163 offsetof(CPUX86State,
4164 xmm_regs[reg].ZMM_L(val & 3)));
4165 } else { /* pinsrq */
4166 #ifdef TARGET_X86_64
4167 if (mod == 3) {
4168 gen_op_mov_v_reg(ot, cpu_tmp1_i64, rm);
4169 } else {
4170 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0,
4171 s->mem_index, MO_LEQ);
4172 }
4173 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
4174 offsetof(CPUX86State,
4175 xmm_regs[reg].ZMM_Q(val & 1)));
4176 #else
4177 goto illegal_op;
4178 #endif
4179 }
4180 break;
4181 }
4182 return;
4183 }
4184
4185 if (b1) {
4186 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
4187 if (mod == 3) {
4188 op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
4189 } else {
4190 op2_offset = offsetof(CPUX86State,xmm_t0);
4191 gen_lea_modrm(env, s, modrm);
4192 gen_ldo_env_A0(s, op2_offset);
4193 }
4194 } else {
4195 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
4196 if (mod == 3) {
4197 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
4198 } else {
4199 op2_offset = offsetof(CPUX86State,mmx_t0);
4200 gen_lea_modrm(env, s, modrm);
4201 gen_ldq_env_A0(s, op2_offset);
4202 }
4203 }
4204 val = cpu_ldub_code(env, s->pc++);
4205
4206 if ((b & 0xfc) == 0x60) { /* pcmpXstrX */
4207 set_cc_op(s, CC_OP_EFLAGS);
4208
4209 if (s->dflag == MO_64) {
4210 /* The helper must use entire 64-bit gp registers */
4211 val |= 1 << 8;
4212 }
4213 }
4214
4215 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4216 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4217 sse_fn_eppi(cpu_env, cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
4218 break;
4219
4220 case 0x33a:
4221 /* Various integer extensions at 0f 3a f[0-f]. */
4222 b = modrm | (b1 << 8);
4223 modrm = cpu_ldub_code(env, s->pc++);
4224 reg = ((modrm >> 3) & 7) | rex_r;
4225
4226 switch (b) {
4227 case 0x3f0: /* rorx Gy,Ey, Ib */
4228 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
4229 || !(s->prefix & PREFIX_VEX)
4230 || s->vex_l != 0) {
4231 goto illegal_op;
4232 }
4233 ot = mo_64_32(s->dflag);
4234 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4235 b = cpu_ldub_code(env, s->pc++);
4236 if (ot == MO_64) {
4237 tcg_gen_rotri_tl(cpu_T0, cpu_T0, b & 63);
4238 } else {
4239 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
4240 tcg_gen_rotri_i32(cpu_tmp2_i32, cpu_tmp2_i32, b & 31);
4241 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
4242 }
4243 gen_op_mov_reg_v(ot, reg, cpu_T0);
4244 break;
4245
4246 default:
4247 goto unknown_op;
4248 }
4249 break;
4250
4251 default:
4252 unknown_op:
4253 gen_unknown_opcode(env, s);
4254 return;
4255 }
4256 } else {
4257 /* generic MMX or SSE operation */
4258 switch(b) {
4259 case 0x70: /* pshufx insn */
4260 case 0xc6: /* pshufx insn */
4261 case 0xc2: /* compare insns */
4262 s->rip_offset = 1;
4263 break;
4264 default:
4265 break;
4266 }
4267 if (is_xmm) {
4268 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
4269 if (mod != 3) {
4270 int sz = 4;
4271
4272 gen_lea_modrm(env, s, modrm);
4273 op2_offset = offsetof(CPUX86State,xmm_t0);
4274
4275 switch (b) {
4276 case 0x50 ... 0x5a:
4277 case 0x5c ... 0x5f:
4278 case 0xc2:
4279 /* Most sse scalar operations. */
4280 if (b1 == 2) {
4281 sz = 2;
4282 } else if (b1 == 3) {
4283 sz = 3;
4284 }
4285 break;
4286
4287 case 0x2e: /* ucomis[sd] */
4288 case 0x2f: /* comis[sd] */
4289 if (b1 == 0) {
4290 sz = 2;
4291 } else {
4292 sz = 3;
4293 }
4294 break;
4295 }
4296
4297 switch (sz) {
4298 case 2:
4299 /* 32 bit access */
4300 gen_op_ld_v(s, MO_32, cpu_T0, cpu_A0);
4301 tcg_gen_st32_tl(cpu_T0, cpu_env,
4302 offsetof(CPUX86State,xmm_t0.ZMM_L(0)));
4303 break;
4304 case 3:
4305 /* 64 bit access */
4306 gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_D(0)));
4307 break;
4308 default:
4309 /* 128 bit access */
4310 gen_ldo_env_A0(s, op2_offset);
4311 break;
4312 }
4313 } else {
4314 rm = (modrm & 7) | REX_B(s);
4315 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
4316 }
4317 } else {
4318 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
4319 if (mod != 3) {
4320 gen_lea_modrm(env, s, modrm);
4321 op2_offset = offsetof(CPUX86State,mmx_t0);
4322 gen_ldq_env_A0(s, op2_offset);
4323 } else {
4324 rm = (modrm & 7);
4325 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
4326 }
4327 }
4328 switch(b) {
4329 case 0x0f: /* 3DNow! data insns */
4330 val = cpu_ldub_code(env, s->pc++);
4331 sse_fn_epp = sse_op_table5[val];
4332 if (!sse_fn_epp) {
4333 goto unknown_op;
4334 }
4335 if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) {
4336 goto illegal_op;
4337 }
4338 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4339 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4340 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4341 break;
4342 case 0x70: /* pshufx insn */
4343 case 0xc6: /* pshufx insn */
4344 val = cpu_ldub_code(env, s->pc++);
4345 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4346 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4347 /* XXX: introduce a new table? */
4348 sse_fn_ppi = (SSEFunc_0_ppi)sse_fn_epp;
4349 sse_fn_ppi(cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
4350 break;
4351 case 0xc2:
4352 /* compare insns */
4353 val = cpu_ldub_code(env, s->pc++);
4354 if (val >= 8)
4355 goto unknown_op;
4356 sse_fn_epp = sse_op_table4[val][b1];
4357
4358 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4359 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4360 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4361 break;
4362 case 0xf7:
4363 /* maskmov : we must prepare A0 */
4364 if (mod != 3)
4365 goto illegal_op;
4366 tcg_gen_mov_tl(cpu_A0, cpu_regs[R_EDI]);
4367 gen_extu(s->aflag, cpu_A0);
4368 gen_add_A0_ds_seg(s);
4369
4370 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4371 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4372 /* XXX: introduce a new table? */
4373 sse_fn_eppt = (SSEFunc_0_eppt)sse_fn_epp;
4374 sse_fn_eppt(cpu_env, cpu_ptr0, cpu_ptr1, cpu_A0);
4375 break;
4376 default:
4377 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
4378 tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
4379 sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);
4380 break;
4381 }
4382 if (b == 0x2e || b == 0x2f) {
4383 set_cc_op(s, CC_OP_EFLAGS);
4384 }
4385 }
4386 }
4387
4388 /* convert one instruction. s->is_jmp is set if the translation must
4389 be stopped. Return the next pc value */
4390 static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
4391 target_ulong pc_start)
4392 {
4393 int b, prefixes;
4394 int shift;
4395 TCGMemOp ot, aflag, dflag;
4396 int modrm, reg, rm, mod, op, opreg, val;
4397 target_ulong next_eip, tval;
4398 int rex_w, rex_r;
4399
4400 s->pc_start = s->pc = pc_start;
4401 prefixes = 0;
4402 s->override = -1;
4403 rex_w = -1;
4404 rex_r = 0;
4405 #ifdef TARGET_X86_64
4406 s->rex_x = 0;
4407 s->rex_b = 0;
4408 x86_64_hregs = 0;
4409 #endif
4410 s->rip_offset = 0; /* for relative ip address */
4411 s->vex_l = 0;
4412 s->vex_v = 0;
4413 next_byte:
4414 b = cpu_ldub_code(env, s->pc);
4415 s->pc++;
4416 /* Collect prefixes. */
4417 switch (b) {
4418 case 0xf3:
4419 prefixes |= PREFIX_REPZ;
4420 goto next_byte;
4421 case 0xf2:
4422 prefixes |= PREFIX_REPNZ;
4423 goto next_byte;
4424 case 0xf0:
4425 prefixes |= PREFIX_LOCK;
4426 goto next_byte;
4427 case 0x2e:
4428 s->override = R_CS;
4429 goto next_byte;
4430 case 0x36:
4431 s->override = R_SS;
4432 goto next_byte;
4433 case 0x3e:
4434 s->override = R_DS;
4435 goto next_byte;
4436 case 0x26:
4437 s->override = R_ES;
4438 goto next_byte;
4439 case 0x64:
4440 s->override = R_FS;
4441 goto next_byte;
4442 case 0x65:
4443 s->override = R_GS;
4444 goto next_byte;
4445 case 0x66:
4446 prefixes |= PREFIX_DATA;
4447 goto next_byte;
4448 case 0x67:
4449 prefixes |= PREFIX_ADR;
4450 goto next_byte;
4451 #ifdef TARGET_X86_64
4452 case 0x40 ... 0x4f:
4453 if (CODE64(s)) {
4454 /* REX prefix */
4455 rex_w = (b >> 3) & 1;
4456 rex_r = (b & 0x4) << 1;
4457 s->rex_x = (b & 0x2) << 2;
4458 REX_B(s) = (b & 0x1) << 3;
4459 x86_64_hregs = 1; /* select uniform byte register addressing */
4460 goto next_byte;
4461 }
4462 break;
4463 #endif
4464 case 0xc5: /* 2-byte VEX */
4465 case 0xc4: /* 3-byte VEX */
4466 /* VEX prefixes cannot be used except in 32-bit mode.
4467 Otherwise the instruction is LES or LDS. */
4468 if (s->code32 && !s->vm86) {
4469 static const int pp_prefix[4] = {
4470 0, PREFIX_DATA, PREFIX_REPZ, PREFIX_REPNZ
4471 };
4472 int vex3, vex2 = cpu_ldub_code(env, s->pc);
4473
4474 if (!CODE64(s) && (vex2 & 0xc0) != 0xc0) {
4475 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4476 otherwise the instruction is LES or LDS. */
4477 break;
4478 }
4479 s->pc++;
4480
4481 /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
4482 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ
4483 | PREFIX_LOCK | PREFIX_DATA)) {
4484 goto illegal_op;
4485 }
4486 #ifdef TARGET_X86_64
4487 if (x86_64_hregs) {
4488 goto illegal_op;
4489 }
4490 #endif
4491 rex_r = (~vex2 >> 4) & 8;
4492 if (b == 0xc5) {
4493 vex3 = vex2;
4494 b = cpu_ldub_code(env, s->pc++);
4495 } else {
4496 #ifdef TARGET_X86_64
4497 s->rex_x = (~vex2 >> 3) & 8;
4498 s->rex_b = (~vex2 >> 2) & 8;
4499 #endif
4500 vex3 = cpu_ldub_code(env, s->pc++);
4501 rex_w = (vex3 >> 7) & 1;
4502 switch (vex2 & 0x1f) {
4503 case 0x01: /* Implied 0f leading opcode bytes. */
4504 b = cpu_ldub_code(env, s->pc++) | 0x100;
4505 break;
4506 case 0x02: /* Implied 0f 38 leading opcode bytes. */
4507 b = 0x138;
4508 break;
4509 case 0x03: /* Implied 0f 3a leading opcode bytes. */
4510 b = 0x13a;
4511 break;
4512 default: /* Reserved for future use. */
4513 goto unknown_op;
4514 }
4515 }
4516 s->vex_v = (~vex3 >> 3) & 0xf;
4517 s->vex_l = (vex3 >> 2) & 1;
4518 prefixes |= pp_prefix[vex3 & 3] | PREFIX_VEX;
4519 }
4520 break;
4521 }
4522
4523 /* Post-process prefixes. */
4524 if (CODE64(s)) {
4525 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit
4526 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4527 over 0x66 if both are present. */
4528 dflag = (rex_w > 0 ? MO_64 : prefixes & PREFIX_DATA ? MO_16 : MO_32);
4529 /* In 64-bit mode, 0x67 selects 32-bit addressing. */
4530 aflag = (prefixes & PREFIX_ADR ? MO_32 : MO_64);
4531 } else {
4532 /* In 16/32-bit mode, 0x66 selects the opposite data size. */
4533 if (s->code32 ^ ((prefixes & PREFIX_DATA) != 0)) {
4534 dflag = MO_32;
4535 } else {
4536 dflag = MO_16;
4537 }
4538 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */
4539 if (s->code32 ^ ((prefixes & PREFIX_ADR) != 0)) {
4540 aflag = MO_32;
4541 } else {
4542 aflag = MO_16;
4543 }
4544 }
4545
4546 s->prefix = prefixes;
4547 s->aflag = aflag;
4548 s->dflag = dflag;
4549
4550 /* now check op code */
4551 reswitch:
4552 switch(b) {
4553 case 0x0f:
4554 /**************************/
4555 /* extended op code */
4556 b = cpu_ldub_code(env, s->pc++) | 0x100;
4557 goto reswitch;
4558
4559 /**************************/
4560 /* arith & logic */
4561 case 0x00 ... 0x05:
4562 case 0x08 ... 0x0d:
4563 case 0x10 ... 0x15:
4564 case 0x18 ... 0x1d:
4565 case 0x20 ... 0x25:
4566 case 0x28 ... 0x2d:
4567 case 0x30 ... 0x35:
4568 case 0x38 ... 0x3d:
4569 {
4570 int op, f, val;
4571 op = (b >> 3) & 7;
4572 f = (b >> 1) & 3;
4573
4574 ot = mo_b_d(b, dflag);
4575
4576 switch(f) {
4577 case 0: /* OP Ev, Gv */
4578 modrm = cpu_ldub_code(env, s->pc++);
4579 reg = ((modrm >> 3) & 7) | rex_r;
4580 mod = (modrm >> 6) & 3;
4581 rm = (modrm & 7) | REX_B(s);
4582 if (mod != 3) {
4583 gen_lea_modrm(env, s, modrm);
4584 opreg = OR_TMP0;
4585 } else if (op == OP_XORL && rm == reg) {
4586 xor_zero:
4587 /* xor reg, reg optimisation */
4588 set_cc_op(s, CC_OP_CLR);
4589 tcg_gen_movi_tl(cpu_T0, 0);
4590 gen_op_mov_reg_v(ot, reg, cpu_T0);
4591 break;
4592 } else {
4593 opreg = rm;
4594 }
4595 gen_op_mov_v_reg(ot, cpu_T1, reg);
4596 gen_op(s, op, ot, opreg);
4597 break;
4598 case 1: /* OP Gv, Ev */
4599 modrm = cpu_ldub_code(env, s->pc++);
4600 mod = (modrm >> 6) & 3;
4601 reg = ((modrm >> 3) & 7) | rex_r;
4602 rm = (modrm & 7) | REX_B(s);
4603 if (mod != 3) {
4604 gen_lea_modrm(env, s, modrm);
4605 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
4606 } else if (op == OP_XORL && rm == reg) {
4607 goto xor_zero;
4608 } else {
4609 gen_op_mov_v_reg(ot, cpu_T1, rm);
4610 }
4611 gen_op(s, op, ot, reg);
4612 break;
4613 case 2: /* OP A, Iv */
4614 val = insn_get(env, s, ot);
4615 tcg_gen_movi_tl(cpu_T1, val);
4616 gen_op(s, op, ot, OR_EAX);
4617 break;
4618 }
4619 }
4620 break;
4621
4622 case 0x82:
4623 if (CODE64(s))
4624 goto illegal_op;
4625 case 0x80: /* GRP1 */
4626 case 0x81:
4627 case 0x83:
4628 {
4629 int val;
4630
4631 ot = mo_b_d(b, dflag);
4632
4633 modrm = cpu_ldub_code(env, s->pc++);
4634 mod = (modrm >> 6) & 3;
4635 rm = (modrm & 7) | REX_B(s);
4636 op = (modrm >> 3) & 7;
4637
4638 if (mod != 3) {
4639 if (b == 0x83)
4640 s->rip_offset = 1;
4641 else
4642 s->rip_offset = insn_const_size(ot);
4643 gen_lea_modrm(env, s, modrm);
4644 opreg = OR_TMP0;
4645 } else {
4646 opreg = rm;
4647 }
4648
4649 switch(b) {
4650 default:
4651 case 0x80:
4652 case 0x81:
4653 case 0x82:
4654 val = insn_get(env, s, ot);
4655 break;
4656 case 0x83:
4657 val = (int8_t)insn_get(env, s, MO_8);
4658 break;
4659 }
4660 tcg_gen_movi_tl(cpu_T1, val);
4661 gen_op(s, op, ot, opreg);
4662 }
4663 break;
4664
4665 /**************************/
4666 /* inc, dec, and other misc arith */
4667 case 0x40 ... 0x47: /* inc Gv */
4668 ot = dflag;
4669 gen_inc(s, ot, OR_EAX + (b & 7), 1);
4670 break;
4671 case 0x48 ... 0x4f: /* dec Gv */
4672 ot = dflag;
4673 gen_inc(s, ot, OR_EAX + (b & 7), -1);
4674 break;
4675 case 0xf6: /* GRP3 */
4676 case 0xf7:
4677 ot = mo_b_d(b, dflag);
4678
4679 modrm = cpu_ldub_code(env, s->pc++);
4680 mod = (modrm >> 6) & 3;
4681 rm = (modrm & 7) | REX_B(s);
4682 op = (modrm >> 3) & 7;
4683 if (mod != 3) {
4684 if (op == 0) {
4685 s->rip_offset = insn_const_size(ot);
4686 }
4687 gen_lea_modrm(env, s, modrm);
4688 /* For those below that handle locked memory, don't load here. */
4689 if (!(s->prefix & PREFIX_LOCK)
4690 || op != 2) {
4691 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
4692 }
4693 } else {
4694 gen_op_mov_v_reg(ot, cpu_T0, rm);
4695 }
4696
4697 switch(op) {
4698 case 0: /* test */
4699 val = insn_get(env, s, ot);
4700 tcg_gen_movi_tl(cpu_T1, val);
4701 gen_op_testl_T0_T1_cc();
4702 set_cc_op(s, CC_OP_LOGICB + ot);
4703 break;
4704 case 2: /* not */
4705 if (s->prefix & PREFIX_LOCK) {
4706 if (mod == 3) {
4707 goto illegal_op;
4708 }
4709 tcg_gen_movi_tl(cpu_T0, ~0);
4710 tcg_gen_atomic_xor_fetch_tl(cpu_T0, cpu_A0, cpu_T0,
4711 s->mem_index, ot | MO_LE);
4712 } else {
4713 tcg_gen_not_tl(cpu_T0, cpu_T0);
4714 if (mod != 3) {
4715 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
4716 } else {
4717 gen_op_mov_reg_v(ot, rm, cpu_T0);
4718 }
4719 }
4720 break;
4721 case 3: /* neg */
4722 if (s->prefix & PREFIX_LOCK) {
4723 TCGLabel *label1;
4724 TCGv a0, t0, t1, t2;
4725
4726 if (mod == 3) {
4727 goto illegal_op;
4728 }
4729 a0 = tcg_temp_local_new();
4730 t0 = tcg_temp_local_new();
4731 label1 = gen_new_label();
4732
4733 tcg_gen_mov_tl(a0, cpu_A0);
4734 tcg_gen_mov_tl(t0, cpu_T0);
4735
4736 gen_set_label(label1);
4737 t1 = tcg_temp_new();
4738 t2 = tcg_temp_new();
4739 tcg_gen_mov_tl(t2, t0);
4740 tcg_gen_neg_tl(t1, t0);
4741 tcg_gen_atomic_cmpxchg_tl(t0, a0, t0, t1,
4742 s->mem_index, ot | MO_LE);
4743 tcg_temp_free(t1);
4744 tcg_gen_brcond_tl(TCG_COND_NE, t0, t2, label1);
4745
4746 tcg_temp_free(t2);
4747 tcg_temp_free(a0);
4748 tcg_gen_mov_tl(cpu_T0, t0);
4749 tcg_temp_free(t0);
4750 } else {
4751 tcg_gen_neg_tl(cpu_T0, cpu_T0);
4752 if (mod != 3) {
4753 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
4754 } else {
4755 gen_op_mov_reg_v(ot, rm, cpu_T0);
4756 }
4757 }
4758 gen_op_update_neg_cc();
4759 set_cc_op(s, CC_OP_SUBB + ot);
4760 break;
4761 case 4: /* mul */
4762 switch(ot) {
4763 case MO_8:
4764 gen_op_mov_v_reg(MO_8, cpu_T1, R_EAX);
4765 tcg_gen_ext8u_tl(cpu_T0, cpu_T0);
4766 tcg_gen_ext8u_tl(cpu_T1, cpu_T1);
4767 /* XXX: use 32 bit mul which could be faster */
4768 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
4769 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
4770 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4771 tcg_gen_andi_tl(cpu_cc_src, cpu_T0, 0xff00);
4772 set_cc_op(s, CC_OP_MULB);
4773 break;
4774 case MO_16:
4775 gen_op_mov_v_reg(MO_16, cpu_T1, R_EAX);
4776 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
4777 tcg_gen_ext16u_tl(cpu_T1, cpu_T1);
4778 /* XXX: use 32 bit mul which could be faster */
4779 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
4780 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
4781 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4782 tcg_gen_shri_tl(cpu_T0, cpu_T0, 16);
4783 gen_op_mov_reg_v(MO_16, R_EDX, cpu_T0);
4784 tcg_gen_mov_tl(cpu_cc_src, cpu_T0);
4785 set_cc_op(s, CC_OP_MULW);
4786 break;
4787 default:
4788 case MO_32:
4789 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
4790 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_regs[R_EAX]);
4791 tcg_gen_mulu2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
4792 cpu_tmp2_i32, cpu_tmp3_i32);
4793 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], cpu_tmp2_i32);
4794 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], cpu_tmp3_i32);
4795 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4796 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]);
4797 set_cc_op(s, CC_OP_MULL);
4798 break;
4799 #ifdef TARGET_X86_64
4800 case MO_64:
4801 tcg_gen_mulu2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX],
4802 cpu_T0, cpu_regs[R_EAX]);
4803 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4804 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]);
4805 set_cc_op(s, CC_OP_MULQ);
4806 break;
4807 #endif
4808 }
4809 break;
4810 case 5: /* imul */
4811 switch(ot) {
4812 case MO_8:
4813 gen_op_mov_v_reg(MO_8, cpu_T1, R_EAX);
4814 tcg_gen_ext8s_tl(cpu_T0, cpu_T0);
4815 tcg_gen_ext8s_tl(cpu_T1, cpu_T1);
4816 /* XXX: use 32 bit mul which could be faster */
4817 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
4818 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
4819 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4820 tcg_gen_ext8s_tl(cpu_tmp0, cpu_T0);
4821 tcg_gen_sub_tl(cpu_cc_src, cpu_T0, cpu_tmp0);
4822 set_cc_op(s, CC_OP_MULB);
4823 break;
4824 case MO_16:
4825 gen_op_mov_v_reg(MO_16, cpu_T1, R_EAX);
4826 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
4827 tcg_gen_ext16s_tl(cpu_T1, cpu_T1);
4828 /* XXX: use 32 bit mul which could be faster */
4829 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
4830 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
4831 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
4832 tcg_gen_ext16s_tl(cpu_tmp0, cpu_T0);
4833 tcg_gen_sub_tl(cpu_cc_src, cpu_T0, cpu_tmp0);
4834 tcg_gen_shri_tl(cpu_T0, cpu_T0, 16);
4835 gen_op_mov_reg_v(MO_16, R_EDX, cpu_T0);
4836 set_cc_op(s, CC_OP_MULW);
4837 break;
4838 default:
4839 case MO_32:
4840 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
4841 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_regs[R_EAX]);
4842 tcg_gen_muls2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
4843 cpu_tmp2_i32, cpu_tmp3_i32);
4844 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], cpu_tmp2_i32);
4845 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], cpu_tmp3_i32);
4846 tcg_gen_sari_i32(cpu_tmp2_i32, cpu_tmp2_i32, 31);
4847 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4848 tcg_gen_sub_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
4849 tcg_gen_extu_i32_tl(cpu_cc_src, cpu_tmp2_i32);
4850 set_cc_op(s, CC_OP_MULL);
4851 break;
4852 #ifdef TARGET_X86_64
4853 case MO_64:
4854 tcg_gen_muls2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX],
4855 cpu_T0, cpu_regs[R_EAX]);
4856 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4857 tcg_gen_sari_tl(cpu_cc_src, cpu_regs[R_EAX], 63);
4858 tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, cpu_regs[R_EDX]);
4859 set_cc_op(s, CC_OP_MULQ);
4860 break;
4861 #endif
4862 }
4863 break;
4864 case 6: /* div */
4865 switch(ot) {
4866 case MO_8:
4867 gen_helper_divb_AL(cpu_env, cpu_T0);
4868 break;
4869 case MO_16:
4870 gen_helper_divw_AX(cpu_env, cpu_T0);
4871 break;
4872 default:
4873 case MO_32:
4874 gen_helper_divl_EAX(cpu_env, cpu_T0);
4875 break;
4876 #ifdef TARGET_X86_64
4877 case MO_64:
4878 gen_helper_divq_EAX(cpu_env, cpu_T0);
4879 break;
4880 #endif
4881 }
4882 break;
4883 case 7: /* idiv */
4884 switch(ot) {
4885 case MO_8:
4886 gen_helper_idivb_AL(cpu_env, cpu_T0);
4887 break;
4888 case MO_16:
4889 gen_helper_idivw_AX(cpu_env, cpu_T0);
4890 break;
4891 default:
4892 case MO_32:
4893 gen_helper_idivl_EAX(cpu_env, cpu_T0);
4894 break;
4895 #ifdef TARGET_X86_64
4896 case MO_64:
4897 gen_helper_idivq_EAX(cpu_env, cpu_T0);
4898 break;
4899 #endif
4900 }
4901 break;
4902 default:
4903 goto unknown_op;
4904 }
4905 break;
4906
4907 case 0xfe: /* GRP4 */
4908 case 0xff: /* GRP5 */
4909 ot = mo_b_d(b, dflag);
4910
4911 modrm = cpu_ldub_code(env, s->pc++);
4912 mod = (modrm >> 6) & 3;
4913 rm = (modrm & 7) | REX_B(s);
4914 op = (modrm >> 3) & 7;
4915 if (op >= 2 && b == 0xfe) {
4916 goto unknown_op;
4917 }
4918 if (CODE64(s)) {
4919 if (op == 2 || op == 4) {
4920 /* operand size for jumps is 64 bit */
4921 ot = MO_64;
4922 } else if (op == 3 || op == 5) {
4923 ot = dflag != MO_16 ? MO_32 + (rex_w == 1) : MO_16;
4924 } else if (op == 6) {
4925 /* default push size is 64 bit */
4926 ot = mo_pushpop(s, dflag);
4927 }
4928 }
4929 if (mod != 3) {
4930 gen_lea_modrm(env, s, modrm);
4931 if (op >= 2 && op != 3 && op != 5)
4932 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
4933 } else {
4934 gen_op_mov_v_reg(ot, cpu_T0, rm);
4935 }
4936
4937 switch(op) {
4938 case 0: /* inc Ev */
4939 if (mod != 3)
4940 opreg = OR_TMP0;
4941 else
4942 opreg = rm;
4943 gen_inc(s, ot, opreg, 1);
4944 break;
4945 case 1: /* dec Ev */
4946 if (mod != 3)
4947 opreg = OR_TMP0;
4948 else
4949 opreg = rm;
4950 gen_inc(s, ot, opreg, -1);
4951 break;
4952 case 2: /* call Ev */
4953 /* XXX: optimize if memory (no 'and' is necessary) */
4954 if (dflag == MO_16) {
4955 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
4956 }
4957 next_eip = s->pc - s->cs_base;
4958 tcg_gen_movi_tl(cpu_T1, next_eip);
4959 gen_push_v(s, cpu_T1);
4960 gen_op_jmp_v(cpu_T0);
4961 gen_bnd_jmp(s);
4962 gen_eob(s);
4963 break;
4964 case 3: /* lcall Ev */
4965 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
4966 gen_add_A0_im(s, 1 << ot);
4967 gen_op_ld_v(s, MO_16, cpu_T0, cpu_A0);
4968 do_lcall:
4969 if (s->pe && !s->vm86) {
4970 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
4971 gen_helper_lcall_protected(cpu_env, cpu_tmp2_i32, cpu_T1,
4972 tcg_const_i32(dflag - 1),
4973 tcg_const_tl(s->pc - s->cs_base));
4974 } else {
4975 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
4976 gen_helper_lcall_real(cpu_env, cpu_tmp2_i32, cpu_T1,
4977 tcg_const_i32(dflag - 1),
4978 tcg_const_i32(s->pc - s->cs_base));
4979 }
4980 gen_eob(s);
4981 break;
4982 case 4: /* jmp Ev */
4983 if (dflag == MO_16) {
4984 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
4985 }
4986 gen_op_jmp_v(cpu_T0);
4987 gen_bnd_jmp(s);
4988 gen_eob(s);
4989 break;
4990 case 5: /* ljmp Ev */
4991 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
4992 gen_add_A0_im(s, 1 << ot);
4993 gen_op_ld_v(s, MO_16, cpu_T0, cpu_A0);
4994 do_ljmp:
4995 if (s->pe && !s->vm86) {
4996 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
4997 gen_helper_ljmp_protected(cpu_env, cpu_tmp2_i32, cpu_T1,
4998 tcg_const_tl(s->pc - s->cs_base));
4999 } else {
5000 gen_op_movl_seg_T0_vm(R_CS);
5001 gen_op_jmp_v(cpu_T1);
5002 }
5003 gen_eob(s);
5004 break;
5005 case 6: /* push Ev */
5006 gen_push_v(s, cpu_T0);
5007 break;
5008 default:
5009 goto unknown_op;
5010 }
5011 break;
5012
5013 case 0x84: /* test Ev, Gv */
5014 case 0x85:
5015 ot = mo_b_d(b, dflag);
5016
5017 modrm = cpu_ldub_code(env, s->pc++);
5018 reg = ((modrm >> 3) & 7) | rex_r;
5019
5020 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5021 gen_op_mov_v_reg(ot, cpu_T1, reg);
5022 gen_op_testl_T0_T1_cc();
5023 set_cc_op(s, CC_OP_LOGICB + ot);
5024 break;
5025
5026 case 0xa8: /* test eAX, Iv */
5027 case 0xa9:
5028 ot = mo_b_d(b, dflag);
5029 val = insn_get(env, s, ot);
5030
5031 gen_op_mov_v_reg(ot, cpu_T0, OR_EAX);
5032 tcg_gen_movi_tl(cpu_T1, val);
5033 gen_op_testl_T0_T1_cc();
5034 set_cc_op(s, CC_OP_LOGICB + ot);
5035 break;
5036
5037 case 0x98: /* CWDE/CBW */
5038 switch (dflag) {
5039 #ifdef TARGET_X86_64
5040 case MO_64:
5041 gen_op_mov_v_reg(MO_32, cpu_T0, R_EAX);
5042 tcg_gen_ext32s_tl(cpu_T0, cpu_T0);
5043 gen_op_mov_reg_v(MO_64, R_EAX, cpu_T0);
5044 break;
5045 #endif
5046 case MO_32:
5047 gen_op_mov_v_reg(MO_16, cpu_T0, R_EAX);
5048 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
5049 gen_op_mov_reg_v(MO_32, R_EAX, cpu_T0);
5050 break;
5051 case MO_16:
5052 gen_op_mov_v_reg(MO_8, cpu_T0, R_EAX);
5053 tcg_gen_ext8s_tl(cpu_T0, cpu_T0);
5054 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
5055 break;
5056 default:
5057 tcg_abort();
5058 }
5059 break;
5060 case 0x99: /* CDQ/CWD */
5061 switch (dflag) {
5062 #ifdef TARGET_X86_64
5063 case MO_64:
5064 gen_op_mov_v_reg(MO_64, cpu_T0, R_EAX);
5065 tcg_gen_sari_tl(cpu_T0, cpu_T0, 63);
5066 gen_op_mov_reg_v(MO_64, R_EDX, cpu_T0);
5067 break;
5068 #endif
5069 case MO_32:
5070 gen_op_mov_v_reg(MO_32, cpu_T0, R_EAX);
5071 tcg_gen_ext32s_tl(cpu_T0, cpu_T0);
5072 tcg_gen_sari_tl(cpu_T0, cpu_T0, 31);
5073 gen_op_mov_reg_v(MO_32, R_EDX, cpu_T0);
5074 break;
5075 case MO_16:
5076 gen_op_mov_v_reg(MO_16, cpu_T0, R_EAX);
5077 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
5078 tcg_gen_sari_tl(cpu_T0, cpu_T0, 15);
5079 gen_op_mov_reg_v(MO_16, R_EDX, cpu_T0);
5080 break;
5081 default:
5082 tcg_abort();
5083 }
5084 break;
5085 case 0x1af: /* imul Gv, Ev */
5086 case 0x69: /* imul Gv, Ev, I */
5087 case 0x6b:
5088 ot = dflag;
5089 modrm = cpu_ldub_code(env, s->pc++);
5090 reg = ((modrm >> 3) & 7) | rex_r;
5091 if (b == 0x69)
5092 s->rip_offset = insn_const_size(ot);
5093 else if (b == 0x6b)
5094 s->rip_offset = 1;
5095 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5096 if (b == 0x69) {
5097 val = insn_get(env, s, ot);
5098 tcg_gen_movi_tl(cpu_T1, val);
5099 } else if (b == 0x6b) {
5100 val = (int8_t)insn_get(env, s, MO_8);
5101 tcg_gen_movi_tl(cpu_T1, val);
5102 } else {
5103 gen_op_mov_v_reg(ot, cpu_T1, reg);
5104 }
5105 switch (ot) {
5106 #ifdef TARGET_X86_64
5107 case MO_64:
5108 tcg_gen_muls2_i64(cpu_regs[reg], cpu_T1, cpu_T0, cpu_T1);
5109 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]);
5110 tcg_gen_sari_tl(cpu_cc_src, cpu_cc_dst, 63);
5111 tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, cpu_T1);
5112 break;
5113 #endif
5114 case MO_32:
5115 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
5116 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T1);
5117 tcg_gen_muls2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
5118 cpu_tmp2_i32, cpu_tmp3_i32);
5119 tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);
5120 tcg_gen_sari_i32(cpu_tmp2_i32, cpu_tmp2_i32, 31);
5121 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]);
5122 tcg_gen_sub_i32(cpu_tmp2_i32, cpu_tmp2_i32, cpu_tmp3_i32);
5123 tcg_gen_extu_i32_tl(cpu_cc_src, cpu_tmp2_i32);
5124 break;
5125 default:
5126 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
5127 tcg_gen_ext16s_tl(cpu_T1, cpu_T1);
5128 /* XXX: use 32 bit mul which could be faster */
5129 tcg_gen_mul_tl(cpu_T0, cpu_T0, cpu_T1);
5130 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
5131 tcg_gen_ext16s_tl(cpu_tmp0, cpu_T0);
5132 tcg_gen_sub_tl(cpu_cc_src, cpu_T0, cpu_tmp0);
5133 gen_op_mov_reg_v(ot, reg, cpu_T0);
5134 break;
5135 }
5136 set_cc_op(s, CC_OP_MULB + ot);
5137 break;
5138 case 0x1c0:
5139 case 0x1c1: /* xadd Ev, Gv */
5140 ot = mo_b_d(b, dflag);
5141 modrm = cpu_ldub_code(env, s->pc++);
5142 reg = ((modrm >> 3) & 7) | rex_r;
5143 mod = (modrm >> 6) & 3;
5144 gen_op_mov_v_reg(ot, cpu_T0, reg);
5145 if (mod == 3) {
5146 rm = (modrm & 7) | REX_B(s);
5147 gen_op_mov_v_reg(ot, cpu_T1, rm);
5148 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
5149 gen_op_mov_reg_v(ot, reg, cpu_T1);
5150 gen_op_mov_reg_v(ot, rm, cpu_T0);
5151 } else {
5152 gen_lea_modrm(env, s, modrm);
5153 if (s->prefix & PREFIX_LOCK) {
5154 tcg_gen_atomic_fetch_add_tl(cpu_T1, cpu_A0, cpu_T0,
5155 s->mem_index, ot | MO_LE);
5156 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
5157 } else {
5158 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
5159 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
5160 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
5161 }
5162 gen_op_mov_reg_v(ot, reg, cpu_T1);
5163 }
5164 gen_op_update2_cc();
5165 set_cc_op(s, CC_OP_ADDB + ot);
5166 break;
5167 case 0x1b0:
5168 case 0x1b1: /* cmpxchg Ev, Gv */
5169 {
5170 TCGv oldv, newv, cmpv;
5171
5172 ot = mo_b_d(b, dflag);
5173 modrm = cpu_ldub_code(env, s->pc++);
5174 reg = ((modrm >> 3) & 7) | rex_r;
5175 mod = (modrm >> 6) & 3;
5176 oldv = tcg_temp_new();
5177 newv = tcg_temp_new();
5178 cmpv = tcg_temp_new();
5179 gen_op_mov_v_reg(ot, newv, reg);
5180 tcg_gen_mov_tl(cmpv, cpu_regs[R_EAX]);
5181
5182 if (s->prefix & PREFIX_LOCK) {
5183 if (mod == 3) {
5184 goto illegal_op;
5185 }
5186 gen_lea_modrm(env, s, modrm);
5187 tcg_gen_atomic_cmpxchg_tl(oldv, cpu_A0, cmpv, newv,
5188 s->mem_index, ot | MO_LE);
5189 gen_op_mov_reg_v(ot, R_EAX, oldv);
5190 } else {
5191 if (mod == 3) {
5192 rm = (modrm & 7) | REX_B(s);
5193 gen_op_mov_v_reg(ot, oldv, rm);
5194 } else {
5195 gen_lea_modrm(env, s, modrm);
5196 gen_op_ld_v(s, ot, oldv, cpu_A0);
5197 rm = 0; /* avoid warning */
5198 }
5199 gen_extu(ot, oldv);
5200 gen_extu(ot, cmpv);
5201 /* store value = (old == cmp ? new : old); */
5202 tcg_gen_movcond_tl(TCG_COND_EQ, newv, oldv, cmpv, newv, oldv);
5203 if (mod == 3) {
5204 gen_op_mov_reg_v(ot, R_EAX, oldv);
5205 gen_op_mov_reg_v(ot, rm, newv);
5206 } else {
5207 /* Perform an unconditional store cycle like physical cpu;
5208 must be before changing accumulator to ensure
5209 idempotency if the store faults and the instruction
5210 is restarted */
5211 gen_op_st_v(s, ot, newv, cpu_A0);
5212 gen_op_mov_reg_v(ot, R_EAX, oldv);
5213 }
5214 }
5215 tcg_gen_mov_tl(cpu_cc_src, oldv);
5216 tcg_gen_mov_tl(cpu_cc_srcT, cmpv);
5217 tcg_gen_sub_tl(cpu_cc_dst, cmpv, oldv);
5218 set_cc_op(s, CC_OP_SUBB + ot);
5219 tcg_temp_free(oldv);
5220 tcg_temp_free(newv);
5221 tcg_temp_free(cmpv);
5222 }
5223 break;
5224 case 0x1c7: /* cmpxchg8b */
5225 modrm = cpu_ldub_code(env, s->pc++);
5226 mod = (modrm >> 6) & 3;
5227 if ((mod == 3) || ((modrm & 0x38) != 0x8))
5228 goto illegal_op;
5229 #ifdef TARGET_X86_64
5230 if (dflag == MO_64) {
5231 if (!(s->cpuid_ext_features & CPUID_EXT_CX16))
5232 goto illegal_op;
5233 gen_lea_modrm(env, s, modrm);
5234 if ((s->prefix & PREFIX_LOCK) && parallel_cpus) {
5235 gen_helper_cmpxchg16b(cpu_env, cpu_A0);
5236 } else {
5237 gen_helper_cmpxchg16b_unlocked(cpu_env, cpu_A0);
5238 }
5239 } else
5240 #endif
5241 {
5242 if (!(s->cpuid_features & CPUID_CX8))
5243 goto illegal_op;
5244 gen_lea_modrm(env, s, modrm);
5245 if ((s->prefix & PREFIX_LOCK) && parallel_cpus) {
5246 gen_helper_cmpxchg8b(cpu_env, cpu_A0);
5247 } else {
5248 gen_helper_cmpxchg8b_unlocked(cpu_env, cpu_A0);
5249 }
5250 }
5251 set_cc_op(s, CC_OP_EFLAGS);
5252 break;
5253
5254 /**************************/
5255 /* push/pop */
5256 case 0x50 ... 0x57: /* push */
5257 gen_op_mov_v_reg(MO_32, cpu_T0, (b & 7) | REX_B(s));
5258 gen_push_v(s, cpu_T0);
5259 break;
5260 case 0x58 ... 0x5f: /* pop */
5261 ot = gen_pop_T0(s);
5262 /* NOTE: order is important for pop %sp */
5263 gen_pop_update(s, ot);
5264 gen_op_mov_reg_v(ot, (b & 7) | REX_B(s), cpu_T0);
5265 break;
5266 case 0x60: /* pusha */
5267 if (CODE64(s))
5268 goto illegal_op;
5269 gen_pusha(s);
5270 break;
5271 case 0x61: /* popa */
5272 if (CODE64(s))
5273 goto illegal_op;
5274 gen_popa(s);
5275 break;
5276 case 0x68: /* push Iv */
5277 case 0x6a:
5278 ot = mo_pushpop(s, dflag);
5279 if (b == 0x68)
5280 val = insn_get(env, s, ot);
5281 else
5282 val = (int8_t)insn_get(env, s, MO_8);
5283 tcg_gen_movi_tl(cpu_T0, val);
5284 gen_push_v(s, cpu_T0);
5285 break;
5286 case 0x8f: /* pop Ev */
5287 modrm = cpu_ldub_code(env, s->pc++);
5288 mod = (modrm >> 6) & 3;
5289 ot = gen_pop_T0(s);
5290 if (mod == 3) {
5291 /* NOTE: order is important for pop %sp */
5292 gen_pop_update(s, ot);
5293 rm = (modrm & 7) | REX_B(s);
5294 gen_op_mov_reg_v(ot, rm, cpu_T0);
5295 } else {
5296 /* NOTE: order is important too for MMU exceptions */
5297 s->popl_esp_hack = 1 << ot;
5298 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5299 s->popl_esp_hack = 0;
5300 gen_pop_update(s, ot);
5301 }
5302 break;
5303 case 0xc8: /* enter */
5304 {
5305 int level;
5306 val = cpu_lduw_code(env, s->pc);
5307 s->pc += 2;
5308 level = cpu_ldub_code(env, s->pc++);
5309 gen_enter(s, val, level);
5310 }
5311 break;
5312 case 0xc9: /* leave */
5313 gen_leave(s);
5314 break;
5315 case 0x06: /* push es */
5316 case 0x0e: /* push cs */
5317 case 0x16: /* push ss */
5318 case 0x1e: /* push ds */
5319 if (CODE64(s))
5320 goto illegal_op;
5321 gen_op_movl_T0_seg(b >> 3);
5322 gen_push_v(s, cpu_T0);
5323 break;
5324 case 0x1a0: /* push fs */
5325 case 0x1a8: /* push gs */
5326 gen_op_movl_T0_seg((b >> 3) & 7);
5327 gen_push_v(s, cpu_T0);
5328 break;
5329 case 0x07: /* pop es */
5330 case 0x17: /* pop ss */
5331 case 0x1f: /* pop ds */
5332 if (CODE64(s))
5333 goto illegal_op;
5334 reg = b >> 3;
5335 ot = gen_pop_T0(s);
5336 gen_movl_seg_T0(s, reg);
5337 gen_pop_update(s, ot);
5338 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5339 if (s->is_jmp) {
5340 gen_jmp_im(s->pc - s->cs_base);
5341 if (reg == R_SS) {
5342 s->tf = 0;
5343 gen_eob_inhibit_irq(s, true);
5344 } else {
5345 gen_eob(s);
5346 }
5347 }
5348 break;
5349 case 0x1a1: /* pop fs */
5350 case 0x1a9: /* pop gs */
5351 ot = gen_pop_T0(s);
5352 gen_movl_seg_T0(s, (b >> 3) & 7);
5353 gen_pop_update(s, ot);
5354 if (s->is_jmp) {
5355 gen_jmp_im(s->pc - s->cs_base);
5356 gen_eob(s);
5357 }
5358 break;
5359
5360 /**************************/
5361 /* mov */
5362 case 0x88:
5363 case 0x89: /* mov Gv, Ev */
5364 ot = mo_b_d(b, dflag);
5365 modrm = cpu_ldub_code(env, s->pc++);
5366 reg = ((modrm >> 3) & 7) | rex_r;
5367
5368 /* generate a generic store */
5369 gen_ldst_modrm(env, s, modrm, ot, reg, 1);
5370 break;
5371 case 0xc6:
5372 case 0xc7: /* mov Ev, Iv */
5373 ot = mo_b_d(b, dflag);
5374 modrm = cpu_ldub_code(env, s->pc++);
5375 mod = (modrm >> 6) & 3;
5376 if (mod != 3) {
5377 s->rip_offset = insn_const_size(ot);
5378 gen_lea_modrm(env, s, modrm);
5379 }
5380 val = insn_get(env, s, ot);
5381 tcg_gen_movi_tl(cpu_T0, val);
5382 if (mod != 3) {
5383 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
5384 } else {
5385 gen_op_mov_reg_v(ot, (modrm & 7) | REX_B(s), cpu_T0);
5386 }
5387 break;
5388 case 0x8a:
5389 case 0x8b: /* mov Ev, Gv */
5390 ot = mo_b_d(b, dflag);
5391 modrm = cpu_ldub_code(env, s->pc++);
5392 reg = ((modrm >> 3) & 7) | rex_r;
5393
5394 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5395 gen_op_mov_reg_v(ot, reg, cpu_T0);
5396 break;
5397 case 0x8e: /* mov seg, Gv */
5398 modrm = cpu_ldub_code(env, s->pc++);
5399 reg = (modrm >> 3) & 7;
5400 if (reg >= 6 || reg == R_CS)
5401 goto illegal_op;
5402 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
5403 gen_movl_seg_T0(s, reg);
5404 /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
5405 if (s->is_jmp) {
5406 gen_jmp_im(s->pc - s->cs_base);
5407 if (reg == R_SS) {
5408 s->tf = 0;
5409 gen_eob_inhibit_irq(s, true);
5410 } else {
5411 gen_eob(s);
5412 }
5413 }
5414 break;
5415 case 0x8c: /* mov Gv, seg */
5416 modrm = cpu_ldub_code(env, s->pc++);
5417 reg = (modrm >> 3) & 7;
5418 mod = (modrm >> 6) & 3;
5419 if (reg >= 6)
5420 goto illegal_op;
5421 gen_op_movl_T0_seg(reg);
5422 ot = mod == 3 ? dflag : MO_16;
5423 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5424 break;
5425
5426 case 0x1b6: /* movzbS Gv, Eb */
5427 case 0x1b7: /* movzwS Gv, Eb */
5428 case 0x1be: /* movsbS Gv, Eb */
5429 case 0x1bf: /* movswS Gv, Eb */
5430 {
5431 TCGMemOp d_ot;
5432 TCGMemOp s_ot;
5433
5434 /* d_ot is the size of destination */
5435 d_ot = dflag;
5436 /* ot is the size of source */
5437 ot = (b & 1) + MO_8;
5438 /* s_ot is the sign+size of source */
5439 s_ot = b & 8 ? MO_SIGN | ot : ot;
5440
5441 modrm = cpu_ldub_code(env, s->pc++);
5442 reg = ((modrm >> 3) & 7) | rex_r;
5443 mod = (modrm >> 6) & 3;
5444 rm = (modrm & 7) | REX_B(s);
5445
5446 if (mod == 3) {
5447 if (s_ot == MO_SB && byte_reg_is_xH(rm)) {
5448 tcg_gen_sextract_tl(cpu_T0, cpu_regs[rm - 4], 8, 8);
5449 } else {
5450 gen_op_mov_v_reg(ot, cpu_T0, rm);
5451 switch (s_ot) {
5452 case MO_UB:
5453 tcg_gen_ext8u_tl(cpu_T0, cpu_T0);
5454 break;
5455 case MO_SB:
5456 tcg_gen_ext8s_tl(cpu_T0, cpu_T0);
5457 break;
5458 case MO_UW:
5459 tcg_gen_ext16u_tl(cpu_T0, cpu_T0);
5460 break;
5461 default:
5462 case MO_SW:
5463 tcg_gen_ext16s_tl(cpu_T0, cpu_T0);
5464 break;
5465 }
5466 }
5467 gen_op_mov_reg_v(d_ot, reg, cpu_T0);
5468 } else {
5469 gen_lea_modrm(env, s, modrm);
5470 gen_op_ld_v(s, s_ot, cpu_T0, cpu_A0);
5471 gen_op_mov_reg_v(d_ot, reg, cpu_T0);
5472 }
5473 }
5474 break;
5475
5476 case 0x8d: /* lea */
5477 modrm = cpu_ldub_code(env, s->pc++);
5478 mod = (modrm >> 6) & 3;
5479 if (mod == 3)
5480 goto illegal_op;
5481 reg = ((modrm >> 3) & 7) | rex_r;
5482 {
5483 AddressParts a = gen_lea_modrm_0(env, s, modrm);
5484 TCGv ea = gen_lea_modrm_1(a);
5485 gen_lea_v_seg(s, s->aflag, ea, -1, -1);
5486 gen_op_mov_reg_v(dflag, reg, cpu_A0);
5487 }
5488 break;
5489
5490 case 0xa0: /* mov EAX, Ov */
5491 case 0xa1:
5492 case 0xa2: /* mov Ov, EAX */
5493 case 0xa3:
5494 {
5495 target_ulong offset_addr;
5496
5497 ot = mo_b_d(b, dflag);
5498 switch (s->aflag) {
5499 #ifdef TARGET_X86_64
5500 case MO_64:
5501 offset_addr = cpu_ldq_code(env, s->pc);
5502 s->pc += 8;
5503 break;
5504 #endif
5505 default:
5506 offset_addr = insn_get(env, s, s->aflag);
5507 break;
5508 }
5509 tcg_gen_movi_tl(cpu_A0, offset_addr);
5510 gen_add_A0_ds_seg(s);
5511 if ((b & 2) == 0) {
5512 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
5513 gen_op_mov_reg_v(ot, R_EAX, cpu_T0);
5514 } else {
5515 gen_op_mov_v_reg(ot, cpu_T0, R_EAX);
5516 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
5517 }
5518 }
5519 break;
5520 case 0xd7: /* xlat */
5521 tcg_gen_mov_tl(cpu_A0, cpu_regs[R_EBX]);
5522 tcg_gen_ext8u_tl(cpu_T0, cpu_regs[R_EAX]);
5523 tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T0);
5524 gen_extu(s->aflag, cpu_A0);
5525 gen_add_A0_ds_seg(s);
5526 gen_op_ld_v(s, MO_8, cpu_T0, cpu_A0);
5527 gen_op_mov_reg_v(MO_8, R_EAX, cpu_T0);
5528 break;
5529 case 0xb0 ... 0xb7: /* mov R, Ib */
5530 val = insn_get(env, s, MO_8);
5531 tcg_gen_movi_tl(cpu_T0, val);
5532 gen_op_mov_reg_v(MO_8, (b & 7) | REX_B(s), cpu_T0);
5533 break;
5534 case 0xb8 ... 0xbf: /* mov R, Iv */
5535 #ifdef TARGET_X86_64
5536 if (dflag == MO_64) {
5537 uint64_t tmp;
5538 /* 64 bit case */
5539 tmp = cpu_ldq_code(env, s->pc);
5540 s->pc += 8;
5541 reg = (b & 7) | REX_B(s);
5542 tcg_gen_movi_tl(cpu_T0, tmp);
5543 gen_op_mov_reg_v(MO_64, reg, cpu_T0);
5544 } else
5545 #endif
5546 {
5547 ot = dflag;
5548 val = insn_get(env, s, ot);
5549 reg = (b & 7) | REX_B(s);
5550 tcg_gen_movi_tl(cpu_T0, val);
5551 gen_op_mov_reg_v(ot, reg, cpu_T0);
5552 }
5553 break;
5554
5555 case 0x91 ... 0x97: /* xchg R, EAX */
5556 do_xchg_reg_eax:
5557 ot = dflag;
5558 reg = (b & 7) | REX_B(s);
5559 rm = R_EAX;
5560 goto do_xchg_reg;
5561 case 0x86:
5562 case 0x87: /* xchg Ev, Gv */
5563 ot = mo_b_d(b, dflag);
5564 modrm = cpu_ldub_code(env, s->pc++);
5565 reg = ((modrm >> 3) & 7) | rex_r;
5566 mod = (modrm >> 6) & 3;
5567 if (mod == 3) {
5568 rm = (modrm & 7) | REX_B(s);
5569 do_xchg_reg:
5570 gen_op_mov_v_reg(ot, cpu_T0, reg);
5571 gen_op_mov_v_reg(ot, cpu_T1, rm);
5572 gen_op_mov_reg_v(ot, rm, cpu_T0);
5573 gen_op_mov_reg_v(ot, reg, cpu_T1);
5574 } else {
5575 gen_lea_modrm(env, s, modrm);
5576 gen_op_mov_v_reg(ot, cpu_T0, reg);
5577 /* for xchg, lock is implicit */
5578 tcg_gen_atomic_xchg_tl(cpu_T1, cpu_A0, cpu_T0,
5579 s->mem_index, ot | MO_LE);
5580 gen_op_mov_reg_v(ot, reg, cpu_T1);
5581 }
5582 break;
5583 case 0xc4: /* les Gv */
5584 /* In CODE64 this is VEX3; see above. */
5585 op = R_ES;
5586 goto do_lxx;
5587 case 0xc5: /* lds Gv */
5588 /* In CODE64 this is VEX2; see above. */
5589 op = R_DS;
5590 goto do_lxx;
5591 case 0x1b2: /* lss Gv */
5592 op = R_SS;
5593 goto do_lxx;
5594 case 0x1b4: /* lfs Gv */
5595 op = R_FS;
5596 goto do_lxx;
5597 case 0x1b5: /* lgs Gv */
5598 op = R_GS;
5599 do_lxx:
5600 ot = dflag != MO_16 ? MO_32 : MO_16;
5601 modrm = cpu_ldub_code(env, s->pc++);
5602 reg = ((modrm >> 3) & 7) | rex_r;
5603 mod = (modrm >> 6) & 3;
5604 if (mod == 3)
5605 goto illegal_op;
5606 gen_lea_modrm(env, s, modrm);
5607 gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
5608 gen_add_A0_im(s, 1 << ot);
5609 /* load the segment first to handle exceptions properly */
5610 gen_op_ld_v(s, MO_16, cpu_T0, cpu_A0);
5611 gen_movl_seg_T0(s, op);
5612 /* then put the data */
5613 gen_op_mov_reg_v(ot, reg, cpu_T1);
5614 if (s->is_jmp) {
5615 gen_jmp_im(s->pc - s->cs_base);
5616 gen_eob(s);
5617 }
5618 break;
5619
5620 /************************/
5621 /* shifts */
5622 case 0xc0:
5623 case 0xc1:
5624 /* shift Ev,Ib */
5625 shift = 2;
5626 grp2:
5627 {
5628 ot = mo_b_d(b, dflag);
5629 modrm = cpu_ldub_code(env, s->pc++);
5630 mod = (modrm >> 6) & 3;
5631 op = (modrm >> 3) & 7;
5632
5633 if (mod != 3) {
5634 if (shift == 2) {
5635 s->rip_offset = 1;
5636 }
5637 gen_lea_modrm(env, s, modrm);
5638 opreg = OR_TMP0;
5639 } else {
5640 opreg = (modrm & 7) | REX_B(s);
5641 }
5642
5643 /* simpler op */
5644 if (shift == 0) {
5645 gen_shift(s, op, ot, opreg, OR_ECX);
5646 } else {
5647 if (shift == 2) {
5648 shift = cpu_ldub_code(env, s->pc++);
5649 }
5650 gen_shifti(s, op, ot, opreg, shift);
5651 }
5652 }
5653 break;
5654 case 0xd0:
5655 case 0xd1:
5656 /* shift Ev,1 */
5657 shift = 1;
5658 goto grp2;
5659 case 0xd2:
5660 case 0xd3:
5661 /* shift Ev,cl */
5662 shift = 0;
5663 goto grp2;
5664
5665 case 0x1a4: /* shld imm */
5666 op = 0;
5667 shift = 1;
5668 goto do_shiftd;
5669 case 0x1a5: /* shld cl */
5670 op = 0;
5671 shift = 0;
5672 goto do_shiftd;
5673 case 0x1ac: /* shrd imm */
5674 op = 1;
5675 shift = 1;
5676 goto do_shiftd;
5677 case 0x1ad: /* shrd cl */
5678 op = 1;
5679 shift = 0;
5680 do_shiftd:
5681 ot = dflag;
5682 modrm = cpu_ldub_code(env, s->pc++);
5683 mod = (modrm >> 6) & 3;
5684 rm = (modrm & 7) | REX_B(s);
5685 reg = ((modrm >> 3) & 7) | rex_r;
5686 if (mod != 3) {
5687 gen_lea_modrm(env, s, modrm);
5688 opreg = OR_TMP0;
5689 } else {
5690 opreg = rm;
5691 }
5692 gen_op_mov_v_reg(ot, cpu_T1, reg);
5693
5694 if (shift) {
5695 TCGv imm = tcg_const_tl(cpu_ldub_code(env, s->pc++));
5696 gen_shiftd_rm_T1(s, ot, opreg, op, imm);
5697 tcg_temp_free(imm);
5698 } else {
5699 gen_shiftd_rm_T1(s, ot, opreg, op, cpu_regs[R_ECX]);
5700 }
5701 break;
5702
5703 /************************/
5704 /* floats */
5705 case 0xd8 ... 0xdf:
5706 if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
5707 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5708 /* XXX: what to do if illegal op ? */
5709 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
5710 break;
5711 }
5712 modrm = cpu_ldub_code(env, s->pc++);
5713 mod = (modrm >> 6) & 3;
5714 rm = modrm & 7;
5715 op = ((b & 7) << 3) | ((modrm >> 3) & 7);
5716 if (mod != 3) {
5717 /* memory op */
5718 gen_lea_modrm(env, s, modrm);
5719 switch(op) {
5720 case 0x00 ... 0x07: /* fxxxs */
5721 case 0x10 ... 0x17: /* fixxxl */
5722 case 0x20 ... 0x27: /* fxxxl */
5723 case 0x30 ... 0x37: /* fixxx */
5724 {
5725 int op1;
5726 op1 = op & 7;
5727
5728 switch(op >> 4) {
5729 case 0:
5730 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5731 s->mem_index, MO_LEUL);
5732 gen_helper_flds_FT0(cpu_env, cpu_tmp2_i32);
5733 break;
5734 case 1:
5735 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5736 s->mem_index, MO_LEUL);
5737 gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32);
5738 break;
5739 case 2:
5740 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0,
5741 s->mem_index, MO_LEQ);
5742 gen_helper_fldl_FT0(cpu_env, cpu_tmp1_i64);
5743 break;
5744 case 3:
5745 default:
5746 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5747 s->mem_index, MO_LESW);
5748 gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32);
5749 break;
5750 }
5751
5752 gen_helper_fp_arith_ST0_FT0(op1);
5753 if (op1 == 3) {
5754 /* fcomp needs pop */
5755 gen_helper_fpop(cpu_env);
5756 }
5757 }
5758 break;
5759 case 0x08: /* flds */
5760 case 0x0a: /* fsts */
5761 case 0x0b: /* fstps */
5762 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5763 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5764 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5765 switch(op & 7) {
5766 case 0:
5767 switch(op >> 4) {
5768 case 0:
5769 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5770 s->mem_index, MO_LEUL);
5771 gen_helper_flds_ST0(cpu_env, cpu_tmp2_i32);
5772 break;
5773 case 1:
5774 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5775 s->mem_index, MO_LEUL);
5776 gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32);
5777 break;
5778 case 2:
5779 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0,
5780 s->mem_index, MO_LEQ);
5781 gen_helper_fldl_ST0(cpu_env, cpu_tmp1_i64);
5782 break;
5783 case 3:
5784 default:
5785 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5786 s->mem_index, MO_LESW);
5787 gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32);
5788 break;
5789 }
5790 break;
5791 case 1:
5792 /* XXX: the corresponding CPUID bit must be tested ! */
5793 switch(op >> 4) {
5794 case 1:
5795 gen_helper_fisttl_ST0(cpu_tmp2_i32, cpu_env);
5796 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5797 s->mem_index, MO_LEUL);
5798 break;
5799 case 2:
5800 gen_helper_fisttll_ST0(cpu_tmp1_i64, cpu_env);
5801 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0,
5802 s->mem_index, MO_LEQ);
5803 break;
5804 case 3:
5805 default:
5806 gen_helper_fistt_ST0(cpu_tmp2_i32, cpu_env);
5807 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5808 s->mem_index, MO_LEUW);
5809 break;
5810 }
5811 gen_helper_fpop(cpu_env);
5812 break;
5813 default:
5814 switch(op >> 4) {
5815 case 0:
5816 gen_helper_fsts_ST0(cpu_tmp2_i32, cpu_env);
5817 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5818 s->mem_index, MO_LEUL);
5819 break;
5820 case 1:
5821 gen_helper_fistl_ST0(cpu_tmp2_i32, cpu_env);
5822 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5823 s->mem_index, MO_LEUL);
5824 break;
5825 case 2:
5826 gen_helper_fstl_ST0(cpu_tmp1_i64, cpu_env);
5827 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0,
5828 s->mem_index, MO_LEQ);
5829 break;
5830 case 3:
5831 default:
5832 gen_helper_fist_ST0(cpu_tmp2_i32, cpu_env);
5833 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5834 s->mem_index, MO_LEUW);
5835 break;
5836 }
5837 if ((op & 7) == 3)
5838 gen_helper_fpop(cpu_env);
5839 break;
5840 }
5841 break;
5842 case 0x0c: /* fldenv mem */
5843 gen_helper_fldenv(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5844 break;
5845 case 0x0d: /* fldcw mem */
5846 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
5847 s->mem_index, MO_LEUW);
5848 gen_helper_fldcw(cpu_env, cpu_tmp2_i32);
5849 break;
5850 case 0x0e: /* fnstenv mem */
5851 gen_helper_fstenv(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5852 break;
5853 case 0x0f: /* fnstcw mem */
5854 gen_helper_fnstcw(cpu_tmp2_i32, cpu_env);
5855 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5856 s->mem_index, MO_LEUW);
5857 break;
5858 case 0x1d: /* fldt mem */
5859 gen_helper_fldt_ST0(cpu_env, cpu_A0);
5860 break;
5861 case 0x1f: /* fstpt mem */
5862 gen_helper_fstt_ST0(cpu_env, cpu_A0);
5863 gen_helper_fpop(cpu_env);
5864 break;
5865 case 0x2c: /* frstor mem */
5866 gen_helper_frstor(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5867 break;
5868 case 0x2e: /* fnsave mem */
5869 gen_helper_fsave(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
5870 break;
5871 case 0x2f: /* fnstsw mem */
5872 gen_helper_fnstsw(cpu_tmp2_i32, cpu_env);
5873 tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
5874 s->mem_index, MO_LEUW);
5875 break;
5876 case 0x3c: /* fbld */
5877 gen_helper_fbld_ST0(cpu_env, cpu_A0);
5878 break;
5879 case 0x3e: /* fbstp */
5880 gen_helper_fbst_ST0(cpu_env, cpu_A0);
5881 gen_helper_fpop(cpu_env);
5882 break;
5883 case 0x3d: /* fildll */
5884 tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
5885 gen_helper_fildll_ST0(cpu_env, cpu_tmp1_i64);
5886 break;
5887 case 0x3f: /* fistpll */
5888 gen_helper_fistll_ST0(cpu_tmp1_i64, cpu_env);
5889 tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
5890 gen_helper_fpop(cpu_env);
5891 break;
5892 default:
5893 goto unknown_op;
5894 }
5895 } else {
5896 /* register float ops */
5897 opreg = rm;
5898
5899 switch(op) {
5900 case 0x08: /* fld sti */
5901 gen_helper_fpush(cpu_env);
5902 gen_helper_fmov_ST0_STN(cpu_env,
5903 tcg_const_i32((opreg + 1) & 7));
5904 break;
5905 case 0x09: /* fxchg sti */
5906 case 0x29: /* fxchg4 sti, undocumented op */
5907 case 0x39: /* fxchg7 sti, undocumented op */
5908 gen_helper_fxchg_ST0_STN(cpu_env, tcg_const_i32(opreg));
5909 break;
5910 case 0x0a: /* grp d9/2 */
5911 switch(rm) {
5912 case 0: /* fnop */
5913 /* check exceptions (FreeBSD FPU probe) */
5914 gen_helper_fwait(cpu_env);
5915 break;
5916 default:
5917 goto unknown_op;
5918 }
5919 break;
5920 case 0x0c: /* grp d9/4 */
5921 switch(rm) {
5922 case 0: /* fchs */
5923 gen_helper_fchs_ST0(cpu_env);
5924 break;
5925 case 1: /* fabs */
5926 gen_helper_fabs_ST0(cpu_env);
5927 break;
5928 case 4: /* ftst */
5929 gen_helper_fldz_FT0(cpu_env);
5930 gen_helper_fcom_ST0_FT0(cpu_env);
5931 break;
5932 case 5: /* fxam */
5933 gen_helper_fxam_ST0(cpu_env);
5934 break;
5935 default:
5936 goto unknown_op;
5937 }
5938 break;
5939 case 0x0d: /* grp d9/5 */
5940 {
5941 switch(rm) {
5942 case 0:
5943 gen_helper_fpush(cpu_env);
5944 gen_helper_fld1_ST0(cpu_env);
5945 break;
5946 case 1:
5947 gen_helper_fpush(cpu_env);
5948 gen_helper_fldl2t_ST0(cpu_env);
5949 break;
5950 case 2:
5951 gen_helper_fpush(cpu_env);
5952 gen_helper_fldl2e_ST0(cpu_env);
5953 break;
5954 case 3:
5955 gen_helper_fpush(cpu_env);
5956 gen_helper_fldpi_ST0(cpu_env);
5957 break;
5958 case 4:
5959 gen_helper_fpush(cpu_env);
5960 gen_helper_fldlg2_ST0(cpu_env);
5961 break;
5962 case 5:
5963 gen_helper_fpush(cpu_env);
5964 gen_helper_fldln2_ST0(cpu_env);
5965 break;
5966 case 6:
5967 gen_helper_fpush(cpu_env);
5968 gen_helper_fldz_ST0(cpu_env);
5969 break;
5970 default:
5971 goto unknown_op;
5972 }
5973 }
5974 break;
5975 case 0x0e: /* grp d9/6 */
5976 switch(rm) {
5977 case 0: /* f2xm1 */
5978 gen_helper_f2xm1(cpu_env);
5979 break;
5980 case 1: /* fyl2x */
5981 gen_helper_fyl2x(cpu_env);
5982 break;
5983 case 2: /* fptan */
5984 gen_helper_fptan(cpu_env);
5985 break;
5986 case 3: /* fpatan */
5987 gen_helper_fpatan(cpu_env);
5988 break;
5989 case 4: /* fxtract */
5990 gen_helper_fxtract(cpu_env);
5991 break;
5992 case 5: /* fprem1 */
5993 gen_helper_fprem1(cpu_env);
5994 break;
5995 case 6: /* fdecstp */
5996 gen_helper_fdecstp(cpu_env);
5997 break;
5998 default:
5999 case 7: /* fincstp */
6000 gen_helper_fincstp(cpu_env);
6001 break;
6002 }
6003 break;
6004 case 0x0f: /* grp d9/7 */
6005 switch(rm) {
6006 case 0: /* fprem */
6007 gen_helper_fprem(cpu_env);
6008 break;
6009 case 1: /* fyl2xp1 */
6010 gen_helper_fyl2xp1(cpu_env);
6011 break;
6012 case 2: /* fsqrt */
6013 gen_helper_fsqrt(cpu_env);
6014 break;
6015 case 3: /* fsincos */
6016 gen_helper_fsincos(cpu_env);
6017 break;
6018 case 5: /* fscale */
6019 gen_helper_fscale(cpu_env);
6020 break;
6021 case 4: /* frndint */
6022 gen_helper_frndint(cpu_env);
6023 break;
6024 case 6: /* fsin */
6025 gen_helper_fsin(cpu_env);
6026 break;
6027 default:
6028 case 7: /* fcos */
6029 gen_helper_fcos(cpu_env);
6030 break;
6031 }
6032 break;
6033 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6034 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6035 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6036 {
6037 int op1;
6038
6039 op1 = op & 7;
6040 if (op >= 0x20) {
6041 gen_helper_fp_arith_STN_ST0(op1, opreg);
6042 if (op >= 0x30)
6043 gen_helper_fpop(cpu_env);
6044 } else {
6045 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6046 gen_helper_fp_arith_ST0_FT0(op1);
6047 }
6048 }
6049 break;
6050 case 0x02: /* fcom */
6051 case 0x22: /* fcom2, undocumented op */
6052 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6053 gen_helper_fcom_ST0_FT0(cpu_env);
6054 break;
6055 case 0x03: /* fcomp */
6056 case 0x23: /* fcomp3, undocumented op */
6057 case 0x32: /* fcomp5, undocumented op */
6058 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6059 gen_helper_fcom_ST0_FT0(cpu_env);
6060 gen_helper_fpop(cpu_env);
6061 break;
6062 case 0x15: /* da/5 */
6063 switch(rm) {
6064 case 1: /* fucompp */
6065 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
6066 gen_helper_fucom_ST0_FT0(cpu_env);
6067 gen_helper_fpop(cpu_env);
6068 gen_helper_fpop(cpu_env);
6069 break;
6070 default:
6071 goto unknown_op;
6072 }
6073 break;
6074 case 0x1c:
6075 switch(rm) {
6076 case 0: /* feni (287 only, just do nop here) */
6077 break;
6078 case 1: /* fdisi (287 only, just do nop here) */
6079 break;
6080 case 2: /* fclex */
6081 gen_helper_fclex(cpu_env);
6082 break;
6083 case 3: /* fninit */
6084 gen_helper_fninit(cpu_env);
6085 break;
6086 case 4: /* fsetpm (287 only, just do nop here) */
6087 break;
6088 default:
6089 goto unknown_op;
6090 }
6091 break;
6092 case 0x1d: /* fucomi */
6093 if (!(s->cpuid_features & CPUID_CMOV)) {
6094 goto illegal_op;
6095 }
6096 gen_update_cc_op(s);
6097 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6098 gen_helper_fucomi_ST0_FT0(cpu_env);
6099 set_cc_op(s, CC_OP_EFLAGS);
6100 break;
6101 case 0x1e: /* fcomi */
6102 if (!(s->cpuid_features & CPUID_CMOV)) {
6103 goto illegal_op;
6104 }
6105 gen_update_cc_op(s);
6106 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6107 gen_helper_fcomi_ST0_FT0(cpu_env);
6108 set_cc_op(s, CC_OP_EFLAGS);
6109 break;
6110 case 0x28: /* ffree sti */
6111 gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
6112 break;
6113 case 0x2a: /* fst sti */
6114 gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
6115 break;
6116 case 0x2b: /* fstp sti */
6117 case 0x0b: /* fstp1 sti, undocumented op */
6118 case 0x3a: /* fstp8 sti, undocumented op */
6119 case 0x3b: /* fstp9 sti, undocumented op */
6120 gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
6121 gen_helper_fpop(cpu_env);
6122 break;
6123 case 0x2c: /* fucom st(i) */
6124 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6125 gen_helper_fucom_ST0_FT0(cpu_env);
6126 break;
6127 case 0x2d: /* fucomp st(i) */
6128 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6129 gen_helper_fucom_ST0_FT0(cpu_env);
6130 gen_helper_fpop(cpu_env);
6131 break;
6132 case 0x33: /* de/3 */
6133 switch(rm) {
6134 case 1: /* fcompp */
6135 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
6136 gen_helper_fcom_ST0_FT0(cpu_env);
6137 gen_helper_fpop(cpu_env);
6138 gen_helper_fpop(cpu_env);
6139 break;
6140 default:
6141 goto unknown_op;
6142 }
6143 break;
6144 case 0x38: /* ffreep sti, undocumented op */
6145 gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
6146 gen_helper_fpop(cpu_env);
6147 break;
6148 case 0x3c: /* df/4 */
6149 switch(rm) {
6150 case 0:
6151 gen_helper_fnstsw(cpu_tmp2_i32, cpu_env);
6152 tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);
6153 gen_op_mov_reg_v(MO_16, R_EAX, cpu_T0);
6154 break;
6155 default:
6156 goto unknown_op;
6157 }
6158 break;
6159 case 0x3d: /* fucomip */
6160 if (!(s->cpuid_features & CPUID_CMOV)) {
6161 goto illegal_op;
6162 }
6163 gen_update_cc_op(s);
6164 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6165 gen_helper_fucomi_ST0_FT0(cpu_env);
6166 gen_helper_fpop(cpu_env);
6167 set_cc_op(s, CC_OP_EFLAGS);
6168 break;
6169 case 0x3e: /* fcomip */
6170 if (!(s->cpuid_features & CPUID_CMOV)) {
6171 goto illegal_op;
6172 }
6173 gen_update_cc_op(s);
6174 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6175 gen_helper_fcomi_ST0_FT0(cpu_env);
6176 gen_helper_fpop(cpu_env);
6177 set_cc_op(s, CC_OP_EFLAGS);
6178 break;
6179 case 0x10 ... 0x13: /* fcmovxx */
6180 case 0x18 ... 0x1b:
6181 {
6182 int op1;
6183 TCGLabel *l1;
6184 static const uint8_t fcmov_cc[8] = {
6185 (JCC_B << 1),
6186 (JCC_Z << 1),
6187 (JCC_BE << 1),
6188 (JCC_P << 1),
6189 };
6190
6191 if (!(s->cpuid_features & CPUID_CMOV)) {
6192 goto illegal_op;
6193 }
6194 op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1);
6195 l1 = gen_new_label();
6196 gen_jcc1_noeob(s, op1, l1);
6197 gen_helper_fmov_ST0_STN(cpu_env, tcg_const_i32(opreg));
6198 gen_set_label(l1);
6199 }
6200 break;
6201 default:
6202 goto unknown_op;
6203 }
6204 }
6205 break;
6206 /************************/
6207 /* string ops */
6208
6209 case 0xa4: /* movsS */
6210 case 0xa5:
6211 ot = mo_b_d(b, dflag);
6212 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6213 gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6214 } else {
6215 gen_movs(s, ot);
6216 }
6217 break;
6218
6219 case 0xaa: /* stosS */
6220 case 0xab:
6221 ot = mo_b_d(b, dflag);
6222 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6223 gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6224 } else {
6225 gen_stos(s, ot);
6226 }
6227 break;
6228 case 0xac: /* lodsS */
6229 case 0xad:
6230 ot = mo_b_d(b, dflag);
6231 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6232 gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6233 } else {
6234 gen_lods(s, ot);
6235 }
6236 break;
6237 case 0xae: /* scasS */
6238 case 0xaf:
6239 ot = mo_b_d(b, dflag);
6240 if (prefixes & PREFIX_REPNZ) {
6241 gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
6242 } else if (prefixes & PREFIX_REPZ) {
6243 gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
6244 } else {
6245 gen_scas(s, ot);
6246 }
6247 break;
6248
6249 case 0xa6: /* cmpsS */
6250 case 0xa7:
6251 ot = mo_b_d(b, dflag);
6252 if (prefixes & PREFIX_REPNZ) {
6253 gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
6254 } else if (prefixes & PREFIX_REPZ) {
6255 gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
6256 } else {
6257 gen_cmps(s, ot);
6258 }
6259 break;
6260 case 0x6c: /* insS */
6261 case 0x6d:
6262 ot = mo_b_d32(b, dflag);
6263 tcg_gen_ext16u_tl(cpu_T0, cpu_regs[R_EDX]);
6264 gen_check_io(s, ot, pc_start - s->cs_base,
6265 SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) | 4);
6266 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6267 gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6268 } else {
6269 gen_ins(s, ot);
6270 if (s->tb->cflags & CF_USE_ICOUNT) {
6271 gen_jmp(s, s->pc - s->cs_base);
6272 }
6273 }
6274 break;
6275 case 0x6e: /* outsS */
6276 case 0x6f:
6277 ot = mo_b_d32(b, dflag);
6278 tcg_gen_ext16u_tl(cpu_T0, cpu_regs[R_EDX]);
6279 gen_check_io(s, ot, pc_start - s->cs_base,
6280 svm_is_rep(prefixes) | 4);
6281 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6282 gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6283 } else {
6284 gen_outs(s, ot);
6285 if (s->tb->cflags & CF_USE_ICOUNT) {
6286 gen_jmp(s, s->pc - s->cs_base);
6287 }
6288 }
6289 break;
6290
6291 /************************/
6292 /* port I/O */
6293
6294 case 0xe4:
6295 case 0xe5:
6296 ot = mo_b_d32(b, dflag);
6297 val = cpu_ldub_code(env, s->pc++);
6298 tcg_gen_movi_tl(cpu_T0, val);
6299 gen_check_io(s, ot, pc_start - s->cs_base,
6300 SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6301 if (s->tb->cflags & CF_USE_ICOUNT) {
6302 gen_io_start();
6303 }
6304 tcg_gen_movi_i32(cpu_tmp2_i32, val);
6305 gen_helper_in_func(ot, cpu_T1, cpu_tmp2_i32);
6306 gen_op_mov_reg_v(ot, R_EAX, cpu_T1);
6307 gen_bpt_io(s, cpu_tmp2_i32, ot);
6308 if (s->tb->cflags & CF_USE_ICOUNT) {
6309 gen_io_end();
6310 gen_jmp(s, s->pc - s->cs_base);
6311 }
6312 break;
6313 case 0xe6:
6314 case 0xe7:
6315 ot = mo_b_d32(b, dflag);
6316 val = cpu_ldub_code(env, s->pc++);
6317 tcg_gen_movi_tl(cpu_T0, val);
6318 gen_check_io(s, ot, pc_start - s->cs_base,
6319 svm_is_rep(prefixes));
6320 gen_op_mov_v_reg(ot, cpu_T1, R_EAX);
6321
6322 if (s->tb->cflags & CF_USE_ICOUNT) {
6323 gen_io_start();
6324 }
6325 tcg_gen_movi_i32(cpu_tmp2_i32, val);
6326 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T1);
6327 gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6328 gen_bpt_io(s, cpu_tmp2_i32, ot);
6329 if (s->tb->cflags & CF_USE_ICOUNT) {
6330 gen_io_end();
6331 gen_jmp(s, s->pc - s->cs_base);
6332 }
6333 break;
6334 case 0xec:
6335 case 0xed:
6336 ot = mo_b_d32(b, dflag);
6337 tcg_gen_ext16u_tl(cpu_T0, cpu_regs[R_EDX]);
6338 gen_check_io(s, ot, pc_start - s->cs_base,
6339 SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6340 if (s->tb->cflags & CF_USE_ICOUNT) {
6341 gen_io_start();
6342 }
6343 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
6344 gen_helper_in_func(ot, cpu_T1, cpu_tmp2_i32);
6345 gen_op_mov_reg_v(ot, R_EAX, cpu_T1);
6346 gen_bpt_io(s, cpu_tmp2_i32, ot);
6347 if (s->tb->cflags & CF_USE_ICOUNT) {
6348 gen_io_end();
6349 gen_jmp(s, s->pc - s->cs_base);
6350 }
6351 break;
6352 case 0xee:
6353 case 0xef:
6354 ot = mo_b_d32(b, dflag);
6355 tcg_gen_ext16u_tl(cpu_T0, cpu_regs[R_EDX]);
6356 gen_check_io(s, ot, pc_start - s->cs_base,
6357 svm_is_rep(prefixes));
6358 gen_op_mov_v_reg(ot, cpu_T1, R_EAX);
6359
6360 if (s->tb->cflags & CF_USE_ICOUNT) {
6361 gen_io_start();
6362 }
6363 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
6364 tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T1);
6365 gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
6366 gen_bpt_io(s, cpu_tmp2_i32, ot);
6367 if (s->tb->cflags & CF_USE_ICOUNT) {
6368 gen_io_end();
6369 gen_jmp(s, s->pc - s->cs_base);
6370 }
6371 break;
6372
6373 /************************/
6374 /* control */
6375 case 0xc2: /* ret im */
6376 val = cpu_ldsw_code(env, s->pc);
6377 s->pc += 2;
6378 ot = gen_pop_T0(s);
6379 gen_stack_update(s, val + (1 << ot));
6380 /* Note that gen_pop_T0 uses a zero-extending load. */
6381 gen_op_jmp_v(cpu_T0);
6382 gen_bnd_jmp(s);
6383 gen_eob(s);
6384 break;
6385 case 0xc3: /* ret */
6386 ot = gen_pop_T0(s);
6387 gen_pop_update(s, ot);
6388 /* Note that gen_pop_T0 uses a zero-extending load. */
6389 gen_op_jmp_v(cpu_T0);
6390 gen_bnd_jmp(s);
6391 gen_eob(s);
6392 break;
6393 case 0xca: /* lret im */
6394 val = cpu_ldsw_code(env, s->pc);
6395 s->pc += 2;
6396 do_lret:
6397 if (s->pe && !s->vm86) {
6398 gen_update_cc_op(s);
6399 gen_jmp_im(pc_start - s->cs_base);
6400 gen_helper_lret_protected(cpu_env, tcg_const_i32(dflag - 1),
6401 tcg_const_i32(val));
6402 } else {
6403 gen_stack_A0(s);
6404 /* pop offset */
6405 gen_op_ld_v(s, dflag, cpu_T0, cpu_A0);
6406 /* NOTE: keeping EIP updated is not a problem in case of
6407 exception */
6408 gen_op_jmp_v(cpu_T0);
6409 /* pop selector */
6410 gen_add_A0_im(s, 1 << dflag);
6411 gen_op_ld_v(s, dflag, cpu_T0, cpu_A0);
6412 gen_op_movl_seg_T0_vm(R_CS);
6413 /* add stack offset */
6414 gen_stack_update(s, val + (2 << dflag));
6415 }
6416 gen_eob(s);
6417 break;
6418 case 0xcb: /* lret */
6419 val = 0;
6420 goto do_lret;
6421 case 0xcf: /* iret */
6422 gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET);
6423 if (!s->pe) {
6424 /* real mode */
6425 gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
6426 set_cc_op(s, CC_OP_EFLAGS);
6427 } else if (s->vm86) {
6428 if (s->iopl != 3) {
6429 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6430 } else {
6431 gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
6432 set_cc_op(s, CC_OP_EFLAGS);
6433 }
6434 } else {
6435 gen_helper_iret_protected(cpu_env, tcg_const_i32(dflag - 1),
6436 tcg_const_i32(s->pc - s->cs_base));
6437 set_cc_op(s, CC_OP_EFLAGS);
6438 }
6439 /* TF handling for the syscall insn is different. The TF bit is checked
6440 after the syscall insn completes. This allows #DB to not be
6441 generated after one has entered CPL0 if TF is set in FMASK. */
6442 gen_eob_worker(s, false, true);
6443 break;
6444 case 0xe8: /* call im */
6445 {
6446 if (dflag != MO_16) {
6447 tval = (int32_t)insn_get(env, s, MO_32);
6448 } else {
6449 tval = (int16_t)insn_get(env, s, MO_16);
6450 }
6451 next_eip = s->pc - s->cs_base;
6452 tval += next_eip;
6453 if (dflag == MO_16) {
6454 tval &= 0xffff;
6455 } else if (!CODE64(s)) {
6456 tval &= 0xffffffff;
6457 }
6458 tcg_gen_movi_tl(cpu_T0, next_eip);
6459 gen_push_v(s, cpu_T0);
6460 gen_bnd_jmp(s);
6461 gen_jmp(s, tval);
6462 }
6463 break;
6464 case 0x9a: /* lcall im */
6465 {
6466 unsigned int selector, offset;
6467
6468 if (CODE64(s))
6469 goto illegal_op;
6470 ot = dflag;
6471 offset = insn_get(env, s, ot);
6472 selector = insn_get(env, s, MO_16);
6473
6474 tcg_gen_movi_tl(cpu_T0, selector);
6475 tcg_gen_movi_tl(cpu_T1, offset);
6476 }
6477 goto do_lcall;
6478 case 0xe9: /* jmp im */
6479 if (dflag != MO_16) {
6480 tval = (int32_t)insn_get(env, s, MO_32);
6481 } else {
6482 tval = (int16_t)insn_get(env, s, MO_16);
6483 }
6484 tval += s->pc - s->cs_base;
6485 if (dflag == MO_16) {
6486 tval &= 0xffff;
6487 } else if (!CODE64(s)) {
6488 tval &= 0xffffffff;
6489 }
6490 gen_bnd_jmp(s);
6491 gen_jmp(s, tval);
6492 break;
6493 case 0xea: /* ljmp im */
6494 {
6495 unsigned int selector, offset;
6496
6497 if (CODE64(s))
6498 goto illegal_op;
6499 ot = dflag;
6500 offset = insn_get(env, s, ot);
6501 selector = insn_get(env, s, MO_16);
6502
6503 tcg_gen_movi_tl(cpu_T0, selector);
6504 tcg_gen_movi_tl(cpu_T1, offset);
6505 }
6506 goto do_ljmp;
6507 case 0xeb: /* jmp Jb */
6508 tval = (int8_t)insn_get(env, s, MO_8);
6509 tval += s->pc - s->cs_base;
6510 if (dflag == MO_16) {
6511 tval &= 0xffff;
6512 }
6513 gen_jmp(s, tval);
6514 break;
6515 case 0x70 ... 0x7f: /* jcc Jb */
6516 tval = (int8_t)insn_get(env, s, MO_8);
6517 goto do_jcc;
6518 case 0x180 ... 0x18f: /* jcc Jv */
6519 if (dflag != MO_16) {
6520 tval = (int32_t)insn_get(env, s, MO_32);
6521 } else {
6522 tval = (int16_t)insn_get(env, s, MO_16);
6523 }
6524 do_jcc:
6525 next_eip = s->pc - s->cs_base;
6526 tval += next_eip;
6527 if (dflag == MO_16) {
6528 tval &= 0xffff;
6529 }
6530 gen_bnd_jmp(s);
6531 gen_jcc(s, b, tval, next_eip);
6532 break;
6533
6534 case 0x190 ... 0x19f: /* setcc Gv */
6535 modrm = cpu_ldub_code(env, s->pc++);
6536 gen_setcc1(s, b, cpu_T0);
6537 gen_ldst_modrm(env, s, modrm, MO_8, OR_TMP0, 1);
6538 break;
6539 case 0x140 ... 0x14f: /* cmov Gv, Ev */
6540 if (!(s->cpuid_features & CPUID_CMOV)) {
6541 goto illegal_op;
6542 }
6543 ot = dflag;
6544 modrm = cpu_ldub_code(env, s->pc++);
6545 reg = ((modrm >> 3) & 7) | rex_r;
6546 gen_cmovcc1(env, s, ot, b, modrm, reg);
6547 break;
6548
6549 /************************/
6550 /* flags */
6551 case 0x9c: /* pushf */
6552 gen_svm_check_intercept(s, pc_start, SVM_EXIT_PUSHF);
6553 if (s->vm86 && s->iopl != 3) {
6554 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6555 } else {
6556 gen_update_cc_op(s);
6557 gen_helper_read_eflags(cpu_T0, cpu_env);
6558 gen_push_v(s, cpu_T0);
6559 }
6560 break;
6561 case 0x9d: /* popf */
6562 gen_svm_check_intercept(s, pc_start, SVM_EXIT_POPF);
6563 if (s->vm86 && s->iopl != 3) {
6564 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6565 } else {
6566 ot = gen_pop_T0(s);
6567 if (s->cpl == 0) {
6568 if (dflag != MO_16) {
6569 gen_helper_write_eflags(cpu_env, cpu_T0,
6570 tcg_const_i32((TF_MASK | AC_MASK |
6571 ID_MASK | NT_MASK |
6572 IF_MASK |
6573 IOPL_MASK)));
6574 } else {
6575 gen_helper_write_eflags(cpu_env, cpu_T0,
6576 tcg_const_i32((TF_MASK | AC_MASK |
6577 ID_MASK | NT_MASK |
6578 IF_MASK | IOPL_MASK)
6579 & 0xffff));
6580 }
6581 } else {
6582 if (s->cpl <= s->iopl) {
6583 if (dflag != MO_16) {
6584 gen_helper_write_eflags(cpu_env, cpu_T0,
6585 tcg_const_i32((TF_MASK |
6586 AC_MASK |
6587 ID_MASK |
6588 NT_MASK |
6589 IF_MASK)));
6590 } else {
6591 gen_helper_write_eflags(cpu_env, cpu_T0,
6592 tcg_const_i32((TF_MASK |
6593 AC_MASK |
6594 ID_MASK |
6595 NT_MASK |
6596 IF_MASK)
6597 & 0xffff));
6598 }
6599 } else {
6600 if (dflag != MO_16) {
6601 gen_helper_write_eflags(cpu_env, cpu_T0,
6602 tcg_const_i32((TF_MASK | AC_MASK |
6603 ID_MASK | NT_MASK)));
6604 } else {
6605 gen_helper_write_eflags(cpu_env, cpu_T0,
6606 tcg_const_i32((TF_MASK | AC_MASK |
6607 ID_MASK | NT_MASK)
6608 & 0xffff));
6609 }
6610 }
6611 }
6612 gen_pop_update(s, ot);
6613 set_cc_op(s, CC_OP_EFLAGS);
6614 /* abort translation because TF/AC flag may change */
6615 gen_jmp_im(s->pc - s->cs_base);
6616 gen_eob(s);
6617 }
6618 break;
6619 case 0x9e: /* sahf */
6620 if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6621 goto illegal_op;
6622 gen_op_mov_v_reg(MO_8, cpu_T0, R_AH);
6623 gen_compute_eflags(s);
6624 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O);
6625 tcg_gen_andi_tl(cpu_T0, cpu_T0, CC_S | CC_Z | CC_A | CC_P | CC_C);
6626 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_T0);
6627 break;
6628 case 0x9f: /* lahf */
6629 if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6630 goto illegal_op;
6631 gen_compute_eflags(s);
6632 /* Note: gen_compute_eflags() only gives the condition codes */
6633 tcg_gen_ori_tl(cpu_T0, cpu_cc_src, 0x02);
6634 gen_op_mov_reg_v(MO_8, R_AH, cpu_T0);
6635 break;
6636 case 0xf5: /* cmc */
6637 gen_compute_eflags(s);
6638 tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6639 break;
6640 case 0xf8: /* clc */
6641 gen_compute_eflags(s);
6642 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C);
6643 break;
6644 case 0xf9: /* stc */
6645 gen_compute_eflags(s);
6646 tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6647 break;
6648 case 0xfc: /* cld */
6649 tcg_gen_movi_i32(cpu_tmp2_i32, 1);
6650 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, df));
6651 break;
6652 case 0xfd: /* std */
6653 tcg_gen_movi_i32(cpu_tmp2_i32, -1);
6654 tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, df));
6655 break;
6656
6657 /************************/
6658 /* bit operations */
6659 case 0x1ba: /* bt/bts/btr/btc Gv, im */
6660 ot = dflag;
6661 modrm = cpu_ldub_code(env, s->pc++);
6662 op = (modrm >> 3) & 7;
6663 mod = (modrm >> 6) & 3;
6664 rm = (modrm & 7) | REX_B(s);
6665 if (mod != 3) {
6666 s->rip_offset = 1;
6667 gen_lea_modrm(env, s, modrm);
6668 if (!(s->prefix & PREFIX_LOCK)) {
6669 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
6670 }
6671 } else {
6672 gen_op_mov_v_reg(ot, cpu_T0, rm);
6673 }
6674 /* load shift */
6675 val = cpu_ldub_code(env, s->pc++);
6676 tcg_gen_movi_tl(cpu_T1, val);
6677 if (op < 4)
6678 goto unknown_op;
6679 op -= 4;
6680 goto bt_op;
6681 case 0x1a3: /* bt Gv, Ev */
6682 op = 0;
6683 goto do_btx;
6684 case 0x1ab: /* bts */
6685 op = 1;
6686 goto do_btx;
6687 case 0x1b3: /* btr */
6688 op = 2;
6689 goto do_btx;
6690 case 0x1bb: /* btc */
6691 op = 3;
6692 do_btx:
6693 ot = dflag;
6694 modrm = cpu_ldub_code(env, s->pc++);
6695 reg = ((modrm >> 3) & 7) | rex_r;
6696 mod = (modrm >> 6) & 3;
6697 rm = (modrm & 7) | REX_B(s);
6698 gen_op_mov_v_reg(MO_32, cpu_T1, reg);
6699 if (mod != 3) {
6700 AddressParts a = gen_lea_modrm_0(env, s, modrm);
6701 /* specific case: we need to add a displacement */
6702 gen_exts(ot, cpu_T1);
6703 tcg_gen_sari_tl(cpu_tmp0, cpu_T1, 3 + ot);
6704 tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, ot);
6705 tcg_gen_add_tl(cpu_A0, gen_lea_modrm_1(a), cpu_tmp0);
6706 gen_lea_v_seg(s, s->aflag, cpu_A0, a.def_seg, s->override);
6707 if (!(s->prefix & PREFIX_LOCK)) {
6708 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
6709 }
6710 } else {
6711 gen_op_mov_v_reg(ot, cpu_T0, rm);
6712 }
6713 bt_op:
6714 tcg_gen_andi_tl(cpu_T1, cpu_T1, (1 << (3 + ot)) - 1);
6715 tcg_gen_movi_tl(cpu_tmp0, 1);
6716 tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T1);
6717 if (s->prefix & PREFIX_LOCK) {
6718 switch (op) {
6719 case 0: /* bt */
6720 /* Needs no atomic ops; we surpressed the normal
6721 memory load for LOCK above so do it now. */
6722 gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
6723 break;
6724 case 1: /* bts */
6725 tcg_gen_atomic_fetch_or_tl(cpu_T0, cpu_A0, cpu_tmp0,
6726 s->mem_index, ot | MO_LE);
6727 break;
6728 case 2: /* btr */
6729 tcg_gen_not_tl(cpu_tmp0, cpu_tmp0);
6730 tcg_gen_atomic_fetch_and_tl(cpu_T0, cpu_A0, cpu_tmp0,
6731 s->mem_index, ot | MO_LE);
6732 break;
6733 default:
6734 case 3: /* btc */
6735 tcg_gen_atomic_fetch_xor_tl(cpu_T0, cpu_A0, cpu_tmp0,
6736 s->mem_index, ot | MO_LE);
6737 break;
6738 }
6739 tcg_gen_shr_tl(cpu_tmp4, cpu_T0, cpu_T1);
6740 } else {
6741 tcg_gen_shr_tl(cpu_tmp4, cpu_T0, cpu_T1);
6742 switch (op) {
6743 case 0: /* bt */
6744 /* Data already loaded; nothing to do. */
6745 break;
6746 case 1: /* bts */
6747 tcg_gen_or_tl(cpu_T0, cpu_T0, cpu_tmp0);
6748 break;
6749 case 2: /* btr */
6750 tcg_gen_andc_tl(cpu_T0, cpu_T0, cpu_tmp0);
6751 break;
6752 default:
6753 case 3: /* btc */
6754 tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_tmp0);
6755 break;
6756 }
6757 if (op != 0) {
6758 if (mod != 3) {
6759 gen_op_st_v(s, ot, cpu_T0, cpu_A0);
6760 } else {
6761 gen_op_mov_reg_v(ot, rm, cpu_T0);
6762 }
6763 }
6764 }
6765
6766 /* Delay all CC updates until after the store above. Note that
6767 C is the result of the test, Z is unchanged, and the others
6768 are all undefined. */
6769 switch (s->cc_op) {
6770 case CC_OP_MULB ... CC_OP_MULQ:
6771 case CC_OP_ADDB ... CC_OP_ADDQ:
6772 case CC_OP_ADCB ... CC_OP_ADCQ:
6773 case CC_OP_SUBB ... CC_OP_SUBQ:
6774 case CC_OP_SBBB ... CC_OP_SBBQ:
6775 case CC_OP_LOGICB ... CC_OP_LOGICQ:
6776 case CC_OP_INCB ... CC_OP_INCQ:
6777 case CC_OP_DECB ... CC_OP_DECQ:
6778 case CC_OP_SHLB ... CC_OP_SHLQ:
6779 case CC_OP_SARB ... CC_OP_SARQ:
6780 case CC_OP_BMILGB ... CC_OP_BMILGQ:
6781 /* Z was going to be computed from the non-zero status of CC_DST.
6782 We can get that same Z value (and the new C value) by leaving
6783 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
6784 same width. */
6785 tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
6786 set_cc_op(s, ((s->cc_op - CC_OP_MULB) & 3) + CC_OP_SARB);
6787 break;
6788 default:
6789 /* Otherwise, generate EFLAGS and replace the C bit. */
6790 gen_compute_eflags(s);
6791 tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, cpu_tmp4,
6792 ctz32(CC_C), 1);
6793 break;
6794 }
6795 break;
6796 case 0x1bc: /* bsf / tzcnt */
6797 case 0x1bd: /* bsr / lzcnt */
6798 ot = dflag;
6799 modrm = cpu_ldub_code(env, s->pc++);
6800 reg = ((modrm >> 3) & 7) | rex_r;
6801 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
6802 gen_extu(ot, cpu_T0);
6803
6804 /* Note that lzcnt and tzcnt are in different extensions. */
6805 if ((prefixes & PREFIX_REPZ)
6806 && (b & 1
6807 ? s->cpuid_ext3_features & CPUID_EXT3_ABM
6808 : s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)) {
6809 int size = 8 << ot;
6810 tcg_gen_mov_tl(cpu_cc_src, cpu_T0);
6811 if (b & 1) {
6812 /* For lzcnt, reduce the target_ulong result by the
6813 number of zeros that we expect to find at the top. */
6814 gen_helper_clz(cpu_T0, cpu_T0);
6815 tcg_gen_subi_tl(cpu_T0, cpu_T0, TARGET_LONG_BITS - size);
6816 } else {
6817 /* For tzcnt, a zero input must return the operand size:
6818 force all bits outside the operand size to 1. */
6819 target_ulong mask = (target_ulong)-2 << (size - 1);
6820 tcg_gen_ori_tl(cpu_T0, cpu_T0, mask);
6821 gen_helper_ctz(cpu_T0, cpu_T0);
6822 }
6823 /* For lzcnt/tzcnt, C and Z bits are defined and are
6824 related to the result. */
6825 gen_op_update1_cc();
6826 set_cc_op(s, CC_OP_BMILGB + ot);
6827 } else {
6828 /* For bsr/bsf, only the Z bit is defined and it is related
6829 to the input and not the result. */
6830 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
6831 set_cc_op(s, CC_OP_LOGICB + ot);
6832 if (b & 1) {
6833 /* For bsr, return the bit index of the first 1 bit,
6834 not the count of leading zeros. */
6835 gen_helper_clz(cpu_T0, cpu_T0);
6836 tcg_gen_xori_tl(cpu_T0, cpu_T0, TARGET_LONG_BITS - 1);
6837 } else {
6838 gen_helper_ctz(cpu_T0, cpu_T0);
6839 }
6840 /* ??? The manual says that the output is undefined when the
6841 input is zero, but real hardware leaves it unchanged, and
6842 real programs appear to depend on that. */
6843 tcg_gen_movi_tl(cpu_tmp0, 0);
6844 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_T0, cpu_cc_dst, cpu_tmp0,
6845 cpu_regs[reg], cpu_T0);
6846 }
6847 gen_op_mov_reg_v(ot, reg, cpu_T0);
6848 break;
6849 /************************/
6850 /* bcd */
6851 case 0x27: /* daa */
6852 if (CODE64(s))
6853 goto illegal_op;
6854 gen_update_cc_op(s);
6855 gen_helper_daa(cpu_env);
6856 set_cc_op(s, CC_OP_EFLAGS);
6857 break;
6858 case 0x2f: /* das */
6859 if (CODE64(s))
6860 goto illegal_op;
6861 gen_update_cc_op(s);
6862 gen_helper_das(cpu_env);
6863 set_cc_op(s, CC_OP_EFLAGS);
6864 break;
6865 case 0x37: /* aaa */
6866 if (CODE64(s))
6867 goto illegal_op;
6868 gen_update_cc_op(s);
6869 gen_helper_aaa(cpu_env);
6870 set_cc_op(s, CC_OP_EFLAGS);
6871 break;
6872 case 0x3f: /* aas */
6873 if (CODE64(s))
6874 goto illegal_op;
6875 gen_update_cc_op(s);
6876 gen_helper_aas(cpu_env);
6877 set_cc_op(s, CC_OP_EFLAGS);
6878 break;
6879 case 0xd4: /* aam */
6880 if (CODE64(s))
6881 goto illegal_op;
6882 val = cpu_ldub_code(env, s->pc++);
6883 if (val == 0) {
6884 gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base);
6885 } else {
6886 gen_helper_aam(cpu_env, tcg_const_i32(val));
6887 set_cc_op(s, CC_OP_LOGICB);
6888 }
6889 break;
6890 case 0xd5: /* aad */
6891 if (CODE64(s))
6892 goto illegal_op;
6893 val = cpu_ldub_code(env, s->pc++);
6894 gen_helper_aad(cpu_env, tcg_const_i32(val));
6895 set_cc_op(s, CC_OP_LOGICB);
6896 break;
6897 /************************/
6898 /* misc */
6899 case 0x90: /* nop */
6900 /* XXX: correct lock test for all insn */
6901 if (prefixes & PREFIX_LOCK) {
6902 goto illegal_op;
6903 }
6904 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
6905 if (REX_B(s)) {
6906 goto do_xchg_reg_eax;
6907 }
6908 if (prefixes & PREFIX_REPZ) {
6909 gen_update_cc_op(s);
6910 gen_jmp_im(pc_start - s->cs_base);
6911 gen_helper_pause(cpu_env, tcg_const_i32(s->pc - pc_start));
6912 s->is_jmp = DISAS_TB_JUMP;
6913 }
6914 break;
6915 case 0x9b: /* fwait */
6916 if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
6917 (HF_MP_MASK | HF_TS_MASK)) {
6918 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
6919 } else {
6920 gen_helper_fwait(cpu_env);
6921 }
6922 break;
6923 case 0xcc: /* int3 */
6924 gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
6925 break;
6926 case 0xcd: /* int N */
6927 val = cpu_ldub_code(env, s->pc++);
6928 if (s->vm86 && s->iopl != 3) {
6929 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6930 } else {
6931 gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
6932 }
6933 break;
6934 case 0xce: /* into */
6935 if (CODE64(s))
6936 goto illegal_op;
6937 gen_update_cc_op(s);
6938 gen_jmp_im(pc_start - s->cs_base);
6939 gen_helper_into(cpu_env, tcg_const_i32(s->pc - pc_start));
6940 break;
6941 #ifdef WANT_ICEBP
6942 case 0xf1: /* icebp (undocumented, exits to external debugger) */
6943 gen_svm_check_intercept(s, pc_start, SVM_EXIT_ICEBP);
6944 #if 1
6945 gen_debug(s, pc_start - s->cs_base);
6946 #else
6947 /* start debug */
6948 tb_flush(CPU(x86_env_get_cpu(env)));
6949 qemu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM);
6950 #endif
6951 break;
6952 #endif
6953 case 0xfa: /* cli */
6954 if (!s->vm86) {
6955 if (s->cpl <= s->iopl) {
6956 gen_helper_cli(cpu_env);
6957 } else {
6958 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6959 }
6960 } else {
6961 if (s->iopl == 3) {
6962 gen_helper_cli(cpu_env);
6963 } else {
6964 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6965 }
6966 }
6967 break;
6968 case 0xfb: /* sti */
6969 if (s->vm86 ? s->iopl == 3 : s->cpl <= s->iopl) {
6970 gen_helper_sti(cpu_env);
6971 /* interruptions are enabled only the first insn after sti */
6972 gen_jmp_im(s->pc - s->cs_base);
6973 gen_eob_inhibit_irq(s, true);
6974 } else {
6975 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6976 }
6977 break;
6978 case 0x62: /* bound */
6979 if (CODE64(s))
6980 goto illegal_op;
6981 ot = dflag;
6982 modrm = cpu_ldub_code(env, s->pc++);
6983 reg = (modrm >> 3) & 7;
6984 mod = (modrm >> 6) & 3;
6985 if (mod == 3)
6986 goto illegal_op;
6987 gen_op_mov_v_reg(ot, cpu_T0, reg);
6988 gen_lea_modrm(env, s, modrm);
6989 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
6990 if (ot == MO_16) {
6991 gen_helper_boundw(cpu_env, cpu_A0, cpu_tmp2_i32);
6992 } else {
6993 gen_helper_boundl(cpu_env, cpu_A0, cpu_tmp2_i32);
6994 }
6995 break;
6996 case 0x1c8 ... 0x1cf: /* bswap reg */
6997 reg = (b & 7) | REX_B(s);
6998 #ifdef TARGET_X86_64
6999 if (dflag == MO_64) {
7000 gen_op_mov_v_reg(MO_64, cpu_T0, reg);
7001 tcg_gen_bswap64_i64(cpu_T0, cpu_T0);
7002 gen_op_mov_reg_v(MO_64, reg, cpu_T0);
7003 } else
7004 #endif
7005 {
7006 gen_op_mov_v_reg(MO_32, cpu_T0, reg);
7007 tcg_gen_ext32u_tl(cpu_T0, cpu_T0);
7008 tcg_gen_bswap32_tl(cpu_T0, cpu_T0);
7009 gen_op_mov_reg_v(MO_32, reg, cpu_T0);
7010 }
7011 break;
7012 case 0xd6: /* salc */
7013 if (CODE64(s))
7014 goto illegal_op;
7015 gen_compute_eflags_c(s, cpu_T0);
7016 tcg_gen_neg_tl(cpu_T0, cpu_T0);
7017 gen_op_mov_reg_v(MO_8, R_EAX, cpu_T0);
7018 break;
7019 case 0xe0: /* loopnz */
7020 case 0xe1: /* loopz */
7021 case 0xe2: /* loop */
7022 case 0xe3: /* jecxz */
7023 {
7024 TCGLabel *l1, *l2, *l3;
7025
7026 tval = (int8_t)insn_get(env, s, MO_8);
7027 next_eip = s->pc - s->cs_base;
7028 tval += next_eip;
7029 if (dflag == MO_16) {
7030 tval &= 0xffff;
7031 }
7032
7033 l1 = gen_new_label();
7034 l2 = gen_new_label();
7035 l3 = gen_new_label();
7036 b &= 3;
7037 switch(b) {
7038 case 0: /* loopnz */
7039 case 1: /* loopz */
7040 gen_op_add_reg_im(s->aflag, R_ECX, -1);
7041 gen_op_jz_ecx(s->aflag, l3);
7042 gen_jcc1(s, (JCC_Z << 1) | (b ^ 1), l1);
7043 break;
7044 case 2: /* loop */
7045 gen_op_add_reg_im(s->aflag, R_ECX, -1);
7046 gen_op_jnz_ecx(s->aflag, l1);
7047 break;
7048 default:
7049 case 3: /* jcxz */
7050 gen_op_jz_ecx(s->aflag, l1);
7051 break;
7052 }
7053
7054 gen_set_label(l3);
7055 gen_jmp_im(next_eip);
7056 tcg_gen_br(l2);
7057
7058 gen_set_label(l1);
7059 gen_jmp_im(tval);
7060 gen_set_label(l2);
7061 gen_eob(s);
7062 }
7063 break;
7064 case 0x130: /* wrmsr */
7065 case 0x132: /* rdmsr */
7066 if (s->cpl != 0) {
7067 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7068 } else {
7069 gen_update_cc_op(s);
7070 gen_jmp_im(pc_start - s->cs_base);
7071 if (b & 2) {
7072 gen_helper_rdmsr(cpu_env);
7073 } else {
7074 gen_helper_wrmsr(cpu_env);
7075 }
7076 }
7077 break;
7078 case 0x131: /* rdtsc */
7079 gen_update_cc_op(s);
7080 gen_jmp_im(pc_start - s->cs_base);
7081 if (s->tb->cflags & CF_USE_ICOUNT) {
7082 gen_io_start();
7083 }
7084 gen_helper_rdtsc(cpu_env);
7085 if (s->tb->cflags & CF_USE_ICOUNT) {
7086 gen_io_end();
7087 gen_jmp(s, s->pc - s->cs_base);
7088 }
7089 break;
7090 case 0x133: /* rdpmc */
7091 gen_update_cc_op(s);
7092 gen_jmp_im(pc_start - s->cs_base);
7093 gen_helper_rdpmc(cpu_env);
7094 break;
7095 case 0x134: /* sysenter */
7096 /* For Intel SYSENTER is valid on 64-bit */
7097 if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
7098 goto illegal_op;
7099 if (!s->pe) {
7100 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7101 } else {
7102 gen_helper_sysenter(cpu_env);
7103 gen_eob(s);
7104 }
7105 break;
7106 case 0x135: /* sysexit */
7107 /* For Intel SYSEXIT is valid on 64-bit */
7108 if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
7109 goto illegal_op;
7110 if (!s->pe) {
7111 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7112 } else {
7113 gen_helper_sysexit(cpu_env, tcg_const_i32(dflag - 1));
7114 gen_eob(s);
7115 }
7116 break;
7117 #ifdef TARGET_X86_64
7118 case 0x105: /* syscall */
7119 /* XXX: is it usable in real mode ? */
7120 gen_update_cc_op(s);
7121 gen_jmp_im(pc_start - s->cs_base);
7122 gen_helper_syscall(cpu_env, tcg_const_i32(s->pc - pc_start));
7123 gen_eob(s);
7124 break;
7125 case 0x107: /* sysret */
7126 if (!s->pe) {
7127 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7128 } else {
7129 gen_helper_sysret(cpu_env, tcg_const_i32(dflag - 1));
7130 /* condition codes are modified only in long mode */
7131 if (s->lma) {
7132 set_cc_op(s, CC_OP_EFLAGS);
7133 }
7134 /* TF handling for the sysret insn is different. The TF bit is
7135 checked after the sysret insn completes. This allows #DB to be
7136 generated "as if" the syscall insn in userspace has just
7137 completed. */
7138 gen_eob_worker(s, false, true);
7139 }
7140 break;
7141 #endif
7142 case 0x1a2: /* cpuid */
7143 gen_update_cc_op(s);
7144 gen_jmp_im(pc_start - s->cs_base);
7145 gen_helper_cpuid(cpu_env);
7146 break;
7147 case 0xf4: /* hlt */
7148 if (s->cpl != 0) {
7149 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7150 } else {
7151 gen_update_cc_op(s);
7152 gen_jmp_im(pc_start - s->cs_base);
7153 gen_helper_hlt(cpu_env, tcg_const_i32(s->pc - pc_start));
7154 s->is_jmp = DISAS_TB_JUMP;
7155 }
7156 break;
7157 case 0x100:
7158 modrm = cpu_ldub_code(env, s->pc++);
7159 mod = (modrm >> 6) & 3;
7160 op = (modrm >> 3) & 7;
7161 switch(op) {
7162 case 0: /* sldt */
7163 if (!s->pe || s->vm86)
7164 goto illegal_op;
7165 gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_READ);
7166 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
7167 offsetof(CPUX86State, ldt.selector));
7168 ot = mod == 3 ? dflag : MO_16;
7169 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7170 break;
7171 case 2: /* lldt */
7172 if (!s->pe || s->vm86)
7173 goto illegal_op;
7174 if (s->cpl != 0) {
7175 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7176 } else {
7177 gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_WRITE);
7178 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7179 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
7180 gen_helper_lldt(cpu_env, cpu_tmp2_i32);
7181 }
7182 break;
7183 case 1: /* str */
7184 if (!s->pe || s->vm86)
7185 goto illegal_op;
7186 gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_READ);
7187 tcg_gen_ld32u_tl(cpu_T0, cpu_env,
7188 offsetof(CPUX86State, tr.selector));
7189 ot = mod == 3 ? dflag : MO_16;
7190 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7191 break;
7192 case 3: /* ltr */
7193 if (!s->pe || s->vm86)
7194 goto illegal_op;
7195 if (s->cpl != 0) {
7196 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7197 } else {
7198 gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_WRITE);
7199 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7200 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
7201 gen_helper_ltr(cpu_env, cpu_tmp2_i32);
7202 }
7203 break;
7204 case 4: /* verr */
7205 case 5: /* verw */
7206 if (!s->pe || s->vm86)
7207 goto illegal_op;
7208 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7209 gen_update_cc_op(s);
7210 if (op == 4) {
7211 gen_helper_verr(cpu_env, cpu_T0);
7212 } else {
7213 gen_helper_verw(cpu_env, cpu_T0);
7214 }
7215 set_cc_op(s, CC_OP_EFLAGS);
7216 break;
7217 default:
7218 goto unknown_op;
7219 }
7220 break;
7221
7222 case 0x101:
7223 modrm = cpu_ldub_code(env, s->pc++);
7224 switch (modrm) {
7225 CASE_MODRM_MEM_OP(0): /* sgdt */
7226 gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_READ);
7227 gen_lea_modrm(env, s, modrm);
7228 tcg_gen_ld32u_tl(cpu_T0,
7229 cpu_env, offsetof(CPUX86State, gdt.limit));
7230 gen_op_st_v(s, MO_16, cpu_T0, cpu_A0);
7231 gen_add_A0_im(s, 2);
7232 tcg_gen_ld_tl(cpu_T0, cpu_env, offsetof(CPUX86State, gdt.base));
7233 if (dflag == MO_16) {
7234 tcg_gen_andi_tl(cpu_T0, cpu_T0, 0xffffff);
7235 }
7236 gen_op_st_v(s, CODE64(s) + MO_32, cpu_T0, cpu_A0);
7237 break;
7238
7239 case 0xc8: /* monitor */
7240 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || s->cpl != 0) {
7241 goto illegal_op;
7242 }
7243 gen_update_cc_op(s);
7244 gen_jmp_im(pc_start - s->cs_base);
7245 tcg_gen_mov_tl(cpu_A0, cpu_regs[R_EAX]);
7246 gen_extu(s->aflag, cpu_A0);
7247 gen_add_A0_ds_seg(s);
7248 gen_helper_monitor(cpu_env, cpu_A0);
7249 break;
7250
7251 case 0xc9: /* mwait */
7252 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || s->cpl != 0) {
7253 goto illegal_op;
7254 }
7255 gen_update_cc_op(s);
7256 gen_jmp_im(pc_start - s->cs_base);
7257 gen_helper_mwait(cpu_env, tcg_const_i32(s->pc - pc_start));
7258 gen_eob(s);
7259 break;
7260
7261 case 0xca: /* clac */
7262 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)
7263 || s->cpl != 0) {
7264 goto illegal_op;
7265 }
7266 gen_helper_clac(cpu_env);
7267 gen_jmp_im(s->pc - s->cs_base);
7268 gen_eob(s);
7269 break;
7270
7271 case 0xcb: /* stac */
7272 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)
7273 || s->cpl != 0) {
7274 goto illegal_op;
7275 }
7276 gen_helper_stac(cpu_env);
7277 gen_jmp_im(s->pc - s->cs_base);
7278 gen_eob(s);
7279 break;
7280
7281 CASE_MODRM_MEM_OP(1): /* sidt */
7282 gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_READ);
7283 gen_lea_modrm(env, s, modrm);
7284 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State, idt.limit));
7285 gen_op_st_v(s, MO_16, cpu_T0, cpu_A0);
7286 gen_add_A0_im(s, 2);
7287 tcg_gen_ld_tl(cpu_T0, cpu_env, offsetof(CPUX86State, idt.base));
7288 if (dflag == MO_16) {
7289 tcg_gen_andi_tl(cpu_T0, cpu_T0, 0xffffff);
7290 }
7291 gen_op_st_v(s, CODE64(s) + MO_32, cpu_T0, cpu_A0);
7292 break;
7293
7294 case 0xd0: /* xgetbv */
7295 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
7296 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA
7297 | PREFIX_REPZ | PREFIX_REPNZ))) {
7298 goto illegal_op;
7299 }
7300 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_ECX]);
7301 gen_helper_xgetbv(cpu_tmp1_i64, cpu_env, cpu_tmp2_i32);
7302 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], cpu_tmp1_i64);
7303 break;
7304
7305 case 0xd1: /* xsetbv */
7306 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
7307 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA
7308 | PREFIX_REPZ | PREFIX_REPNZ))) {
7309 goto illegal_op;
7310 }
7311 if (s->cpl != 0) {
7312 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7313 break;
7314 }
7315 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
7316 cpu_regs[R_EDX]);
7317 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_ECX]);
7318 gen_helper_xsetbv(cpu_env, cpu_tmp2_i32, cpu_tmp1_i64);
7319 /* End TB because translation flags may change. */
7320 gen_jmp_im(s->pc - s->cs_base);
7321 gen_eob(s);
7322 break;
7323
7324 case 0xd8: /* VMRUN */
7325 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7326 goto illegal_op;
7327 }
7328 if (s->cpl != 0) {
7329 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7330 break;
7331 }
7332 gen_update_cc_op(s);
7333 gen_jmp_im(pc_start - s->cs_base);
7334 gen_helper_vmrun(cpu_env, tcg_const_i32(s->aflag - 1),
7335 tcg_const_i32(s->pc - pc_start));
7336 tcg_gen_exit_tb(0);
7337 s->is_jmp = DISAS_TB_JUMP;
7338 break;
7339
7340 case 0xd9: /* VMMCALL */
7341 if (!(s->flags & HF_SVME_MASK)) {
7342 goto illegal_op;
7343 }
7344 gen_update_cc_op(s);
7345 gen_jmp_im(pc_start - s->cs_base);
7346 gen_helper_vmmcall(cpu_env);
7347 break;
7348
7349 case 0xda: /* VMLOAD */
7350 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7351 goto illegal_op;
7352 }
7353 if (s->cpl != 0) {
7354 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7355 break;
7356 }
7357 gen_update_cc_op(s);
7358 gen_jmp_im(pc_start - s->cs_base);
7359 gen_helper_vmload(cpu_env, tcg_const_i32(s->aflag - 1));
7360 break;
7361
7362 case 0xdb: /* VMSAVE */
7363 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7364 goto illegal_op;
7365 }
7366 if (s->cpl != 0) {
7367 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7368 break;
7369 }
7370 gen_update_cc_op(s);
7371 gen_jmp_im(pc_start - s->cs_base);
7372 gen_helper_vmsave(cpu_env, tcg_const_i32(s->aflag - 1));
7373 break;
7374
7375 case 0xdc: /* STGI */
7376 if ((!(s->flags & HF_SVME_MASK)
7377 && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
7378 || !s->pe) {
7379 goto illegal_op;
7380 }
7381 if (s->cpl != 0) {
7382 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7383 break;
7384 }
7385 gen_update_cc_op(s);
7386 gen_jmp_im(pc_start - s->cs_base);
7387 gen_helper_stgi(cpu_env);
7388 break;
7389
7390 case 0xdd: /* CLGI */
7391 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7392 goto illegal_op;
7393 }
7394 if (s->cpl != 0) {
7395 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7396 break;
7397 }
7398 gen_update_cc_op(s);
7399 gen_jmp_im(pc_start - s->cs_base);
7400 gen_helper_clgi(cpu_env);
7401 break;
7402
7403 case 0xde: /* SKINIT */
7404 if ((!(s->flags & HF_SVME_MASK)
7405 && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
7406 || !s->pe) {
7407 goto illegal_op;
7408 }
7409 gen_update_cc_op(s);
7410 gen_jmp_im(pc_start - s->cs_base);
7411 gen_helper_skinit(cpu_env);
7412 break;
7413
7414 case 0xdf: /* INVLPGA */
7415 if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7416 goto illegal_op;
7417 }
7418 if (s->cpl != 0) {
7419 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7420 break;
7421 }
7422 gen_update_cc_op(s);
7423 gen_jmp_im(pc_start - s->cs_base);
7424 gen_helper_invlpga(cpu_env, tcg_const_i32(s->aflag - 1));
7425 break;
7426
7427 CASE_MODRM_MEM_OP(2): /* lgdt */
7428 if (s->cpl != 0) {
7429 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7430 break;
7431 }
7432 gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_WRITE);
7433 gen_lea_modrm(env, s, modrm);
7434 gen_op_ld_v(s, MO_16, cpu_T1, cpu_A0);
7435 gen_add_A0_im(s, 2);
7436 gen_op_ld_v(s, CODE64(s) + MO_32, cpu_T0, cpu_A0);
7437 if (dflag == MO_16) {
7438 tcg_gen_andi_tl(cpu_T0, cpu_T0, 0xffffff);
7439 }
7440 tcg_gen_st_tl(cpu_T0, cpu_env, offsetof(CPUX86State, gdt.base));
7441 tcg_gen_st32_tl(cpu_T1, cpu_env, offsetof(CPUX86State, gdt.limit));
7442 break;
7443
7444 CASE_MODRM_MEM_OP(3): /* lidt */
7445 if (s->cpl != 0) {
7446 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7447 break;
7448 }
7449 gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_WRITE);
7450 gen_lea_modrm(env, s, modrm);
7451 gen_op_ld_v(s, MO_16, cpu_T1, cpu_A0);
7452 gen_add_A0_im(s, 2);
7453 gen_op_ld_v(s, CODE64(s) + MO_32, cpu_T0, cpu_A0);
7454 if (dflag == MO_16) {
7455 tcg_gen_andi_tl(cpu_T0, cpu_T0, 0xffffff);
7456 }
7457 tcg_gen_st_tl(cpu_T0, cpu_env, offsetof(CPUX86State, idt.base));
7458 tcg_gen_st32_tl(cpu_T1, cpu_env, offsetof(CPUX86State, idt.limit));
7459 break;
7460
7461 CASE_MODRM_OP(4): /* smsw */
7462 gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0);
7463 tcg_gen_ld_tl(cpu_T0, cpu_env, offsetof(CPUX86State, cr[0]));
7464 if (CODE64(s)) {
7465 mod = (modrm >> 6) & 3;
7466 ot = (mod != 3 ? MO_16 : s->dflag);
7467 } else {
7468 ot = MO_16;
7469 }
7470 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7471 break;
7472 case 0xee: /* rdpkru */
7473 if (prefixes & PREFIX_LOCK) {
7474 goto illegal_op;
7475 }
7476 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_ECX]);
7477 gen_helper_rdpkru(cpu_tmp1_i64, cpu_env, cpu_tmp2_i32);
7478 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], cpu_tmp1_i64);
7479 break;
7480 case 0xef: /* wrpkru */
7481 if (prefixes & PREFIX_LOCK) {
7482 goto illegal_op;
7483 }
7484 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
7485 cpu_regs[R_EDX]);
7486 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_ECX]);
7487 gen_helper_wrpkru(cpu_env, cpu_tmp2_i32, cpu_tmp1_i64);
7488 break;
7489 CASE_MODRM_OP(6): /* lmsw */
7490 if (s->cpl != 0) {
7491 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7492 break;
7493 }
7494 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
7495 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7496 gen_helper_lmsw(cpu_env, cpu_T0);
7497 gen_jmp_im(s->pc - s->cs_base);
7498 gen_eob(s);
7499 break;
7500
7501 CASE_MODRM_MEM_OP(7): /* invlpg */
7502 if (s->cpl != 0) {
7503 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7504 break;
7505 }
7506 gen_update_cc_op(s);
7507 gen_jmp_im(pc_start - s->cs_base);
7508 gen_lea_modrm(env, s, modrm);
7509 gen_helper_invlpg(cpu_env, cpu_A0);
7510 gen_jmp_im(s->pc - s->cs_base);
7511 gen_eob(s);
7512 break;
7513
7514 case 0xf8: /* swapgs */
7515 #ifdef TARGET_X86_64
7516 if (CODE64(s)) {
7517 if (s->cpl != 0) {
7518 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7519 } else {
7520 tcg_gen_mov_tl(cpu_T0, cpu_seg_base[R_GS]);
7521 tcg_gen_ld_tl(cpu_seg_base[R_GS], cpu_env,
7522 offsetof(CPUX86State, kernelgsbase));
7523 tcg_gen_st_tl(cpu_T0, cpu_env,
7524 offsetof(CPUX86State, kernelgsbase));
7525 }
7526 break;
7527 }
7528 #endif
7529 goto illegal_op;
7530
7531 case 0xf9: /* rdtscp */
7532 if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP)) {
7533 goto illegal_op;
7534 }
7535 gen_update_cc_op(s);
7536 gen_jmp_im(pc_start - s->cs_base);
7537 if (s->tb->cflags & CF_USE_ICOUNT) {
7538 gen_io_start();
7539 }
7540 gen_helper_rdtscp(cpu_env);
7541 if (s->tb->cflags & CF_USE_ICOUNT) {
7542 gen_io_end();
7543 gen_jmp(s, s->pc - s->cs_base);
7544 }
7545 break;
7546
7547 default:
7548 goto unknown_op;
7549 }
7550 break;
7551
7552 case 0x108: /* invd */
7553 case 0x109: /* wbinvd */
7554 if (s->cpl != 0) {
7555 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7556 } else {
7557 gen_svm_check_intercept(s, pc_start, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD);
7558 /* nothing to do */
7559 }
7560 break;
7561 case 0x63: /* arpl or movslS (x86_64) */
7562 #ifdef TARGET_X86_64
7563 if (CODE64(s)) {
7564 int d_ot;
7565 /* d_ot is the size of destination */
7566 d_ot = dflag;
7567
7568 modrm = cpu_ldub_code(env, s->pc++);
7569 reg = ((modrm >> 3) & 7) | rex_r;
7570 mod = (modrm >> 6) & 3;
7571 rm = (modrm & 7) | REX_B(s);
7572
7573 if (mod == 3) {
7574 gen_op_mov_v_reg(MO_32, cpu_T0, rm);
7575 /* sign extend */
7576 if (d_ot == MO_64) {
7577 tcg_gen_ext32s_tl(cpu_T0, cpu_T0);
7578 }
7579 gen_op_mov_reg_v(d_ot, reg, cpu_T0);
7580 } else {
7581 gen_lea_modrm(env, s, modrm);
7582 gen_op_ld_v(s, MO_32 | MO_SIGN, cpu_T0, cpu_A0);
7583 gen_op_mov_reg_v(d_ot, reg, cpu_T0);
7584 }
7585 } else
7586 #endif
7587 {
7588 TCGLabel *label1;
7589 TCGv t0, t1, t2, a0;
7590
7591 if (!s->pe || s->vm86)
7592 goto illegal_op;
7593 t0 = tcg_temp_local_new();
7594 t1 = tcg_temp_local_new();
7595 t2 = tcg_temp_local_new();
7596 ot = MO_16;
7597 modrm = cpu_ldub_code(env, s->pc++);
7598 reg = (modrm >> 3) & 7;
7599 mod = (modrm >> 6) & 3;
7600 rm = modrm & 7;
7601 if (mod != 3) {
7602 gen_lea_modrm(env, s, modrm);
7603 gen_op_ld_v(s, ot, t0, cpu_A0);
7604 a0 = tcg_temp_local_new();
7605 tcg_gen_mov_tl(a0, cpu_A0);
7606 } else {
7607 gen_op_mov_v_reg(ot, t0, rm);
7608 TCGV_UNUSED(a0);
7609 }
7610 gen_op_mov_v_reg(ot, t1, reg);
7611 tcg_gen_andi_tl(cpu_tmp0, t0, 3);
7612 tcg_gen_andi_tl(t1, t1, 3);
7613 tcg_gen_movi_tl(t2, 0);
7614 label1 = gen_new_label();
7615 tcg_gen_brcond_tl(TCG_COND_GE, cpu_tmp0, t1, label1);
7616 tcg_gen_andi_tl(t0, t0, ~3);
7617 tcg_gen_or_tl(t0, t0, t1);
7618 tcg_gen_movi_tl(t2, CC_Z);
7619 gen_set_label(label1);
7620 if (mod != 3) {
7621 gen_op_st_v(s, ot, t0, a0);
7622 tcg_temp_free(a0);
7623 } else {
7624 gen_op_mov_reg_v(ot, rm, t0);
7625 }
7626 gen_compute_eflags(s);
7627 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z);
7628 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t2);
7629 tcg_temp_free(t0);
7630 tcg_temp_free(t1);
7631 tcg_temp_free(t2);
7632 }
7633 break;
7634 case 0x102: /* lar */
7635 case 0x103: /* lsl */
7636 {
7637 TCGLabel *label1;
7638 TCGv t0;
7639 if (!s->pe || s->vm86)
7640 goto illegal_op;
7641 ot = dflag != MO_16 ? MO_32 : MO_16;
7642 modrm = cpu_ldub_code(env, s->pc++);
7643 reg = ((modrm >> 3) & 7) | rex_r;
7644 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7645 t0 = tcg_temp_local_new();
7646 gen_update_cc_op(s);
7647 if (b == 0x102) {
7648 gen_helper_lar(t0, cpu_env, cpu_T0);
7649 } else {
7650 gen_helper_lsl(t0, cpu_env, cpu_T0);
7651 }
7652 tcg_gen_andi_tl(cpu_tmp0, cpu_cc_src, CC_Z);
7653 label1 = gen_new_label();
7654 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
7655 gen_op_mov_reg_v(ot, reg, t0);
7656 gen_set_label(label1);
7657 set_cc_op(s, CC_OP_EFLAGS);
7658 tcg_temp_free(t0);
7659 }
7660 break;
7661 case 0x118:
7662 modrm = cpu_ldub_code(env, s->pc++);
7663 mod = (modrm >> 6) & 3;
7664 op = (modrm >> 3) & 7;
7665 switch(op) {
7666 case 0: /* prefetchnta */
7667 case 1: /* prefetchnt0 */
7668 case 2: /* prefetchnt0 */
7669 case 3: /* prefetchnt0 */
7670 if (mod == 3)
7671 goto illegal_op;
7672 gen_nop_modrm(env, s, modrm);
7673 /* nothing more to do */
7674 break;
7675 default: /* nop (multi byte) */
7676 gen_nop_modrm(env, s, modrm);
7677 break;
7678 }
7679 break;
7680 case 0x11a:
7681 modrm = cpu_ldub_code(env, s->pc++);
7682 if (s->flags & HF_MPX_EN_MASK) {
7683 mod = (modrm >> 6) & 3;
7684 reg = ((modrm >> 3) & 7) | rex_r;
7685 if (prefixes & PREFIX_REPZ) {
7686 /* bndcl */
7687 if (reg >= 4
7688 || (prefixes & PREFIX_LOCK)
7689 || s->aflag == MO_16) {
7690 goto illegal_op;
7691 }
7692 gen_bndck(env, s, modrm, TCG_COND_LTU, cpu_bndl[reg]);
7693 } else if (prefixes & PREFIX_REPNZ) {
7694 /* bndcu */
7695 if (reg >= 4
7696 || (prefixes & PREFIX_LOCK)
7697 || s->aflag == MO_16) {
7698 goto illegal_op;
7699 }
7700 TCGv_i64 notu = tcg_temp_new_i64();
7701 tcg_gen_not_i64(notu, cpu_bndu[reg]);
7702 gen_bndck(env, s, modrm, TCG_COND_GTU, notu);
7703 tcg_temp_free_i64(notu);
7704 } else if (prefixes & PREFIX_DATA) {
7705 /* bndmov -- from reg/mem */
7706 if (reg >= 4 || s->aflag == MO_16) {
7707 goto illegal_op;
7708 }
7709 if (mod == 3) {
7710 int reg2 = (modrm & 7) | REX_B(s);
7711 if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) {
7712 goto illegal_op;
7713 }
7714 if (s->flags & HF_MPX_IU_MASK) {
7715 tcg_gen_mov_i64(cpu_bndl[reg], cpu_bndl[reg2]);
7716 tcg_gen_mov_i64(cpu_bndu[reg], cpu_bndu[reg2]);
7717 }
7718 } else {
7719 gen_lea_modrm(env, s, modrm);
7720 if (CODE64(s)) {
7721 tcg_gen_qemu_ld_i64(cpu_bndl[reg], cpu_A0,
7722 s->mem_index, MO_LEQ);
7723 tcg_gen_addi_tl(cpu_A0, cpu_A0, 8);
7724 tcg_gen_qemu_ld_i64(cpu_bndu[reg], cpu_A0,
7725 s->mem_index, MO_LEQ);
7726 } else {
7727 tcg_gen_qemu_ld_i64(cpu_bndl[reg], cpu_A0,
7728 s->mem_index, MO_LEUL);
7729 tcg_gen_addi_tl(cpu_A0, cpu_A0, 4);
7730 tcg_gen_qemu_ld_i64(cpu_bndu[reg], cpu_A0,
7731 s->mem_index, MO_LEUL);
7732 }
7733 /* bnd registers are now in-use */
7734 gen_set_hflag(s, HF_MPX_IU_MASK);
7735 }
7736 } else if (mod != 3) {
7737 /* bndldx */
7738 AddressParts a = gen_lea_modrm_0(env, s, modrm);
7739 if (reg >= 4
7740 || (prefixes & PREFIX_LOCK)
7741 || s->aflag == MO_16
7742 || a.base < -1) {
7743 goto illegal_op;
7744 }
7745 if (a.base >= 0) {
7746 tcg_gen_addi_tl(cpu_A0, cpu_regs[a.base], a.disp);
7747 } else {
7748 tcg_gen_movi_tl(cpu_A0, 0);
7749 }
7750 gen_lea_v_seg(s, s->aflag, cpu_A0, a.def_seg, s->override);
7751 if (a.index >= 0) {
7752 tcg_gen_mov_tl(cpu_T0, cpu_regs[a.index]);
7753 } else {
7754 tcg_gen_movi_tl(cpu_T0, 0);
7755 }
7756 if (CODE64(s)) {
7757 gen_helper_bndldx64(cpu_bndl[reg], cpu_env, cpu_A0, cpu_T0);
7758 tcg_gen_ld_i64(cpu_bndu[reg], cpu_env,
7759 offsetof(CPUX86State, mmx_t0.MMX_Q(0)));
7760 } else {
7761 gen_helper_bndldx32(cpu_bndu[reg], cpu_env, cpu_A0, cpu_T0);
7762 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndu[reg]);
7763 tcg_gen_shri_i64(cpu_bndu[reg], cpu_bndu[reg], 32);
7764 }
7765 gen_set_hflag(s, HF_MPX_IU_MASK);
7766 }
7767 }
7768 gen_nop_modrm(env, s, modrm);
7769 break;
7770 case 0x11b:
7771 modrm = cpu_ldub_code(env, s->pc++);
7772 if (s->flags & HF_MPX_EN_MASK) {
7773 mod = (modrm >> 6) & 3;
7774 reg = ((modrm >> 3) & 7) | rex_r;
7775 if (mod != 3 && (prefixes & PREFIX_REPZ)) {
7776 /* bndmk */
7777 if (reg >= 4
7778 || (prefixes & PREFIX_LOCK)
7779 || s->aflag == MO_16) {
7780 goto illegal_op;
7781 }
7782 AddressParts a = gen_lea_modrm_0(env, s, modrm);
7783 if (a.base >= 0) {
7784 tcg_gen_extu_tl_i64(cpu_bndl[reg], cpu_regs[a.base]);
7785 if (!CODE64(s)) {
7786 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndl[reg]);
7787 }
7788 } else if (a.base == -1) {
7789 /* no base register has lower bound of 0 */
7790 tcg_gen_movi_i64(cpu_bndl[reg], 0);
7791 } else {
7792 /* rip-relative generates #ud */
7793 goto illegal_op;
7794 }
7795 tcg_gen_not_tl(cpu_A0, gen_lea_modrm_1(a));
7796 if (!CODE64(s)) {
7797 tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
7798 }
7799 tcg_gen_extu_tl_i64(cpu_bndu[reg], cpu_A0);
7800 /* bnd registers are now in-use */
7801 gen_set_hflag(s, HF_MPX_IU_MASK);
7802 break;
7803 } else if (prefixes & PREFIX_REPNZ) {
7804 /* bndcn */
7805 if (reg >= 4
7806 || (prefixes & PREFIX_LOCK)
7807 || s->aflag == MO_16) {
7808 goto illegal_op;
7809 }
7810 gen_bndck(env, s, modrm, TCG_COND_GTU, cpu_bndu[reg]);
7811 } else if (prefixes & PREFIX_DATA) {
7812 /* bndmov -- to reg/mem */
7813 if (reg >= 4 || s->aflag == MO_16) {
7814 goto illegal_op;
7815 }
7816 if (mod == 3) {
7817 int reg2 = (modrm & 7) | REX_B(s);
7818 if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) {
7819 goto illegal_op;
7820 }
7821 if (s->flags & HF_MPX_IU_MASK) {
7822 tcg_gen_mov_i64(cpu_bndl[reg2], cpu_bndl[reg]);
7823 tcg_gen_mov_i64(cpu_bndu[reg2], cpu_bndu[reg]);
7824 }
7825 } else {
7826 gen_lea_modrm(env, s, modrm);
7827 if (CODE64(s)) {
7828 tcg_gen_qemu_st_i64(cpu_bndl[reg], cpu_A0,
7829 s->mem_index, MO_LEQ);
7830 tcg_gen_addi_tl(cpu_A0, cpu_A0, 8);
7831 tcg_gen_qemu_st_i64(cpu_bndu[reg], cpu_A0,
7832 s->mem_index, MO_LEQ);
7833 } else {
7834 tcg_gen_qemu_st_i64(cpu_bndl[reg], cpu_A0,
7835 s->mem_index, MO_LEUL);
7836 tcg_gen_addi_tl(cpu_A0, cpu_A0, 4);
7837 tcg_gen_qemu_st_i64(cpu_bndu[reg], cpu_A0,
7838 s->mem_index, MO_LEUL);
7839 }
7840 }
7841 } else if (mod != 3) {
7842 /* bndstx */
7843 AddressParts a = gen_lea_modrm_0(env, s, modrm);
7844 if (reg >= 4
7845 || (prefixes & PREFIX_LOCK)
7846 || s->aflag == MO_16
7847 || a.base < -1) {
7848 goto illegal_op;
7849 }
7850 if (a.base >= 0) {
7851 tcg_gen_addi_tl(cpu_A0, cpu_regs[a.base], a.disp);
7852 } else {
7853 tcg_gen_movi_tl(cpu_A0, 0);
7854 }
7855 gen_lea_v_seg(s, s->aflag, cpu_A0, a.def_seg, s->override);
7856 if (a.index >= 0) {
7857 tcg_gen_mov_tl(cpu_T0, cpu_regs[a.index]);
7858 } else {
7859 tcg_gen_movi_tl(cpu_T0, 0);
7860 }
7861 if (CODE64(s)) {
7862 gen_helper_bndstx64(cpu_env, cpu_A0, cpu_T0,
7863 cpu_bndl[reg], cpu_bndu[reg]);
7864 } else {
7865 gen_helper_bndstx32(cpu_env, cpu_A0, cpu_T0,
7866 cpu_bndl[reg], cpu_bndu[reg]);
7867 }
7868 }
7869 }
7870 gen_nop_modrm(env, s, modrm);
7871 break;
7872 case 0x119: case 0x11c ... 0x11f: /* nop (multi byte) */
7873 modrm = cpu_ldub_code(env, s->pc++);
7874 gen_nop_modrm(env, s, modrm);
7875 break;
7876 case 0x120: /* mov reg, crN */
7877 case 0x122: /* mov crN, reg */
7878 if (s->cpl != 0) {
7879 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7880 } else {
7881 modrm = cpu_ldub_code(env, s->pc++);
7882 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7883 * AMD documentation (24594.pdf) and testing of
7884 * intel 386 and 486 processors all show that the mod bits
7885 * are assumed to be 1's, regardless of actual values.
7886 */
7887 rm = (modrm & 7) | REX_B(s);
7888 reg = ((modrm >> 3) & 7) | rex_r;
7889 if (CODE64(s))
7890 ot = MO_64;
7891 else
7892 ot = MO_32;
7893 if ((prefixes & PREFIX_LOCK) && (reg == 0) &&
7894 (s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) {
7895 reg = 8;
7896 }
7897 switch(reg) {
7898 case 0:
7899 case 2:
7900 case 3:
7901 case 4:
7902 case 8:
7903 gen_update_cc_op(s);
7904 gen_jmp_im(pc_start - s->cs_base);
7905 if (b & 2) {
7906 gen_op_mov_v_reg(ot, cpu_T0, rm);
7907 gen_helper_write_crN(cpu_env, tcg_const_i32(reg),
7908 cpu_T0);
7909 gen_jmp_im(s->pc - s->cs_base);
7910 gen_eob(s);
7911 } else {
7912 gen_helper_read_crN(cpu_T0, cpu_env, tcg_const_i32(reg));
7913 gen_op_mov_reg_v(ot, rm, cpu_T0);
7914 }
7915 break;
7916 default:
7917 goto unknown_op;
7918 }
7919 }
7920 break;
7921 case 0x121: /* mov reg, drN */
7922 case 0x123: /* mov drN, reg */
7923 if (s->cpl != 0) {
7924 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7925 } else {
7926 modrm = cpu_ldub_code(env, s->pc++);
7927 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
7928 * AMD documentation (24594.pdf) and testing of
7929 * intel 386 and 486 processors all show that the mod bits
7930 * are assumed to be 1's, regardless of actual values.
7931 */
7932 rm = (modrm & 7) | REX_B(s);
7933 reg = ((modrm >> 3) & 7) | rex_r;
7934 if (CODE64(s))
7935 ot = MO_64;
7936 else
7937 ot = MO_32;
7938 if (reg >= 8) {
7939 goto illegal_op;
7940 }
7941 if (b & 2) {
7942 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
7943 gen_op_mov_v_reg(ot, cpu_T0, rm);
7944 tcg_gen_movi_i32(cpu_tmp2_i32, reg);
7945 gen_helper_set_dr(cpu_env, cpu_tmp2_i32, cpu_T0);
7946 gen_jmp_im(s->pc - s->cs_base);
7947 gen_eob(s);
7948 } else {
7949 gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_DR0 + reg);
7950 tcg_gen_movi_i32(cpu_tmp2_i32, reg);
7951 gen_helper_get_dr(cpu_T0, cpu_env, cpu_tmp2_i32);
7952 gen_op_mov_reg_v(ot, rm, cpu_T0);
7953 }
7954 }
7955 break;
7956 case 0x106: /* clts */
7957 if (s->cpl != 0) {
7958 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7959 } else {
7960 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
7961 gen_helper_clts(cpu_env);
7962 /* abort block because static cpu state changed */
7963 gen_jmp_im(s->pc - s->cs_base);
7964 gen_eob(s);
7965 }
7966 break;
7967 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
7968 case 0x1c3: /* MOVNTI reg, mem */
7969 if (!(s->cpuid_features & CPUID_SSE2))
7970 goto illegal_op;
7971 ot = mo_64_32(dflag);
7972 modrm = cpu_ldub_code(env, s->pc++);
7973 mod = (modrm >> 6) & 3;
7974 if (mod == 3)
7975 goto illegal_op;
7976 reg = ((modrm >> 3) & 7) | rex_r;
7977 /* generate a generic store */
7978 gen_ldst_modrm(env, s, modrm, ot, reg, 1);
7979 break;
7980 case 0x1ae:
7981 modrm = cpu_ldub_code(env, s->pc++);
7982 switch (modrm) {
7983 CASE_MODRM_MEM_OP(0): /* fxsave */
7984 if (!(s->cpuid_features & CPUID_FXSR)
7985 || (prefixes & PREFIX_LOCK)) {
7986 goto illegal_op;
7987 }
7988 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
7989 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
7990 break;
7991 }
7992 gen_lea_modrm(env, s, modrm);
7993 gen_helper_fxsave(cpu_env, cpu_A0);
7994 break;
7995
7996 CASE_MODRM_MEM_OP(1): /* fxrstor */
7997 if (!(s->cpuid_features & CPUID_FXSR)
7998 || (prefixes & PREFIX_LOCK)) {
7999 goto illegal_op;
8000 }
8001 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
8002 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
8003 break;
8004 }
8005 gen_lea_modrm(env, s, modrm);
8006 gen_helper_fxrstor(cpu_env, cpu_A0);
8007 break;
8008
8009 CASE_MODRM_MEM_OP(2): /* ldmxcsr */
8010 if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) {
8011 goto illegal_op;
8012 }
8013 if (s->flags & HF_TS_MASK) {
8014 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
8015 break;
8016 }
8017 gen_lea_modrm(env, s, modrm);
8018 tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0, s->mem_index, MO_LEUL);
8019 gen_helper_ldmxcsr(cpu_env, cpu_tmp2_i32);
8020 break;
8021
8022 CASE_MODRM_MEM_OP(3): /* stmxcsr */
8023 if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) {
8024 goto illegal_op;
8025 }
8026 if (s->flags & HF_TS_MASK) {
8027 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
8028 break;
8029 }
8030 gen_lea_modrm(env, s, modrm);
8031 tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State, mxcsr));
8032 gen_op_st_v(s, MO_32, cpu_T0, cpu_A0);
8033 break;
8034
8035 CASE_MODRM_MEM_OP(4): /* xsave */
8036 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
8037 || (prefixes & (PREFIX_LOCK | PREFIX_DATA
8038 | PREFIX_REPZ | PREFIX_REPNZ))) {
8039 goto illegal_op;
8040 }
8041 gen_lea_modrm(env, s, modrm);
8042 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
8043 cpu_regs[R_EDX]);
8044 gen_helper_xsave(cpu_env, cpu_A0, cpu_tmp1_i64);
8045 break;
8046
8047 CASE_MODRM_MEM_OP(5): /* xrstor */
8048 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
8049 || (prefixes & (PREFIX_LOCK | PREFIX_DATA
8050 | PREFIX_REPZ | PREFIX_REPNZ))) {
8051 goto illegal_op;
8052 }
8053 gen_lea_modrm(env, s, modrm);
8054 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
8055 cpu_regs[R_EDX]);
8056 gen_helper_xrstor(cpu_env, cpu_A0, cpu_tmp1_i64);
8057 /* XRSTOR is how MPX is enabled, which changes how
8058 we translate. Thus we need to end the TB. */
8059 gen_update_cc_op(s);
8060 gen_jmp_im(s->pc - s->cs_base);
8061 gen_eob(s);
8062 break;
8063
8064 CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */
8065 if (prefixes & PREFIX_LOCK) {
8066 goto illegal_op;
8067 }
8068 if (prefixes & PREFIX_DATA) {
8069 /* clwb */
8070 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLWB)) {
8071 goto illegal_op;
8072 }
8073 gen_nop_modrm(env, s, modrm);
8074 } else {
8075 /* xsaveopt */
8076 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
8077 || (s->cpuid_xsave_features & CPUID_XSAVE_XSAVEOPT) == 0
8078 || (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))) {
8079 goto illegal_op;
8080 }
8081 gen_lea_modrm(env, s, modrm);
8082 tcg_gen_concat_tl_i64(cpu_tmp1_i64, cpu_regs[R_EAX],
8083 cpu_regs[R_EDX]);
8084 gen_helper_xsaveopt(cpu_env, cpu_A0, cpu_tmp1_i64);
8085 }
8086 break;
8087
8088 CASE_MODRM_MEM_OP(7): /* clflush / clflushopt */
8089 if (prefixes & PREFIX_LOCK) {
8090 goto illegal_op;
8091 }
8092 if (prefixes & PREFIX_DATA) {
8093 /* clflushopt */
8094 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLFLUSHOPT)) {
8095 goto illegal_op;
8096 }
8097 } else {
8098 /* clflush */
8099 if ((s->prefix & (PREFIX_REPZ | PREFIX_REPNZ))
8100 || !(s->cpuid_features & CPUID_CLFLUSH)) {
8101 goto illegal_op;
8102 }
8103 }
8104 gen_nop_modrm(env, s, modrm);
8105 break;
8106
8107 case 0xc0 ... 0xc7: /* rdfsbase (f3 0f ae /0) */
8108 case 0xc8 ... 0xc8: /* rdgsbase (f3 0f ae /1) */
8109 case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */
8110 case 0xd8 ... 0xd8: /* wrgsbase (f3 0f ae /3) */
8111 if (CODE64(s)
8112 && (prefixes & PREFIX_REPZ)
8113 && !(prefixes & PREFIX_LOCK)
8114 && (s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_FSGSBASE)) {
8115 TCGv base, treg, src, dst;
8116
8117 /* Preserve hflags bits by testing CR4 at runtime. */
8118 tcg_gen_movi_i32(cpu_tmp2_i32, CR4_FSGSBASE_MASK);
8119 gen_helper_cr4_testbit(cpu_env, cpu_tmp2_i32);
8120
8121 base = cpu_seg_base[modrm & 8 ? R_GS : R_FS];
8122 treg = cpu_regs[(modrm & 7) | REX_B(s)];
8123
8124 if (modrm & 0x10) {
8125 /* wr*base */
8126 dst = base, src = treg;
8127 } else {
8128 /* rd*base */
8129 dst = treg, src = base;
8130 }
8131
8132 if (s->dflag == MO_32) {
8133 tcg_gen_ext32u_tl(dst, src);
8134 } else {
8135 tcg_gen_mov_tl(dst, src);
8136 }
8137 break;
8138 }
8139 goto unknown_op;
8140
8141 case 0xf8: /* sfence / pcommit */
8142 if (prefixes & PREFIX_DATA) {
8143 /* pcommit */
8144 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_PCOMMIT)
8145 || (prefixes & PREFIX_LOCK)) {
8146 goto illegal_op;
8147 }
8148 break;
8149 }
8150 /* fallthru */
8151 case 0xf9 ... 0xff: /* sfence */
8152 if (!(s->cpuid_features & CPUID_SSE)
8153 || (prefixes & PREFIX_LOCK)) {
8154 goto illegal_op;
8155 }
8156 tcg_gen_mb(TCG_MO_ST_ST | TCG_BAR_SC);
8157 break;
8158 case 0xe8 ... 0xef: /* lfence */
8159 if (!(s->cpuid_features & CPUID_SSE)
8160 || (prefixes & PREFIX_LOCK)) {
8161 goto illegal_op;
8162 }
8163 tcg_gen_mb(TCG_MO_LD_LD | TCG_BAR_SC);
8164 break;
8165 case 0xf0 ... 0xf7: /* mfence */
8166 if (!(s->cpuid_features & CPUID_SSE2)
8167 || (prefixes & PREFIX_LOCK)) {
8168 goto illegal_op;
8169 }
8170 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8171 break;
8172
8173 default:
8174 goto unknown_op;
8175 }
8176 break;
8177
8178 case 0x10d: /* 3DNow! prefetch(w) */
8179 modrm = cpu_ldub_code(env, s->pc++);
8180 mod = (modrm >> 6) & 3;
8181 if (mod == 3)
8182 goto illegal_op;
8183 gen_nop_modrm(env, s, modrm);
8184 break;
8185 case 0x1aa: /* rsm */
8186 gen_svm_check_intercept(s, pc_start, SVM_EXIT_RSM);
8187 if (!(s->flags & HF_SMM_MASK))
8188 goto illegal_op;
8189 gen_update_cc_op(s);
8190 gen_jmp_im(s->pc - s->cs_base);
8191 gen_helper_rsm(cpu_env);
8192 gen_eob(s);
8193 break;
8194 case 0x1b8: /* SSE4.2 popcnt */
8195 if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) !=
8196 PREFIX_REPZ)
8197 goto illegal_op;
8198 if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT))
8199 goto illegal_op;
8200
8201 modrm = cpu_ldub_code(env, s->pc++);
8202 reg = ((modrm >> 3) & 7) | rex_r;
8203
8204 if (s->prefix & PREFIX_DATA) {
8205 ot = MO_16;
8206 } else {
8207 ot = mo_64_32(dflag);
8208 }
8209
8210 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
8211 gen_helper_popcnt(cpu_T0, cpu_env, cpu_T0, tcg_const_i32(ot));
8212 gen_op_mov_reg_v(ot, reg, cpu_T0);
8213
8214 set_cc_op(s, CC_OP_EFLAGS);
8215 break;
8216 case 0x10e ... 0x10f:
8217 /* 3DNow! instructions, ignore prefixes */
8218 s->prefix &= ~(PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA);
8219 case 0x110 ... 0x117:
8220 case 0x128 ... 0x12f:
8221 case 0x138 ... 0x13a:
8222 case 0x150 ... 0x179:
8223 case 0x17c ... 0x17f:
8224 case 0x1c2:
8225 case 0x1c4 ... 0x1c6:
8226 case 0x1d0 ... 0x1fe:
8227 gen_sse(env, s, b, pc_start, rex_r);
8228 break;
8229 default:
8230 goto unknown_op;
8231 }
8232 return s->pc;
8233 illegal_op:
8234 gen_illegal_opcode(s);
8235 return s->pc;
8236 unknown_op:
8237 gen_unknown_opcode(env, s);
8238 return s->pc;
8239 }
8240
8241 void tcg_x86_init(void)
8242 {
8243 static const char reg_names[CPU_NB_REGS][4] = {
8244 #ifdef TARGET_X86_64
8245 [R_EAX] = "rax",
8246 [R_EBX] = "rbx",
8247 [R_ECX] = "rcx",
8248 [R_EDX] = "rdx",
8249 [R_ESI] = "rsi",
8250 [R_EDI] = "rdi",
8251 [R_EBP] = "rbp",
8252 [R_ESP] = "rsp",
8253 [8] = "r8",
8254 [9] = "r9",
8255 [10] = "r10",
8256 [11] = "r11",
8257 [12] = "r12",
8258 [13] = "r13",
8259 [14] = "r14",
8260 [15] = "r15",
8261 #else
8262 [R_EAX] = "eax",
8263 [R_EBX] = "ebx",
8264 [R_ECX] = "ecx",
8265 [R_EDX] = "edx",
8266 [R_ESI] = "esi",
8267 [R_EDI] = "edi",
8268 [R_EBP] = "ebp",
8269 [R_ESP] = "esp",
8270 #endif
8271 };
8272 static const char seg_base_names[6][8] = {
8273 [R_CS] = "cs_base",
8274 [R_DS] = "ds_base",
8275 [R_ES] = "es_base",
8276 [R_FS] = "fs_base",
8277 [R_GS] = "gs_base",
8278 [R_SS] = "ss_base",
8279 };
8280 static const char bnd_regl_names[4][8] = {
8281 "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb"
8282 };
8283 static const char bnd_regu_names[4][8] = {
8284 "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub"
8285 };
8286 int i;
8287 static bool initialized;
8288
8289 if (initialized) {
8290 return;
8291 }
8292 initialized = true;
8293
8294 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
8295 tcg_ctx.tcg_env = cpu_env;
8296 cpu_cc_op = tcg_global_mem_new_i32(cpu_env,
8297 offsetof(CPUX86State, cc_op), "cc_op");
8298 cpu_cc_dst = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_dst),
8299 "cc_dst");
8300 cpu_cc_src = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src),
8301 "cc_src");
8302 cpu_cc_src2 = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src2),
8303 "cc_src2");
8304
8305 for (i = 0; i < CPU_NB_REGS; ++i) {
8306 cpu_regs[i] = tcg_global_mem_new(cpu_env,
8307 offsetof(CPUX86State, regs[i]),
8308 reg_names[i]);
8309 }
8310
8311 for (i = 0; i < 6; ++i) {
8312 cpu_seg_base[i]
8313 = tcg_global_mem_new(cpu_env,
8314 offsetof(CPUX86State, segs[i].base),
8315 seg_base_names[i]);
8316 }
8317
8318 for (i = 0; i < 4; ++i) {
8319 cpu_bndl[i]
8320 = tcg_global_mem_new_i64(cpu_env,
8321 offsetof(CPUX86State, bnd_regs[i].lb),
8322 bnd_regl_names[i]);
8323 cpu_bndu[i]
8324 = tcg_global_mem_new_i64(cpu_env,
8325 offsetof(CPUX86State, bnd_regs[i].ub),
8326 bnd_regu_names[i]);
8327 }
8328 }
8329
8330 /* generate intermediate code for basic block 'tb'. */
8331 void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb)
8332 {
8333 X86CPU *cpu = x86_env_get_cpu(env);
8334 CPUState *cs = CPU(cpu);
8335 DisasContext dc1, *dc = &dc1;
8336 target_ulong pc_ptr;
8337 uint32_t flags;
8338 target_ulong pc_start;
8339 target_ulong cs_base;
8340 int num_insns;
8341 int max_insns;
8342
8343 /* generate intermediate code */
8344 pc_start = tb->pc;
8345 cs_base = tb->cs_base;
8346 flags = tb->flags;
8347
8348 dc->pe = (flags >> HF_PE_SHIFT) & 1;
8349 dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
8350 dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
8351 dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
8352 dc->f_st = 0;
8353 dc->vm86 = (flags >> VM_SHIFT) & 1;
8354 dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
8355 dc->iopl = (flags >> IOPL_SHIFT) & 3;
8356 dc->tf = (flags >> TF_SHIFT) & 1;
8357 dc->singlestep_enabled = cs->singlestep_enabled;
8358 dc->cc_op = CC_OP_DYNAMIC;
8359 dc->cc_op_dirty = false;
8360 dc->cs_base = cs_base;
8361 dc->tb = tb;
8362 dc->popl_esp_hack = 0;
8363 /* select memory access functions */
8364 dc->mem_index = 0;
8365 #ifdef CONFIG_SOFTMMU
8366 dc->mem_index = cpu_mmu_index(env, false);
8367 #endif
8368 dc->cpuid_features = env->features[FEAT_1_EDX];
8369 dc->cpuid_ext_features = env->features[FEAT_1_ECX];
8370 dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX];
8371 dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX];
8372 dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX];
8373 dc->cpuid_xsave_features = env->features[FEAT_XSAVE];
8374 #ifdef TARGET_X86_64
8375 dc->lma = (flags >> HF_LMA_SHIFT) & 1;
8376 dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
8377 #endif
8378 dc->flags = flags;
8379 dc->jmp_opt = !(dc->tf || cs->singlestep_enabled ||
8380 (flags & HF_INHIBIT_IRQ_MASK));
8381 /* Do not optimize repz jumps at all in icount mode, because
8382 rep movsS instructions are execured with different paths
8383 in !repz_opt and repz_opt modes. The first one was used
8384 always except single step mode. And this setting
8385 disables jumps optimization and control paths become
8386 equivalent in run and single step modes.
8387 Now there will be no jump optimization for repz in
8388 record/replay modes and there will always be an
8389 additional step for ecx=0 when icount is enabled.
8390 */
8391 dc->repz_opt = !dc->jmp_opt && !(tb->cflags & CF_USE_ICOUNT);
8392 #if 0
8393 /* check addseg logic */
8394 if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
8395 printf("ERROR addseg\n");
8396 #endif
8397
8398 cpu_T0 = tcg_temp_new();
8399 cpu_T1 = tcg_temp_new();
8400 cpu_A0 = tcg_temp_new();
8401
8402 cpu_tmp0 = tcg_temp_new();
8403 cpu_tmp1_i64 = tcg_temp_new_i64();
8404 cpu_tmp2_i32 = tcg_temp_new_i32();
8405 cpu_tmp3_i32 = tcg_temp_new_i32();
8406 cpu_tmp4 = tcg_temp_new();
8407 cpu_ptr0 = tcg_temp_new_ptr();
8408 cpu_ptr1 = tcg_temp_new_ptr();
8409 cpu_cc_srcT = tcg_temp_local_new();
8410
8411 dc->is_jmp = DISAS_NEXT;
8412 pc_ptr = pc_start;
8413 num_insns = 0;
8414 max_insns = tb->cflags & CF_COUNT_MASK;
8415 if (max_insns == 0) {
8416 max_insns = CF_COUNT_MASK;
8417 }
8418 if (max_insns > TCG_MAX_INSNS) {
8419 max_insns = TCG_MAX_INSNS;
8420 }
8421
8422 gen_tb_start(tb);
8423 for(;;) {
8424 tcg_gen_insn_start(pc_ptr, dc->cc_op);
8425 num_insns++;
8426
8427 /* If RF is set, suppress an internally generated breakpoint. */
8428 if (unlikely(cpu_breakpoint_test(cs, pc_ptr,
8429 tb->flags & HF_RF_MASK
8430 ? BP_GDB : BP_ANY))) {
8431 gen_debug(dc, pc_ptr - dc->cs_base);
8432 /* The address covered by the breakpoint must be included in
8433 [tb->pc, tb->pc + tb->size) in order to for it to be
8434 properly cleared -- thus we increment the PC here so that
8435 the logic setting tb->size below does the right thing. */
8436 pc_ptr += 1;
8437 goto done_generating;
8438 }
8439 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
8440 gen_io_start();
8441 }
8442
8443 pc_ptr = disas_insn(env, dc, pc_ptr);
8444 /* stop translation if indicated */
8445 if (dc->is_jmp)
8446 break;
8447 /* if single step mode, we generate only one instruction and
8448 generate an exception */
8449 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
8450 the flag and abort the translation to give the irqs a
8451 change to be happen */
8452 if (dc->tf || dc->singlestep_enabled ||
8453 (flags & HF_INHIBIT_IRQ_MASK)) {
8454 gen_jmp_im(pc_ptr - dc->cs_base);
8455 gen_eob(dc);
8456 break;
8457 }
8458 /* Do not cross the boundary of the pages in icount mode,
8459 it can cause an exception. Do it only when boundary is
8460 crossed by the first instruction in the block.
8461 If current instruction already crossed the bound - it's ok,
8462 because an exception hasn't stopped this code.
8463 */
8464 if ((tb->cflags & CF_USE_ICOUNT)
8465 && ((pc_ptr & TARGET_PAGE_MASK)
8466 != ((pc_ptr + TARGET_MAX_INSN_SIZE - 1) & TARGET_PAGE_MASK)
8467 || (pc_ptr & ~TARGET_PAGE_MASK) == 0)) {
8468 gen_jmp_im(pc_ptr - dc->cs_base);
8469 gen_eob(dc);
8470 break;
8471 }
8472 /* if too long translation, stop generation too */
8473 if (tcg_op_buf_full() ||
8474 (pc_ptr - pc_start) >= (TARGET_PAGE_SIZE - 32) ||
8475 num_insns >= max_insns) {
8476 gen_jmp_im(pc_ptr - dc->cs_base);
8477 gen_eob(dc);
8478 break;
8479 }
8480 if (singlestep) {
8481 gen_jmp_im(pc_ptr - dc->cs_base);
8482 gen_eob(dc);
8483 break;
8484 }
8485 }
8486 if (tb->cflags & CF_LAST_IO)
8487 gen_io_end();
8488 done_generating:
8489 gen_tb_end(tb, num_insns);
8490
8491 #ifdef DEBUG_DISAS
8492 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
8493 && qemu_log_in_addr_range(pc_start)) {
8494 int disas_flags;
8495 qemu_log_lock();
8496 qemu_log("----------------\n");
8497 qemu_log("IN: %s\n", lookup_symbol(pc_start));
8498 #ifdef TARGET_X86_64
8499 if (dc->code64)
8500 disas_flags = 2;
8501 else
8502 #endif
8503 disas_flags = !dc->code32;
8504 log_target_disas(cs, pc_start, pc_ptr - pc_start, disas_flags);
8505 qemu_log("\n");
8506 qemu_log_unlock();
8507 }
8508 #endif
8509
8510 tb->size = pc_ptr - pc_start;
8511 tb->icount = num_insns;
8512 }
8513
8514 void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb,
8515 target_ulong *data)
8516 {
8517 int cc_op = data[1];
8518 env->eip = data[0] - tb->cs_base;
8519 if (cc_op != CC_OP_DYNAMIC) {
8520 env->cc_op = cc_op;
8521 }
8522 }