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