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