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