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