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