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