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