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