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