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