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