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