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