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