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