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