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