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